From 056e631240a1fa2cdf091e62c975b7285a46f508 Mon Sep 17 00:00:00 2001 From: austin Date: Sun, 4 Aug 2024 16:18:35 -0400 Subject: [PATCH] dual-hand equipping animation logic --- assets/Data/creatures/human.json | 43 +++- assets/Data/items.json | 2 +- .../client/sim/ClientSimulation.java | 2 +- src/main/java/electrosphere/engine/Main.java | 2 +- .../entity/btree/StateTransitionUtil.java | 21 +- .../entity/state/attack/ClientAttackTree.java | 6 +- .../entity/state/block/ClientBlockTree.java | 55 +++- .../client/firstPerson/FirstPersonTree.java | 8 +- .../entity/state/equip/ClientEquipState.java | 22 +- .../entity/state/equip/ServerEquipState.java | 7 +- .../entity/state/idle/ClientIdleTree.java | 2 +- .../inventory/RelationalInventoryState.java | 61 +++++ .../entity/state/movement/FallTree.java | 2 +- .../groundmove/ClientGroundMovementTree.java | 6 +- .../state/movement/jump/ClientJumpTree.java | 2 +- .../data/creature/type/block/BlockSystem.java | 9 + .../data/creature/type/equip/EquipPoint.java | 55 ++++ .../menu/ingame/MenuGeneratorsInventory.java | 236 ++++++++++-------- 18 files changed, 385 insertions(+), 156 deletions(-) diff --git a/assets/Data/creatures/human.json b/assets/Data/creatures/human.json index 8f2386b5..9ef5beee 100644 --- a/assets/Data/creatures/human.json +++ b/assets/Data/creatures/human.json @@ -253,10 +253,33 @@ "equippedAnimation" : { "nameThirdPerson" : "Idle1", "nameFirstPerson" : "Idle", - "priorityCategory" : "MODIFIER_MAX", + "priorityCategory" : "MODIFIER_HIGH", "boneGroups" : ["handRight"] } }, + { + "equipPointId" : "handsCombined", + "bone" : "Hand.R", + "firstPersonBone" : "hand.R", + "offsetVectorFirstPerson" : [-0.01,-0.05,-0.10], + "offsetVectorThirdPerson" : [0.02,-0.06,0], + "offsetRotationThirdPerson" : [-0.334,0.145,-0.28,0.89], + "offsetRotationFirstPerson" : [0.02,-0.977,-0.211,-0.005], + "canBlock" : true, + "equipClassWhitelist" : [ + "tool", + "weapon2H", + "item" + ], + "equippedAnimation" : { + "nameThirdPerson" : "HoldItemR2H", + "nameFirstPerson" : "HoldItemR2H", + "priorityCategory" : "MODIFIER_HIGH", + "boneGroups" : ["armLeft", "armRight", "handLeft", "handRight"] + }, + "isCombinedPoint": true, + "subPoints" : ["handLeft","handRight"] + }, { "equipPointId" : "Torso", "bone" : "Bone", @@ -301,6 +324,24 @@ "itemClassEquipped" : "weapon" } ] + }, + { + "variantId": "block2H", + "mainAnimation" : { + "nameThirdPerson": "HoldItemR2HBlock", + "nameFirstPerson": "HoldItemR2HBlock", + "priorityCategory": "MOVEMENT_MODIFIER", + "boneGroups" : ["armLeft", "armRight", "handLeft", "handRight"] + }, + "mainAudio" : { + "audioPath" : "Audio/weapons/swordUnsheath1.ogg" + }, + "defaults" : [ + { + "equipPoint" : "handsCombined", + "itemClassEquipped" : "weapon2H" + } + ] } ] }, diff --git a/assets/Data/items.json b/assets/Data/items.json index 5caffa93..a215c224 100644 --- a/assets/Data/items.json +++ b/assets/Data/items.json @@ -78,7 +78,7 @@ ] }, "equipData": { - "equipClass" : "weapon" + "equipClass" : "weapon2H" }, "tokens" : [ "GRAVITY", diff --git a/src/main/java/electrosphere/client/sim/ClientSimulation.java b/src/main/java/electrosphere/client/sim/ClientSimulation.java index 2a677f60..0a34ff10 100644 --- a/src/main/java/electrosphere/client/sim/ClientSimulation.java +++ b/src/main/java/electrosphere/client/sim/ClientSimulation.java @@ -92,7 +92,7 @@ public class ClientSimulation { // //update audio engine Globals.profiler.beginCpuSample("audio engine update"); - if(Globals.audioEngine!=null){ + if(Globals.audioEngine != null && Globals.audioEngine.initialized() && Globals.virtualAudioSourceManager != null){ Globals.audioEngine.update(); Globals.virtualAudioSourceManager.update((float)Globals.timekeeper.getSimFrameTime()); } diff --git a/src/main/java/electrosphere/engine/Main.java b/src/main/java/electrosphere/engine/Main.java index 3f4892b9..2870d624 100644 --- a/src/main/java/electrosphere/engine/Main.java +++ b/src/main/java/electrosphere/engine/Main.java @@ -188,9 +188,9 @@ public class Main { // } //create the audio context + Globals.audioEngine = new AudioEngine(); if(Globals.RUN_CLIENT && !Globals.HEADLESS && Globals.RUN_AUDIO){ Globals.virtualAudioSourceManager = new VirtualAudioSourceManager(); - Globals.audioEngine = new AudioEngine(); Globals.audioEngine.init(); Globals.audioEngine.listAllDevices(); Globals.initDefaultAudioResources(); diff --git a/src/main/java/electrosphere/entity/btree/StateTransitionUtil.java b/src/main/java/electrosphere/entity/btree/StateTransitionUtil.java index f55bc813..e5e6ae6c 100644 --- a/src/main/java/electrosphere/entity/btree/StateTransitionUtil.java +++ b/src/main/java/electrosphere/entity/btree/StateTransitionUtil.java @@ -127,12 +127,12 @@ public class StateTransitionUtil { if(parent == Globals.playerEntity && !Globals.controlHandler.cameraIsThirdPerson() && animation != null){ //first person //play first person audio - if(audioData != null && audioData.getAudioPath() != null){ + if(Globals.audioEngine.initialized() && audioData != null && audioData.getAudioPath() != null){ Globals.virtualAudioSourceManager.createVirtualAudioSource(audioData.getAudioPath(), VirtualAudioSourceType.CREATURE, false); } } else { //play third person audio - if(audioData != null && audioData.getAudioPath() != null){ + if(Globals.audioEngine.initialized() && audioData != null && audioData.getAudioPath() != null){ Globals.virtualAudioSourceManager.createVirtualAudioSource(audioData.getAudioPath(), VirtualAudioSourceType.CREATURE, false, EntityUtils.getPosition(parent)); } } @@ -151,7 +151,7 @@ public class StateTransitionUtil { //Play animation in first person // if(animation != null){ - FirstPersonTree.conditionallyPlayAnimation(Globals.firstPersonEntity, animation); + FirstPersonTree.conditionallyPlayAnimation(parent, animation); } } } @@ -303,21 +303,6 @@ public class StateTransitionUtil { //Tracks whether the animation has been played or not boolean startedAnimation = false; - - /** - * Gets the animation priority - * @return The animation priority - */ - int getAnimationPriority(){ - int priority = AnimationPriorities.getValue(AnimationPriorities.DEFAULT); - if(animation != null && animation.getPriority() != null){ - priority = animation.getPriority(); - } else if(getAnimation != null && getAnimation.get().getPriority() != null){ - priority = getAnimation.get().getPriority(); - } - return priority; - } - /** * Constructor */ diff --git a/src/main/java/electrosphere/entity/state/attack/ClientAttackTree.java b/src/main/java/electrosphere/entity/state/attack/ClientAttackTree.java index df3a62b9..8a56056a 100644 --- a/src/main/java/electrosphere/entity/state/attack/ClientAttackTree.java +++ b/src/main/java/electrosphere/entity/state/attack/ClientAttackTree.java @@ -246,7 +246,7 @@ public class ClientAttackTree implements BehaviorTree { entityActor.incrementAnimationTime(0.0001); } FirstPersonTree.conditionallyPlayAnimation( - Globals.firstPersonEntity, + parent, currentMove.getAnimationWindup() ); } @@ -261,7 +261,7 @@ public class ClientAttackTree implements BehaviorTree { entityActor.incrementAnimationTime(0.0001); } FirstPersonTree.conditionallyPlayAnimation( - Globals.firstPersonEntity, + parent, currentMove.getAnimationHold() ); } @@ -276,7 +276,7 @@ public class ClientAttackTree implements BehaviorTree { entityActor.incrementAnimationTime(0.0001); } FirstPersonTree.conditionallyPlayAnimation( - Globals.firstPersonEntity, + parent, currentMove.getAnimationAttack() ); } diff --git a/src/main/java/electrosphere/entity/state/block/ClientBlockTree.java b/src/main/java/electrosphere/entity/state/block/ClientBlockTree.java index d1e8a58c..1365fc77 100644 --- a/src/main/java/electrosphere/entity/state/block/ClientBlockTree.java +++ b/src/main/java/electrosphere/entity/state/block/ClientBlockTree.java @@ -8,6 +8,7 @@ import electrosphere.entity.btree.BehaviorTree; import electrosphere.entity.btree.StateTransitionUtil; import electrosphere.entity.btree.StateTransitionUtil.StateTransitionUtilItem; import electrosphere.game.data.creature.type.block.BlockSystem; +import electrosphere.game.data.creature.type.block.BlockVariant; import electrosphere.net.synchronization.BehaviorTreeIdEnums; import electrosphere.net.synchronization.annotation.SyncedField; @@ -55,20 +56,62 @@ public class ClientBlockTree implements BehaviorTree { this.stateTransitionUtil = StateTransitionUtil.create(parent, false, new StateTransitionUtilItem[]{ StateTransitionUtilItem.create( BlockState.WIND_UP, - () -> {return this.blockSystem.getBlockVariant(this.currentBlockVariant).getWindUpAnimation();}, - () -> {return this.blockSystem.getBlockVariant(this.currentBlockVariant).getWindUpAudio();}, + () -> { + BlockVariant variant = this.blockSystem.getBlockVariant(this.currentBlockVariant); + if(variant == null){ + return null; + } else { + return variant.getWindUpAnimation(); + } + }, + () -> { + BlockVariant variant = this.blockSystem.getBlockVariant(this.currentBlockVariant); + if(variant == null){ + return null; + } else { + return variant.getWindUpAudio(); + } + }, null ), StateTransitionUtilItem.create( BlockState.BLOCKING, - () -> {return this.blockSystem.getBlockVariant(this.currentBlockVariant).getMainAnimation();}, - () -> {return this.blockSystem.getBlockVariant(this.currentBlockVariant).getMainAudio();}, + () -> { + BlockVariant variant = this.blockSystem.getBlockVariant(this.currentBlockVariant); + if(variant == null){ + return null; + } else { + return variant.getMainAnimation(); + } + }, + () -> { + BlockVariant variant = this.blockSystem.getBlockVariant(this.currentBlockVariant); + if(variant == null){ + return null; + } else { + return variant.getMainAudio(); + } + }, null ), StateTransitionUtilItem.create( BlockState.COOLDOWN, - () -> {return this.blockSystem.getBlockVariant(this.currentBlockVariant).getCooldownAnimation();}, - () -> {return this.blockSystem.getBlockVariant(this.currentBlockVariant).getCooldownAudio();}, + () -> { + BlockVariant variant = this.blockSystem.getBlockVariant(this.currentBlockVariant); + if(variant == null){ + return null; + } else { + return variant.getCooldownAnimation(); + } + }, + () -> { + BlockVariant variant = this.blockSystem.getBlockVariant(this.currentBlockVariant); + if(variant == null){ + return null; + } else { + return variant.getCooldownAudio(); + } + }, null ), }); diff --git a/src/main/java/electrosphere/entity/state/client/firstPerson/FirstPersonTree.java b/src/main/java/electrosphere/entity/state/client/firstPerson/FirstPersonTree.java index 548abfa4..bd19e079 100644 --- a/src/main/java/electrosphere/entity/state/client/firstPerson/FirstPersonTree.java +++ b/src/main/java/electrosphere/entity/state/client/firstPerson/FirstPersonTree.java @@ -145,8 +145,8 @@ public class FirstPersonTree implements BehaviorTree { * @param priority The priority of the animation */ public static void conditionallyPlayAnimation(Entity entity, String animationName, int priority){ - if(entity != null && FirstPersonTree.hasTree(entity)){ - FirstPersonTree.getTree(entity).playAnimation(animationName, priority); + if(entity != null && entity == Globals.playerEntity && FirstPersonTree.hasTree(Globals.firstPersonEntity)){ + FirstPersonTree.getTree(Globals.firstPersonEntity).playAnimation(animationName, priority); } } @@ -156,8 +156,8 @@ public class FirstPersonTree implements BehaviorTree { * @param animationName the name of the animation */ public static void conditionallyPlayAnimation(Entity entity, TreeDataAnimation animation){ - if(entity != null && FirstPersonTree.hasTree(entity)){ - FirstPersonTree.getTree(entity).playAnimation(animation); + if(entity != null && entity == Globals.playerEntity && FirstPersonTree.hasTree(Globals.firstPersonEntity)){ + FirstPersonTree.getTree(Globals.firstPersonEntity).playAnimation(animation); } } diff --git a/src/main/java/electrosphere/entity/state/equip/ClientEquipState.java b/src/main/java/electrosphere/entity/state/equip/ClientEquipState.java index 3bc772ee..3f8ade8f 100644 --- a/src/main/java/electrosphere/entity/state/equip/ClientEquipState.java +++ b/src/main/java/electrosphere/entity/state/equip/ClientEquipState.java @@ -16,10 +16,12 @@ import electrosphere.entity.EntityDataStrings; import electrosphere.entity.EntityTags; import electrosphere.entity.EntityUtils; import electrosphere.entity.btree.BehaviorTree; +import electrosphere.entity.state.client.firstPerson.FirstPersonTree; import electrosphere.entity.state.gravity.GravityUtils; import electrosphere.entity.types.attach.AttachUtils; import electrosphere.entity.types.creature.CreatureUtils; import electrosphere.entity.types.item.ItemUtils; +import electrosphere.game.data.common.TreeDataAnimation; import electrosphere.game.data.creature.type.equip.EquipPoint; import electrosphere.game.data.item.type.EquipWhitelist; import electrosphere.logger.LoggerInterface; @@ -405,9 +407,23 @@ public class ClientEquipState implements BehaviorTree { @Override public void simulate(float deltaTime) { - - - + Actor thirdPersonActor = EntityUtils.getActor(parent); + //play animations for equip points that have items equipped + for(EquipPoint point : this.equipPoints){ + if(this.hasEquippedAtPoint(point.getEquipPointId()) && point.getEquippedAnimation() != null){ + TreeDataAnimation animation = point.getEquippedAnimation(); + //play third person + if(!thirdPersonActor.isPlayingAnimation() || !thirdPersonActor.isPlayingAnimation(animation)){ + if(animation != null){ + thirdPersonActor.playAnimation(animation,true); + } + thirdPersonActor.incrementAnimationTime(0.0001); + } + + //play first person + FirstPersonTree.conditionallyPlayAnimation(parent, animation); + } + } } diff --git a/src/main/java/electrosphere/entity/state/equip/ServerEquipState.java b/src/main/java/electrosphere/entity/state/equip/ServerEquipState.java index 6c4db1ae..0f25213e 100644 --- a/src/main/java/electrosphere/entity/state/equip/ServerEquipState.java +++ b/src/main/java/electrosphere/entity/state/equip/ServerEquipState.java @@ -31,6 +31,7 @@ import electrosphere.game.data.creature.type.block.BlockSystem; import electrosphere.game.data.creature.type.block.BlockVariant; import electrosphere.game.data.creature.type.equip.EquipPoint; import electrosphere.game.data.item.type.EquipWhitelist; +import electrosphere.logger.LoggerInterface; import electrosphere.net.parser.net.message.InventoryMessage; import electrosphere.net.parser.net.message.NetworkMessage; import electrosphere.net.server.player.Player; @@ -411,7 +412,11 @@ public class ServerEquipState implements BehaviorTree { //TODO: refactor to allow sending more than one variant at a time //ie if you have two items equipped and you want to block with both - blockTree.setCurrentBlockVariant(blockVariant.getVariantId()); + if(blockVariant != null){ + blockTree.setCurrentBlockVariant(blockVariant.getVariantId()); + } else { + LoggerInterface.loggerEngine.ERROR(new IllegalStateException("Equipped item to equip point that does not have assigned block variant!!")); + } } } } diff --git a/src/main/java/electrosphere/entity/state/idle/ClientIdleTree.java b/src/main/java/electrosphere/entity/state/idle/ClientIdleTree.java index 77c25519..298ecafc 100644 --- a/src/main/java/electrosphere/entity/state/idle/ClientIdleTree.java +++ b/src/main/java/electrosphere/entity/state/idle/ClientIdleTree.java @@ -93,7 +93,7 @@ public class ClientIdleTree implements BehaviorTree { entityActor.playAnimation(idleData.getAnimation(),true); entityActor.incrementAnimationTime(0.0001); } - FirstPersonTree.conditionallyPlayAnimation(Globals.firstPersonEntity, idleData.getAnimation()); + FirstPersonTree.conditionallyPlayAnimation(parent, idleData.getAnimation()); } break; case NOT_IDLE: diff --git a/src/main/java/electrosphere/entity/state/inventory/RelationalInventoryState.java b/src/main/java/electrosphere/entity/state/inventory/RelationalInventoryState.java index 492eaa99..d6a689a4 100644 --- a/src/main/java/electrosphere/entity/state/inventory/RelationalInventoryState.java +++ b/src/main/java/electrosphere/entity/state/inventory/RelationalInventoryState.java @@ -8,6 +8,7 @@ import java.util.Map; import electrosphere.entity.Entity; import electrosphere.entity.types.item.ItemUtils; import electrosphere.game.data.creature.type.equip.EquipPoint; +import electrosphere.logger.LoggerInterface; public class RelationalInventoryState { @@ -80,6 +81,12 @@ public class RelationalInventoryState { return null; } + /** + * Checks if the inventory can equip the item to the given slot + * @param item The item + * @param slot The slot + * @return true if can equip, false otherwise + */ public boolean canEquipItemToSlot(Entity item, String slot){ String itemClass = ItemUtils.getEquipClass(item); if(slotWhitelists.get(slot).contains(itemClass)){ @@ -88,8 +95,62 @@ public class RelationalInventoryState { return false; } + /** + * Gets an equip point from a given slot name + * @param slot The name of the slot + * @return The equip point + */ public EquipPoint getEquipPointFromSlot(String slot){ return equipPoints.get(slot); } + /** + * Gets whether the item can equipped to a combined slot that contains the singular slot provided + * @param item The item + * @param slot The singular (non-combined) slot + * @return true if there is a combined slot that includes slot which can equip the item, false otherwise + */ + public boolean canEquipItemToCombinedSlot(Entity item, String slot){ + String itemClass = ItemUtils.getEquipClass(item); + EquipPoint singlePoint = getEquipPointFromSlot(slot); + EquipPoint combinedPoint = null; + for(String currentPointNames : this.equipPoints.keySet()){ + EquipPoint currentPoint = this.equipPoints.get(currentPointNames); + if(currentPoint.isCombinedPoint() && currentPoint.getSubPoints().contains(singlePoint.getEquipPointId())){ + combinedPoint = currentPoint; + break; + } + } + if(combinedPoint != null){ + for(String equipClassWhitelisted : combinedPoint.getEquipClassWhitelist()){ + if(equipClassWhitelisted.equalsIgnoreCase(itemClass) && !equipClassWhitelisted.equals(itemClass)){ + String message = "Combined equip point passed over because the item class for the equip point does not match the item's defined item class\n" + + "However, the difference is only in capitalization! Equip point defined class:" + equipClassWhitelisted + " Item-defined class:" + itemClass; + ; + LoggerInterface.loggerEngine.WARNING(message); + } + } + if(combinedPoint.getEquipClassWhitelist().contains(itemClass)){ + return true; + } + } + return false; + } + + /** + * Gets the combined point that contains this point + * @param slot The singular (non-combined) slot + * @return The combined point if it exists, null otherwise + */ + public EquipPoint getCombinedPoint(String slot){ + EquipPoint singlePoint = getEquipPointFromSlot(slot); + for(String currentPointNames : this.equipPoints.keySet()){ + EquipPoint currentPoint = this.equipPoints.get(currentPointNames); + if(currentPoint.isCombinedPoint() && currentPoint.getSubPoints().contains(singlePoint.getEquipPointId())){ + return currentPoint; + } + } + return null; + } + } diff --git a/src/main/java/electrosphere/entity/state/movement/FallTree.java b/src/main/java/electrosphere/entity/state/movement/FallTree.java index 6dd9cf20..b473e4b0 100644 --- a/src/main/java/electrosphere/entity/state/movement/FallTree.java +++ b/src/main/java/electrosphere/entity/state/movement/FallTree.java @@ -97,7 +97,7 @@ public class FallTree implements BehaviorTree { entityActor.playAnimation(fallMovementSystem.getLandState().getAnimation().getNameThirdPerson(),AnimationPriorities.getValue(AnimationPriorities.MOVEMENT_MODIFIER)); entityActor.incrementAnimationTime(0.0001); } - FirstPersonTree.conditionallyPlayAnimation(Globals.firstPersonEntity, fallMovementSystem.getLandState().getAnimation()); + FirstPersonTree.conditionallyPlayAnimation(parent, fallMovementSystem.getLandState().getAnimation()); } } } diff --git a/src/main/java/electrosphere/entity/state/movement/groundmove/ClientGroundMovementTree.java b/src/main/java/electrosphere/entity/state/movement/groundmove/ClientGroundMovementTree.java index c478fc99..ee1947e1 100644 --- a/src/main/java/electrosphere/entity/state/movement/groundmove/ClientGroundMovementTree.java +++ b/src/main/java/electrosphere/entity/state/movement/groundmove/ClientGroundMovementTree.java @@ -298,7 +298,7 @@ public class ClientGroundMovementTree implements BehaviorTree { entityActor.playAnimation(animationToPlay,AnimationPriorities.getValue(AnimationPriorities.CORE_MOVEMENT)); entityActor.incrementAnimationTime(0.0001); } - FirstPersonTree.conditionallyPlayAnimation(Globals.firstPersonEntity, groundMovementData.getAnimationStartup().getNameFirstPerson(), AnimationPriorities.getValue(AnimationPriorities.CORE_MOVEMENT)); + FirstPersonTree.conditionallyPlayAnimation(parent, groundMovementData.getAnimationStartup().getNameFirstPerson(), AnimationPriorities.getValue(AnimationPriorities.CORE_MOVEMENT)); } //run startup code velocity = velocity + acceleration * (float)Globals.timekeeper.getSimFrameTime(); @@ -332,7 +332,7 @@ public class ClientGroundMovementTree implements BehaviorTree { entityActor.playAnimation(animationToPlay,AnimationPriorities.getValue(AnimationPriorities.CORE_MOVEMENT)); entityActor.incrementAnimationTime(0.0001); } - FirstPersonTree.conditionallyPlayAnimation(Globals.firstPersonEntity, groundMovementData.getAnimationLoop().getNameFirstPerson(), AnimationPriorities.getValue(AnimationPriorities.CORE_MOVEMENT)); + FirstPersonTree.conditionallyPlayAnimation(parent, groundMovementData.getAnimationLoop().getNameFirstPerson(), AnimationPriorities.getValue(AnimationPriorities.CORE_MOVEMENT)); } if(velocity != maxNaturalVelocity){ velocity = maxNaturalVelocity; @@ -360,7 +360,7 @@ public class ClientGroundMovementTree implements BehaviorTree { entityActor.playAnimation(animationToPlay,AnimationPriorities.getValue(AnimationPriorities.CORE_MOVEMENT)); entityActor.incrementAnimationTime(0.0001); } - FirstPersonTree.conditionallyPlayAnimation(Globals.firstPersonEntity, groundMovementData.getAnimationWindDown().getNameFirstPerson(), AnimationPriorities.getValue(AnimationPriorities.CORE_MOVEMENT)); + FirstPersonTree.conditionallyPlayAnimation(parent, groundMovementData.getAnimationWindDown().getNameFirstPerson(), AnimationPriorities.getValue(AnimationPriorities.CORE_MOVEMENT)); } //velocity stuff velocity = velocity - acceleration * (float)Globals.timekeeper.getSimFrameTime(); diff --git a/src/main/java/electrosphere/entity/state/movement/jump/ClientJumpTree.java b/src/main/java/electrosphere/entity/state/movement/jump/ClientJumpTree.java index 27eb763a..b36196b8 100644 --- a/src/main/java/electrosphere/entity/state/movement/jump/ClientJumpTree.java +++ b/src/main/java/electrosphere/entity/state/movement/jump/ClientJumpTree.java @@ -96,7 +96,7 @@ public class ClientJumpTree implements BehaviorTree { entityActor.playAnimation(jumpData.getAnimationJump().getNameThirdPerson(),AnimationPriorities.getValue(AnimationPriorities.MOVEMENT_MODIFIER)); entityActor.incrementAnimationTime(0.0001); } - FirstPersonTree.conditionallyPlayAnimation(Globals.firstPersonEntity, jumpData.getAnimationJump()); + FirstPersonTree.conditionallyPlayAnimation(parent, jumpData.getAnimationJump()); } //stop body falling if it is DBody body = PhysicsEntityUtils.getDBody(parent); diff --git a/src/main/java/electrosphere/game/data/creature/type/block/BlockSystem.java b/src/main/java/electrosphere/game/data/creature/type/block/BlockSystem.java index 1c8df725..9cf1f2a6 100644 --- a/src/main/java/electrosphere/game/data/creature/type/block/BlockSystem.java +++ b/src/main/java/electrosphere/game/data/creature/type/block/BlockSystem.java @@ -2,6 +2,8 @@ package electrosphere.game.data.creature.type.block; import java.util.List; +import electrosphere.logger.LoggerInterface; + /** * Stores data related to an entity blocking attacks */ @@ -10,6 +12,7 @@ public class BlockSystem { //blocking with a weapon equipped in the right hand //NOTE: the names provided here should line up with the actual field names on this object public static final String BLOCK_VARIANT_WEAPON_RIGHT = "blockWeaponRight"; + public static final String BLOCK_VARIANT_WEAPON_2H = "block2H"; //the list of block variants List variants; @@ -45,6 +48,12 @@ public class BlockSystem { public BlockVariant getVariantForPointWithItem(String equipPoint, String itemClass){ for(BlockVariant variant : variants){ for(VariantDefaults variantDefault : variant.getDefaults()){ + if(variantDefault.itemClassEquipped.equalsIgnoreCase(itemClass) && !variantDefault.itemClassEquipped.equals(itemClass)){ + String message = "Block variant passed over because the item class for the block variant does not match the item's defined item class\n" + + "However, the difference is only in capitalization! Block-variant defined class:" + variantDefault.itemClassEquipped + " Item-defined class:" + itemClass; + ; + LoggerInterface.loggerEngine.WARNING(message); + } if(variantDefault.equipPoint.equals(equipPoint) && variantDefault.itemClassEquipped.equals(itemClass)){ return variant; } diff --git a/src/main/java/electrosphere/game/data/creature/type/equip/EquipPoint.java b/src/main/java/electrosphere/game/data/creature/type/equip/EquipPoint.java index 4be48c4d..6c250972 100644 --- a/src/main/java/electrosphere/game/data/creature/type/equip/EquipPoint.java +++ b/src/main/java/electrosphere/game/data/creature/type/equip/EquipPoint.java @@ -39,6 +39,45 @@ public class EquipPoint { //The animation to play when this equip point has an item equipped (ie if a hand is grasping something) TreeDataAnimation equippedAnimation; + + + + + + + + /** + * + * + * COMBINED EQUIP POINTS + * + * The idea of a combined equip point is that it is a combination of multiple single equip points. + * Think of equipping an item in both the left and right hands of a character at once (ie a two handed sword). + * + */ + + + /** + * Indicates whether this is a conbined equip point or not + */ + boolean isCombinedPoint; + + /** + * The list of points that are contained within a combined equip point + */ + List subPoints; + + + + + + + + + + + + /** * Gets the equip point id * @return the id of the equip point @@ -152,5 +191,21 @@ public class EquipPoint { public TreeDataAnimation getEquippedAnimation(){ return equippedAnimation; } + + /** + * Checks whether this is a combined equip point or not + * @return true if this is a combined equip point, false otherwise + */ + public boolean isCombinedPoint(){ + return this.isCombinedPoint; + } + + /** + * Gets the list of sub point ids that are contained within a combined point + * @return The list of sub point ids + */ + public List getSubPoints(){ + return this.subPoints; + } } diff --git a/src/main/java/electrosphere/menu/ingame/MenuGeneratorsInventory.java b/src/main/java/electrosphere/menu/ingame/MenuGeneratorsInventory.java index fb514545..2d84de4d 100644 --- a/src/main/java/electrosphere/menu/ingame/MenuGeneratorsInventory.java +++ b/src/main/java/electrosphere/menu/ingame/MenuGeneratorsInventory.java @@ -11,6 +11,7 @@ import electrosphere.entity.state.inventory.InventoryUtils; import electrosphere.entity.state.inventory.RelationalInventoryState; import electrosphere.entity.state.inventory.UnrelationalInventoryState; import electrosphere.entity.types.item.ItemUtils; +import electrosphere.game.data.creature.type.equip.EquipPoint; import electrosphere.menu.WindowStrings; import electrosphere.menu.WindowUtils; import electrosphere.renderer.ui.elements.Div; @@ -275,128 +276,141 @@ public class MenuGeneratorsInventory { List slots = inventory.getSlots(); int numSlots = slots.size(); + EquipPoint equipPoint = null; // int numRows = (numSlots / 2) + (numSlots % 2 == 1 ? 1 : 0); int incrementer = 0; for(int i = 0; i < numSlots; i++){ String texturePath = "Textures/icons/itemIconEmpty.png"; boolean hasItem = false; - if(inventory.getItemSlot(slots.get(i)) != null){ - Entity currentItem = inventory.getItemSlot(slots.get(i)); - //get texture path from item - texturePath = ItemUtils.getItemIcon(currentItem); - //flag that this isn't an empty slot - hasItem = true; - } - if(!Globals.assetManager.hasLoadedTexture(texturePath)){ - Globals.assetManager.addTexturePathtoQueue(texturePath); - } - int panelWidth = 50; - int panelHeight = 50; - int posX = 20; - if((incrementer % 2) == 1){ - posX = posX + 400; - } - int posY = 60 + (i / 2 * (panelHeight + slotSpacing)); - int itemPosX = posX; - int itemPosY = posY; - ImagePanel panel = new ImagePanel(posX,posY,panelWidth,panelHeight,texturePath); - panel.setAbsolutePosition(true); - if(hasItem == true){ - int itemId = i; - panel.setOnDragStart(new DragEventCallback() {public boolean execute(DragEvent event){ - // System.out.println("Drag start"); - Globals.dragSourceInventory = inventory; - Globals.draggedItem = inventory.getItemSlot(slots.get(itemId)); - ContainerElement container = (ContainerElement)panel.getParent(); - container.removeChild(panel); - WindowUtils.pushItemIconToItemWindow(panel); - //play sound effect - if(Globals.virtualAudioSourceManager != null){ - Globals.virtualAudioSourceManager.createVirtualAudioSource("/Audio/inventoryGrabItem.ogg", VirtualAudioSourceType.UI, false); - } - return false; - }}); - panel.setOnDrag(new DragEventCallback() {public boolean execute(DragEvent event){ - // System.out.println("Drag"); - panel.setPositionX(event.getCurrentX() - panelWidth / 2); - panel.setPositionY(event.getCurrentY() - panelHeight / 2); - return false; - }}); - panel.setOnDragRelease(new DragEventCallback(){public boolean execute(DragEvent event){ - if(panel.getParent() != div){ - if(panel.getParent() != null){ - ContainerElement container = (ContainerElement)panel.getParent(); - container.removeChild(panel); + equipPoint = inventory.getEquipPointFromSlot(slots.get(i)); + if(!equipPoint.isCombinedPoint()){ + if(inventory.getItemSlot(slots.get(i)) != null){ + Entity currentItem = inventory.getItemSlot(slots.get(i)); + //get texture path from item + texturePath = ItemUtils.getItemIcon(currentItem); + //flag that this isn't an empty slot + hasItem = true; + } + if(!Globals.assetManager.hasLoadedTexture(texturePath)){ + Globals.assetManager.addTexturePathtoQueue(texturePath); + } + int panelWidth = 50; + int panelHeight = 50; + int posX = 20; + if((incrementer % 2) == 1){ + posX = posX + 400; + } + int posY = 60 + (i / 2 * (panelHeight + slotSpacing)); + int itemPosX = posX; + int itemPosY = posY; + ImagePanel panel = new ImagePanel(posX,posY,panelWidth,panelHeight,texturePath); + panel.setAbsolutePosition(true); + if(hasItem == true){ + int itemId = i; + panel.setOnDragStart(new DragEventCallback() {public boolean execute(DragEvent event){ + // System.out.println("Drag start"); + Globals.dragSourceInventory = inventory; + Globals.draggedItem = inventory.getItemSlot(slots.get(itemId)); + ContainerElement container = (ContainerElement)panel.getParent(); + container.removeChild(panel); + WindowUtils.pushItemIconToItemWindow(panel); + //play sound effect + if(Globals.virtualAudioSourceManager != null){ + Globals.virtualAudioSourceManager.createVirtualAudioSource("/Audio/inventoryGrabItem.ogg", VirtualAudioSourceType.UI, false); } - div.addChild(panel); - Globals.elementManager.fireEvent(event, panel.getAbsoluteX(), panel.getAbsoluteY()); - } - panel.setPositionX(div.getAbsoluteX() + itemPosX); - panel.setPositionY(div.getAbsoluteY() + itemPosY); - return false; - }}); - - } else { - int itemId = i; - panel.setOnDragRelease(new DragEventCallback(){public boolean execute(DragEvent event){ - // panel.setPositionX(posX); - // panel.setPositionY(posY); - if(Globals.dragSourceInventory instanceof UnrelationalInventoryState){ - UnrelationalInventoryState sourceInventory = (UnrelationalInventoryState) Globals.dragSourceInventory; - Entity item = Globals.draggedItem; - if(inventory.canEquipItemToSlot(item, slots.get(itemId))){ - //fire equip event to equip state - ClientEquipState equipState = ClientEquipState.getEquipState(Globals.playerEntity); - equipState.commandAttemptEquip(item,inventory.getEquipPointFromSlot(slots.get(itemId))); - //play sound effect - if(Globals.virtualAudioSourceManager != null){ - Globals.virtualAudioSourceManager.createVirtualAudioSource("/Audio/inventorySlotItem.ogg", VirtualAudioSourceType.UI, false); + return false; + }}); + panel.setOnDrag(new DragEventCallback() {public boolean execute(DragEvent event){ + // System.out.println("Drag"); + panel.setPositionX(event.getCurrentX() - panelWidth / 2); + panel.setPositionY(event.getCurrentY() - panelHeight / 2); + return false; + }}); + panel.setOnDragRelease(new DragEventCallback(){public boolean execute(DragEvent event){ + if(panel.getParent() != div){ + if(panel.getParent() != null){ + ContainerElement container = (ContainerElement)panel.getParent(); + container.removeChild(panel); } + div.addChild(panel); + Globals.elementManager.fireEvent(event, panel.getAbsoluteX(), panel.getAbsoluteY()); } - //update ui - Globals.dragSourceInventory = null; - Globals.draggedItem = null; - //clear item container ui - WindowUtils.cleanItemDraggingWindow(); - //rerender both inventories - //re-render inventory - WindowUtils.replaceWindow(WindowStrings.WINDOW_CHARACTER, MenuGeneratorsInventory.createCharacterInventoryMenu(inventory)); - //re-render inventory - WindowUtils.replaceWindow(WindowUtils.getInventoryWindowID(sourceInventory.getId()), MenuGeneratorsInventory.createNaturalInventoryMenu(sourceInventory)); - } - //now the fun begins :) - //if transfer item - // remove item from current inventory - // place item in new inventory - // trigger recreation of the menu - //if drop item - // remove item from current inventory - // create item in world in front of character - // trigger recreation of the menu - //if neither of above - // replace item icon position to origin - // System.out.println("Release drag"); - //rebuild inventory windows - return false; - }}); - } - div.addChild(panel); + panel.setPositionX(div.getAbsoluteX() + itemPosX); + panel.setPositionY(div.getAbsoluteY() + itemPosY); + return false; + }}); + + } else { + int itemId = i; + panel.setOnDragRelease(new DragEventCallback(){public boolean execute(DragEvent event){ + // panel.setPositionX(posX); + // panel.setPositionY(posY); + if(Globals.dragSourceInventory instanceof UnrelationalInventoryState){ + UnrelationalInventoryState sourceInventory = (UnrelationalInventoryState) Globals.dragSourceInventory; + Entity item = Globals.draggedItem; + if(inventory.canEquipItemToSlot(item, slots.get(itemId))){ + //fire equip event to equip state + ClientEquipState equipState = ClientEquipState.getEquipState(Globals.playerEntity); + equipState.commandAttemptEquip(item,inventory.getEquipPointFromSlot(slots.get(itemId))); + //play sound effect + if(Globals.virtualAudioSourceManager != null){ + Globals.virtualAudioSourceManager.createVirtualAudioSource("/Audio/inventorySlotItem.ogg", VirtualAudioSourceType.UI, false); + } + } else if(inventory.canEquipItemToCombinedSlot(item, slots.get(itemId))){ + EquipPoint combinedPoint = inventory.getCombinedPoint(slots.get(itemId)); + //fire equip event to equip state + ClientEquipState equipState = ClientEquipState.getEquipState(Globals.playerEntity); + equipState.commandAttemptEquip(item,combinedPoint); + //play sound effect + if(Globals.virtualAudioSourceManager != null){ + Globals.virtualAudioSourceManager.createVirtualAudioSource("/Audio/inventorySlotItem.ogg", VirtualAudioSourceType.UI, false); + } + } + //update ui + Globals.dragSourceInventory = null; + Globals.draggedItem = null; + //clear item container ui + WindowUtils.cleanItemDraggingWindow(); + //rerender both inventories + //re-render inventory + WindowUtils.replaceWindow(WindowStrings.WINDOW_CHARACTER, MenuGeneratorsInventory.createCharacterInventoryMenu(inventory)); + //re-render inventory + WindowUtils.replaceWindow(WindowUtils.getInventoryWindowID(sourceInventory.getId()), MenuGeneratorsInventory.createNaturalInventoryMenu(sourceInventory)); + } + //now the fun begins :) + //if transfer item + // remove item from current inventory + // place item in new inventory + // trigger recreation of the menu + //if drop item + // remove item from current inventory + // create item in world in front of character + // trigger recreation of the menu + //if neither of above + // replace item icon position to origin + // System.out.println("Release drag"); + //rebuild inventory windows + return false; + }}); + } + div.addChild(panel); - //create the slot text - posX = 80; - if((incrementer % 2) == 1){ - posX = posX + 190; - } - posY = posY + 15; - Label slotText = new Label(0.7f); - slotText.setText(slots.get(i)); - slotText.setPositionX(posX); - slotText.setPositionY(posY); - slotText.setAbsolutePosition(true); - div.addChild(slotText); + //create the slot text + posX = 80; + if((incrementer % 2) == 1){ + posX = posX + 190; + } + posY = posY + 15; + Label slotText = new Label(0.7f); + slotText.setText(slots.get(i)); + slotText.setPositionX(posX); + slotText.setPositionY(posY); + slotText.setAbsolutePosition(true); + div.addChild(slotText); - incrementer++; + incrementer++; + } } return rVal;