diff --git a/assets/Data/creatures.json b/assets/Data/creatures.json index d7a1a634..db2f8747 100644 --- a/assets/Data/creatures.json +++ b/assets/Data/creatures.json @@ -112,7 +112,14 @@ "type" : "MELEE_WEAPON_SWING_ONE_HAND", "animationName" : "Armature|SwingWeapon", "damageStartFrame" : 10, - "damageEndFrame" : 30 + "damageEndFrame" : 30, + "nextMoveId" : "", + "nextAttackMoveWindowStart" : 0, + "nextAttackMoveWindowEnd" : 1, + "movementStart" : 0, + "movementEnd" : 0, + "movementGoal" : 0, + "initialMove" : true } ], "healthSystem" : { diff --git a/assets/Data/creatures/human.json b/assets/Data/creatures/human.json index c4a438d1..826735db 100644 --- a/assets/Data/creatures/human.json +++ b/assets/Data/creatures/human.json @@ -142,10 +142,32 @@ }, "attackMoves" : [ { + "attackMoveId" : "Sword1HSlash1", "type" : "MELEE_WEAPON_SWING_ONE_HAND", - "animationName" : "Armature|SwingWeapon", + "animationName" : "Armature|Sword1HSlash1", "damageStartFrame" : 30, - "damageEndFrame" : 60 + "damageEndFrame" : 60, + "nextMoveId" : "Sword1HSlash2", + "nextAttackMoveWindowStart" : 0, + "nextAttackMoveWindowEnd" : 1, + "movementStart" : 2, + "movementEnd" : 10, + "movementGoal" : 0.1, + "initialMove" : true + }, + { + "attackMoveId" : "Sword1HSlash2", + "type" : "MELEE_WEAPON_SWING_ONE_HAND", + "animationName" : "Armature|Sword1HSlash2", + "damageStartFrame" : 30, + "damageEndFrame" : 60, + "nextMoveId" : "Sword1HSlash1", + "nextAttackMoveWindowStart" : 0, + "nextAttackMoveWindowEnd" : 1, + "movementStart" : 2, + "movementEnd" : 10, + "movementGoal" : 0.1, + "initialMove" : false } ], "healthSystem" : { diff --git a/assets/Data/creatures/human2.json b/assets/Data/creatures/human2.json index 7f810977..6c775e69 100644 --- a/assets/Data/creatures/human2.json +++ b/assets/Data/creatures/human2.json @@ -158,7 +158,14 @@ "type" : "MELEE_WEAPON_SWING_ONE_HAND", "animationName" : "Armature|SwingWeapon", "damageStartFrame" : 30, - "damageEndFrame" : 60 + "damageEndFrame" : 60, + "nextMoveId" : "", + "nextAttackMoveWindowStart" : 0, + "nextAttackMoveWindowEnd" : 1, + "movementStart" : 0, + "movementEnd" : 0, + "movementGoal" : 0, + "initialMove" : true } ], "healthSystem" : { diff --git a/assets/Models/baseman.fbx b/assets/Models/baseman.fbx index 44c90e68..fb11237a 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 e795e6ae..d7862e53 100644 --- a/src/main/java/electrosphere/controls/ControlHandler.java +++ b/src/main/java/electrosphere/controls/ControlHandler.java @@ -566,10 +566,10 @@ public class ControlHandler { mainGameControlList.add(controls.get(DATA_STRING_INPUT_CODE_ATTACK_PRIMARY)); controls.get(DATA_STRING_INPUT_CODE_ATTACK_PRIMARY).setOnPress(new ControlMethod(){public void execute(){ if(Globals.playerCharacter != null){ - Vector3f cameraEyeVector = CameraEntityUtils.getCameraEye(Globals.playerCamera); + // 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()); + // CreatureUtils.setFacingVector(Globals.playerCharacter, new Vector3d(-cameraEyeVector.x,0,-cameraEyeVector.z).normalize()); attackTree.start(EntityDataStrings.ATTACK_MOVE_TYPE_MELEE_SWING_ONE_HAND); } } diff --git a/src/main/java/electrosphere/engine/LoadingThread.java b/src/main/java/electrosphere/engine/LoadingThread.java index 99f4373d..b56242f1 100644 --- a/src/main/java/electrosphere/engine/LoadingThread.java +++ b/src/main/java/electrosphere/engine/LoadingThread.java @@ -381,7 +381,7 @@ public class LoadingThread extends Thread { static void initServerArenaWorldData(){ Globals.serverWorldData = ServerWorldData.createArenaWorld(); - Globals.spawnPoint = new Vector3f(1,3,1); + Globals.spawnPoint = new Vector3f(1,0.1f,1); // Globals.serverTerrainManager.getChunk(0, 0).addModification(new TerrainModification(0,0,5,5,5)); } @@ -678,10 +678,12 @@ public class LoadingThread extends Thread { // MindlessAttacker.attachToCreature(goblin); // OpportunisticAttacker.attachToCreature(goblin); + Entity sword = ItemUtils.spawnBasicItem("Katana"); + EntityUtils.getPosition(sword).set(new Vector3f(1,0.1f,2)); Entity shorts = ItemUtils.spawnBasicItem("boots1"); - EntityUtils.getPosition(shorts).set(new Vector3f(2,1,2)); + EntityUtils.getPosition(shorts).set(new Vector3f(2,0.1f,2)); Entity hair = ItemUtils.spawnBasicItem("hairshort1"); - EntityUtils.getPosition(hair).set(new Vector3f(2,1,1)); + EntityUtils.getPosition(hair).set(new Vector3f(2,0.1f,1)); // goblin = CreatureUtils.spawnBasicCreature("Goblin"); // CollisionObjUtils.positionCharacter(goblin, new Vector3f(3, 0, 4)); diff --git a/src/main/java/electrosphere/entity/state/AttackTree.java b/src/main/java/electrosphere/entity/state/AttackTree.java index 9ab16c2c..21e46372 100644 --- a/src/main/java/electrosphere/entity/state/AttackTree.java +++ b/src/main/java/electrosphere/entity/state/AttackTree.java @@ -3,10 +3,13 @@ package electrosphere.entity.state; import electrosphere.entity.Entity; import electrosphere.entity.EntityDataStrings; import electrosphere.entity.EntityUtils; +import electrosphere.entity.state.collidable.Impulse; 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.game.data.creature.type.AttackMove; +import electrosphere.game.collision.collidable.Collidable; +import electrosphere.game.data.creature.type.attack.AttackMove; import electrosphere.main.Globals; import electrosphere.net.parser.net.message.EntityMessage; import electrosphere.renderer.actor.Actor; @@ -29,7 +32,7 @@ public class AttackTree { Entity parent; - CopyOnWriteArrayList networkMessageQueue = new CopyOnWriteArrayList(); + CopyOnWriteArrayList networkMessageQueue = new CopyOnWriteArrayList(); long lastUpdateTime = 0; @@ -41,6 +44,9 @@ public class AttackTree { String animationName = "SwingWeapon"; int maxFrame = 60; + + List currentMoveset = null; + AttackMove currentMove = null; public AttackTree(Entity e){ state = AttackTreeState.IDLE; @@ -54,22 +60,32 @@ public class AttackTree { public void start(String attackType){ if(canAttack(attackType)){ parent.putData(EntityDataStrings.ATTACK_MOVE_TYPE_ACTIVE, attackType); - AttackMove currentMove; + currentMoveset = (List)parent.getData(attackType); switch(attackType){ case EntityDataStrings.ATTACK_MOVE_TYPE_MELEE_SWING_ONE_HAND: - currentMove = (AttackMove)parent.getData(EntityDataStrings.ATTACK_MOVE_TYPE_MELEE_SWING_ONE_HAND); - damageStartFrame = currentMove.getDamageStartFrame(); - damageEndFrame = currentMove.getDamageEndFrame(); - animationName = currentMove.getAnimationName(); + if(currentMove == null){ + currentMove = currentMoveset.get(0); + } else { + currentMove = getNextMove(currentMoveset,currentMove.getNextMoveId()); + } + 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; + } break; } - 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)); - state = AttackTreeState.WINDUP; - frameCurrent = 0; } } @@ -270,7 +286,9 @@ public class AttackTree { } break; case IDLE: - break; + currentMove = null; + currentMoveset = null; + break; } } @@ -281,27 +299,41 @@ public class AttackTree { boolean canAttack(String attackType){ boolean rVal = true; if(state != AttackTreeState.IDLE){ - rVal = false; + if(currentMove.getNextMoveId() != null && !currentMove.getNextMoveId().equals("")){ + rVal = true; + } + } else { + if(parent.getDataKeys().contains(EntityDataStrings.EQUIP_STATE)){ + EquipState equipState = (EquipState)parent.getData(EntityDataStrings.EQUIP_STATE); + if(equipState.hasEquipPrimary()){ + switch(attackType){ + case EntityDataStrings.ATTACK_MOVE_TYPE_MELEE_SWING_ONE_HAND: + break; + default: + rVal = false; + break; + } + } else { + switch(attackType){ + case EntityDataStrings.ATTACK_MOVE_TYPE_MELEE_SWING_ONE_HAND: + rVal = false; + break; + default: + rVal = false; + break; + } + } + } } - if(parent.getDataKeys().contains(EntityDataStrings.EQUIP_STATE)){ - EquipState equipState = (EquipState)parent.getData(EntityDataStrings.EQUIP_STATE); - if(equipState.hasEquipPrimary()){ - switch(attackType){ - case EntityDataStrings.ATTACK_MOVE_TYPE_MELEE_SWING_ONE_HAND: - break; - default: - rVal = false; - break; - } - } else { - switch(attackType){ - case EntityDataStrings.ATTACK_MOVE_TYPE_MELEE_SWING_ONE_HAND: - rVal = false; - break; - default: - rVal = false; - break; - } + return rVal; + } + + AttackMove getNextMove(List moveset, String nextMoveId){ + AttackMove rVal = null; + for(AttackMove move : moveset){ + if(move.getAttackMoveId().equals(nextMoveId)){ + rVal = move; + break; } } return rVal; diff --git a/src/main/java/electrosphere/entity/types/creature/CreatureUtils.java b/src/main/java/electrosphere/entity/types/creature/CreatureUtils.java index 49ffa49c..c7b2b77e 100644 --- a/src/main/java/electrosphere/entity/types/creature/CreatureUtils.java +++ b/src/main/java/electrosphere/entity/types/creature/CreatureUtils.java @@ -20,9 +20,9 @@ import electrosphere.entity.state.life.LifeState; import electrosphere.entity.state.movement.SprintTree; import electrosphere.game.collision.PhysicsUtils; import electrosphere.game.collision.collidable.Collidable; -import electrosphere.game.data.creature.type.AttackMove; import electrosphere.game.data.creature.type.CollidableTemplate; import electrosphere.game.data.creature.type.SprintSystem; +import electrosphere.game.data.creature.type.attack.AttackMove; import electrosphere.game.data.creature.type.visualattribute.AttributeVariant; import electrosphere.game.data.creature.type.visualattribute.VisualAttribute; import electrosphere.logger.LoggerInterface; @@ -146,6 +146,16 @@ public class CreatureUtils { rVal.putData(EntityDataStrings.ATTACK_TREE, attackTree); rVal.putData(EntityDataStrings.ATTACK_MOVE_TYPE_ACTIVE, null); Globals.entityManager.registerAttackerEntity(rVal); + //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; + } + } + } break; case "GRAVITY": Collidable collidable = (Collidable)rVal.getData(EntityDataStrings.PHYSICS_COLLIDABLE); @@ -160,7 +170,7 @@ public class CreatureUtils { Globals.entityManager.registerTargetableEntity(rVal); break; case "CAN_EQUIP": - rVal.putData(EntityDataStrings.EQUIP_STATE, new EquipState(rVal,"Bone.031")); + rVal.putData(EntityDataStrings.EQUIP_STATE, new EquipState(rVal,"MiddleLower.R")); break; } } @@ -179,16 +189,6 @@ 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, attackMove); - break; - } - } - } //add health system rVal.putData(EntityDataStrings.LIFE_STATE, new LifeState(rVal, rawType.getHealthSystem())); Globals.entityManager.registerLifeStateEntity(rVal); diff --git a/src/main/java/electrosphere/game/data/Config.java b/src/main/java/electrosphere/game/data/Config.java index 18d07c0f..f121efb0 100644 --- a/src/main/java/electrosphere/game/data/Config.java +++ b/src/main/java/electrosphere/game/data/Config.java @@ -5,6 +5,7 @@ import java.util.List; import electrosphere.game.data.creature.type.CreatureType; import electrosphere.game.data.creature.type.CreatureTypeLoader; +import electrosphere.game.data.creature.type.attack.AttackMoveResolver; import electrosphere.game.data.creature.type.model.CreatureTypeMap; import electrosphere.game.data.foliage.type.model.FoliageTypeMap; import electrosphere.game.data.item.type.model.ItemTypeMap; @@ -58,6 +59,9 @@ public class Config { CreatureTypeLoader loader = new CreatureTypeLoader(); List typeList = readCreatureTypeFile(initialPath); for(CreatureType type : typeList){ + if(type.getAttackMoves() != null){ + type.setAttackMoveResolver(new AttackMoveResolver(type.getAttackMoves())); + } loader.putCreature(type.getCreatureId(), type); } return loader; diff --git a/src/main/java/electrosphere/game/data/creature/type/AttackMove.java b/src/main/java/electrosphere/game/data/creature/type/AttackMove.java deleted file mode 100644 index ae18bc98..00000000 --- a/src/main/java/electrosphere/game/data/creature/type/AttackMove.java +++ /dev/null @@ -1,30 +0,0 @@ -package electrosphere.game.data.creature.type; - -/** - * - * @author amaterasu - */ -public class AttackMove { - String type; - String animationName; - int damageStartFrame; - int damageEndFrame; - - public String getType() { - return type; - } - - public String getAnimationName() { - return animationName; - } - - public int getDamageStartFrame() { - return damageStartFrame; - } - - public int getDamageEndFrame() { - return damageEndFrame; - } - - -} diff --git a/src/main/java/electrosphere/game/data/creature/type/CreatureType.java b/src/main/java/electrosphere/game/data/creature/type/CreatureType.java index 7d062f23..c9a06d4e 100644 --- a/src/main/java/electrosphere/game/data/creature/type/CreatureType.java +++ b/src/main/java/electrosphere/game/data/creature/type/CreatureType.java @@ -1,6 +1,8 @@ package electrosphere.game.data.creature.type; import electrosphere.entity.types.hitbox.HitboxData; +import electrosphere.game.data.creature.type.attack.AttackMove; +import electrosphere.game.data.creature.type.attack.AttackMoveResolver; import electrosphere.game.data.creature.type.rotator.RotatorSystem; import electrosphere.game.data.creature.type.visualattribute.VisualAttribute; @@ -19,6 +21,8 @@ public class CreatureType { LookAtSystem lookAtSystem; String modelPath; + AttackMoveResolver attackMoveResolver; + public String getCreatureId() { return creatureId; } @@ -62,6 +66,14 @@ public class CreatureType { public RotatorSystem getRotatorSystem() { return rotatorSystem; } + + public void setAttackMoveResolver(AttackMoveResolver resolver){ + attackMoveResolver = resolver; + } + + public AttackMoveResolver getAttackMoveResolver(){ + return attackMoveResolver; + } } 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 new file mode 100644 index 00000000..813ca030 --- /dev/null +++ b/src/main/java/electrosphere/game/data/creature/type/attack/AttackMove.java @@ -0,0 +1,53 @@ +package electrosphere.game.data.creature.type.attack; + +/** + * + * @author amaterasu + */ +public class AttackMove { + + String attackMoveId; + String type; + String animationName; + int damageStartFrame; + int damageEndFrame; + String nextMoveId; + String movementStart; + String movementEnd; + float movementGoal; // this is the amount we want the animation to push us forward + boolean initialMove; // is this the initial move in its movelist? + + public String getAttackMoveId(){ + return attackMoveId; + } + + public String getType() { + return type; + } + + public String getAnimationName() { + return animationName; + } + + public int getDamageStartFrame() { + return damageStartFrame; + } + + public int getDamageEndFrame() { + return damageEndFrame; + } + + public String getNextMoveId() { + return nextMoveId; + } + + public float getMovementGoal(){ + return movementGoal; + } + + public boolean isInitialMove(){ + return initialMove; + } + + +} diff --git a/src/main/java/electrosphere/game/data/creature/type/attack/AttackMoveResolver.java b/src/main/java/electrosphere/game/data/creature/type/attack/AttackMoveResolver.java new file mode 100644 index 00000000..67d25391 --- /dev/null +++ b/src/main/java/electrosphere/game/data/creature/type/attack/AttackMoveResolver.java @@ -0,0 +1,74 @@ +package electrosphere.game.data.creature.type.attack; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import electrosphere.logger.LoggerInterface; + +public class AttackMoveResolver { + + Map> attackMovesetMap = new HashMap>(); + + public AttackMoveResolver(List movelist){ + //get all moves + for(AttackMove move : movelist){ + String type = move.getType(); + if(attackMovesetMap.containsKey(type)){ + attackMovesetMap.get(type).add(move); + } else { + List moveList = new LinkedList(); + moveList.add(move); + attackMovesetMap.put(type,moveList); + } + } + //reorder + for(List toOrder : attackMovesetMap.values()){ + reorderMoveset(toOrder); + } + } + + public List getMoveset(String attackType){ + return attackMovesetMap.get(attackType); + } + + void reorderMoveset(List finalMovelist){ + AttackMove currentMove = null; + //solve for initial move + for(AttackMove move : finalMovelist){ + if(move.isInitialMove()){ + currentMove = move; + break; + } + } + //order list + if(currentMove != null){ + List orderedList = new LinkedList(); + orderedList.add(currentMove); + String nextId = currentMove.getNextMoveId(); + while(nextId != null && !nextId.equals("")){ + if(finalMovelist.size() == 0){ + break; + } + for(AttackMove move : finalMovelist){ + if(move.getAttackMoveId().equals(nextId)){ + currentMove = move; + finalMovelist.remove(move); + orderedList.add(currentMove); + nextId = currentMove.nextMoveId; + break; + } + } + } + //replace final list contents with ordered list contents + finalMovelist.clear(); + for(AttackMove move : orderedList){ + finalMovelist.add(move); + } + } else { + LoggerInterface.loggerEngine.WARNING("FAILED TO LOAD INITIAL MOVE IN AttackMoveResolver"); + } + } + +} diff --git a/src/main/java/electrosphere/main/Globals.java b/src/main/java/electrosphere/main/Globals.java index 9d78460a..87c3beb8 100644 --- a/src/main/java/electrosphere/main/Globals.java +++ b/src/main/java/electrosphere/main/Globals.java @@ -219,7 +219,7 @@ public class Globals { public static Menu currentMenu; - public static List inGameUI = new LinkedList(); + public static List inGameUI = new LinkedList(); public static String particleBillboardModel; @@ -328,7 +328,7 @@ public class Globals { //create entity manager entityManager = new EntityManager(); //temporary hold for skybox colors - skyboxColors = new ArrayList(); + skyboxColors = new ArrayList(); //load asset manager assetManager = new AssetManager(); //load widget manager diff --git a/src/main/java/electrosphere/main/Main.java b/src/main/java/electrosphere/main/Main.java index 292da23a..a4a60c86 100644 --- a/src/main/java/electrosphere/main/Main.java +++ b/src/main/java/electrosphere/main/Main.java @@ -68,6 +68,7 @@ public class Main { //These are used in calculating the time between frames for visualization (camera) control and such public static float deltaTime = 0.0f; public static float lastFrame = 0.0f; + public static long frameCount = 0; //View Controls public static float view_Range = 200000.0f; /* @@ -384,6 +385,7 @@ public class Main { } else { sleep(1); } + frameCount++; // sleep((int)(1000.0*Math.max(0.001, deltaTime-targetFrameRate))); } //Terminate the program. diff --git a/src/main/java/electrosphere/renderer/Mesh.java b/src/main/java/electrosphere/renderer/Mesh.java index 72bdfe21..fed46c20 100644 --- a/src/main/java/electrosphere/renderer/Mesh.java +++ b/src/main/java/electrosphere/renderer/Mesh.java @@ -30,6 +30,8 @@ import static org.lwjgl.opengl.GL11.GL_INT; import static org.lwjgl.opengl.GL11.GL_TRIANGLES; import static org.lwjgl.opengl.GL11.GL_UNSIGNED_INT; import org.lwjgl.opengl.GL15; +import org.lwjgl.opengl.GL15C; + import static org.lwjgl.opengl.GL15.GL_ARRAY_BUFFER; import static org.lwjgl.opengl.GL15.GL_ELEMENT_ARRAY_BUFFER; import static org.lwjgl.opengl.GL15.GL_STATIC_DRAW; @@ -867,6 +869,7 @@ public class Mesh { glUniformMatrix4fv(Globals.renderingEngine.getActiveShader().shaderVertexProjectionLoc, false, Globals.projectionMatrix.get(new float[16])); glUniform3fv(Globals.renderingEngine.getActiveShader().shaderVertexViewPosLoc, CameraEntityUtils.getCameraEye(Globals.playerCamera).get(BufferUtils.createFloatBuffer(3))); glUniformMatrix4fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "lightSpaceMatrix"), false, Globals.lightDepthMatrix.get(new float[16])); + glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "frame"), (int)Main.frameCount); } if(bufferNonStandardUniforms){