2018-09-12 01:29:49 +02:00
|
|
|
package com.minelittlepony.unicopia.player;
|
|
|
|
|
2019-02-03 10:45:45 +01:00
|
|
|
import javax.annotation.Nonnull;
|
2019-02-02 17:50:15 +01:00
|
|
|
import javax.annotation.Nullable;
|
|
|
|
|
2018-09-12 01:29:49 +02:00
|
|
|
import com.minelittlepony.jumpingcastle.api.Target;
|
|
|
|
import com.minelittlepony.unicopia.Unicopia;
|
|
|
|
import com.minelittlepony.unicopia.network.MsgPlayerAbility;
|
|
|
|
import com.minelittlepony.unicopia.power.IData;
|
|
|
|
import com.minelittlepony.unicopia.power.IPower;
|
|
|
|
import com.minelittlepony.unicopia.power.PowersRegistry;
|
2019-01-22 17:39:30 +01:00
|
|
|
import com.minelittlepony.unicopia.util.serialisation.InbtSerialisable;
|
2018-09-12 01:29:49 +02:00
|
|
|
|
|
|
|
import net.minecraft.entity.player.EntityPlayer;
|
|
|
|
import net.minecraft.nbt.NBTTagCompound;
|
|
|
|
|
2018-09-16 00:45:44 +02:00
|
|
|
class PlayerAbilityDelegate implements IAbilityReceiver, IUpdatable<EntityPlayer>, InbtSerialisable {
|
2018-09-12 01:29:49 +02:00
|
|
|
|
|
|
|
private final IPlayer player;
|
|
|
|
|
2019-02-03 10:45:45 +01:00
|
|
|
/**
|
|
|
|
* Ticks of warmup before an ability is triggered.
|
|
|
|
*/
|
|
|
|
private int warmup;
|
2018-09-12 01:29:49 +02:00
|
|
|
|
2019-02-03 10:45:45 +01:00
|
|
|
/**
|
|
|
|
* Ticks of cooldown after an ability has been triggered.
|
|
|
|
*/
|
|
|
|
private int cooldown;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* True once the current ability has been triggered.
|
|
|
|
*/
|
|
|
|
private boolean triggered;
|
2018-09-12 01:29:49 +02:00
|
|
|
|
2019-02-02 17:50:15 +01:00
|
|
|
@Nullable
|
2018-09-12 01:29:49 +02:00
|
|
|
private IPower<?> activeAbility = null;
|
|
|
|
|
|
|
|
public PlayerAbilityDelegate(IPlayer player) {
|
|
|
|
this.player = player;
|
|
|
|
}
|
|
|
|
|
2019-02-03 10:45:45 +01:00
|
|
|
/**
|
|
|
|
* Returns true if the currrent ability can we swapped out.
|
|
|
|
*/
|
2018-09-12 01:29:49 +02:00
|
|
|
boolean canSwitchStates() {
|
2019-02-03 10:45:45 +01:00
|
|
|
return activeAbility == null || (warmup != 0) || (triggered && cooldown == 0);
|
2018-09-12 01:29:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2019-02-03 10:45:45 +01:00
|
|
|
public void tryUseAbility(IPower<?> power) {
|
|
|
|
if (canSwitchStates()) {
|
|
|
|
setAbility(power);
|
2018-09-12 01:29:49 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2019-02-03 10:45:45 +01:00
|
|
|
public void tryClearAbility() {
|
2019-02-02 17:50:15 +01:00
|
|
|
if (canSwitchStates()) {
|
2019-02-03 10:45:45 +01:00
|
|
|
setAbility(null);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected synchronized void setAbility(@Nullable IPower<?> power) {
|
|
|
|
if (activeAbility != power) {
|
2019-02-03 16:43:37 +01:00
|
|
|
triggered = false;
|
2019-02-03 10:45:45 +01:00
|
|
|
activeAbility = power;
|
|
|
|
warmup = power == null ? 0 : power.getWarmupTime(player);
|
2018-09-12 01:29:49 +02:00
|
|
|
cooldown = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-03 10:45:45 +01:00
|
|
|
@Nullable
|
|
|
|
protected synchronized IPower<?> getUsableAbility() {
|
|
|
|
if (!(activeAbility == null || (triggered && warmup == 0 && cooldown == 0)) && activeAbility.canUse(player.getPlayerSpecies())) {
|
|
|
|
return activeAbility;
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2018-09-12 01:29:49 +02:00
|
|
|
@Override
|
|
|
|
public int getRemainingCooldown() {
|
|
|
|
return cooldown;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2019-02-03 10:45:45 +01:00
|
|
|
public void onUpdate(EntityPlayer entity) {
|
|
|
|
IPower<?> ability = getUsableAbility();
|
|
|
|
|
|
|
|
if (ability == null) {
|
|
|
|
return;
|
|
|
|
}
|
2019-02-02 17:50:15 +01:00
|
|
|
|
2019-02-03 10:45:45 +01:00
|
|
|
if (warmup > 0) {
|
|
|
|
warmup--;
|
|
|
|
ability.preApply(player);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (cooldown > 0) {
|
|
|
|
cooldown--;
|
|
|
|
ability.postApply(player);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (triggered) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ability.canActivate(player.getWorld(), player)) {
|
|
|
|
triggered = true;
|
|
|
|
cooldown = ability.getCooldownTime(player);
|
|
|
|
|
|
|
|
if (player.isClientPlayer()) {
|
|
|
|
activateAbility(ability);
|
2018-09-12 01:29:49 +02:00
|
|
|
}
|
|
|
|
}
|
2019-02-03 10:45:45 +01:00
|
|
|
|
|
|
|
if (cooldown <= 0) {
|
|
|
|
setAbility(null);
|
|
|
|
}
|
2018-09-12 01:29:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void writeToNBT(NBTTagCompound compound) {
|
2019-02-03 10:45:45 +01:00
|
|
|
compound.setBoolean("triggered", triggered);
|
2018-09-12 01:29:49 +02:00
|
|
|
compound.setInteger("warmup", warmup);
|
|
|
|
compound.setInteger("cooldown", cooldown);
|
|
|
|
|
2019-02-03 10:45:45 +01:00
|
|
|
IPower<?> ability = getUsableAbility();
|
|
|
|
|
|
|
|
if (ability != null) {
|
|
|
|
compound.setString("activeAbility", ability.getKeyName());
|
2018-09-12 01:29:49 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void readFromNBT(NBTTagCompound compound) {
|
2019-02-03 10:45:45 +01:00
|
|
|
activeAbility = null;
|
|
|
|
|
|
|
|
triggered = compound.getBoolean("triggered");
|
2018-09-12 01:29:49 +02:00
|
|
|
warmup = compound.getInteger("warmup");
|
|
|
|
cooldown = compound.getInteger("cooldown");
|
|
|
|
|
|
|
|
if (compound.hasKey("activeAbility")) {
|
2019-02-03 10:45:45 +01:00
|
|
|
PowersRegistry.instance()
|
|
|
|
.getPowerFromName(compound.getString("activeAbility"))
|
|
|
|
.ifPresent(p -> activeAbility = p);
|
2018-09-12 01:29:49 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-03 10:45:45 +01:00
|
|
|
/**
|
|
|
|
* Attempts to activate the current stored ability.
|
|
|
|
* Returns true if the ability suceeded, otherwise false.
|
|
|
|
*/
|
|
|
|
protected boolean activateAbility(@Nonnull IPower<?> ability) {
|
|
|
|
IData data = ability.tryActivate(player);
|
2018-09-12 01:29:49 +02:00
|
|
|
|
|
|
|
if (data != null) {
|
2019-02-03 10:45:45 +01:00
|
|
|
Unicopia.channel.send(new MsgPlayerAbility(player.getOwner(), ability, data), Target.SERVER);
|
2018-09-12 01:29:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return data != null;
|
|
|
|
}
|
|
|
|
}
|