diff --git a/README.md b/README.md index c554313e..1b8e0db0 100644 --- a/README.md +++ b/README.md @@ -24,10 +24,14 @@ There are a few paper-cuts in developing mods (especially for older versions of them is to build and run the project using IntelliJ IDEA. It seems to build everything from source, as opposed to the `./gradlew runClient` and `./gradlew runServer` scripts, which fail at bootup. +### Troubleshooting +- IntelliJ freaks out and can't find symbols in the project, but compiles fine. + - `File > Invalidate Caches/Restart` works like a charm <3 + ## Creating addons Addons are a way to extend the functionality of Mo' Bends, e.g. adding support for new mobs. -There's an example addon that I set up a while back, but the sources for CustomNPCs are not longer available, which -makes it impossible to use. I'm looking for a replacement soon. +There's an example addon that I set up a while back, but the sources for CustomNPCs are +no longer available, which makes it impossible to use. I'm looking for a replacement soon. [CustomNPCs Support Addon](https://github.com/mobends/mobends-addon-customnpcs) diff --git a/build.gradle b/build.gradle index e0f0471b..747e235f 100644 --- a/build.gradle +++ b/build.gradle @@ -139,6 +139,13 @@ shadowJar.finalizedBy('reobfShadowJar') // However if you are in a multi-project build, dev time needs unobfed jar files, so you can delay the obfuscation until publishing by doing //publish.dependsOn('reobfShadowJar') +task srcJar(type: Jar) { + build.dependsOn it + from sourceSets.main.allSource + classifier = 'sources' + from file("LICENSE") +} + processResources { // this will ensure that this task is redone when the versions change. inputs.property "version", mod_version @@ -171,6 +178,7 @@ publishing { publications { mavenJava(MavenPublication) { artifact shadowJar + artifact srcJar } } repositories { diff --git a/gradle.properties b/gradle.properties index 42a7045b..879d869a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,7 +3,7 @@ org.gradle.jvmargs=-Xmx5G org.gradle.daemon=false -mod_version=1.1.0 +mod_version=1.2.1 minecraft_version=1.12.2 forge_version=14.23.5.2859 mappings_channel=snapshot diff --git a/src/main/java/goblinbob/mobends/core/animation/bit/AnimationBit.java b/src/main/java/goblinbob/mobends/core/animation/bit/AnimationBit.java index 5f5fd7ce..bea5a72c 100644 --- a/src/main/java/goblinbob/mobends/core/animation/bit/AnimationBit.java +++ b/src/main/java/goblinbob/mobends/core/animation/bit/AnimationBit.java @@ -5,7 +5,6 @@ public abstract class AnimationBit> { - /** * The layer that this bit is performed by. Used to callback, e.g. when the animation is finished. */ @@ -23,7 +22,7 @@ public void setupForPlay(AnimationLayer layer, T entityData) /** * Returns the actions currently being performed by the entityData. Used by BendsPacks */ - public abstract String[] getActions(T entityData); + public String[] getActions(T entityData) { return new String[] {}; } /** * Called by setupForPlay to setup the beginning of this animation bit. @@ -34,5 +33,4 @@ public void onPlay(T entityData) {} * Called by an AnimationLayer to perform a continuous animation. */ public abstract void perform(T entityData); - } \ No newline at end of file diff --git a/src/main/java/goblinbob/mobends/core/animation/bit/KeyframeAnimationBit.java b/src/main/java/goblinbob/mobends/core/animation/bit/KeyframeAnimationBit.java index 7f9dc87a..08745bb1 100644 --- a/src/main/java/goblinbob/mobends/core/animation/bit/KeyframeAnimationBit.java +++ b/src/main/java/goblinbob/mobends/core/animation/bit/KeyframeAnimationBit.java @@ -11,7 +11,6 @@ public class KeyframeAnimationBit> extends AnimationBit { - protected KeyframeAnimation performedAnimation = null; private ArmatureMask mask = null; private TriggerMode triggerMode = TriggerMode.RETRIGGER; @@ -162,5 +161,4 @@ public static enum TriggerMode RETRIGGER, CONTINUE } - } diff --git a/src/main/java/goblinbob/mobends/core/animation/keyframe/BinaryAnimationLoader.java b/src/main/java/goblinbob/mobends/core/animation/keyframe/BinaryAnimationLoader.java index 3bb3a49c..18954554 100644 --- a/src/main/java/goblinbob/mobends/core/animation/keyframe/BinaryAnimationLoader.java +++ b/src/main/java/goblinbob/mobends/core/animation/keyframe/BinaryAnimationLoader.java @@ -1,15 +1,18 @@ package goblinbob.mobends.core.animation.keyframe; +import goblinbob.mobends.core.util.SerialHelper; import org.apache.http.util.ByteArrayBuffer; import java.io.DataInputStream; import java.io.IOException; import java.io.InputStream; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.HashMap; public class BinaryAnimationLoader { + private static final String HEADER = "BENDSANIM"; private static final byte HAS_POSITION = 1; private static final byte HAS_ROTATION = 2; @@ -17,11 +20,18 @@ public class BinaryAnimationLoader public static KeyframeAnimation loadFromBinaryInputStream(InputStream stream) throws IOException { + DataInputStream dataInputStream = new DataInputStream(stream); + + // Checking header + String header = SerialHelper.readChar(dataInputStream, HEADER.length()); + if (!header.equals(HEADER)) + { + throw new IOException("File doesn't start with the header."); + } + KeyframeAnimation animation = new KeyframeAnimation(); animation.bones = new HashMap<>(); - DataInputStream dataInputStream = new DataInputStream(stream); - int version = dataInputStream.readInt(); int amountOfKeyframes = dataInputStream.readInt(); int amountOfBones = dataInputStream.readInt(); @@ -36,7 +46,7 @@ public static KeyframeAnimation loadFromBinaryInputStream(InputStream stream) th character = dataInputStream.readByte(); } - String boneName = new String(buffer.toByteArray(), "UTF-8"); + String boneName = new String(buffer.toByteArray(), StandardCharsets.UTF_8); Bone bone = new Bone(); bone.keyframes = new ArrayList<>(); diff --git a/src/main/java/goblinbob/mobends/core/bender/EntityBender.java b/src/main/java/goblinbob/mobends/core/bender/EntityBender.java index dd753c98..88de77a1 100644 --- a/src/main/java/goblinbob/mobends/core/bender/EntityBender.java +++ b/src/main/java/goblinbob/mobends/core/bender/EntityBender.java @@ -186,12 +186,6 @@ protected T createPreviewEntity() return null; } - public void transformModelToCharacterSpace(IMat4x4d matrixOut) - { - TransformUtils.scale(matrixOut, -1.0F, -1.0F, 1.0F); - TransformUtils.translate(matrixOut, 0.0F, -1.501F, 0.0F); - } - public Mutator getMutator(RenderLivingBase renderer) { return this.mutatorMap.get(renderer); diff --git a/src/main/java/goblinbob/mobends/core/bender/EntityBenderRegistry.java b/src/main/java/goblinbob/mobends/core/bender/EntityBenderRegistry.java index eeff55ec..b83f4a47 100644 --- a/src/main/java/goblinbob/mobends/core/bender/EntityBenderRegistry.java +++ b/src/main/java/goblinbob/mobends/core/bender/EntityBenderRegistry.java @@ -63,40 +63,25 @@ public EntityBender getForEntityClass(Class c public EntityBender getForEntity(E entity) { - if (entityToBenderMap.containsKey(entity)) - // noinspection unchecked - return (EntityBender) entityToBenderMap.get(entity); + // noinspection unchecked + return (EntityBender) entityToBenderMap.computeIfAbsent(entity, key -> { + // Checking the config blacklist + if (ModConfig.shouldKeepEntityAsVanilla(entity)) + return null; + + // Checking direct registration + Class entityClass = entity.getClass(); + for (EntityBender entityBender : entityClassToBenderMap.values()) + if (entityBender.entityClass.equals(entityClass)) + return entityBender; + + // Checking indirect inheritance + for (EntityBender entityBender : entityClassToBenderMap.values()) + if (entityBender.entityClass.isInstance(entity)) + return entityBender; - // Checking the config blacklist - if (ModConfig.shouldKeepEntityAsVanilla(entity)) - { return null; - } - - // Checking direct registration - Class entityClass = entity.getClass(); - for (EntityBender entityBender : entityClassToBenderMap.values()) - { - if (entityBender.entityClass.equals(entityClass)) - { - entityToBenderMap.put(entity, entityBender); - // noinspection unchecked - return (EntityBender) entityBender; - } - } - - // Checking indirect inheritance - for (EntityBender entityBender : entityClassToBenderMap.values()) - { - if (entityBender.entityClass.isInstance(entity)) - { - entityToBenderMap.put(entity, entityBender); - // noinspection unchecked - return (EntityBender) entityBender; - } - } - - return null; + }); } public void clearCache(E entity) diff --git a/src/main/java/goblinbob/mobends/core/util/SerialHelper.java b/src/main/java/goblinbob/mobends/core/util/SerialHelper.java new file mode 100644 index 00000000..b9ed308f --- /dev/null +++ b/src/main/java/goblinbob/mobends/core/util/SerialHelper.java @@ -0,0 +1,21 @@ +package goblinbob.mobends.core.util; + +import org.apache.http.util.ByteArrayBuffer; + +import java.io.DataInputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; + +public class SerialHelper +{ + public static String readChar(DataInputStream stream, int length) throws IOException + { + ByteArrayBuffer buffer = new ByteArrayBuffer(length); + for (int i = 0; i < length; ++i) + { + buffer.append(stream.readByte()); + } + + return new String(buffer.toByteArray(), StandardCharsets.UTF_8); + } +} diff --git a/src/main/java/goblinbob/mobends/standard/AttackActionType.java b/src/main/java/goblinbob/mobends/standard/AttackActionType.java new file mode 100644 index 00000000..ed55f0c5 --- /dev/null +++ b/src/main/java/goblinbob/mobends/standard/AttackActionType.java @@ -0,0 +1,8 @@ +package goblinbob.mobends.standard; + +public enum AttackActionType +{ + TOOL, + FISTS, + SWORD, +} diff --git a/src/main/java/goblinbob/mobends/standard/UseActionType.java b/src/main/java/goblinbob/mobends/standard/UseActionType.java new file mode 100644 index 00000000..a047e26b --- /dev/null +++ b/src/main/java/goblinbob/mobends/standard/UseActionType.java @@ -0,0 +1,8 @@ +package goblinbob.mobends.standard; + +public enum UseActionType +{ + FOOD, + BOW, + SHIELD, +} diff --git a/src/main/java/goblinbob/mobends/standard/animation/bit/biped/AttackSlashDownAnimationBit.java b/src/main/java/goblinbob/mobends/standard/animation/bit/biped/AttackSlashDownAnimationBit.java index 203fccf0..4d497c02 100644 --- a/src/main/java/goblinbob/mobends/standard/animation/bit/biped/AttackSlashDownAnimationBit.java +++ b/src/main/java/goblinbob/mobends/standard/animation/bit/biped/AttackSlashDownAnimationBit.java @@ -14,15 +14,7 @@ public class AttackSlashDownAnimationBit extends AnimationBit> { - private static final String[] ACTIONS = new String[] { "attack", "attack_slash_down" }; - private float ticksPlayed; - - @Override - public String[] getActions(BipedEntityData entityData) - { - return ACTIONS; - } @Override public void onPlay(BipedEntityData data) diff --git a/src/main/java/goblinbob/mobends/standard/animation/bit/biped/AttackSlashInwardAnimationBit.java b/src/main/java/goblinbob/mobends/standard/animation/bit/biped/AttackSlashInwardAnimationBit.java index 83d234cd..8cb371cc 100644 --- a/src/main/java/goblinbob/mobends/standard/animation/bit/biped/AttackSlashInwardAnimationBit.java +++ b/src/main/java/goblinbob/mobends/standard/animation/bit/biped/AttackSlashInwardAnimationBit.java @@ -13,7 +13,6 @@ public class AttackSlashInwardAnimationBit extends AnimationBit> { - private static final String[] ACTIONS = new String[] { "attack", "attack_slash_inward" }; @Override @@ -89,5 +88,4 @@ public void perform(BipedEntityData data) mainItemRotation.setSmoothness(.9F).orientInstantX(50.0F); } - } diff --git a/src/main/java/goblinbob/mobends/standard/animation/bit/player/AttackStanceAnimationBit.java b/src/main/java/goblinbob/mobends/standard/animation/bit/biped/AttackStanceAnimationBit.java similarity index 76% rename from src/main/java/goblinbob/mobends/standard/animation/bit/player/AttackStanceAnimationBit.java rename to src/main/java/goblinbob/mobends/standard/animation/bit/biped/AttackStanceAnimationBit.java index efd0a0d2..47b10af2 100644 --- a/src/main/java/goblinbob/mobends/standard/animation/bit/player/AttackStanceAnimationBit.java +++ b/src/main/java/goblinbob/mobends/standard/animation/bit/biped/AttackStanceAnimationBit.java @@ -1,38 +1,32 @@ -package goblinbob.mobends.standard.animation.bit.player; +package goblinbob.mobends.standard.animation.bit.biped; import goblinbob.mobends.core.animation.bit.AnimationBit; import goblinbob.mobends.core.client.event.DataUpdateHandler; import goblinbob.mobends.core.client.model.IModelPart; import goblinbob.mobends.core.math.SmoothOrientation; -import goblinbob.mobends.standard.data.PlayerData; -import net.minecraft.client.entity.AbstractClientPlayer; +import goblinbob.mobends.standard.data.BipedEntityData; +import net.minecraft.entity.EntityLivingBase; import net.minecraft.util.EnumHandSide; import net.minecraft.util.math.MathHelper; -public class AttackStanceAnimationBit extends AnimationBit +public class AttackStanceAnimationBit extends AnimationBit> { protected final float PI = (float) Math.PI; protected final float kneelDuration = 0.15F; protected final float legSpreadSpeed = 0.1F; protected float legSpreadAnimation = 0F; - - @Override - public String[] getActions(PlayerData entityData) - { - return new String[] { "attack_stance" }; - } - + @Override - public void onPlay(PlayerData entityData) + public void onPlay(BipedEntityData entityData) { this.legSpreadAnimation = 0F; } @Override - public void perform(PlayerData data) + public void perform(BipedEntityData data) { - AbstractClientPlayer player = data.getEntity(); - EnumHandSide primaryHand = player.getPrimaryHand(); + EntityLivingBase entity = data.getEntity(); + EnumHandSide primaryHand = entity.getPrimaryHand(); boolean mainHandSwitch = primaryHand == EnumHandSide.RIGHT; // Main Hand Direction Multiplier - it helps switch animation sides depending on @@ -42,10 +36,6 @@ public void perform(PlayerData data) IModelPart offArm = mainHandSwitch ? data.leftArm : data.rightArm; IModelPart mainForeArm = mainHandSwitch ? data.rightForeArm : data.leftForeArm; IModelPart offForeArm = mainHandSwitch ? data.leftForeArm : data.rightForeArm; - IModelPart mainLeg = mainHandSwitch ? data.rightLeg : data.leftLeg; - IModelPart offLeg = mainHandSwitch ? data.leftLeg : data.rightLeg; - IModelPart mainForeLeg = mainHandSwitch ? data.rightForeLeg : data.leftForeLeg; - IModelPart offForeLeg = mainHandSwitch ? data.leftForeLeg : data.rightForeLeg; SmoothOrientation mainItemRotation = mainHandSwitch ? data.renderRightItemRotation : data.renderLeftItemRotation; // ItemStack offHandItemStack = player.getHeldItemOffhand(); @@ -89,5 +79,4 @@ public void perform(PlayerData data) data.globalOffset.setY(-MathHelper.sin(touchdown * PI) * 2F - 2F); } } - } diff --git a/src/main/java/goblinbob/mobends/standard/animation/bit/biped/AttackStanceSprintAnimationBit.java b/src/main/java/goblinbob/mobends/standard/animation/bit/biped/AttackStanceSprintAnimationBit.java index 5d03cd04..c92aabd0 100644 --- a/src/main/java/goblinbob/mobends/standard/animation/bit/biped/AttackStanceSprintAnimationBit.java +++ b/src/main/java/goblinbob/mobends/standard/animation/bit/biped/AttackStanceSprintAnimationBit.java @@ -10,15 +10,6 @@ public class AttackStanceSprintAnimationBit extends AnimationBit> { - - private static final String[] ACTIONS = new String[] { "attack_stance_sprint" }; - - @Override - public String[] getActions(BipedEntityData entityData) - { - return ACTIONS; - } - @Override public void perform(BipedEntityData data) { @@ -44,7 +35,7 @@ public void perform(BipedEntityData data) data.body.rotation.rotateY(20 * handDirMtp); data.head.rotation.rotateY(-20 * handDirMtp); mainArm.getRotation().orientZ(60.0F * handDirMtp); - mainArm.getRotation().rotateY(60.0F); + mainArm.getRotation().rotateY(60.0F * handDirMtp); offArm.getRotation().rotateZ(-30.0F * handDirMtp); if (mainHandSwitch) @@ -56,5 +47,4 @@ public void perform(BipedEntityData data) data.renderLeftItemRotation.setSmoothness(.3F).orientX(45); } } - } diff --git a/src/main/java/goblinbob/mobends/standard/animation/bit/biped/AttackWhirlSlashAnimationBit.java b/src/main/java/goblinbob/mobends/standard/animation/bit/biped/AttackWhirlSlashAnimationBit.java index 3c814e4f..1ec870d8 100644 --- a/src/main/java/goblinbob/mobends/standard/animation/bit/biped/AttackWhirlSlashAnimationBit.java +++ b/src/main/java/goblinbob/mobends/standard/animation/bit/biped/AttackWhirlSlashAnimationBit.java @@ -14,14 +14,6 @@ public class AttackWhirlSlashAnimationBit extends AnimationBit> { - private static final String[] ACTIONS = new String[] { "attack", "attack_2" }; - - @Override - public String[] getActions(BipedEntityData entityData) - { - return ACTIONS; - } - @Override public void perform(BipedEntityData data) { @@ -47,10 +39,7 @@ public void perform(BipedEntityData data) if (living.getHeldItem(EnumHand.MAIN_HAND) != null) { - if (living.getHeldItem(EnumHand.MAIN_HAND).getItem() instanceof ItemSword) - { - data.swordTrail.add(data); - } + data.swordTrail.add(data); } float attackState = data.getTicksAfterAttack() / 10.0f; @@ -66,13 +55,13 @@ public void perform(BipedEntityData data) data.body.rotation.setSmoothness(.9F).orientX(bodyRot.x) .orientY(bodyRot.y); data.head.rotation.orientX(MathHelper.wrapDegrees(data.headPitch.get()) - bodyRot.x) - .rotateY(MathHelper.wrapDegrees(data.headYaw.get()) - bodyRot.y - 30); + .rotateY(MathHelper.wrapDegrees(data.headYaw.get()) - bodyRot.y - 30 * handDirMtp); offArm.getRotation().setSmoothness(.3F).orientZ(20F * handDirMtp); offArm.getRotation().setSmoothness(.3F).orientZ(-80F * handDirMtp); mainArm.getRotation().setSmoothness(.3F).orientZ(-(-10.0f - var5 * 120) * handDirMtp) - .rotateInstantY(-20 + armSwing * 70); + .rotateInstantY((-20 + armSwing * 70) * handDirMtp); mainForeArm.getRotation().setSmoothness(.3F).orientX(-20); offForeArm.getRotation().setSmoothness(.3F).orientX(-60); diff --git a/src/main/java/goblinbob/mobends/standard/animation/bit/biped/EatingAnimationBit.java b/src/main/java/goblinbob/mobends/standard/animation/bit/biped/EatingAnimationBit.java index 834cd1f7..a9e08943 100644 --- a/src/main/java/goblinbob/mobends/standard/animation/bit/biped/EatingAnimationBit.java +++ b/src/main/java/goblinbob/mobends/standard/animation/bit/biped/EatingAnimationBit.java @@ -9,24 +9,15 @@ public class EatingAnimationBit extends AnimationBit> { - - private static final String[] ACTIONS = new String[] { "eating" }; - - protected EnumHandSide actionHand = EnumHandSide.RIGHT; + protected final EnumHandSide actionHand; protected float bringUpAnimation; - - @Override - public String[] getActions(BipedEntityData data) - { - return ACTIONS; - } - public void setActionHand(EnumHandSide handSide) + public EatingAnimationBit(EnumHandSide handSide) { this.actionHand = handSide; } - + @Override public void onPlay(BipedEntityData data) { @@ -61,5 +52,4 @@ public void perform(BipedEntityData data) .rotateZ(45.0F * bringUpAnimation * handDirMtp); mainForeArm.rotation.orientX(bringUpAnimation * -45.0F); } - } diff --git a/src/main/java/goblinbob/mobends/standard/animation/bit/biped/FistGuardAnimationBit.java b/src/main/java/goblinbob/mobends/standard/animation/bit/biped/FistGuardAnimationBit.java index 6595278b..7e074ca7 100644 --- a/src/main/java/goblinbob/mobends/standard/animation/bit/biped/FistGuardAnimationBit.java +++ b/src/main/java/goblinbob/mobends/standard/animation/bit/biped/FistGuardAnimationBit.java @@ -25,7 +25,13 @@ public void perform(BipedEntityData data) // Main Hand Direction Multiplier - it helps switch animation sides depending on // what is your main hand. float handDirMtp = mainHandSwitch ? 1 : -1; - + + if (!data.isStillHorizontally()) + { + // Skipping the fist guard if the entity is moving around. + return; + } + data.globalOffset.slideY(-2.0F); data.renderRotation.setSmoothness(.3F).orientY(-20 * handDirMtp); diff --git a/src/main/java/goblinbob/mobends/standard/animation/bit/biped/ShieldAnimationBit.java b/src/main/java/goblinbob/mobends/standard/animation/bit/biped/ShieldAnimationBit.java index cf7dc45e..47532641 100644 --- a/src/main/java/goblinbob/mobends/standard/animation/bit/biped/ShieldAnimationBit.java +++ b/src/main/java/goblinbob/mobends/standard/animation/bit/biped/ShieldAnimationBit.java @@ -8,22 +8,21 @@ public class ShieldAnimationBit extends AnimationBit> { - private static final String[] ACTIONS = new String[] { "shield" }; - protected EnumHandSide actionHand = EnumHandSide.RIGHT; + protected final EnumHandSide actionHand; protected float bringUpAnimation; - @Override - public String[] getActions(BipedEntityData data) + public ShieldAnimationBit(EnumHandSide handSide) { - return ACTIONS; + this.actionHand = handSide; } - public void setActionHand(EnumHandSide handSide) + @Override + public String[] getActions(BipedEntityData data) { - this.actionHand = handSide; + return ACTIONS; } @Override diff --git a/src/main/java/goblinbob/mobends/standard/animation/bit/biped/item/BipedActionController.java b/src/main/java/goblinbob/mobends/standard/animation/bit/biped/item/BipedActionController.java new file mode 100644 index 00000000..185e0cf8 --- /dev/null +++ b/src/main/java/goblinbob/mobends/standard/animation/bit/biped/item/BipedActionController.java @@ -0,0 +1,176 @@ +package goblinbob.mobends.standard.animation.bit.biped.item; + +import goblinbob.mobends.core.animation.bit.AnimationBit; +import goblinbob.mobends.core.animation.layer.HardAnimationLayer; +import goblinbob.mobends.core.data.EntityData; +import goblinbob.mobends.core.data.LivingEntityData; +import goblinbob.mobends.standard.AttackActionType; +import goblinbob.mobends.standard.UseActionType; +import goblinbob.mobends.standard.animation.bit.biped.EatingAnimationBit; +import goblinbob.mobends.standard.animation.bit.biped.ShieldAnimationBit; +import goblinbob.mobends.standard.data.BipedEntityData; +import goblinbob.mobends.standard.main.ModConfig; +import net.minecraft.client.model.ModelBiped; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.init.Items; +import net.minecraft.item.*; +import net.minecraft.util.EnumHand; +import net.minecraft.util.EnumHandSide; + +import java.util.HashMap; +import java.util.Map; + +public class BipedActionController +{ + protected HardAnimationLayer> layerAction = new HardAnimationLayer<>(); + protected UseActionType currentUseActionType = null; + protected AttackActionType currentAttackActionType = null; + protected AnimationBit> actionBit = null; + + private static final Map>>> ITEM_USE_ACTION_MAP = new HashMap<>(); + private static final Map>>> ITEM_ATTACK_ACTION_MAP = new HashMap<>(); + static + { + ITEM_USE_ACTION_MAP.put(UseActionType.FOOD, EatingAnimationBit::new); + ITEM_USE_ACTION_MAP.put(UseActionType.BOW, BowAction::new); + ITEM_USE_ACTION_MAP.put(UseActionType.SHIELD, ShieldAnimationBit::new); + + ITEM_ATTACK_ACTION_MAP.put(AttackActionType.TOOL, ToolAction::new); + ITEM_ATTACK_ACTION_MAP.put(AttackActionType.FISTS, PunchingAction::new); + ITEM_ATTACK_ACTION_MAP.put(AttackActionType.SWORD, SwordAction::new); + + // Completeness checks + for (UseActionType type : UseActionType.values()) + { + if (!ITEM_USE_ACTION_MAP.containsKey(type)) + throw new IllegalStateException("The ITEM_USE_ACTION_MAP map needs to be complete."); + } + + // Completeness checks + for (AttackActionType type : AttackActionType.values()) + { + if (!ITEM_ATTACK_ACTION_MAP.containsKey(type)) + throw new IllegalStateException("The ITEM_ATTACK_ACTION_MAP map needs to be complete."); + } + } + + private static ModelBiped.ArmPose getAction(EntityLivingBase entity, ItemStack heldItem) + { + if (!heldItem.isEmpty()) + { + if (entity.getItemInUseCount() > 0) + { + EnumAction enumaction = heldItem.getItemUseAction(); + + if (enumaction == EnumAction.BLOCK) + return ModelBiped.ArmPose.BLOCK; + else if (enumaction == EnumAction.BOW) + return ModelBiped.ArmPose.BOW_AND_ARROW; + } + + return ModelBiped.ArmPose.ITEM; + } + + return ModelBiped.ArmPose.EMPTY; + } + + public static UseActionType getBuiltInItemUseAction(Item item, ModelBiped.ArmPose armPoseMain, ModelBiped.ArmPose armPoseOff) + { + if (item == Items.AIR) + return null; + + if (item instanceof ItemFood) + return UseActionType.FOOD; + + if (item instanceof ItemBow || armPoseMain == ModelBiped.ArmPose.BOW_AND_ARROW || armPoseOff == ModelBiped.ArmPose.BOW_AND_ARROW) + return UseActionType.BOW; + + if (armPoseMain == ModelBiped.ArmPose.BLOCK || armPoseOff == ModelBiped.ArmPose.BLOCK) + return UseActionType.SHIELD; + + return UseActionType.FOOD; + } + + public static UseActionType getItemUseAction(Item item, ModelBiped.ArmPose armPoseMain, ModelBiped.ArmPose armPoseOff) + { + UseActionType useActionType = ModConfig.getItemUseAction(item); + + return useActionType != null ? useActionType : getBuiltInItemUseAction(item, armPoseMain, armPoseOff); + } + + public static AttackActionType getBuiltInItemAttackAction(Item item) + { + if (item instanceof ItemSword) + return AttackActionType.SWORD; + + if (item == Items.AIR) + return AttackActionType.FISTS; + + return AttackActionType.TOOL; + } + + public static AttackActionType getItemAttackAction(Item item) + { + AttackActionType attackActionType = ModConfig.getItemAttackAction(item); + + return attackActionType != null ? attackActionType : getBuiltInItemAttackAction(item); + } + + public void perform( + BipedEntityData data, + EnumHandSide primaryHand, + ItemStack heldItemMainhand, + ItemStack heldItemOffhand, + Item activeItem + ) { + final EntityLivingBase entity = data.getEntity(); + final EnumHandSide offHand = primaryHand == EnumHandSide.RIGHT ? EnumHandSide.LEFT : EnumHandSide.RIGHT; + final ModelBiped.ArmPose armPoseMain = getAction(entity, heldItemMainhand); + final ModelBiped.ArmPose armPoseOff = getAction(entity, heldItemOffhand); + final EnumHandSide activeHandSide = entity.getActiveHand() == EnumHand.MAIN_HAND ? primaryHand : offHand; + + UseActionType useActionType = getItemUseAction(activeItem, armPoseMain, armPoseOff); + if (useActionType != currentUseActionType) + { + currentUseActionType = useActionType; + + if (useActionType != null) + { + ItemActionFactory>> factory = ITEM_USE_ACTION_MAP.get(useActionType); + this.actionBit = factory.create(activeHandSide); + this.layerAction.playOrContinueBit(this.actionBit, data); + } + else + { + this.layerAction.clearAnimation(); + this.currentAttackActionType = null; + } + } + + AttackActionType attackActionType = getItemAttackAction(heldItemMainhand.getItem()); + + if (this.currentAttackActionType != attackActionType) + { + this.currentAttackActionType = attackActionType; + + ItemActionFactory>> factory = ITEM_ATTACK_ACTION_MAP.get(attackActionType); + if (factory == null) + { + this.actionBit = null; + this.layerAction.clearAnimation(); + } + else + { + this.actionBit = factory.create(primaryHand); + this.layerAction.playOrContinueBit(this.actionBit, data); + } + } + + this.layerAction.perform(data); + } + + public void clearAction() + { + layerAction.clearAnimation(); + } +} diff --git a/src/main/java/goblinbob/mobends/standard/animation/bit/biped/BowAnimationBit.java b/src/main/java/goblinbob/mobends/standard/animation/bit/biped/item/BowAction.java similarity index 86% rename from src/main/java/goblinbob/mobends/standard/animation/bit/biped/BowAnimationBit.java rename to src/main/java/goblinbob/mobends/standard/animation/bit/biped/item/BowAction.java index 1272117a..7d5a04b2 100644 --- a/src/main/java/goblinbob/mobends/standard/animation/bit/biped/BowAnimationBit.java +++ b/src/main/java/goblinbob/mobends/standard/animation/bit/biped/item/BowAction.java @@ -1,4 +1,4 @@ -package goblinbob.mobends.standard.animation.bit.biped; +package goblinbob.mobends.standard.animation.bit.biped.item; import goblinbob.mobends.core.animation.bit.AnimationBit; import goblinbob.mobends.core.client.model.ModelPartTransform; @@ -8,19 +8,11 @@ import net.minecraft.util.EnumHandSide; import net.minecraft.util.math.MathHelper; -public class BowAnimationBit extends AnimationBit> +public class BowAction extends AnimationBit> { - private static final String[] ACTIONS = new String[] { "bow" }; - - protected EnumHandSide actionHand = EnumHandSide.RIGHT; - - @Override - public String[] getActions(BipedEntityData entityData) - { - return ACTIONS; - } + protected final EnumHandSide actionHand; - public void setActionHand(EnumHandSide handSide) + public BowAction(EnumHandSide handSide) { this.actionHand = handSide; } diff --git a/src/main/java/goblinbob/mobends/standard/animation/bit/biped/item/ItemActionFactory.java b/src/main/java/goblinbob/mobends/standard/animation/bit/biped/item/ItemActionFactory.java new file mode 100644 index 00000000..5b1a3efe --- /dev/null +++ b/src/main/java/goblinbob/mobends/standard/animation/bit/biped/item/ItemActionFactory.java @@ -0,0 +1,10 @@ +package goblinbob.mobends.standard.animation.bit.biped.item; + +import goblinbob.mobends.core.animation.bit.AnimationBit; +import net.minecraft.util.EnumHandSide; + +@FunctionalInterface +public interface ItemActionFactory> +{ + T create(EnumHandSide actionHand); +} diff --git a/src/main/java/goblinbob/mobends/standard/animation/bit/biped/item/PunchingAction.java b/src/main/java/goblinbob/mobends/standard/animation/bit/biped/item/PunchingAction.java new file mode 100644 index 00000000..6575c14e --- /dev/null +++ b/src/main/java/goblinbob/mobends/standard/animation/bit/biped/item/PunchingAction.java @@ -0,0 +1,53 @@ +package goblinbob.mobends.standard.animation.bit.biped.item; + +import goblinbob.mobends.core.animation.bit.AnimationBit; +import goblinbob.mobends.core.animation.layer.HardAnimationLayer; +import goblinbob.mobends.standard.animation.bit.biped.FistGuardAnimationBit; +import goblinbob.mobends.standard.animation.bit.player.PunchAnimationBit; +import goblinbob.mobends.standard.data.BipedEntityData; +import net.minecraft.util.EnumHandSide; + +public class PunchingAction extends AnimationBit> +{ + protected final HardAnimationLayer> layerBase = new HardAnimationLayer<>(); + + protected final FistGuardAnimationBit bitFistGuard = new FistGuardAnimationBit(); + protected final PunchAnimationBit bitPunchLeft = new PunchAnimationBit(EnumHandSide.LEFT); + protected final PunchAnimationBit bitPunchRight = new PunchAnimationBit(EnumHandSide.RIGHT); + + protected EnumHandSide punchingFist = EnumHandSide.LEFT; + protected float lastTicksAfterAttack = 0; + + public PunchingAction(EnumHandSide ignoredHandSide) + { + + } + + @Override + public void perform(BipedEntityData entityData) + { + // Switching punching hand + float ticksAfterAttack = entityData.getTicksAfterAttack(); + if (ticksAfterAttack < lastTicksAfterAttack) + { + punchingFist = punchingFist == EnumHandSide.LEFT ? EnumHandSide.RIGHT : EnumHandSide.LEFT; + } + lastTicksAfterAttack = ticksAfterAttack; + + // Playing appropriate bits + if (ticksAfterAttack < 10) + { + this.layerBase.playOrContinueBit(punchingFist == EnumHandSide.LEFT ? bitPunchLeft : bitPunchRight, entityData); + } + else if (ticksAfterAttack < 60) + { + this.layerBase.playOrContinueBit(bitFistGuard, entityData); + } + else + { + this.layerBase.clearAnimation(); + } + + this.layerBase.perform(entityData); + } +} diff --git a/src/main/java/goblinbob/mobends/standard/animation/bit/biped/item/SwordAction.java b/src/main/java/goblinbob/mobends/standard/animation/bit/biped/item/SwordAction.java new file mode 100644 index 00000000..ba961b29 --- /dev/null +++ b/src/main/java/goblinbob/mobends/standard/animation/bit/biped/item/SwordAction.java @@ -0,0 +1,97 @@ +package goblinbob.mobends.standard.animation.bit.biped.item; + +import goblinbob.mobends.core.animation.bit.AnimationBit; +import goblinbob.mobends.core.animation.layer.HardAnimationLayer; +import goblinbob.mobends.standard.animation.bit.biped.*; +import goblinbob.mobends.standard.animation.bit.biped.AttackStanceAnimationBit; +import goblinbob.mobends.standard.data.BipedEntityData; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.util.EnumHandSide; + +import java.util.Arrays; +import java.util.List; + +public class SwordAction extends AnimationBit> +{ + protected final HardAnimationLayer> layerBase = new HardAnimationLayer<>(); + protected final AttackStanceAnimationBit bitAttackStance = new AttackStanceAnimationBit(); + protected final AttackStanceSprintAnimationBit bitAttackStanceSprint = new AttackStanceSprintAnimationBit(); + + protected float lastTicksAfterAttack = 0.0F; + protected int moveId = 0; + + private static final List>> bits = Arrays.asList( + new AttackSlashUpAnimationBit(), + new AttackSlashDownAnimationBit(), + new AttackSlashInwardAnimationBit(), + new AttackSlashOutwardAnimationBit(), + new AttackWhirlSlashAnimationBit() + ); + + public SwordAction(EnumHandSide ignoredHandSide) + { + + } + + private void nextMove(BipedEntityData entityData) + { + AnimationBit> bit = bits.get(moveId); + + if (bit != null) + { + this.layerBase.playBit(bit, entityData); + } + else + { + this.layerBase.clearAnimation(); + } + + moveId = (moveId + 1) % bits.size(); + } + + @Override + public void perform(BipedEntityData entityData) + { + float ticksAfterAttack = entityData.getTicksAfterAttack(); + if (ticksAfterAttack < lastTicksAfterAttack) + { + nextMove(entityData); + } + lastTicksAfterAttack = ticksAfterAttack; + + EntityLivingBase entity = entityData.getEntity(); + + int comboClearTime = 20; + + // Creating the combo. + if (ticksAfterAttack > comboClearTime) + { + moveId = 0; + } + + if (ticksAfterAttack < 10) + { + } + else if (ticksAfterAttack < 60 && entityData.isOnGround()) + { + if (entity.isSprinting()) + { + this.layerBase.playOrContinueBit(this.bitAttackStanceSprint, entityData); + } + else if (entityData.isStillHorizontally()) + { + this.layerBase.playOrContinueBit(this.bitAttackStance, entityData); + } + else + { + this.layerBase.clearAnimation(); + } + } + else + { + this.layerBase.clearAnimation(); + } + + this.layerBase.perform(entityData); + } +} diff --git a/src/main/java/goblinbob/mobends/standard/animation/bit/biped/HarvestAnimationBit.java b/src/main/java/goblinbob/mobends/standard/animation/bit/biped/item/ToolAction.java similarity index 79% rename from src/main/java/goblinbob/mobends/standard/animation/bit/biped/HarvestAnimationBit.java rename to src/main/java/goblinbob/mobends/standard/animation/bit/biped/item/ToolAction.java index 0b248db9..03e49240 100644 --- a/src/main/java/goblinbob/mobends/standard/animation/bit/biped/HarvestAnimationBit.java +++ b/src/main/java/goblinbob/mobends/standard/animation/bit/biped/item/ToolAction.java @@ -1,34 +1,30 @@ -package goblinbob.mobends.standard.animation.bit.biped; +package goblinbob.mobends.standard.animation.bit.biped.item; import goblinbob.mobends.core.animation.bit.AnimationBit; import goblinbob.mobends.core.client.model.ModelPartTransform; import goblinbob.mobends.standard.data.BipedEntityData; +import net.minecraft.entity.EntityLivingBase; import net.minecraft.util.EnumHandSide; import net.minecraft.util.math.MathHelper; -public class HarvestAnimationBit extends AnimationBit> +public class ToolAction extends AnimationBit> { + protected final EnumHandSide actionHand; - private static final String[] ACTIONS = new String[] { "harvest" }; - - protected EnumHandSide actionHand = EnumHandSide.RIGHT; - - @Override - public String[] getActions(BipedEntityData entityData) - { - return ACTIONS; - } - - public void setActionHand(EnumHandSide handSide) + public ToolAction(EnumHandSide actionHand) { - this.actionHand = handSide; + this.actionHand = actionHand; } - public HarvestAnimationBit() {} - @Override public void perform(BipedEntityData data) { + EntityLivingBase entity = data.getEntity(); + if (!entity.isSwingInProgress) + { + return; + } + final float headPitch = data.headPitch.get(); final float headYaw = data.headYaw.get(); @@ -61,5 +57,4 @@ public void perform(BipedEntityData data) mainArm.rotation.orientInstantX(MathHelper.sin(MathHelper.sqrt(swingProgress) * ((float)Math.PI * 2F)) * 50.0F - 30.0F); mainArm.rotation.localRotateZ(MathHelper.cos(MathHelper.sqrt(swingProgress) * ((float)Math.PI * 2F)) * -20.0F + 10.0F).finish(); } - } diff --git a/src/main/java/goblinbob/mobends/standard/animation/bit/player/AttackAnimationBit.java b/src/main/java/goblinbob/mobends/standard/animation/bit/player/AttackAnimationBit.java index 2f00834f..5324718f 100644 --- a/src/main/java/goblinbob/mobends/standard/animation/bit/player/AttackAnimationBit.java +++ b/src/main/java/goblinbob/mobends/standard/animation/bit/player/AttackAnimationBit.java @@ -10,122 +10,112 @@ import net.minecraft.item.ItemStack; import net.minecraft.util.EnumHand; -public class AttackAnimationBit extends AnimationBit -{ +public class AttackAnimationBit extends AnimationBit { - protected HardAnimationLayer> layerBase; - protected AttackStanceAnimationBit bitAttackStance; - protected AttackStanceSprintAnimationBit bitAttackStanceSprint; - protected AttackSlashUpAnimationBit bitAttackSlashUp; - protected AttackSlashDownAnimationBit bitAttackSlashDown; - protected AttackSlashInwardAnimationBit bitAttackSlashInward; - protected AttackSlashOutwardAnimationBit bitAttackSlashOutward; - protected AttackWhirlSlashAnimationBit bitAttackWhirlSlash; - protected FistGuardAnimationBit bitFistGuard; - protected PunchAnimationBit bitPunch; + protected HardAnimationLayer> layerBase; - public AttackAnimationBit() - { - this.layerBase = new HardAnimationLayer<>(); - this.bitAttackStance = new AttackStanceAnimationBit(); - this.bitAttackStanceSprint = new AttackStanceSprintAnimationBit(); - this.bitAttackSlashUp = new AttackSlashUpAnimationBit(); - this.bitAttackSlashDown = new AttackSlashDownAnimationBit(); - this.bitAttackSlashInward = new AttackSlashInwardAnimationBit(); - this.bitAttackSlashOutward = new AttackSlashOutwardAnimationBit(); - this.bitAttackWhirlSlash = new AttackWhirlSlashAnimationBit(); - this.bitFistGuard = new FistGuardAnimationBit(); - this.bitPunch = new PunchAnimationBit(); - } + protected AttackSlashUpAnimationBit bitAttackSlashUp; + protected AttackSlashDownAnimationBit bitAttackSlashDown; + protected AttackSlashInwardAnimationBit bitAttackSlashInward; + protected AttackSlashOutwardAnimationBit bitAttackSlashOutward; + protected AttackWhirlSlashAnimationBit bitAttackWhirlSlash; + protected FistGuardAnimationBit bitFistGuard; - @Override - public String[] getActions(PlayerData entityData) - { - if (this.layerBase.isPlaying()) - { - return this.layerBase.getPerformedBit().getActions(entityData); - } + public AttackAnimationBit() { + this.layerBase = new HardAnimationLayer<>(); + this.bitAttackSlashUp = new AttackSlashUpAnimationBit(); + this.bitAttackSlashDown = new AttackSlashDownAnimationBit(); + this.bitAttackSlashInward = new AttackSlashInwardAnimationBit(); + this.bitAttackSlashOutward = new AttackSlashOutwardAnimationBit(); + this.bitAttackWhirlSlash = new AttackWhirlSlashAnimationBit(); + this.bitFistGuard = new FistGuardAnimationBit(); + } - return null; - } + @Override + public String[] getActions(PlayerData entityData) { + if (this.layerBase.isPlaying()) { + return this.layerBase.getPerformedBit().getActions(entityData); + } - public boolean shouldPerformAttack(AbstractClientPlayer player) - { - final ItemStack heldItemStack = player.getHeldItem(EnumHand.MAIN_HAND); - return heldItemStack.getItem() != Items.AIR; - } + return null; + } - @Override - public void perform(PlayerData playerData) - { - final AbstractClientPlayer player = playerData.getEntity(); - - if (this.shouldPerformAttack(player)) - { - if (playerData.getTicksAfterAttack() < 10) - { - if (playerData.getCurrentAttack() == 1) - { - this.layerBase.playOrContinueBit(this.bitAttackSlashUp, playerData); - } - else if (playerData.getCurrentAttack() == 2) - { - this.layerBase.playOrContinueBit(this.bitAttackSlashDown, playerData); - } - else if (playerData.getCurrentAttack() == 3) - { - this.layerBase.playOrContinueBit(this.bitAttackSlashInward, playerData); - } - else if (playerData.getCurrentAttack() == 4) - { - this.layerBase.playOrContinueBit(this.bitAttackSlashOutward, playerData); - } - else if (playerData.getCurrentAttack() == 5) - { - this.layerBase.playOrContinueBit(this.bitAttackWhirlSlash, playerData); - } - else - { - this.layerBase.clearAnimation(); - } - } - else if (playerData.getTicksAfterAttack() < 60 && playerData.isOnGround()) - { - if (player.isSprinting()) - { - this.layerBase.playOrContinueBit(this.bitAttackStanceSprint, playerData); - } - else if (playerData.isStillHorizontally()) - { - this.layerBase.playOrContinueBit(this.bitAttackStance, playerData); - } - else - { - this.layerBase.clearAnimation(); - } - } - else - { - this.layerBase.clearAnimation(); - } - } - else - { - if (playerData.getTicksAfterAttack() < 10) - { - this.layerBase.playOrContinueBit(this.bitPunch, playerData); - } - else if (playerData.getTicksAfterAttack() < 60 && playerData.isStillHorizontally()) - { - this.layerBase.playOrContinueBit(this.bitFistGuard, playerData); - } - else - { - this.layerBase.clearAnimation(); - } - } + public boolean shouldPerformAttack(AbstractClientPlayer player) { + final ItemStack heldItemStack = player.getHeldItem(EnumHand.MAIN_HAND); + return heldItemStack.getItem() != Items.AIR; + } - this.layerBase.perform(playerData); - } + @Override + public void perform(PlayerData playerData) { + // TODO: Find out why this was commented out years ago + // + // final AbstractClientPlayer player = playerData.getEntity(); + // + // if (this.shouldPerformAttack(player)) + // { + // if (playerData.getTicksAfterAttack() < 10) + // { + // if (playerData.getCurrentAttack() == 1) + // { + // this.layerBase.playOrContinueBit(this.bitAttackSlashUp, playerData); + // } + // else if (playerData.getCurrentAttack() == 2) + // { + // this.layerBase.playOrContinueBit(this.bitAttackSlashDown, playerData); + // } + // else if (playerData.getCurrentAttack() == 3) + // { + // this.layerBase.playOrContinueBit(this.bitAttackSlashInward, playerData); + // } + // else if (playerData.getCurrentAttack() == 4) + // { + // this.layerBase.playOrContinueBit(this.bitAttackSlashOutward, playerData); + // } + // else if (playerData.getCurrentAttack() == 5) + // { + // this.layerBase.playOrContinueBit(this.bitAttackWhirlSlash, playerData); + // } + // else + // { + // this.layerBase.clearAnimation(); + // } + // } + // else if (playerData.getTicksAfterAttack() < 60 && playerData.isOnGround()) + // { + // if (player.isSprinting()) + // { + // this.layerBase.playOrContinueBit(this.bitAttackStanceSprint, playerData); + // } + // else if (playerData.isStillHorizontally()) + // { + // this.layerBase.playOrContinueBit(this.bitAttackStance, playerData); + // } + // else + // { + // this.layerBase.clearAnimation(); + // } + // } + // else + // { + // this.layerBase.clearAnimation(); + // } + // } + // else + // { + // if (playerData.getTicksAfterAttack() < 10) + // { + // this.layerBase.playOrContinueBit(this.bitPunch, playerData); + // } + // else if (playerData.getTicksAfterAttack() < 60 && playerData.isStillHorizontally()) + // { + // this.layerBase.playOrContinueBit(this.bitFistGuard, playerData); + // } + // else + // { + // this.layerBase.clearAnimation(); + // } + // } + this.layerBase.perform(playerData); + } } diff --git a/src/main/java/goblinbob/mobends/standard/animation/bit/player/PunchAnimationBit.java b/src/main/java/goblinbob/mobends/standard/animation/bit/player/PunchAnimationBit.java index 584d63ac..b801f577 100644 --- a/src/main/java/goblinbob/mobends/standard/animation/bit/player/PunchAnimationBit.java +++ b/src/main/java/goblinbob/mobends/standard/animation/bit/player/PunchAnimationBit.java @@ -1,19 +1,20 @@ package goblinbob.mobends.standard.animation.bit.player; import goblinbob.mobends.core.animation.bit.AnimationBit; -import goblinbob.mobends.standard.data.PlayerData; +import goblinbob.mobends.standard.data.BipedEntityData; +import net.minecraft.util.EnumHandSide; -public class PunchAnimationBit extends AnimationBit +public class PunchAnimationBit extends AnimationBit> { + private final EnumHandSide fistPunchArm; - @Override - public String[] getActions(PlayerData entityData) + public PunchAnimationBit(EnumHandSide fistPunchArm) { - return new String[] { "attack", "punch" }; + this.fistPunchArm = fistPunchArm; } @Override - public void perform(PlayerData data) + public void perform(BipedEntityData data) { data.rightArm.rotation.setSmoothness(.3F).orientX(-90).rotateZ(20); data.leftArm.rotation.setSmoothness(.3F).orientZ(-20).rotateX(-90); @@ -34,7 +35,7 @@ public void perform(PlayerData data) data.leftForeLeg.rotation.setSmoothness(.3F).orientX(30); } - if (data.getFistPunchArm()) + if (this.fistPunchArm == EnumHandSide.RIGHT) { data.rightArm.rotation.setSmoothness(.9F).orientY(-90).rotateX(-90.0f + data.headPitch.get()).rotateY(10); data.rightForeArm.rotation.setSmoothness(.9F).orientX(0); @@ -53,5 +54,4 @@ public void perform(PlayerData data) data.renderRotation.orientY(renderRotationY); } - } diff --git a/src/main/java/goblinbob/mobends/standard/animation/controller/PlayerController.java b/src/main/java/goblinbob/mobends/standard/animation/controller/PlayerController.java index ed132237..d299af63 100644 --- a/src/main/java/goblinbob/mobends/standard/animation/controller/PlayerController.java +++ b/src/main/java/goblinbob/mobends/standard/animation/controller/PlayerController.java @@ -5,17 +5,13 @@ import goblinbob.mobends.core.animation.keyframe.ArmatureMask; import goblinbob.mobends.core.animation.layer.HardAnimationLayer; import goblinbob.mobends.standard.animation.bit.biped.*; +import goblinbob.mobends.standard.animation.bit.biped.item.*; import goblinbob.mobends.standard.animation.bit.player.*; import goblinbob.mobends.standard.data.BipedEntityData; import goblinbob.mobends.standard.data.PlayerData; -import goblinbob.mobends.standard.main.ModConfig; -import goblinbob.mobends.standard.main.ModConfig.ItemClassification; import net.minecraft.client.entity.AbstractClientPlayer; -import net.minecraft.client.model.ModelBiped; -import net.minecraft.client.model.ModelBiped.ArmPose; import net.minecraft.entity.EntityLivingBase; import net.minecraft.item.*; -import net.minecraft.util.EnumHand; import net.minecraft.util.EnumHandSide; import java.util.ArrayList; @@ -32,7 +28,6 @@ public class PlayerController implements IAnimationController protected HardAnimationLayer> layerBase = new HardAnimationLayer<>(); protected HardAnimationLayer> layerTorch = new HardAnimationLayer<>(); protected HardAnimationLayer> layerSneak = new HardAnimationLayer<>(); - protected HardAnimationLayer> layerAction = new HardAnimationLayer<>(); protected HardAnimationLayer> layerCape = new HardAnimationLayer<>(); protected AnimationBit> bitStand = new StandAnimationBit<>(); @@ -47,16 +42,13 @@ public class PlayerController implements IAnimationController protected AnimationBit bitSprint = new goblinbob.mobends.standard.animation.bit.player.SprintAnimationBit(); protected AnimationBit bitSprintJump = new SprintJumpAnimationBit(); protected AnimationBit> bitTorchHolding = new TorchHoldingAnimationBit(); - protected AnimationBit bitAttack = new AttackAnimationBit(); protected FlyingAnimationBit bitFlying = new FlyingAnimationBit(); protected ElytraAnimationBit bitElytra = new ElytraAnimationBit(); - protected BowAnimationBit bitBow = new BowAnimationBit(); - protected EatingAnimationBit bitEating = new EatingAnimationBit(); - protected HarvestAnimationBit bitHarvest = new HarvestAnimationBit(); - protected ShieldAnimationBit bitShield = new ShieldAnimationBit(); protected CapeAnimationBit bitCape = new CapeAnimationBit(); protected SleepingAnimationBit bitSleeping = new SleepingAnimationBit(); + protected final BipedActionController actionController = new BipedActionController(); + protected ArmatureMask upperBodyOnlyMask; public PlayerController() @@ -70,75 +62,20 @@ public PlayerController() this.upperBodyOnlyMask.exclude("rightForeLeg"); } - public static boolean isHoldingFood(Item activeItem) - { - return activeItem instanceof ItemFood; - } - - public static boolean isHoldingBow(ModelBiped.ArmPose mainArmPose, ModelBiped.ArmPose offArmPose) - { - return mainArmPose == ArmPose.BOW_AND_ARROW || offArmPose == ArmPose.BOW_AND_ARROW; - } - - public static boolean isShielding(ModelBiped.ArmPose mainArmPose, ModelBiped.ArmPose offArmPose) - { - return mainArmPose == ArmPose.BLOCK || offArmPose == ArmPose.BLOCK; - } - - public static boolean isHoldingWeapon(Item heldItemMainhand) - { - ItemClassification classification = ModConfig.getItemClassification(heldItemMainhand); - - return ( - classification == ModConfig.ItemClassification.WEAPON || - (classification == ModConfig.ItemClassification.UNKNOWN && heldItemMainhand instanceof ItemSword) - ); - } - public void performActionAnimations(PlayerData data, AbstractClientPlayer player) { if (player.isEntityAlive() && player.isPlayerSleeping()) { - layerAction.clearAnimation(); + actionController.clearAction(); return; } final EnumHandSide primaryHand = player.getPrimaryHand(); - final EnumHandSide offHand = primaryHand == EnumHandSide.RIGHT ? EnumHandSide.LEFT : EnumHandSide.RIGHT; final ItemStack heldItemMainhand = player.getHeldItemMainhand(); final ItemStack heldItemOffhand = player.getHeldItemOffhand(); final Item activeItem = player.getActiveItemStack().getItem(); - final ModelBiped.ArmPose armPoseMain = getAction(player, heldItemMainhand); - final ModelBiped.ArmPose armPoseOff = getAction(player, heldItemOffhand); - final EnumHandSide activeHandSide = player.getActiveHand() == EnumHand.MAIN_HAND ? primaryHand : offHand; - if (isShielding(armPoseMain, armPoseOff)) - { - bitShield.setActionHand(armPoseMain == ArmPose.BLOCK ? primaryHand : offHand); - layerAction.playOrContinueBit(bitShield, data); - } - else if (isHoldingFood(activeItem)) - { - bitEating.setActionHand(activeHandSide); - layerAction.playOrContinueBit(bitEating, data); - } - else if (isHoldingBow(armPoseMain, armPoseOff)) - { - bitBow.setActionHand(armPoseMain == ArmPose.BOW_AND_ARROW ? primaryHand : offHand); - layerAction.playOrContinueBit(bitBow, data); - } - else if (isHoldingWeapon(heldItemMainhand.getItem()) || heldItemMainhand.isEmpty()) - { - layerAction.playOrContinueBit(bitAttack, data); - } - else - { - bitHarvest.setActionHand(primaryHand); - if (player.isSwingInProgress) - layerAction.playOrContinueBit(bitHarvest, data); - else - layerAction.clearAnimation(); - } + actionController.perform(data, primaryHand, heldItemMainhand, heldItemOffhand, activeItem); } @Override @@ -239,34 +176,17 @@ else if (!data.isOnGround() || data.getTicksAfterTouchdown() < 1) } } - this.performActionAnimations(data, player); + + // Resetting item rotations + data.renderLeftItemRotation.orientZero(); + data.renderRightItemRotation.orientZero(); final List actions = new ArrayList<>(); layerBase.perform(data, actions); layerSneak.perform(data, actions); layerTorch.perform(data, actions); - layerAction.perform(data, actions); + this.performActionAnimations(data, player); layerCape.perform(data, actions); return actions; } - - private ArmPose getAction(AbstractClientPlayer player, ItemStack heldItem) - { - if (!heldItem.isEmpty()) - { - if (player.getItemInUseCount() > 0) - { - EnumAction enumaction = heldItem.getItemUseAction(); - - if (enumaction == EnumAction.BLOCK) - return ArmPose.BLOCK; - else if (enumaction == EnumAction.BOW) - return ArmPose.BOW_AND_ARROW; - } - - return ArmPose.ITEM; - } - - return ArmPose.EMPTY; - } } diff --git a/src/main/java/goblinbob/mobends/standard/animation/controller/SkeletonController.java b/src/main/java/goblinbob/mobends/standard/animation/controller/SkeletonController.java index 04947ad8..ee132bc1 100644 --- a/src/main/java/goblinbob/mobends/standard/animation/controller/SkeletonController.java +++ b/src/main/java/goblinbob/mobends/standard/animation/controller/SkeletonController.java @@ -3,21 +3,15 @@ import goblinbob.mobends.core.animation.bit.AnimationBit; import goblinbob.mobends.core.animation.controller.IAnimationController; import goblinbob.mobends.core.animation.layer.HardAnimationLayer; -import goblinbob.mobends.standard.animation.bit.biped.AttackSlashInwardAnimationBit; -import goblinbob.mobends.standard.animation.bit.biped.BowAnimationBit; -import goblinbob.mobends.standard.animation.bit.biped.HarvestAnimationBit; +import goblinbob.mobends.standard.animation.bit.biped.item.BipedActionController; import goblinbob.mobends.standard.animation.bit.biped.JumpAnimationBit; import goblinbob.mobends.standard.animation.bit.skeleton.StandAnimationBit; import goblinbob.mobends.standard.animation.bit.skeleton.WalkAnimationBit; import goblinbob.mobends.standard.data.BipedEntityData; import goblinbob.mobends.standard.data.SkeletonData; -import goblinbob.mobends.standard.main.ModConfig; -import net.minecraft.client.model.ModelBiped; import net.minecraft.entity.monster.EntitySkeleton; -import net.minecraft.item.EnumAction; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.item.ItemSword; import net.minecraft.util.EnumHandSide; import java.util.ArrayList; @@ -33,61 +27,28 @@ */ public class SkeletonController implements IAnimationController { - protected HardAnimationLayer> layerBase; - protected HardAnimationLayer> layerAction; protected AnimationBit> bitStand, bitWalk, bitJump; - protected AttackSlashInwardAnimationBit bitAttack = new AttackSlashInwardAnimationBit(); - protected BowAnimationBit bitBow = new BowAnimationBit(); - protected HarvestAnimationBit bitHarvest = new HarvestAnimationBit(); + protected final BipedActionController actionController = new BipedActionController(); public SkeletonController() { this.layerBase = new HardAnimationLayer<>(); - this.layerAction = new HardAnimationLayer<>(); this.bitStand = new StandAnimationBit(); this.bitWalk = new WalkAnimationBit(); this.bitJump = new JumpAnimationBit<>(); } - public static boolean isHoldingBow(ModelBiped.ArmPose mainArmPose, ModelBiped.ArmPose offArmPose) - { - return mainArmPose == ModelBiped.ArmPose.BOW_AND_ARROW || offArmPose == ModelBiped.ArmPose.BOW_AND_ARROW; - } - - public static boolean isHoldingWeapon(Item heldItemMainhand) - { - return heldItemMainhand instanceof ItemSword || ModConfig.getItemClassification(heldItemMainhand) == ModConfig.ItemClassification.WEAPON; - } - public void performActionAnimations(SkeletonData data, EntitySkeleton skeleton) { final EnumHandSide primaryHand = skeleton.getPrimaryHand(); - final EnumHandSide offHand = primaryHand == EnumHandSide.RIGHT ? EnumHandSide.LEFT : EnumHandSide.RIGHT; final ItemStack heldItemMainhand = skeleton.getHeldItemMainhand(); final ItemStack heldItemOffhand = skeleton.getHeldItemOffhand(); - final ModelBiped.ArmPose armPoseMain = getAction(skeleton, heldItemMainhand); - final ModelBiped.ArmPose armPoseOff = getAction(skeleton, heldItemOffhand); + final Item activeItem = skeleton.getActiveItemStack().getItem(); - if (isHoldingBow(armPoseMain, armPoseOff)) - { - bitBow.setActionHand(armPoseMain == ModelBiped.ArmPose.BOW_AND_ARROW ? primaryHand : offHand); - layerAction.playOrContinueBit(bitBow, data); - } - else if (isHoldingWeapon(heldItemMainhand.getItem()) || heldItemMainhand.isEmpty()) - { - layerAction.playOrContinueBit(bitAttack, data); - } - else - { - bitHarvest.setActionHand(primaryHand); - if (skeleton.isSwingInProgress) - layerAction.playOrContinueBit(bitHarvest, data); - else - layerAction.clearAnimation(); - } + actionController.perform(data, primaryHand, heldItemMainhand, heldItemOffhand, activeItem); } @Override @@ -111,32 +72,10 @@ public Collection perform(SkeletonData skeletonData) } } - this.performActionAnimations(skeletonData, skeleton); List actions = new ArrayList<>(); this.layerBase.perform(skeletonData, actions); - this.layerAction.perform(skeletonData, actions); + this.performActionAnimations(skeletonData, skeleton); return actions; } - - private ModelBiped.ArmPose getAction(EntitySkeleton skeleton, ItemStack heldItem) - { - if (!heldItem.isEmpty()) - { - if (skeleton.getItemInUseCount() > 0) - { - EnumAction enumaction = heldItem.getItemUseAction(); - - if (enumaction == EnumAction.BLOCK) - return ModelBiped.ArmPose.BLOCK; - else if (enumaction == EnumAction.BOW) - return ModelBiped.ArmPose.BOW_AND_ARROW; - } - - return ModelBiped.ArmPose.ITEM; - } - - return ModelBiped.ArmPose.EMPTY; - } - } diff --git a/src/main/java/goblinbob/mobends/standard/client/ClientProxy.java b/src/main/java/goblinbob/mobends/standard/client/ClientProxy.java index 7ff4686e..9b397bda 100644 --- a/src/main/java/goblinbob/mobends/standard/client/ClientProxy.java +++ b/src/main/java/goblinbob/mobends/standard/client/ClientProxy.java @@ -1,10 +1,13 @@ package goblinbob.mobends.standard.client; import goblinbob.mobends.core.Core; +import goblinbob.mobends.core.addon.AddonHelper; +import goblinbob.mobends.standard.DefaultAddon; import goblinbob.mobends.standard.client.event.RenderingEventHandler; import goblinbob.mobends.standard.client.renderer.entity.RenderBendsSpectralArrow; import goblinbob.mobends.standard.client.renderer.entity.RenderBendsTippedArrow; import goblinbob.mobends.standard.main.CommonProxy; +import goblinbob.mobends.standard.main.ModStatics; import net.minecraft.entity.projectile.EntitySpectralArrow; import net.minecraft.entity.projectile.EntityTippedArrow; import net.minecraftforge.common.MinecraftForge; @@ -24,6 +27,9 @@ public void preInit() public void init() { MinecraftForge.EVENT_BUS.register(new RenderingEventHandler()); + + // Registering the standard set of animations. + AddonHelper.registerAddon(ModStatics.MODID, new DefaultAddon()); } @Override diff --git a/src/main/java/goblinbob/mobends/standard/client/renderer/entity/SwordTrail.java b/src/main/java/goblinbob/mobends/standard/client/renderer/entity/SwordTrail.java index 4c7e8142..d4c3c9ea 100644 --- a/src/main/java/goblinbob/mobends/standard/client/renderer/entity/SwordTrail.java +++ b/src/main/java/goblinbob/mobends/standard/client/renderer/entity/SwordTrail.java @@ -77,13 +77,13 @@ public void draw(boolean first, boolean last) alpha = 1F - alpha; final Vec3f[] points = new Vec3f[] { - new Vec3f(0, 0, -8 + 8 * alpha + (primaryHand == EnumHandSide.LEFT ? -8 : 0)), - new Vec3f(0, 0, -8 - 8 * alpha + (primaryHand == EnumHandSide.LEFT ? -8 : 0)) + new Vec3f(0, 0, -8 + 8 * alpha), + new Vec3f(0, 0, -8 - 8 * alpha) }; GUtil.translate(points, 0, 0, 16); GUtil.rotate(points, itemRotation); - GUtil.translate(points, -1, -6, 0); + GUtil.translate(points, primaryHand == EnumHandSide.LEFT ? 1 : -1, -6, 0); GUtil.rotate(points, foreArm.rotation.getSmooth()); GUtil.translate(points, 0, -6 + 2, 0); GUtil.rotate(points, arm.rotation.getSmooth()); @@ -168,7 +168,6 @@ public void add(BipedEntityData entityData, float velocityX, float velocityY, newPart.arm.syncUp(entityData.leftArm); newPart.foreArm.syncUp(entityData.leftForeArm); newPart.itemRotation.set(entityData.renderLeftItemRotation.getSmooth()); - QuaternionUtils.rotate(newPart.itemRotation, 90F, 0F, 1F, 0F); } newPart.renderOffset.set(entityData.globalOffset.getX(), diff --git a/src/main/java/goblinbob/mobends/standard/main/MalformedConfigException.java b/src/main/java/goblinbob/mobends/standard/main/MalformedConfigException.java new file mode 100644 index 00000000..bc837e1b --- /dev/null +++ b/src/main/java/goblinbob/mobends/standard/main/MalformedConfigException.java @@ -0,0 +1,14 @@ +package goblinbob.mobends.standard.main; + +public class MalformedConfigException extends RuntimeException +{ + public MalformedConfigException(String message) + { + super(message); + } + + public MalformedConfigException(String message, Throwable cause) + { + super(message, cause); + } +} diff --git a/src/main/java/goblinbob/mobends/standard/main/MoBends.java b/src/main/java/goblinbob/mobends/standard/main/MoBends.java index bd6462dc..05f398ae 100644 --- a/src/main/java/goblinbob/mobends/standard/main/MoBends.java +++ b/src/main/java/goblinbob/mobends/standard/main/MoBends.java @@ -1,17 +1,12 @@ package goblinbob.mobends.standard.main; import goblinbob.mobends.core.Core; -import goblinbob.mobends.core.addon.AddonHelper; import goblinbob.mobends.core.addon.Addons; import goblinbob.mobends.core.animation.keyframe.AnimationLoader; -import goblinbob.mobends.core.asset.AssetReloadListener; import goblinbob.mobends.core.bender.EntityBenderRegistry; import goblinbob.mobends.core.data.EntityDatabase; import goblinbob.mobends.core.pack.PackDataProvider; import goblinbob.mobends.core.util.GsonResources; -import goblinbob.mobends.standard.DefaultAddon; -import net.minecraft.client.Minecraft; -import net.minecraft.client.resources.IReloadableResourceManager; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod.EventHandler; import net.minecraftforge.fml.common.Mod.Instance; @@ -47,9 +42,6 @@ public void init(FMLInitializationEvent event) { Core.getInstance().init(event); proxy.init(); - - // Registering the standard set of animations. - AddonHelper.registerAddon(ModStatics.MODID, new DefaultAddon()); } @EventHandler diff --git a/src/main/java/goblinbob/mobends/standard/main/ModConfig.java b/src/main/java/goblinbob/mobends/standard/main/ModConfig.java index 553403cc..ac793b8d 100644 --- a/src/main/java/goblinbob/mobends/standard/main/ModConfig.java +++ b/src/main/java/goblinbob/mobends/standard/main/ModConfig.java @@ -1,6 +1,9 @@ package goblinbob.mobends.standard.main; +import goblinbob.mobends.core.util.ErrorReporter; +import goblinbob.mobends.standard.AttackActionType; import goblinbob.mobends.core.util.WildcardPattern; +import goblinbob.mobends.standard.UseActionType; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityList; import net.minecraft.item.Item; @@ -11,10 +14,8 @@ import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; +import java.util.function.Function; @Config(modid = ModStatics.MODID) public class ModConfig @@ -25,10 +26,10 @@ public class ModConfig public static boolean showSwordTrail = true; @Config.LangKey(ModStatics.MODID + ".config.perform_spin_attack") public static boolean performSpinAttack = true; - @Config.LangKey(ModStatics.MODID + ".config.weapon_items") - public static String[] weaponItems = new String[] {}; - @Config.LangKey(ModStatics.MODID + ".config.tool_items") - public static String[] toolItems = new String[] {}; + @Config.LangKey(ModStatics.MODID + ".config.item_use_classifications") + public static String[] itemUseClassifications = new String[] {}; + @Config.LangKey(ModStatics.MODID + ".config.item_attack_classifications") + public static String[] itemAttackClassifications = new String[] {}; @Config.LangKey(ModStatics.MODID + ".config.keep_armor_as_vanilla") public static String[] keepArmorAsVanilla = new String[] {}; @Config.LangKey(ModStatics.MODID + ".config.keep_entity_as_vanilla") @@ -39,13 +40,20 @@ public class ModConfig @Config.Ignore private static Map keepEntityAsVanillaCache; @Config.Ignore - private static Map itemClassificationCache; + private static Map itemUseClassificationCache; + @Config.Ignore + private static Map itemAttackClassificationCache; + @Config.Ignore + private static LinkedList> itemUseClassificationEntries = new LinkedList<>(); + @Config.Ignore + private static LinkedList> itemAttackClassificationEntries = new LinkedList<>(); @Config.Ignore private static List> caches = Arrays.asList( keepArmorAsVanillaCache = new HashMap<>(), keepEntityAsVanillaCache = new HashMap<>(), - itemClassificationCache = new HashMap<>() + itemUseClassificationCache = new HashMap<>(), + itemAttackClassificationCache = new HashMap<>() ); @Mod.EventBusSubscriber(modid = ModStatics.MODID) @@ -69,16 +77,52 @@ public static void onConfigChanged(final ConfigChangedEvent.OnConfigChangedEvent cache.clear(); } + itemUseClassificationEntries.clear(); + getOrMakeEntries(itemUseClassificationEntries, itemUseClassifications, UseActionType::valueOf); + + itemAttackClassificationEntries.clear(); + getOrMakeEntries(itemAttackClassificationEntries, itemAttackClassifications, AttackActionType::valueOf); + MoBends.refreshSystems(); } } } - public enum ItemClassification + private static LinkedList> getOrMakeEntries(LinkedList> entries, String[] rawEntries, Function parseFunction) { - UNKNOWN, - WEAPON, - TOOL, + if (rawEntries.length == 0) + return entries; + + if (entries.size() == 0) + { + for (String rawEntry : rawEntries) + { + try + { + entries.addFirst(ItemClassificationEntry.parse(rawEntry, parseFunction)); + } + catch(MalformedConfigException e) + { + ErrorReporter.showErrorToPlayer(String.format("Invalid configuration! %s", e.getMessage())); + } + } + } + + return entries; + } + + private static boolean doesLocationMatchPattern(ResourceLocation resourceLocation, String pattern) + { + final ResourceLocation patternLocation = new ResourceLocation(pattern); + + if (resourceLocation.equals(patternLocation)) + return true; + + WildcardPattern domainPattern = new WildcardPattern(patternLocation.getResourceDomain()); + WildcardPattern pathPattern = new WildcardPattern(patternLocation.getResourcePath()); + + return domainPattern.matches(resourceLocation.getResourceDomain()) && + pathPattern.matches(resourceLocation.getResourcePath()); } private static boolean checkForPatterns(ResourceLocation resourceLocation, String[] patterns) @@ -106,29 +150,56 @@ private static boolean checkForPatterns(ResourceLocation resourceLocation, Strin return false; } - public static ItemClassification getItemClassification(Item item) + public static UseActionType getItemUseAction(Item item) { // If cached before, returning the cached classification. - return itemClassificationCache.computeIfAbsent(item, (i) -> { + return itemUseClassificationCache.computeIfAbsent(item, (i) -> { ResourceLocation location = item.getRegistryName(); - if (checkForPatterns(location, weaponItems)) - return ItemClassification.WEAPON; + if (location != null) + { + List> entries = getOrMakeEntries(itemUseClassificationEntries, itemUseClassifications, UseActionType::valueOf); + for (ItemClassificationEntry e : entries) + { + if (doesLocationMatchPattern(location, e.pattern)) + { + return e.classification; + } + } + } - if (checkForPatterns(location, toolItems)) - return ItemClassification.TOOL; + // Unclassified + return null; + }); + } + + public static AttackActionType getItemAttackAction(Item item) + { + // If cached before, returning the cached classification. + return itemAttackClassificationCache.computeIfAbsent(item, (i) -> { + ResourceLocation location = item.getRegistryName(); + + if (location != null) + { + List> entries = getOrMakeEntries(itemAttackClassificationEntries, itemAttackClassifications, AttackActionType::valueOf); + for (ItemClassificationEntry e : entries) + { + if (doesLocationMatchPattern(location, e.pattern)) + { + return e.classification; + } + } + } // Unclassified - return ItemClassification.UNKNOWN; + return null; }); } public static boolean shouldKeepArmorAsVanilla(Item item) { // If cached before, returning the cached result. - return keepArmorAsVanillaCache.computeIfAbsent(item, (i) -> { - return checkForPatterns(i.getRegistryName(), keepArmorAsVanilla); - }); + return keepArmorAsVanillaCache.computeIfAbsent(item, (i) -> checkForPatterns(i.getRegistryName(), keepArmorAsVanilla)); } public static boolean shouldKeepEntityAsVanilla(Entity entity) @@ -141,4 +212,40 @@ public static boolean shouldKeepEntityAsVanilla(Entity entity) return location != null && checkForPatterns(location, keepEntityAsVanilla); }); } + + private static class ItemClassificationEntry + { + public final String pattern; + public final T classification; + + public ItemClassificationEntry(String pattern, T classification) + { + this.pattern = pattern; + this.classification = classification; + } + + public static ItemClassificationEntry parse(String encoded, Function parsingFunction) + { + int indexOfEquals = encoded.indexOf("="); + + if (indexOfEquals == -1) + { + throw new IllegalArgumentException(String.format("No equals sign found in the item classification entry: %s", encoded)); + } + + String pattern = encoded.substring(0, indexOfEquals); + String encodedActionType = encoded.substring(indexOfEquals + 1).toUpperCase(); + + try + { + T actionType = parsingFunction.apply(encodedActionType); + + return new ItemClassificationEntry<>(pattern, actionType); + } + catch(IllegalArgumentException e) + { + throw new MalformedConfigException(String.format("Unknown action type: %s", encodedActionType), e); + } + } + } } diff --git a/src/main/java/goblinbob/mobends/standard/main/ModStatics.java b/src/main/java/goblinbob/mobends/standard/main/ModStatics.java index ab09f0fc..cb0eb5c3 100644 --- a/src/main/java/goblinbob/mobends/standard/main/ModStatics.java +++ b/src/main/java/goblinbob/mobends/standard/main/ModStatics.java @@ -4,7 +4,7 @@ public class ModStatics { public static final String MODID = "mobends"; public static final String LOADER = "forge"; - public static final String VERSION = "1.1.0"; + public static final String VERSION = "1.2.1"; public static final String MCVERSION = "1.12.2"; public static final String VERSION_STRING = VERSION + "/" + MCVERSION + "-" + LOADER; diff --git a/src/main/resources/assets/mobends/animations/wolf_breathing.bendsanim b/src/main/resources/assets/mobends/animations/wolf_breathing.bendsanim index 9bb2e691..a254027b 100644 Binary files a/src/main/resources/assets/mobends/animations/wolf_breathing.bendsanim and b/src/main/resources/assets/mobends/animations/wolf_breathing.bendsanim differ diff --git a/src/main/resources/assets/mobends/animations/wolf_idle.bendsanim b/src/main/resources/assets/mobends/animations/wolf_idle.bendsanim index 8a719647..bb23ad39 100644 Binary files a/src/main/resources/assets/mobends/animations/wolf_idle.bendsanim and b/src/main/resources/assets/mobends/animations/wolf_idle.bendsanim differ diff --git a/src/main/resources/assets/mobends/animations/wolf_run.bendsanim b/src/main/resources/assets/mobends/animations/wolf_run.bendsanim index 5a15a4a2..61e755a7 100644 Binary files a/src/main/resources/assets/mobends/animations/wolf_run.bendsanim and b/src/main/resources/assets/mobends/animations/wolf_run.bendsanim differ diff --git a/src/main/resources/assets/mobends/animations/wolf_sitting.bendsanim b/src/main/resources/assets/mobends/animations/wolf_sitting.bendsanim index 2bfae5ff..f4147667 100644 Binary files a/src/main/resources/assets/mobends/animations/wolf_sitting.bendsanim and b/src/main/resources/assets/mobends/animations/wolf_sitting.bendsanim differ diff --git a/src/main/resources/assets/mobends/animations/wolf_sitting_down.bendsanim b/src/main/resources/assets/mobends/animations/wolf_sitting_down.bendsanim index 3ffae1a2..2a3c8fa5 100644 Binary files a/src/main/resources/assets/mobends/animations/wolf_sitting_down.bendsanim and b/src/main/resources/assets/mobends/animations/wolf_sitting_down.bendsanim differ diff --git a/src/main/resources/assets/mobends/animations/wolf_standing_up.bendsanim b/src/main/resources/assets/mobends/animations/wolf_standing_up.bendsanim index f9ae3e13..156b5dd2 100644 Binary files a/src/main/resources/assets/mobends/animations/wolf_standing_up.bendsanim and b/src/main/resources/assets/mobends/animations/wolf_standing_up.bendsanim differ diff --git a/src/main/resources/assets/mobends/animations/wolf_test.bendsanim b/src/main/resources/assets/mobends/animations/wolf_test.bendsanim index da043e94..02c51f0b 100644 Binary files a/src/main/resources/assets/mobends/animations/wolf_test.bendsanim and b/src/main/resources/assets/mobends/animations/wolf_test.bendsanim differ diff --git a/src/main/resources/assets/mobends/animations/wolf_walking.bendsanim b/src/main/resources/assets/mobends/animations/wolf_walking.bendsanim index ad1c092b..171123f2 100644 Binary files a/src/main/resources/assets/mobends/animations/wolf_walking.bendsanim and b/src/main/resources/assets/mobends/animations/wolf_walking.bendsanim differ diff --git a/src/main/resources/assets/mobends/lang/en_us.lang b/src/main/resources/assets/mobends/lang/en_us.lang index bbe9ef91..fec26ebe 100644 --- a/src/main/resources/assets/mobends/lang/en_us.lang +++ b/src/main/resources/assets/mobends/lang/en_us.lang @@ -30,4 +30,10 @@ mobends.config.show_arrow_trails.tooltip=If true, arrow trails will be shown mobends.config.show_sword_trails=Show Sword Trails mobends.config.show_sword_trails.tooltip=If true, sword trails will be shown mobends.config.perform_spin_attack=Perform Spin Attack -mobends.config.perform_spin_attack.tooltip=If true, the spin attack (whirl slash) will be occur. \ No newline at end of file +mobends.config.perform_spin_attack.tooltip=If true, the spin attack (whirl slash) will be occur. +mobends.config.item_use_classifications=Item use classifications +mobends.config.item_use_classifications.tooltip=A list of "item=classification" mappings. +mobends.config.item_attack_classifications=Item attack classifications +mobends.config.item_attack_classifications.tooltip=A list of "item=classification" mappings. +mobends.config.keep_armor_as_vanilla=Keep armor as vanilla +mobends.config.keep_entity_as_vanilla=Keep entity as vanilla \ No newline at end of file