diff --git a/assets/Data/creatures/human.json b/assets/Data/creatures/human.json index f1ba39ed..06a64465 100644 --- a/assets/Data/creatures/human.json +++ b/assets/Data/creatures/human.json @@ -189,9 +189,10 @@ { "attackMoveId" : "Sword1HSlash1", "type" : "MELEE_WEAPON_SWING_ONE_HAND", - "animationName" : "Armature|Sword1HSlash1", + "attackAnimationName" : "Armature|Sword1HSlash1", "damageStartFrame" : 30, "damageEndFrame" : 60, + "firesProjectile" : false, "nextMoveId" : "Sword1HSlash2", "nextAttackMoveWindowStart" : 0, "nextAttackMoveWindowEnd" : 1, @@ -203,9 +204,10 @@ { "attackMoveId" : "Sword1HSlash2", "type" : "MELEE_WEAPON_SWING_ONE_HAND", - "animationName" : "Armature|Sword1HSlash2", + "attackAnimationName" : "Armature|Sword1HSlash2", "damageStartFrame" : 30, "damageEndFrame" : 60, + "firesProjectile" : false, "nextMoveId" : "Sword1HSlash1", "nextAttackMoveWindowStart" : 0, "nextAttackMoveWindowEnd" : 1, @@ -213,6 +215,23 @@ "movementEnd" : 10, "movementGoal" : 0.1, "initialMove" : false + }, + { + "attackMoveId" : "Bow2HFire", + "type" : "RANGED_WEAPON_BOW_TWO_HAND", + "windupAnimationName" : "Armature|HoldBowString", + "holdAnimationName" : "Armature|HoldBow", + "attackAnimationName" : "Armature|HoldBowString", + "damageStartFrame" : 30, + "damageEndFrame" : 60, + "firesProjectile" : true, + "nextMoveId" : "", + "nextAttackMoveWindowStart" : 0, + "nextAttackMoveWindowEnd" : 1, + "movementStart" : 0, + "movementEnd" : 0, + "movementGoal" : 0, + "initialMove" : false } ], "healthSystem" : { diff --git a/assets/Data/items.json b/assets/Data/items.json index e3513492..e1768a3d 100644 --- a/assets/Data/items.json +++ b/assets/Data/items.json @@ -6,23 +6,26 @@ { "itemId" : "Katana", "modelPath" : "Models/katana1alt.fbx", - "hitboxes" : [ - { - "type": "hit", - "bone": "Blade1", - "radius": 0.04 - }, - { - "type": "hit", - "bone": "Blade2", - "radius": 0.04 - }, - { - "type": "hit", - "bone": "Blade3", - "radius": 0.04 - } - ], + "weaponData" : { + "weaponClass" : "sword1h", + "hitboxes" : [ + { + "type": "hit", + "bone": "Blade1", + "radius": 0.04 + }, + { + "type": "hit", + "bone": "Blade2", + "radius": 0.04 + }, + { + "type": "hit", + "bone": "Blade3", + "radius": 0.04 + } + ] + }, "tokens" : [ "GRAVITY", "BLENDER_TRANSFORM", @@ -43,8 +46,12 @@ "iconPath" : "Textures/icons/itemIconWeapon.png" }, { - "itemId" : "Bow", + "itemId" : "bow1", "modelPath": "Models/bow1.fbx", + "weaponData" : { + "weaponClass" : "bow2h", + "projectileModel" : "Models/arrow1.fbx" + }, "tokens" : [ "GRAVITY", "RANGED", diff --git a/assets/Models/arrow1.fbx b/assets/Models/arrow1.fbx index 7587acc6..73346ebe 100644 Binary files a/assets/Models/arrow1.fbx and b/assets/Models/arrow1.fbx differ diff --git a/assets/Models/baseman.fbx b/assets/Models/baseman.fbx index 7e5caefd..77109e53 100644 Binary files a/assets/Models/baseman.fbx and b/assets/Models/baseman.fbx differ diff --git a/src/main/java/electrosphere/controls/ControlHandler.java b/src/main/java/electrosphere/controls/ControlHandler.java index 28ec89d2..1609616d 100644 --- a/src/main/java/electrosphere/controls/ControlHandler.java +++ b/src/main/java/electrosphere/controls/ControlHandler.java @@ -701,7 +701,17 @@ public class ControlHandler { AttackTree attackTree = CreatureUtils.getAttackTree(Globals.playerCharacter); if(attackTree != null){ // CreatureUtils.setFacingVector(Globals.playerCharacter, new Vector3d(-cameraEyeVector.x,0,-cameraEyeVector.z).normalize()); - attackTree.start(EntityDataStrings.ATTACK_MOVE_TYPE_MELEE_SWING_ONE_HAND); + attackTree.start(); + } + } + }}); + controls.get(DATA_STRING_INPUT_CODE_ATTACK_PRIMARY).setOnRelease(new ControlMethod(){public void execute(){ + if(Globals.playerCharacter != null){ + // Vector3f cameraEyeVector = CameraEntityUtils.getCameraEye(Globals.playerCamera); + AttackTree attackTree = CreatureUtils.getAttackTree(Globals.playerCharacter); + if(attackTree != null){ + // CreatureUtils.setFacingVector(Globals.playerCharacter, new Vector3d(-cameraEyeVector.x,0,-cameraEyeVector.z).normalize()); + attackTree.release(); } } }}); diff --git a/src/main/java/electrosphere/engine/LoadingThread.java b/src/main/java/electrosphere/engine/LoadingThread.java index c17ef342..a6308a43 100644 --- a/src/main/java/electrosphere/engine/LoadingThread.java +++ b/src/main/java/electrosphere/engine/LoadingThread.java @@ -5,7 +5,7 @@ import electrosphere.controls.ControlHandler; import electrosphere.entity.Entity; import electrosphere.entity.EntityDataStrings; import electrosphere.entity.EntityUtils; -import electrosphere.entity.state.ApplyRotationTree; +import electrosphere.entity.state.movement.ApplyRotationTree; import electrosphere.game.collision.CollisionEngine; import electrosphere.entity.types.creature.CreatureUtils; import electrosphere.entity.types.item.ItemUtils; @@ -677,8 +677,10 @@ public class LoadingThread extends Thread { EntityUtils.getPosition(sword).set(new Vector3f(1,0.1f,2)); Entity shorts = ItemUtils.spawnBasicItem("boots1"); EntityUtils.getPosition(shorts).set(new Vector3f(2,0.1f,2)); - Entity hair = ItemUtils.spawnBasicItem("hairshort1"); - EntityUtils.getPosition(hair).set(new Vector3f(2,0.1f,1)); + // Entity hair = ItemUtils.spawnBasicItem("hairshort1"); + // EntityUtils.getPosition(hair).set(new Vector3f(2,0.1f,1)); + Entity bow = ItemUtils.spawnBasicItem("bow1"); + EntityUtils.getPosition(bow).set(new Vector3f(2,0.1f,1)); // //center flame // Entity fire = ParticleUtils.spawnStaticBillboardParticle(); diff --git a/src/main/java/electrosphere/entity/EntityDataStrings.java b/src/main/java/electrosphere/entity/EntityDataStrings.java index fd457427..56a4344b 100644 --- a/src/main/java/electrosphere/entity/EntityDataStrings.java +++ b/src/main/java/electrosphere/entity/EntityDataStrings.java @@ -149,6 +149,8 @@ public class EntityDataStrings { public static final String ITEM_EQUIP_CLASS = "itemEquipClass"; public static final String ITEM_ICON = "itemIcon"; public static final String ITEM_IN_WORLD_REPRESENTATION = "itemInWorldRepresentation"; + public static final String ITEM_WEAPON_CLASS = "itemWeaponClass"; + public static final String ITEM_WEAPON_DATA_RAW = "itemWeaponDataRaw"; /* @@ -158,6 +160,7 @@ public class EntityDataStrings { public static final String ATTACK_MOVE_TYPE_ACTIVE = "attackMoveTypeActive"; public static final String ATTACK_MOVE_TYPE_MELEE_SWING_ONE_HAND = "MELEE_WEAPON_SWING_ONE_HAND"; + public static final String ATTACK_MOVE_TYPE_BOW_TWO_HAND = "RANGED_WEAPON_BOW_TWO_HAND"; /* Health System diff --git a/src/main/java/electrosphere/entity/state/AttackTree.java b/src/main/java/electrosphere/entity/state/AttackTree.java index 4cb9581c..3c77a3a4 100644 --- a/src/main/java/electrosphere/entity/state/AttackTree.java +++ b/src/main/java/electrosphere/entity/state/AttackTree.java @@ -8,14 +8,21 @@ import electrosphere.entity.state.equip.EquipState; import electrosphere.entity.types.collision.CollisionObjUtils; import electrosphere.entity.types.creature.CreatureUtils; import electrosphere.entity.types.hitbox.HitboxUtils; +import electrosphere.entity.types.item.ItemUtils; +import electrosphere.entity.types.projectile.ProjectileUtils; import electrosphere.game.collision.collidable.Collidable; import electrosphere.game.data.creature.type.attack.AttackMove; +import electrosphere.game.data.creature.type.equip.EquipPoint; import electrosphere.main.Globals; import electrosphere.net.parser.net.message.EntityMessage; import electrosphere.renderer.actor.Actor; import electrosphere.renderer.anim.Animation; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; + +import org.joml.Quaterniond; +import org.joml.Quaternionf; +import org.joml.Quaternionfc; import org.joml.Vector3d; import org.joml.Vector3f; @@ -23,6 +30,7 @@ public class AttackTree { public static enum AttackTreeState { WINDUP, + HOLD, ATTACK, COOLDOWN, IDLE, @@ -47,6 +55,13 @@ public class AttackTree { List currentMoveset = null; AttackMove currentMove = null; + Entity currentWeapon = null; + boolean currentMoveHasWindup; + boolean currentMoveCanHold; + boolean stillHold = true; + boolean firesProjectile = false; + String projectileToFire = null; + String attackingPoint = null; public AttackTree(Entity e){ state = AttackTreeState.IDLE; @@ -57,37 +72,61 @@ public class AttackTree { return state; } - public void start(String attackType){ + public void start(){ + currentMoveCanHold = false; + currentMoveHasWindup = false; + stillHold = true; + firesProjectile = false; + projectileToFire = null; + currentWeapon = null; + attackingPoint = null; + //figure out attack type we should be doing + String attackType = getAttackType(); + //if we can attack, setup doing so if(canAttack(attackType)){ parent.putData(EntityDataStrings.ATTACK_MOVE_TYPE_ACTIVE, attackType); currentMoveset = (List)parent.getData(attackType); - switch(attackType){ - case EntityDataStrings.ATTACK_MOVE_TYPE_MELEE_SWING_ONE_HAND: - if(currentMove == null){ - currentMove = currentMoveset.get(0); - } else { - currentMove = getNextMove(currentMoveset,currentMove.getNextMoveId()); + if(currentMoveset != null){ + if(currentMove == null){ + currentMove = currentMoveset.get(0); + } else { + currentMove = getNextMove(currentMoveset,currentMove.getNextMoveId()); + } + if(currentMove != null){ + damageStartFrame = currentMove.getDamageStartFrame(); + damageEndFrame = currentMove.getDamageEndFrame(); + firesProjectile = currentMove.getFiresProjectile(); + if(firesProjectile){ + projectileToFire = ItemUtils.getWeaponDataRaw(currentWeapon).getProjectileModel(); } - if(currentMove != null){ - damageStartFrame = currentMove.getDamageStartFrame(); - damageEndFrame = currentMove.getDamageEndFrame(); - animationName = currentMove.getAnimationName(); - //stop movement tree - if(parent.getDataKeys().contains(EntityDataStrings.DATA_STRING_MOVEMENT_BT)){ - CreatureUtils.getEntityMovementTree(parent).interrupt(); - } - Vector3d movementVector = CreatureUtils.getFacingVector(parent); - EntityUtils.getRotation(parent).rotationTo(new Vector3f(0,0,1), new Vector3f((float)movementVector.x,(float)movementVector.y,(float)movementVector.z)); - //set initial stuff - state = AttackTreeState.WINDUP; - frameCurrent = 0; - } else { - state = AttackTreeState.IDLE; + + animationName = currentMove.getAttackAnimationName(); + //intuit windup from presence of windup anim + currentMoveHasWindup = currentMove.getWindupAnimationName() != null; + if(currentMoveHasWindup){ + animationName = currentMove.getWindupAnimationName(); } - break; + //intuit can hold from presence of windup anim + currentMoveCanHold = currentMove.getHoldAnimationName() != null; + //stop movement tree + if(parent.getDataKeys().contains(EntityDataStrings.DATA_STRING_MOVEMENT_BT)){ + CreatureUtils.getEntityMovementTree(parent).interrupt(); + } + Vector3d movementVector = CreatureUtils.getFacingVector(parent); + EntityUtils.getRotation(parent).rotationTo(new Vector3f(0,0,1), new Vector3f((float)movementVector.x,(float)movementVector.y,(float)movementVector.z)); + //set initial stuff + state = AttackTreeState.WINDUP; + frameCurrent = 0; + } else { + state = AttackTreeState.IDLE; + } } } } + + public void release(){ + stillHold = false; + } public void interrupt(){ state = AttackTreeState.IDLE; @@ -152,7 +191,11 @@ public class AttackTree { } frameCurrent++; if(frameCurrent > damageStartFrame){ - state = AttackTreeState.ATTACK; + if(currentMoveCanHold && stillHold){ + state = AttackTreeState.HOLD; + } else { + state = AttackTreeState.ATTACK; + } } if(Globals.RUN_SERVER){ Globals.server.broadcastMessage( @@ -186,6 +229,48 @@ public class AttackTree { ); } break; + case HOLD: + if(entityActor != null){ + if(!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(animationName)){ + entityActor.playAnimation(animationName,1); + entityActor.incrementAnimationTime(0.01); + } + } + if(!stillHold){ + state = AttackTreeState.ATTACK; + } + // if(Globals.RUN_SERVER){ + // Globals.server.broadcastMessage( + // EntityMessage.constructattackUpdateMessage( + // parent.getId(), + // System.currentTimeMillis(), + // (float)position.x, + // (float)position.y, + // (float)position.z, + // movementVector.x, + // movementVector.y, + // movementVector.z, + // velocity, + // 0 + // ) + // ); + // } else if(Globals.RUN_CLIENT && parent.getId() == Globals.clientCharacterID){ + // Globals.clientConnection.queueOutgoingMessage( + // EntityMessage.constructattackUpdateMessage( + // parent.getId(), + // System.currentTimeMillis(), + // (float)position.x, + // (float)position.y, + // (float)position.z, + // movementVector.x, + // movementVector.y, + // movementVector.z, + // velocity, + // 0 + // ) + // ); + // } + break; case ATTACK: if(parent.getDataKeys().contains(EntityDataStrings.ATTACH_CHILDREN_LIST)){ List attachedEntities = (List)parent.getData(EntityDataStrings.ATTACH_CHILDREN_LIST); @@ -198,6 +283,39 @@ public class AttackTree { } } } + if(firesProjectile && projectileToFire != null){ + //spawn projectile + //TODO: solve spawnPosition, initialVector + Vector3d spawnPosition = new Vector3d(0,0,0); + Quaternionf arrowRotation = new Quaternionf(); + String targetBone = null; + EquipState equipState = (EquipState)parent.getData(EntityDataStrings.EQUIP_STATE); + EquipPoint weaponPoint = null; + if((weaponPoint = equipState.getEquipPoint(attackingPoint)) != null){ + targetBone = weaponPoint.getBone(); + } + if(targetBone != null){ + Actor parentActor = EntityUtils.getActor(parent); + //transform bone space + spawnPosition = new Vector3d(parentActor.getBonePosition(targetBone)); + spawnPosition = spawnPosition.mul(((Vector3f)EntityUtils.getScale(parent))); + Quaternionf rotation = EntityUtils.getRotation(parent); + spawnPosition = spawnPosition.rotate(new Quaterniond(rotation.x,rotation.y,rotation.z,rotation.w)); + //transform worldspace + spawnPosition.add(new Vector3d(EntityUtils.getPosition(parent))); + //set + // EntityUtils.getPosition(currentEntity).set(position); + //set rotation + // Quaternionf rotation = parentActor.getBoneRotation(targetBone); + // EntityUtils.getRotation(currentEntity).set(rotation).normalize(); + // Vector3d facingAngle = CreatureUtils.getFacingVector(parent); + arrowRotation = parentActor.getBoneRotation(targetBone); + // EntityUtils.getRotation(currentEntity).rotationTo(new Vector3f(0,0,1), new Vector3f((float)facingAngle.x,(float)facingAngle.y,(float)facingAngle.z)).mul(parentActor.getBoneRotation(targetBone)).normalize(); + } + Vector3f initialVector = new Vector3f((float)movementVector.x,(float)movementVector.y,(float)movementVector.z).normalize(); + ProjectileUtils.spawnBasicProjectile(projectileToFire, spawnPosition, arrowRotation, 200, initialVector, 0.03f); + projectileToFire = null; + } frameCurrent++; if(frameCurrent > damageEndFrame){ state = AttackTreeState.COOLDOWN; @@ -293,10 +411,35 @@ public class AttackTree { public void addNetworkMessage(EntityMessage networkMessage) { networkMessageQueue.add(networkMessage); } + + String getAttackType(){ + String rVal = null; + if(parent.getDataKeys().contains(EntityDataStrings.EQUIP_STATE)){ + EquipState equipState = (EquipState)parent.getData(EntityDataStrings.EQUIP_STATE); + for(String point : equipState.equippedPoints()){ + Entity item = equipState.getEquippedItemAtPoint(point); + if(ItemUtils.isWeapon(item)){ + attackingPoint = point; + currentWeapon = item; + switch(ItemUtils.getWeaponClass(item)){ + case "sword1h": + rVal = EntityDataStrings.ATTACK_MOVE_TYPE_MELEE_SWING_ONE_HAND; + break; + case "bow2h": + rVal = EntityDataStrings.ATTACK_MOVE_TYPE_BOW_TWO_HAND; + break; + } + } + } + } + return rVal; + } boolean canAttack(String attackType){ boolean rVal = true; - if(state != AttackTreeState.IDLE){ + if(attackType == null){ + return false; + } else if(state != AttackTreeState.IDLE){ if(currentMove.getNextMoveId() != null && !currentMove.getNextMoveId().equals("")){ rVal = true; } diff --git a/src/main/java/electrosphere/entity/state/equip/EquipState.java b/src/main/java/electrosphere/entity/state/equip/EquipState.java index 36c48c3f..29448a54 100644 --- a/src/main/java/electrosphere/entity/state/equip/EquipState.java +++ b/src/main/java/electrosphere/entity/state/equip/EquipState.java @@ -96,6 +96,7 @@ public class EquipState { Globals.entityManager.setTargetable(toEquip, false); } } + // if(!hasEquipPrimary() && ItemUtils.isItem(toEquip) && !AttachUtils.isAttached(toEquip)){ // if(ItemUtils.hasEquipList(toEquip)){ // String parentCreatureId = CreatureUtils.getType(parent); @@ -139,6 +140,19 @@ public class EquipState { // } // } } + + public EquipPoint getEquipPoint(String name){ + for(EquipPoint point : equipPoints){ + if(point.getEquipPointId().equals(name)){ + return point; + } + } + return null; + } + + public Entity getEquippedItemAtPoint(String point){ + return equipMap.get(point); + } // public void drop(Entity entity){ // if(hasEquipPrimary()){ diff --git a/src/main/java/electrosphere/entity/state/ApplyRotationTree.java b/src/main/java/electrosphere/entity/state/movement/ApplyRotationTree.java similarity index 91% rename from src/main/java/electrosphere/entity/state/ApplyRotationTree.java rename to src/main/java/electrosphere/entity/state/movement/ApplyRotationTree.java index 4b0cae70..70d43f24 100644 --- a/src/main/java/electrosphere/entity/state/ApplyRotationTree.java +++ b/src/main/java/electrosphere/entity/state/movement/ApplyRotationTree.java @@ -1,10 +1,11 @@ -package electrosphere.entity.state; +package electrosphere.entity.state.movement; import org.joml.Quaterniond; import org.joml.Quaternionf; import electrosphere.entity.Entity; import electrosphere.entity.EntityUtils; +import electrosphere.entity.state.BehaviorTree; public class ApplyRotationTree implements BehaviorTree { diff --git a/src/main/java/electrosphere/entity/state/movement/ProjectileTree.java b/src/main/java/electrosphere/entity/state/movement/ProjectileTree.java new file mode 100644 index 00000000..c6bc364f --- /dev/null +++ b/src/main/java/electrosphere/entity/state/movement/ProjectileTree.java @@ -0,0 +1,38 @@ +package electrosphere.entity.state.movement; + +import org.joml.Vector3d; +import org.joml.Vector3f; + +import electrosphere.entity.Entity; +import electrosphere.entity.EntityUtils; +import electrosphere.entity.state.BehaviorTree; +import electrosphere.main.Globals; + +public class ProjectileTree implements BehaviorTree { + + Entity parent; + int maxLife; + int lifeCurrent = 0; + Vector3f vector; + + public ProjectileTree(Entity parent, int maxLife, Vector3f initialVector, float velocity){ + this.parent = parent; + this.maxLife = maxLife; + this.vector = initialVector.mul(velocity); + } + + @Override + public void simulate() { + + lifeCurrent++; + if(lifeCurrent >= maxLife){ + Globals.entityManager.deregisterEntity(parent); + Globals.entityManager.removeBehaviorTree(this); + } + + Vector3d positionCurrent = EntityUtils.getPosition(parent); + positionCurrent.add(vector); + + } + +} diff --git a/src/main/java/electrosphere/entity/types/creature/CreatureUtils.java b/src/main/java/electrosphere/entity/types/creature/CreatureUtils.java index a540154d..0092f474 100644 --- a/src/main/java/electrosphere/entity/types/creature/CreatureUtils.java +++ b/src/main/java/electrosphere/entity/types/creature/CreatureUtils.java @@ -168,11 +168,15 @@ public class CreatureUtils { //add all attack moves if(rawType.getAttackMoves() != null && rawType.getAttackMoves().size() > 0){ for(AttackMove attackMove : rawType.getAttackMoves()){ - switch(attackMove.getType()){ - case EntityDataStrings.ATTACK_MOVE_TYPE_MELEE_SWING_ONE_HAND: - rVal.putData(EntityDataStrings.ATTACK_MOVE_TYPE_MELEE_SWING_ONE_HAND, rawType.getAttackMoveResolver().getMoveset(EntityDataStrings.ATTACK_MOVE_TYPE_MELEE_SWING_ONE_HAND)); - break; - } + rVal.putData(attackMove.getType(), rawType.getAttackMoveResolver().getMoveset(attackMove.getType())); + // switch(attackMove.getType()){ + // case EntityDataStrings.ATTACK_MOVE_TYPE_MELEE_SWING_ONE_HAND: + // rVal.putData(EntityDataStrings.ATTACK_MOVE_TYPE_MELEE_SWING_ONE_HAND, rawType.getAttackMoveResolver().getMoveset(EntityDataStrings.ATTACK_MOVE_TYPE_MELEE_SWING_ONE_HAND)); + // break; + // case EntityDataStrings.ATTACK_MOVE_TYPE_BOW_TWO_HAND: + // rVal.putData(EntityDataStrings.ATTACK_MOVE_TYPE_MELEE_SWING_ONE_HAND, rawType.getAttackMoveResolver().getMoveset(EntityDataStrings.ATTACK_MOVE_TYPE_MELEE_SWING_ONE_HAND)); + // break; + // } } } break; diff --git a/src/main/java/electrosphere/entity/types/item/ItemUtils.java b/src/main/java/electrosphere/entity/types/item/ItemUtils.java index 224ec2f6..a27d124e 100644 --- a/src/main/java/electrosphere/entity/types/item/ItemUtils.java +++ b/src/main/java/electrosphere/entity/types/item/ItemUtils.java @@ -17,6 +17,7 @@ import electrosphere.game.data.creature.type.CollidableTemplate; import electrosphere.game.data.creature.type.CreatureType; import electrosphere.game.data.item.type.EquipWhitelist; import electrosphere.game.data.item.type.Item; +import electrosphere.game.data.item.type.WeaponData; import electrosphere.main.Globals; import electrosphere.net.parser.net.message.EntityMessage; import electrosphere.net.parser.net.message.NetworkMessage; @@ -43,14 +44,20 @@ public class ItemUtils { public static Entity spawnBasicItem(String name){ Item item = Globals.gameConfigCurrent.getItemMap().getItem(name); Entity rVal = EntityUtils.spawnDrawableEntity(item.getModelPath()); - if(item.getHitboxes() != null){ - List hitboxList = new LinkedList(); - for(HitboxData hitboxdata : item.getHitboxes()){ - Entity hitbox = HitboxUtils.spawnRegularHitbox(rVal, hitboxdata.getBone(), hitboxdata.getRadius()); - Globals.hitboxManager.registerHitbox(hitbox); - hitboxList.add(hitbox); + if(item.getWeaponData() != null){ + rVal.putData(EntityDataStrings.ITEM_IS_WEAPON, true); + WeaponData weaponData = item.getWeaponData(); + if(weaponData.getHitboxes() != null){ + List hitboxList = new LinkedList(); + for(HitboxData hitboxdata : weaponData.getHitboxes()){ + Entity hitbox = HitboxUtils.spawnRegularHitbox(rVal, hitboxdata.getBone(), hitboxdata.getRadius()); + Globals.hitboxManager.registerHitbox(hitbox); + hitboxList.add(hitbox); + } + rVal.putData(EntityDataStrings.HITBOX_ASSOCIATED_LIST,hitboxList); } - rVal.putData(EntityDataStrings.HITBOX_ASSOCIATED_LIST,hitboxList); + rVal.putData(EntityDataStrings.ITEM_WEAPON_CLASS,weaponData.getWeaponClass()); + rVal.putData(EntityDataStrings.ITEM_WEAPON_DATA_RAW,weaponData); } if(item.getCollidable() != null){ CollidableTemplate physicsTemplate = item.getCollidable(); @@ -244,6 +251,10 @@ public class ItemUtils { } } + public static String getWeaponClass(Entity item){ + return (String)item.getData(EntityDataStrings.ITEM_WEAPON_CLASS); + } + public static void destroyInInventoryItem(Entity item){ Globals.entityManager.deregisterEntity(item); } @@ -264,4 +275,8 @@ public class ItemUtils { return (Entity) inInventory.getData(EntityDataStrings.ITEM_IN_WORLD_REPRESENTATION); } + public static WeaponData getWeaponDataRaw(Entity item){ + return (WeaponData) item.getData(EntityDataStrings.ITEM_WEAPON_DATA_RAW); + } + } diff --git a/src/main/java/electrosphere/entity/types/projectile/ProjectileUtils.java b/src/main/java/electrosphere/entity/types/projectile/ProjectileUtils.java new file mode 100644 index 00000000..5a77697b --- /dev/null +++ b/src/main/java/electrosphere/entity/types/projectile/ProjectileUtils.java @@ -0,0 +1,30 @@ +package electrosphere.entity.types.projectile; + +import org.joml.Quaterniond; +import org.joml.Quaternionf; +import org.joml.Quaternionfc; +import org.joml.Vector3d; +import org.joml.Vector3f; + +import electrosphere.entity.Entity; +import electrosphere.entity.EntityUtils; +import electrosphere.entity.state.movement.ProjectileTree; +import electrosphere.main.Globals; + +public class ProjectileUtils { + + public static Entity spawnBasicProjectile(String model, Vector3d initialPosition, Quaternionf rotation, int maxLife, Vector3f initialVector, float velocity){ + Entity rVal = EntityUtils.spawnDrawableEntity(model); + Globals.assetManager.addModelPathToQueue(model); + ProjectileTree tree = new ProjectileTree(rVal,maxLife,initialVector,velocity); + EntityUtils.getPosition(rVal).set(initialPosition); + // EntityUtils.getRotation(currentEntity).rotationTo(new Vector3f(0,0,1), new Vector3f((float)facingAngle.x,(float)facingAngle.y,(float)facingAngle.z)).mul(parentActor.getBoneRotation(targetBone)).normalize(); + EntityUtils.getRotation(rVal).rotationTo(new Vector3f(0,0,1), new Vector3f((float)initialVector.x,(float)initialVector.y,(float)initialVector.z)).normalize(); + // ParticleTree particleTree = new ParticleTree(rVal, maxLife, destination, velocity, acceleration, true); + // rVal.putData(EntityDataStrings.PARTICLE_TREE, particleTree); + // rVal.putData(EntityDataStrings.IS_PARTICLE, true); + Globals.entityManager.registerBehaviorTree(tree); + return rVal; + } + +} diff --git a/src/main/java/electrosphere/game/data/creature/type/attack/AttackMove.java b/src/main/java/electrosphere/game/data/creature/type/attack/AttackMove.java index 813ca030..ff0f1ea5 100644 --- a/src/main/java/electrosphere/game/data/creature/type/attack/AttackMove.java +++ b/src/main/java/electrosphere/game/data/creature/type/attack/AttackMove.java @@ -1,16 +1,36 @@ package electrosphere.game.data.creature.type.attack; +import java.util.List; + /** * * @author amaterasu */ public class AttackMove { + /* + + */ String attackMoveId; String type; - String animationName; + + /* + Animation stuff + */ + String windupAnimationName; + String holdAnimationName; + String attackAnimationName; + + /* + Damage stuff + */ int damageStartFrame; int damageEndFrame; + boolean firesProjectile; + + /* + move chaining stuff + */ String nextMoveId; String movementStart; String movementEnd; @@ -25,8 +45,16 @@ public class AttackMove { return type; } - public String getAnimationName() { - return animationName; + public String getWindupAnimationName() { + return windupAnimationName; + } + + public String getHoldAnimationName() { + return holdAnimationName; + } + + public String getAttackAnimationName() { + return attackAnimationName; } public int getDamageStartFrame() { @@ -48,6 +76,10 @@ public class AttackMove { public boolean isInitialMove(){ return initialMove; } + + public boolean getFiresProjectile(){ + return firesProjectile; + } } diff --git a/src/main/java/electrosphere/game/data/item/type/Item.java b/src/main/java/electrosphere/game/data/item/type/Item.java index 7b9de107..ff98b41c 100644 --- a/src/main/java/electrosphere/game/data/item/type/Item.java +++ b/src/main/java/electrosphere/game/data/item/type/Item.java @@ -8,13 +8,13 @@ public class Item { String itemId; String modelPath; - List hitboxes; List tokens; CollidableTemplate collidable; List equipWhitelist; String idleAnim; String iconPath; String equipClass; + WeaponData weaponData; public String getItemId() { return itemId; @@ -24,10 +24,6 @@ public class Item { return modelPath; } - public List getHitboxes() { - return hitboxes; - } - public List getTokens() { return tokens; } @@ -51,5 +47,9 @@ public class Item { public String getEquipClass(){ return equipClass; } + + public WeaponData getWeaponData(){ + return weaponData; + } } diff --git a/src/main/java/electrosphere/game/data/item/type/WeaponData.java b/src/main/java/electrosphere/game/data/item/type/WeaponData.java new file mode 100644 index 00000000..a400ce68 --- /dev/null +++ b/src/main/java/electrosphere/game/data/item/type/WeaponData.java @@ -0,0 +1,25 @@ +package electrosphere.game.data.item.type; + +import java.util.List; + +import electrosphere.entity.types.hitbox.HitboxData; + +public class WeaponData { + + String weaponClass; + List hitboxes; + String projectileModel; + + public String getWeaponClass(){ + return weaponClass; + } + + public List getHitboxes(){ + return hitboxes; + } + + public String getProjectileModel(){ + return projectileModel; + } + +} diff --git a/src/main/java/electrosphere/game/server/ai/creature/MindlessAttacker.java b/src/main/java/electrosphere/game/server/ai/creature/MindlessAttacker.java index b0513800..804839c6 100644 --- a/src/main/java/electrosphere/game/server/ai/creature/MindlessAttacker.java +++ b/src/main/java/electrosphere/game/server/ai/creature/MindlessAttacker.java @@ -60,7 +60,7 @@ public class MindlessAttacker extends AI{ if(attackCooldown == 0){ attackCooldown = attackCooldownMax; AttackTree attackTree = CreatureUtils.getAttackTree(character); - attackTree.start(EntityDataStrings.ATTACK_MOVE_TYPE_MELEE_SWING_ONE_HAND); + attackTree.start(); } else { attackCooldown--; } diff --git a/src/main/java/electrosphere/game/server/ai/creature/OpportunisticAttacker.java b/src/main/java/electrosphere/game/server/ai/creature/OpportunisticAttacker.java index 8184e30a..ac060ebf 100644 --- a/src/main/java/electrosphere/game/server/ai/creature/OpportunisticAttacker.java +++ b/src/main/java/electrosphere/game/server/ai/creature/OpportunisticAttacker.java @@ -152,7 +152,7 @@ public class OpportunisticAttacker extends AI { if(attackCooldown == 0){ attackCooldown = attackCooldownMax; AttackTree attackTree = CreatureUtils.getAttackTree(character); - attackTree.start(EntityDataStrings.ATTACK_MOVE_TYPE_MELEE_SWING_ONE_HAND); + attackTree.start(); } else { attackCooldown--; } diff --git a/src/main/java/electrosphere/main/Main.java b/src/main/java/electrosphere/main/Main.java index 461a9596..c401584b 100644 --- a/src/main/java/electrosphere/main/Main.java +++ b/src/main/java/electrosphere/main/Main.java @@ -179,19 +179,19 @@ public class Main { // Globals.assetManager.addModelPathToQueue("/Models/baseman.fbx"); // Globals.assetManager.loadAssetsInQueue(); // Model model = Globals.assetManager.fetchModel("/Models/baseman.fbx"); - // for(electrosphere.renderer.anim.Animation anim : model.animations){ - // if(anim.name.equals("Armature|Idle1")){ - // System.out.println(anim.duration); - // for(electrosphere.renderer.anim.AnimChannel channel : anim.channels){ - // if(channel.getNodeID().equals("Torso")){ - // channel.fullDescribeChannel(); - // } - // // System.out.println("CHannel: " + channel.getNodeID()); - // } - // break; - // } - // } - // // model.describeHighLevel(); + // // for(electrosphere.renderer.anim.Animation anim : model.animations){ + // // if(anim.name.equals("Armature|Idle1")){ + // // System.out.println(anim.duration); + // // for(electrosphere.renderer.anim.AnimChannel channel : anim.channels){ + // // if(channel.getNodeID().equals("Torso")){ + // // channel.fullDescribeChannel(); + // // } + // // // System.out.println("CHannel: " + channel.getNodeID()); + // // } + // // break; + // // } + // // } + // model.describeHighLevel(); // System.exit(0); // }