package com.disklexar.mmorpg.combat; import com.disklexar.mmorpg.MmorpgPlugin; import com.disklexar.mmorpg.core.service.Service; import com.disklexar.mmorpg.player.OnlinePlayer; import com.disklexar.mmorpg.player.OnlinePlayerRegistry; import com.disklexar.mmorpg.player.PlayerSessionService; import com.disklexar.mmorpg.player.model.PlayerProfile; import com.disklexar.mmorpg.rpg.power.PowerCatalog; import com.hypixel.hytale.component.Ref; import com.hypixel.hytale.component.Store; import com.hypixel.hytale.protocol.MovementSettings; import com.hypixel.hytale.server.core.entity.entities.player.movement.MovementManager; import com.hypixel.hytale.server.core.universe.world.storage.EntityStore; import javax.annotation.Nonnull; import java.util.concurrent.ScheduledFuture; /** * Reconciles passive movement effects every couple of seconds. *
* The "Sprinter" power grants {@code +10%} base movement speed while the player is out of combat;
* the bonus is removed while in combat and restored afterwards.
*/
public final class PassiveEffectService implements Service {
private static final long RECONCILE_PERIOD = 2_000L;
private final MmorpgScheduler scheduler;
private final OnlinePlayerRegistry online;
private final PlayerSessionService sessions;
private final CombatStateService combatState;
private ScheduledFuture> task;
public PassiveEffectService(
@Nonnull MmorpgPlugin plugin,
@Nonnull MmorpgScheduler scheduler,
@Nonnull OnlinePlayerRegistry online,
@Nonnull PlayerSessionService sessions,
@Nonnull CombatStateService combatState) {
this.scheduler = scheduler;
this.online = online;
this.sessions = sessions;
this.combatState = combatState;
}
@Override
public void start() {
task = scheduler.runRepeating(this::reconcileAll, RECONCILE_PERIOD, RECONCILE_PERIOD);
}
@Override
public void shutdown() {
if (task != null) {
task.cancel(false);
task = null;
}
}
private void reconcileAll() {
for (OnlinePlayer player : online.all()) {
PlayerProfile profile = sessions.getSession(player.uuid());
if (profile == null) {
continue;
}
boolean sprinter = profile.getPowers().contains(PowerCatalog.SPRINTER.id());
boolean active = sprinter && !combatState.isInCombat(player.uuid());
player.world().execute(() -> applySpeed(player, active));
}
}
private void applySpeed(@Nonnull OnlinePlayer player, boolean buffed) {
Store