diff --git a/src/main/java/pokecube/api/entity/pokemob/moves/PokemobMoveStats.java b/src/main/java/pokecube/api/entity/pokemob/moves/PokemobMoveStats.java index 2ba813607a..67a0d7f690 100644 --- a/src/main/java/pokecube/api/entity/pokemob/moves/PokemobMoveStats.java +++ b/src/main/java/pokecube/api/entity/pokemob/moves/PokemobMoveStats.java @@ -1,170 +1,173 @@ -package pokecube.api.entity.pokemob.moves; - -import java.lang.reflect.Field; -import java.util.List; -import java.util.Set; - -import com.google.common.collect.Lists; -import com.google.common.collect.Sets; - -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.LivingEntity; -import pokecube.api.data.abilities.Ability; -import pokecube.api.entity.pokemob.IPokemob; -import pokecube.api.moves.MoveEntry; -import pokecube.api.moves.utils.IMoveConstants; -import pokecube.api.moves.utils.MoveApplication; -import pokecube.core.network.pokemobs.PacketSyncNewMoves; - -public class PokemobMoveStats -{ - - private static final PokemobMoveStats defaults = new PokemobMoveStats(); - private static final Set IGNORE = Sets.newHashSet(); - static - { - PokemobMoveStats.IGNORE.add("moves"); - PokemobMoveStats.IGNORE.add("g_z_moves"); - PokemobMoveStats.IGNORE.add("newMoves"); - PokemobMoveStats.IGNORE.add("num"); - PokemobMoveStats.IGNORE.add("exp"); - } - - public Entity infatuateTarget; - - // Timers used for various move types. - public int TOXIC_COUNTER = 0; - public int ROLLOUTCOUNTER = 0; - public int FURYCUTTERCOUNTER = 0; - public int DEFENSECURLCOUNTER = 0; - - public boolean Exploding = false; - public int boomState = -1; - - public int SPECIALCOUNTER = 0; - /** Used for cooldown of crit chance moves */ - public int SPECIALTYPE = 0; - - /** Used for moves such as bide/counter/mirror coat */ - public int PHYSICALDAMAGETAKENCOUNTER = 0; - public int SPECIALDAMAGETAKENCOUNTER = 0; - - /** Number of times detect, protect or similar has worked. */ - public int BLOCKCOUNTER = 0; - public int blockTimer = 0; - public boolean blocked = false; - - public boolean biding = false; - - public float substituteHP = 0; - - public int changes = IMoveConstants.CHANGE_NONE; - - /** - * Time when this creeper was last in an active state (Messed up code here, - * probably causes creeper animation to go weird) - */ - public int lastActiveTime; - - /** - * The amount of time since the creeper was close enough to the player to - * ignite - */ - public int timeSinceIgnited; - public int fuseTime = 30; - - /** The Previous lvl, used to determine which moves to try to learn. */ - public int oldLevel = 0; - - /** The array of moves. */ - public String[] moves = new String[4]; - /** The array of moves. */ - public String[] g_z_moves = new String[4]; - /** Moves it is trying to learn. */ - public List newMoves = Lists.newArrayList(); - /** Index of new move to learn from newMoves. */ - public int num = 0; - /** The last move we used. */ - public String lastMove; - /** Storing exp in here as well. */ - public int exp = 0; - /** Cache of currently selected move */ - public MoveEntry selectedMove; - /** The moves we are currently using */ - public List movesInProgress = Lists.newArrayList(); - public boolean targettingSelf = false; - /** - * This is the ability to apply in battle, out of battle it will be reset to - * whatever the mob's normal ability was. - */ - public Ability battleAbility = null; - - // Index in battle of targetted ally, owner is always last in the battle, - // even if not in battle - public int allyIndex = 0; - // Index in battle of targetted enemy. - public int enemyIndex = 0; - - public LivingEntity targetEnemy = null; - public LivingEntity targetAlly = null; - - public void reset() - { - for (final Field f : this.getClass().getFields()) try - { - if (!PokemobMoveStats.IGNORE.contains(f.getName())) f.set(this, f.get(PokemobMoveStats.defaults)); - } - catch (final Exception e) - { - e.printStackTrace(); - } - } - - public void checkMovesInProgress(IPokemob user) - { - targettingSelf = false; - movesInProgress.removeIf(s -> s.isFinished()); - for (var move : movesInProgress) - { - if (move.getTarget() == user.getEntity()) - { - targettingSelf = true; - break; - } - } - } - - public void addMoveInProgress(IPokemob user, MoveApplication application) - { - this.targettingSelf |= application.getTarget() == user.getEntity(); - this.movesInProgress.add(application); - } - - public boolean addPendingMove(String move, IPokemob notify) - { - if (move == null) return false; - if (newMoves.contains(move)) return false; - newMoves.add(move); - newMoves.sort(null); - if (notify != null) PacketSyncNewMoves.sendUpdatePacket(notify); - return true; - } - - public void removePendingMove(String move) - { - this.newMoves.remove(move); - } - - public boolean hasLearningMove() - { - return !this.newMoves.isEmpty(); - } - - public String getLearningMove() - { - if (this.newMoves.isEmpty()) return null; - if (this.num < 0) this.num = this.newMoves.size() - 1; - this.num = this.num % this.newMoves.size(); - return newMoves.get(this.num); - } -} +package pokecube.api.entity.pokemob.moves; + +import java.lang.reflect.Field; +import java.util.List; +import java.util.Set; + +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; + +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.LivingEntity; +import pokecube.api.data.abilities.Ability; +import pokecube.api.entity.pokemob.IPokemob; +import pokecube.api.moves.MoveEntry; +import pokecube.api.moves.utils.IMoveConstants; +import pokecube.api.moves.utils.MoveApplication; +import pokecube.core.network.pokemobs.PacketSyncNewMoves; + +public class PokemobMoveStats +{ + + private static final PokemobMoveStats defaults = new PokemobMoveStats(); + private static final Set IGNORE = Sets.newHashSet(); + static + { + PokemobMoveStats.IGNORE.add("moves"); + PokemobMoveStats.IGNORE.add("g_z_moves"); + PokemobMoveStats.IGNORE.add("newMoves"); + PokemobMoveStats.IGNORE.add("num"); + PokemobMoveStats.IGNORE.add("exp"); + } + + public Entity infatuateTarget; + + // Timers used for various move types. + public int TOXIC_COUNTER = 0; + public int ROLLOUTCOUNTER = 0; + public int FURYCUTTERCOUNTER = 0; + public int DEFENSECURLCOUNTER = 0; + + public boolean Exploding = false; + public int boomState = -1; + + public int SPECIALCOUNTER = 0; + /** Used for cooldown of crit chance moves */ + public int SPECIALTYPE = 0; + + /** Used for moves such as bide/counter/mirror coat */ + public int PHYSICALDAMAGETAKENCOUNTER = 0; + public int SPECIALDAMAGETAKENCOUNTER = 0; + + /** Number of times detect, protect or similar has worked. */ + public int BLOCKCOUNTER = 0; + public int blockTimer = 0; + public boolean blocked = false; + + public boolean biding = false; + + public float substituteHP = 0; + + public int changes = IMoveConstants.CHANGE_NONE; + + /** + * Time when this creeper was last in an active state (Messed up code here, + * probably causes creeper animation to go weird) + */ + public int lastActiveTime; + + /** + * The amount of time since the creeper was close enough to the player to + * ignite + */ + public int timeSinceIgnited; + public int fuseTime = 30; + + /** The Previous lvl, used to determine which moves to try to learn. */ + public int oldLevel = 0; + + /** The array of moves. */ + public String[] moves = new String[4]; + /** The array of moves. */ + public String[] g_z_moves = new String[4]; + /** Moves it is trying to learn. */ + public List newMoves = Lists.newArrayList(); + /** Index of new move to learn from newMoves. */ + public int num = 0; + /** The last move we used. */ + public String lastMove; + /** Storing exp in here as well. */ + public int exp = 0; + /** Cache of currently selected move */ + public MoveEntry selectedMove; + /** The moves we are currently using */ + public List movesInProgress = Lists.newArrayList(); + public boolean targettingSelf = false; + /** + * This is the ability to apply in battle, out of battle it will be reset to + * whatever the mob's normal ability was. + */ + public Ability battleAbility = null; + + // Index in battle of targetted ally, owner is always last in the battle, + // even if not in battle + public int allyIndex = 0; + // Index in battle of targetted enemy. + public int enemyIndex = 0; + + public LivingEntity targetEnemy = null; + public LivingEntity targetAlly = null; + + // Moves for the transformed mob + public String[] transformedMoves = moves; + + public void reset() + { + for (final Field f : this.getClass().getFields()) try + { + if (!PokemobMoveStats.IGNORE.contains(f.getName())) f.set(this, f.get(PokemobMoveStats.defaults)); + } + catch (final Exception e) + { + e.printStackTrace(); + } + } + + public void checkMovesInProgress(IPokemob user) + { + targettingSelf = false; + movesInProgress.removeIf(s -> s.isFinished()); + for (var move : movesInProgress) + { + if (move.getTarget() == user.getEntity()) + { + targettingSelf = true; + break; + } + } + } + + public void addMoveInProgress(IPokemob user, MoveApplication application) + { + this.targettingSelf |= application.getTarget() == user.getEntity(); + this.movesInProgress.add(application); + } + + public boolean addPendingMove(String move, IPokemob notify) + { + if (move == null) return false; + if (newMoves.contains(move)) return false; + newMoves.add(move); + newMoves.sort(null); + if (notify != null) PacketSyncNewMoves.sendUpdatePacket(notify); + return true; + } + + public void removePendingMove(String move) + { + this.newMoves.remove(move); + } + + public boolean hasLearningMove() + { + return !this.newMoves.isEmpty(); + } + + public String getLearningMove() + { + if (this.newMoves.isEmpty()) return null; + if (this.num < 0) this.num = this.newMoves.size() - 1; + this.num = this.num % this.newMoves.size(); + return newMoves.get(this.num); + } +} diff --git a/src/main/java/pokecube/core/ai/logic/LogicMovesUpdates.java b/src/main/java/pokecube/core/ai/logic/LogicMovesUpdates.java index 9b2d45c254..19d7e6ca5c 100644 --- a/src/main/java/pokecube/core/ai/logic/LogicMovesUpdates.java +++ b/src/main/java/pokecube/core/ai/logic/LogicMovesUpdates.java @@ -8,12 +8,14 @@ import net.minecraft.world.InteractionResultHolder; import net.minecraft.world.effect.MobEffectInstance; import net.minecraft.world.effect.MobEffects; +import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; import pokecube.api.PokecubeAPI; import pokecube.api.entity.CapabilityAffected; import pokecube.api.entity.IOngoingAffected; import pokecube.api.entity.pokemob.IPokemob; +import pokecube.api.entity.pokemob.PokemobCaps; import pokecube.api.entity.pokemob.ai.GeneralStates; import pokecube.api.entity.pokemob.ai.LogicStates; import pokecube.api.items.IPokemobUseable; @@ -74,6 +76,10 @@ public void tick(final Level world) super.tick(world); this.v.set(this.entity); + // Set this first, to ensure it is cleaned up properly, it will be reset + // later down if needed. + this.pokemob.getMoveStats().transformedMoves = this.pokemob.getMoveStats().moves; + // Run tasks that only should go on server side. if (!world.isClientSide) { @@ -106,10 +112,39 @@ public void tick(final Level world) this.pokemob.learn(move); } + // Server side if transformed checks + + LivingEntity transformed = this.pokemob.getTransformedTo(); + // Revert transform if not in battle or breeding. - if (this.pokemob.getTransformedTo() != null && !this.pokemob.getGeneralState(GeneralStates.MATING) - && Battle.getBattle(entity) == null) - this.pokemob.setTransformedTo(null); + if (transformed != null) + { + // If we are not mating, and we are not in battle, transform + // back. + if (!(this.pokemob.getGeneralState(GeneralStates.MATING) || Battle.getBattle(entity) != null)) + { + this.pokemob.setTransformedTo(null); + } + // Otherwise set the move stats to the correct moves. + else + { + IPokemob toMob = PokemobCaps.getPokemobFor(transformed); + // This side has the appropriate caps for keeping the moves + // lists, so we sync this over. + if (toMob != null) this.pokemob.getMoveStats().transformedMoves = toMob.getMoves(); + } + } + } + // client side only checks + else + { + + LivingEntity transformed = this.pokemob.getTransformedTo(); + IPokemob toMob = PokemobCaps.getPokemobFor(transformed); + // This side has the appropriate caps for keeping the moves + // lists, so we sync this over. + if (toMob != null) this.pokemob.getMoveStats().transformedMoves = toMob.getMoves(); + } // Run tasks that can be on server or client. diff --git a/src/main/java/pokecube/core/impl/capabilities/impl/PokemobMoves.java b/src/main/java/pokecube/core/impl/capabilities/impl/PokemobMoves.java index 34a946e7c1..060ca92882 100644 --- a/src/main/java/pokecube/core/impl/capabilities/impl/PokemobMoves.java +++ b/src/main/java/pokecube/core/impl/capabilities/impl/PokemobMoves.java @@ -166,11 +166,7 @@ public int getMoveIndex() public String[] getMoves() { final IPokemob transformed = PokemobCaps.getPokemobFor(this.getTransformedTo()); - if (transformed != null && transformed.getTransformedTo() == null) - { - final IPokemob to = transformed; - if (to != this) return to.getMoves(); - } + if (transformed != null) return this.getMoveStats().transformedMoves; return super.getMoves(); } @@ -535,13 +531,11 @@ public void setTransformedTo(LivingEntity to) if (!this.getEntity().level.isClientSide()) { final CompoundTag tag = new CompoundTag(); - if (to != null) to.addAdditionalSaveData(tag); + if (to != null) to.saveWithoutId(tag); this.setCopiedNBT(tag); } final LivingEntity old = this.getCopiedMob(); - this.setCopiedID(id == -1 ? null : RegHelper.getKey(to)); - this.getCopy().onBaseTick(this.getEntity().level, this.getEntity()); if (to != old && !this.getEntity().level.isClientSide()) CapabilitySync.sendUpdate(this.getEntity(), PokemobMoves.TO_SYNC);