Attack chaining

This commit is contained in:
austin 2022-02-18 22:58:09 -05:00
parent 7efa0acf70
commit b446ff6398
16 changed files with 276 additions and 88 deletions

View File

@ -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" : {

View File

@ -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" : {

View File

@ -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" : {

Binary file not shown.

View File

@ -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);
}
}

View File

@ -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));

View File

@ -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<EntityMessage> networkMessageQueue = new CopyOnWriteArrayList();
CopyOnWriteArrayList<EntityMessage> networkMessageQueue = new CopyOnWriteArrayList<EntityMessage>();
long lastUpdateTime = 0;
@ -41,6 +44,9 @@ public class AttackTree {
String animationName = "SwingWeapon";
int maxFrame = 60;
List<AttackMove> 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<AttackMove>)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<AttackMove> moveset, String nextMoveId){
AttackMove rVal = null;
for(AttackMove move : moveset){
if(move.getAttackMoveId().equals(nextMoveId)){
rVal = move;
break;
}
}
return rVal;

View File

@ -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);

View File

@ -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<CreatureType> typeList = readCreatureTypeFile(initialPath);
for(CreatureType type : typeList){
if(type.getAttackMoves() != null){
type.setAttackMoveResolver(new AttackMoveResolver(type.getAttackMoves()));
}
loader.putCreature(type.getCreatureId(), type);
}
return loader;

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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<String,List<AttackMove>> attackMovesetMap = new HashMap<String,List<AttackMove>>();
public AttackMoveResolver(List<AttackMove> movelist){
//get all moves
for(AttackMove move : movelist){
String type = move.getType();
if(attackMovesetMap.containsKey(type)){
attackMovesetMap.get(type).add(move);
} else {
List<AttackMove> moveList = new LinkedList<AttackMove>();
moveList.add(move);
attackMovesetMap.put(type,moveList);
}
}
//reorder
for(List<AttackMove> toOrder : attackMovesetMap.values()){
reorderMoveset(toOrder);
}
}
public List<AttackMove> getMoveset(String attackType){
return attackMovesetMap.get(attackType);
}
void reorderMoveset(List<AttackMove> finalMovelist){
AttackMove currentMove = null;
//solve for initial move
for(AttackMove move : finalMovelist){
if(move.isInitialMove()){
currentMove = move;
break;
}
}
//order list
if(currentMove != null){
List<AttackMove> orderedList = new LinkedList<AttackMove>();
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");
}
}
}

View File

@ -219,7 +219,7 @@ public class Globals {
public static Menu currentMenu;
public static List<Widget> inGameUI = new LinkedList();
public static List<Widget> inGameUI = new LinkedList<Widget>();
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<Vector3f>();
//load asset manager
assetManager = new AssetManager();
//load widget manager

View File

@ -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.

View File

@ -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){