diff --git a/Changelog.md b/Changelog.md index 0ed4af2..f9a7265 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,14 @@ # Upcoming changes +# Version 1.14 + +Implemented support for Creepers in battle. + +Added an option to the config to prevent config from being overwritten on +update. + +Fixed some display text during battle. + # Version 1.13 Disabled midi playback due to currently being unable to change its volume. diff --git a/build.gradle b/build.gradle index 5d0e45c..353be68 100644 --- a/build.gradle +++ b/build.gradle @@ -14,7 +14,7 @@ apply plugin: 'eclipse' //apply plugin: 'maven-publish' apply plugin: 'com.github.johnrengelman.shadow' -version = "1.13" +version = "1.14" group = "com.burnedkirby.TurnBasedMinecraft" archivesBaseName = "TurnBasedMinecraft" diff --git a/src/main/java/com/burnedkirby/TurnBasedMinecraft/client/ClientProxy.java b/src/main/java/com/burnedkirby/TurnBasedMinecraft/client/ClientProxy.java index 3a0ea41..1f23b31 100644 --- a/src/main/java/com/burnedkirby/TurnBasedMinecraft/client/ClientProxy.java +++ b/src/main/java/com/burnedkirby/TurnBasedMinecraft/client/ClientProxy.java @@ -160,13 +160,13 @@ public class ClientProxy extends CommonProxy @Override public void displayString(String message) { - ITextComponent prefix = new StringTextComponent("TBM: "); + StringTextComponent prefix = new StringTextComponent("TBM: "); // func_240718_a_ is set color // func_240713_a_ is set bold - prefix.getStyle().func_240718_a_(Color.func_240743_a_(0xFF00FF00)).func_240713_a_(true); - ITextComponent text = new StringTextComponent(message); + prefix.func_230530_a_(prefix.getStyle().func_240718_a_(Color.func_240743_a_(0xFF00FF00)).func_240713_a_(true)); + StringTextComponent text = new StringTextComponent(message); prefix.getSiblings().add(text); - text.getStyle().func_240718_a_(Color.func_240743_a_(0xFFFFFFFF)).func_240713_a_(false); + text.func_230530_a_(text.getStyle().func_240718_a_(Color.func_240743_a_(0xFFFFFFFF)).func_240713_a_(false)); // UUID is required by sendMessage, but appears to be unused, so just give dummy UUID Minecraft.getInstance().player.sendMessage(prefix, UUID.randomUUID()); } diff --git a/src/main/java/com/burnedkirby/TurnBasedMinecraft/common/Battle.java b/src/main/java/com/burnedkirby/TurnBasedMinecraft/common/Battle.java index f48e5ec..28c09b1 100644 --- a/src/main/java/com/burnedkirby/TurnBasedMinecraft/common/Battle.java +++ b/src/main/java/com/burnedkirby/TurnBasedMinecraft/common/Battle.java @@ -10,12 +10,12 @@ import com.burnedkirby.TurnBasedMinecraft.common.networking.PacketBattleMessage; import net.minecraft.entity.Entity; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.MobEntity; +import net.minecraft.entity.monster.CreeperEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.ServerPlayerEntity; import net.minecraft.item.*; import net.minecraft.util.DamageSource; import net.minecraft.util.RegistryKey; -import net.minecraft.world.DimensionType; import net.minecraft.world.World; import net.minecraftforge.fml.network.PacketDistributor; @@ -86,7 +86,9 @@ public class Battle DEFEND(2), FLEE(3), USE_ITEM(4), - SWITCH_ITEM(5); + SWITCH_ITEM(5), + CREEPER_WAIT(6), + CREEPER_EXPLODE(7); private int value; private static Map map = new HashMap(); @@ -815,6 +817,7 @@ public class Battle { enforceFreezePositions(); } + defuseCreepers(); switch(state) { case DECISION: @@ -826,6 +829,14 @@ public class Battle // picking decision for sideA non-players if(!(c.entity instanceof PlayerEntity) && c.decision == Decision.UNDECIDED && c.entityInfo != null) { + if(c.entity instanceof CreeperEntity) { + if(c.creeperTurns++ < 2) { + c.decision = Decision.CREEPER_WAIT; + } else { + c.decision = Decision.CREEPER_EXPLODE; + } + continue; + } int percentage = random.nextInt(100); if(percentage < c.entityInfo.decisionAttack) { @@ -845,6 +856,14 @@ public class Battle { if(!(c.entity instanceof PlayerEntity) && c.decision == Decision.UNDECIDED && c.entityInfo != null) { + if(c.entity instanceof CreeperEntity) { + if(c.creeperTurns++ < 2) { + c.decision = Decision.CREEPER_WAIT; + } else { + c.decision = Decision.CREEPER_EXPLODE; + } + continue; + } int percentage = random.nextInt(100); if(percentage < c.entityInfo.decisionAttack) { @@ -1315,17 +1334,121 @@ public class Battle sendMessageToAllPlayers(PacketBattleMessage.MessageType.USED_ITEM, next.entity.getEntityId(), 0, PacketBattleMessage.UsedItemAction.USED_INVALID.getValue(), targetItemStack.getDisplayName().getString()); } break; - case SWITCH_ITEM: + case SWITCH_ITEM: { debugLog += " switch item"; - if(next.itemToUse < 0 || next.itemToUse > 8) - { + if (next.itemToUse < 0 || next.itemToUse > 8) { sendMessageToAllPlayers(PacketBattleMessage.MessageType.SWITCHED_ITEM, next.entity.getEntityId(), 0, 0); break; } final Entity nextEntity = next.entity; final int nextItemToUse = next.itemToUse; - ((PlayerEntity)nextEntity).inventory.currentItem = nextItemToUse; + ((PlayerEntity) nextEntity).inventory.currentItem = nextItemToUse; sendMessageToAllPlayers(PacketBattleMessage.MessageType.SWITCHED_ITEM, next.entity.getEntityId(), 0, 1); + } + break; + case CREEPER_WAIT: + debugLog += " creeper wait"; + if(next.creeperTurns < 2) { + sendMessageToAllPlayers(PacketBattleMessage.MessageType.CREEPER_WAIT, next.entity.getEntityId(), 0, 0); + } else { + sendMessageToAllPlayers(PacketBattleMessage.MessageType.CREEPER_WAIT_FINAL, next.entity.getEntityId(), 0, 0); + } + break; + case CREEPER_EXPLODE: { + debugLog += " creeper explode"; + sendMessageToAllPlayers(PacketBattleMessage.MessageType.CREEPER_EXPLODE, next.entity.getEntityId(), 0, 0); + final Entity nextEntity = next.entity; + final EntityInfo nextEntityInfo = next.entityInfo; + for (Combatant c : sideA.values()) { + if (c.entity.getEntityId() != next.entity.getEntityId()) { + int hitChance = next.entityInfo.attackProbability; + if (c.entity instanceof PlayerEntity) { + hitChance = hitChance * (100 - TurnBasedMinecraftMod.proxy.getConfig().getPlayerEvasion()) / 100; + } else { + hitChance = hitChance * (100 - c.entityInfo.evasion) / 100; + } + if (hitChance < TurnBasedMinecraftMod.proxy.getConfig().getMinimumHitPercentage()) { + hitChance = TurnBasedMinecraftMod.proxy.getConfig().getMinimumHitPercentage(); + } + if (random.nextInt(100) < hitChance) { + final Entity targetEntity = c.entity; + final EntityInfo targetEntityInfo = c.entityInfo; + int damageAmount = nextEntityInfo.attackPower; + if (nextEntityInfo.attackVariance > 0) { + damageAmount += random.nextInt(nextEntityInfo.attackVariance * 2 + 1) - nextEntityInfo.attackVariance; + } + if (damageAmount < 0) { + damageAmount = 0; + } + final int finalDamageAmount = damageAmount; + final boolean attackEffectTriggered; + if (nextEntityInfo.attackEffect != EntityInfo.Effect.UNKNOWN && nextEntityInfo.attackEffectProbability > 0) { + if (random.nextInt(100) < nextEntityInfo.attackEffectProbability) { + attackEffectTriggered = true; + } else { + attackEffectTriggered = false; + } + } else { + attackEffectTriggered = false; + } + + TurnBasedMinecraftMod.proxy.setAttackingEntity(nextEntity); + targetEntity.attackEntityFrom(DamageSource.causeMobDamage((LivingEntity) nextEntity), finalDamageAmount); + TurnBasedMinecraftMod.proxy.setAttackingEntity(null); + sendMessageToAllPlayers(PacketBattleMessage.MessageType.ATTACK, nextEntity.getEntityId(), targetEntity.getEntityId(), finalDamageAmount); + if(attackEffectTriggered) { + nextEntityInfo.attackEffect.applyEffectToEntity((LivingEntity)targetEntity); + sendMessageToAllPlayers(PacketBattleMessage.MessageType.WAS_AFFECTED, nextEntity.getEntityId(), targetEntity.getEntityId(), 0, nextEntityInfo.attackEffect.getAffectedString()); + } + } + } + } + for(Combatant c : sideB.values()) { + if (c.entity.getEntityId() != next.entity.getEntityId()) { + int hitChance = next.entityInfo.attackProbability; + if (c.entity instanceof PlayerEntity) { + hitChance = hitChance * (100 - TurnBasedMinecraftMod.proxy.getConfig().getPlayerEvasion()) / 100; + } else { + hitChance = hitChance * (100 - c.entityInfo.evasion) / 100; + } + if (hitChance < TurnBasedMinecraftMod.proxy.getConfig().getMinimumHitPercentage()) { + hitChance = TurnBasedMinecraftMod.proxy.getConfig().getMinimumHitPercentage(); + } + if (random.nextInt(100) < hitChance) { + final Entity targetEntity = c.entity; + final EntityInfo targetEntityInfo = c.entityInfo; + int damageAmount = nextEntityInfo.attackPower; + if (nextEntityInfo.attackVariance > 0) { + damageAmount += random.nextInt(nextEntityInfo.attackVariance * 2 + 1) - nextEntityInfo.attackVariance; + } + if (damageAmount < 0) { + damageAmount = 0; + } + final int finalDamageAmount = damageAmount; + final boolean attackEffectTriggered; + if (nextEntityInfo.attackEffect != EntityInfo.Effect.UNKNOWN && nextEntityInfo.attackEffectProbability > 0) { + if (random.nextInt(100) < nextEntityInfo.attackEffectProbability) { + attackEffectTriggered = true; + } else { + attackEffectTriggered = false; + } + } else { + attackEffectTriggered = false; + } + + TurnBasedMinecraftMod.proxy.setAttackingEntity(nextEntity); + targetEntity.attackEntityFrom(DamageSource.causeMobDamage((LivingEntity) nextEntity), finalDamageAmount); + TurnBasedMinecraftMod.proxy.setAttackingEntity(null); + sendMessageToAllPlayers(PacketBattleMessage.MessageType.ATTACK, nextEntity.getEntityId(), targetEntity.getEntityId(), finalDamageAmount); + if(attackEffectTriggered) { + nextEntityInfo.attackEffect.applyEffectToEntity((LivingEntity)targetEntity); + sendMessageToAllPlayers(PacketBattleMessage.MessageType.WAS_AFFECTED, nextEntity.getEntityId(), targetEntity.getEntityId(), 0, nextEntityInfo.attackEffect.getAffectedString()); + } + } + } + } + ((CreeperEntity)nextEntity).setCreeperState(1000000); + } break; } } @@ -1366,4 +1489,25 @@ public class Battle debugLog = "Update end"; return battleEnded; } // update(final long dt) + + private void defuseCreepers() { + for(Combatant c : sideA.values()) { + if(c.entity instanceof CreeperEntity) { + if(c.creeperTurns <= 2) { + ((CreeperEntity)c.entity).setCreeperState(-10); + } else { + ((CreeperEntity)c.entity).setCreeperState(1000000); + } + } + } + for(Combatant c : sideB.values()) { + if(c.entity instanceof CreeperEntity) { + if(c.creeperTurns <= 2) { + ((CreeperEntity)c.entity).setCreeperState(-10); + } else { + ((CreeperEntity) c.entity).setCreeperState(1000000); + } + } + } + } } diff --git a/src/main/java/com/burnedkirby/TurnBasedMinecraft/common/Combatant.java b/src/main/java/com/burnedkirby/TurnBasedMinecraft/common/Combatant.java index 3ca2b10..037fb0c 100644 --- a/src/main/java/com/burnedkirby/TurnBasedMinecraft/common/Combatant.java +++ b/src/main/java/com/burnedkirby/TurnBasedMinecraft/common/Combatant.java @@ -25,12 +25,14 @@ public class Combatant public float yaw; public float pitch; public long time; + public int creeperTurns; public Combatant() { decision = Battle.Decision.UNDECIDED; recalcSpeedOnCompare = false; remainingDefenses = 0; + creeperTurns = 0; } public Combatant(Entity e, EntityInfo entityInfo) @@ -40,6 +42,7 @@ public class Combatant this.entityInfo = entityInfo; recalcSpeedOnCompare = false; remainingDefenses = 0; + creeperTurns = 0; } /** diff --git a/src/main/java/com/burnedkirby/TurnBasedMinecraft/common/Config.java b/src/main/java/com/burnedkirby/TurnBasedMinecraft/common/Config.java index 4ee4cc1..6174521 100644 --- a/src/main/java/com/burnedkirby/TurnBasedMinecraft/common/Config.java +++ b/src/main/java/com/burnedkirby/TurnBasedMinecraft/common/Config.java @@ -95,7 +95,8 @@ public class Config } int configVersion = getConfigFileVersion(configFile); - if(configVersion < this.configVersion) { + boolean canOverwrite = getCanOverwrite(configFile); + if(configVersion < this.configVersion && canOverwrite) { logger.warn("Config file " + TurnBasedMinecraftMod.CONFIG_FILENAME + " is older version, renaming..."); moveOldConfig(); try { @@ -1021,6 +1022,17 @@ public class Config } } + private boolean getCanOverwrite(File configFile) { + boolean canOverwrite; + + FileConfig conf = FileConfig.of(configFile, TomlFormat.instance()); + conf.load(); + canOverwrite = !(Boolean)conf.getOrElse("do_not_overwrite", false); + conf.close(); + + return canOverwrite; + } + public boolean isIgnoreBattleType(String type) { return ignoreBattleTypes.contains(type); diff --git a/src/main/java/com/burnedkirby/TurnBasedMinecraft/common/TurnBasedMinecraftMod.java b/src/main/java/com/burnedkirby/TurnBasedMinecraft/common/TurnBasedMinecraftMod.java index 6ebd561..2f8244d 100644 --- a/src/main/java/com/burnedkirby/TurnBasedMinecraft/common/TurnBasedMinecraftMod.java +++ b/src/main/java/com/burnedkirby/TurnBasedMinecraft/common/TurnBasedMinecraftMod.java @@ -35,7 +35,7 @@ public class TurnBasedMinecraftMod { public static final String MODID = "com_burnedkirby_turnbasedminecraft"; public static final String NAME = "Turn Based Minecraft Mod"; - public static final String VERSION = "1.13"; + public static final String VERSION = "1.14"; public static final String CONFIG_FILENAME = "TBM_Config.toml"; public static final String DEFAULT_CONFIG_FILENAME = "TBM_Config_DEFAULT.toml"; public static final String CONFIG_DIRECTORY = "config/TurnBasedMinecraft/"; @@ -76,7 +76,7 @@ public class TurnBasedMinecraftMod private void firstInit(final FMLCommonSetupEvent event) { - proxy = DistExecutor.runForDist(()->()->new ClientProxy(), ()->()->new CommonProxy()); + proxy = DistExecutor.safeRunForDist(()->()->new ClientProxy(), ()->()->new CommonProxy()); proxy.setLogger(logger); proxy.initialize(); diff --git a/src/main/java/com/burnedkirby/TurnBasedMinecraft/common/networking/PacketBattleMessage.java b/src/main/java/com/burnedkirby/TurnBasedMinecraft/common/networking/PacketBattleMessage.java index 8625cd1..30009bb 100644 --- a/src/main/java/com/burnedkirby/TurnBasedMinecraft/common/networking/PacketBattleMessage.java +++ b/src/main/java/com/burnedkirby/TurnBasedMinecraft/common/networking/PacketBattleMessage.java @@ -10,8 +10,8 @@ import com.burnedkirby.TurnBasedMinecraft.common.Utility; import net.minecraft.entity.Entity; import net.minecraft.network.PacketBuffer; import net.minecraft.util.RegistryKey; -import net.minecraft.util.ResourceLocation; -import net.minecraft.world.DimensionType; +import net.minecraft.util.text.Color; +import net.minecraft.util.text.StringTextComponent; import net.minecraft.world.World; import net.minecraftforge.fml.network.NetworkEvent; @@ -37,7 +37,10 @@ public class PacketBattleMessage BECAME_CREATIVE(15), FIRED_ARROW(16), ARROW_HIT(17), - BOW_NO_AMMO(18); + BOW_NO_AMMO(18), + CREEPER_WAIT(19), + CREEPER_WAIT_FINAL(20), + CREEPER_EXPLODE(21); private int value; private static Map map = new HashMap(); @@ -296,6 +299,33 @@ public class PacketBattleMessage case BOW_NO_AMMO: TurnBasedMinecraftMod.proxy.displayString(from + " tried to use their bow but ran out of ammo!"); break; + case CREEPER_WAIT: { + StringTextComponent prefix = new StringTextComponent("TBM: "); + prefix.func_230530_a_(prefix.getStyle().func_240718_a_(Color.func_240743_a_(0xFF00FF00)).func_240713_a_(true)); + StringTextComponent message = new StringTextComponent(from + " is charging up!"); + message.func_230530_a_(message.getStyle().func_240718_a_(Color.func_240743_a_(0xFFFFFF00))); + prefix.getSiblings().add(message); + TurnBasedMinecraftMod.proxy.displayTextComponent(prefix); + } + break; + case CREEPER_WAIT_FINAL: { + StringTextComponent prefix = new StringTextComponent("TBM: "); + prefix.func_230530_a_(prefix.getStyle().func_240718_a_(Color.func_240743_a_(0xFF00FF00)).func_240713_a_(true)); + StringTextComponent message = new StringTextComponent(from + " is about to explode!"); + message.func_230530_a_(message.getStyle().func_240718_a_(Color.func_240743_a_(0xFFFF5050))); + prefix.getSiblings().add(message); + TurnBasedMinecraftMod.proxy.displayTextComponent(prefix); + } + break; + case CREEPER_EXPLODE: { + StringTextComponent prefix = new StringTextComponent("TBM: "); + prefix.func_230530_a_(prefix.getStyle().func_240718_a_(Color.func_240743_a_(0xFF00FF00)).func_240713_a_(true)); + StringTextComponent message = new StringTextComponent(from + " exploded!"); + message.func_230530_a_(message.getStyle().func_240718_a_(Color.func_240743_a_(0xFFFF0000))); + prefix.getSiblings().add(message); + TurnBasedMinecraftMod.proxy.displayTextComponent(prefix); + } + break; } }); ctx.get().setPacketHandled(true); diff --git a/src/main/resources/META-INF/mods.toml b/src/main/resources/META-INF/mods.toml index 6b0af67..4ed5397 100644 --- a/src/main/resources/META-INF/mods.toml +++ b/src/main/resources/META-INF/mods.toml @@ -15,7 +15,7 @@ license="MIT" # The modid of the mod modId="com_burnedkirby_turnbasedminecraft" #mandatory # The version number of the mod - there's a few well known ${} variables useable here or just hardcode it -version="1.13" #mandatory +version="1.14" #mandatory # A display name for the mod displayName="TurnBasedMinecraftMod" #mandatory # A URL to query for updates for this mod. See the JSON update specification diff --git a/src/main/resources/assets/com_burnedkirby_turnbasedminecraft/TBM_Config.toml b/src/main/resources/assets/com_burnedkirby_turnbasedminecraft/TBM_Config.toml index fdcf602..919b01c 100644 --- a/src/main/resources/assets/com_burnedkirby_turnbasedminecraft/TBM_Config.toml +++ b/src/main/resources/assets/com_burnedkirby_turnbasedminecraft/TBM_Config.toml @@ -1,6 +1,7 @@ # Please do not change this option, the mod uses this to keep track of what new # changes to add to the config. -version = 3 +version = 4 +do_not_overwrite = false [client_config] @@ -115,9 +116,9 @@ decision_flee_probability = 0 [[server_config.entity]] name = "net.minecraft.entity.monster.CreeperEntity" -ignore_battle = true -attack_power = 15 -attack_probability = 17 +ignore_battle = false +attack_power = 13 +attack_probability = 95 attack_variance = 7 evasion = 5 category = "monster" diff --git a/src/main/resources/mcmod.info b/src/main/resources/mcmod.info index 6e8c08f..45497a9 100644 --- a/src/main/resources/mcmod.info +++ b/src/main/resources/mcmod.info @@ -3,7 +3,7 @@ "modid": "com_burnedkirby_turnbasedminecraft", "name": "Turn Based Minecraft", "description": "Changes battles to be turn-based.", - "version": "1.13", + "version": "1.14", "mcversion": "1.16.3", "url": "", "updateUrl": "",