initial hitstun implementation
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good
This commit is contained in:
parent
b8a0db5974
commit
3d6b71bf01
@ -469,6 +469,7 @@
|
|||||||
"driftFrameStart" : 1,
|
"driftFrameStart" : 1,
|
||||||
"driftFrameEnd" : 10,
|
"driftFrameEnd" : 10,
|
||||||
"initialMove" : true,
|
"initialMove" : true,
|
||||||
|
"hitstun" : 7,
|
||||||
"attackState" : {
|
"attackState" : {
|
||||||
"animation" : {
|
"animation" : {
|
||||||
"nameFirstPerson" : "SwordR2HSlash",
|
"nameFirstPerson" : "SwordR2HSlash",
|
||||||
|
|||||||
@ -353,6 +353,7 @@
|
|||||||
"driftFrameStart" : 1,
|
"driftFrameStart" : 1,
|
||||||
"driftFrameEnd" : 10,
|
"driftFrameEnd" : 10,
|
||||||
"initialMove" : true,
|
"initialMove" : true,
|
||||||
|
"hitstun" : 7,
|
||||||
"attackState" : {
|
"attackState" : {
|
||||||
"animation" : {
|
"animation" : {
|
||||||
"nameFirstPerson" : "SwordR2HSlash1",
|
"nameFirstPerson" : "SwordR2HSlash1",
|
||||||
|
|||||||
@ -125,7 +125,7 @@
|
|||||||
"offsetY" : 0.0,
|
"offsetY" : 0.0,
|
||||||
"offsetZ" : 0.0
|
"offsetZ" : 0.0
|
||||||
},
|
},
|
||||||
"iconPath" : "Textures/icons/itemIconWeapon.png"
|
"iconPath" : "Textures/icons/greatsword.png"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : "bow1",
|
"id" : "bow1",
|
||||||
|
|||||||
BIN
assets/Textures/icons/greatsword.png
Normal file
BIN
assets/Textures/icons/greatsword.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.9 KiB |
@ -16,14 +16,21 @@
|
|||||||
Ticketed randomizer node for BTs to more heavily weight attacking and waiting
|
Ticketed randomizer node for BTs to more heavily weight attacking and waiting
|
||||||
|
|
||||||
+ feedback driven requirements
|
+ feedback driven requirements
|
||||||
UI spacing and scaling
|
|
||||||
Come up with a title for the game and create a title menu for it (ideally with some animation and music)
|
|
||||||
Better skybox
|
|
||||||
Model clothing, hair for the human
|
|
||||||
Hitstun, particles, light on sword collision
|
|
||||||
Idle viewmodel does not show hands
|
Idle viewmodel does not show hands
|
||||||
Add punching/unarmed combat
|
Add punching/unarmed combat
|
||||||
|
UI spacing and scaling
|
||||||
|
Better skybox
|
||||||
|
- Fix transparency calculations for far-out objects
|
||||||
Crouching
|
Crouching
|
||||||
|
Model clothing, hair for the human
|
||||||
|
particles, light on sword collision
|
||||||
|
- Requires particle manager overhaul
|
||||||
|
Come up with a title for the game and create a title menu for it (ideally with some animation and music)
|
||||||
|
- Flames moving up the screen
|
||||||
|
- Requires particle manager overhaul
|
||||||
|
- Requires actor panel that can play scenes
|
||||||
|
- Requires rendering overhaul
|
||||||
|
- Requires finding an sfx for flames
|
||||||
Objectives
|
Objectives
|
||||||
- PVP arena mode initially?
|
- PVP arena mode initially?
|
||||||
- Spawn player at start of a dungeon
|
- Spawn player at start of a dungeon
|
||||||
|
|||||||
@ -792,6 +792,9 @@ Start proliferating audio through ui
|
|||||||
Item-based ui audio
|
Item-based ui audio
|
||||||
Better sfx for opening/closing inventory menu
|
Better sfx for opening/closing inventory menu
|
||||||
Different title menu audio
|
Different title menu audio
|
||||||
|
New katana icon
|
||||||
|
UI fix
|
||||||
|
Initial hitstun implementation
|
||||||
|
|
||||||
|
|
||||||
# TODO
|
# TODO
|
||||||
|
|||||||
@ -0,0 +1,99 @@
|
|||||||
|
package electrosphere.client.collision;
|
||||||
|
|
||||||
|
import org.joml.Vector3d;
|
||||||
|
import org.ode4j.ode.DContactGeom;
|
||||||
|
import org.ode4j.ode.DGeom;
|
||||||
|
|
||||||
|
import electrosphere.collision.collidable.Collidable;
|
||||||
|
import electrosphere.entity.Entity;
|
||||||
|
import electrosphere.entity.state.attach.AttachUtils;
|
||||||
|
import electrosphere.entity.state.attack.ClientAttackTree;
|
||||||
|
import electrosphere.entity.state.hitbox.HitboxCollectionState;
|
||||||
|
import electrosphere.entity.state.hitbox.HitboxCollectionState.HitboxState;
|
||||||
|
import electrosphere.entity.state.hitbox.HitboxCollectionState.HitboxType;
|
||||||
|
|
||||||
|
public class ClientLocalHitboxCollision {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles a damage collision on the client
|
||||||
|
* @param impactor the entity initiating the collision
|
||||||
|
* @param receiver the entity receiving the collision
|
||||||
|
*/
|
||||||
|
public static void clientDamageHitboxColision(DContactGeom contactGeom, DGeom impactorGeom, DGeom receiverGeom, Collidable impactor, Collidable receiver, Vector3d normal, Vector3d localPosition, Vector3d worldPos, float magnitude){
|
||||||
|
|
||||||
|
Entity impactorParent = impactor.getParent();
|
||||||
|
Entity receiverParent = receiver.getParent();
|
||||||
|
HitboxCollectionState impactorState = HitboxCollectionState.getHitboxState(impactorParent);
|
||||||
|
HitboxCollectionState receiverState = HitboxCollectionState.getHitboxState(receiverParent);
|
||||||
|
HitboxState impactorShapeStatus = impactorState.getShapeStatus(impactorGeom);
|
||||||
|
HitboxState receiverShapeStatus = receiverState.getShapeStatus(receiverGeom);
|
||||||
|
|
||||||
|
|
||||||
|
//currently, impactor needs to be an item, and the receiver must not be an item
|
||||||
|
boolean isDamageEvent =
|
||||||
|
impactorShapeStatus != null &&
|
||||||
|
receiverShapeStatus != null &&
|
||||||
|
impactorShapeStatus.getType() == HitboxType.HIT &&
|
||||||
|
receiverShapeStatus.getType() == HitboxType.HURT &&
|
||||||
|
AttachUtils.getParent(impactorParent) != receiverParent
|
||||||
|
;
|
||||||
|
|
||||||
|
if(impactorShapeStatus != null){
|
||||||
|
impactorShapeStatus.setHadCollision(true);
|
||||||
|
}
|
||||||
|
if(receiverShapeStatus != null){
|
||||||
|
receiverShapeStatus.setHadCollision(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isDamageEvent){
|
||||||
|
//TODO: client logic for audio etc
|
||||||
|
if(AttachUtils.hasParent(impactorParent)){
|
||||||
|
Entity parent = AttachUtils.getParent(impactorParent);
|
||||||
|
if(ClientAttackTree.getClientAttackTree(parent) != null){
|
||||||
|
ClientAttackTree clientAttackTree = ClientAttackTree.getClientAttackTree(parent);
|
||||||
|
if(clientAttackTree.canCollideEntity(receiverParent)){
|
||||||
|
clientAttackTree.collideEntity(receiverParent);
|
||||||
|
clientAttackTree.freezeFrame();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Entity hitboxParent = (Entity)impactor.getData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT);
|
||||||
|
// Entity hurtboxParent = (Entity)receiver.getData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT);
|
||||||
|
|
||||||
|
//if the entity is attached to is an item, we need to compare with the parent of the item
|
||||||
|
//to make sure you don't stab yourself for instance
|
||||||
|
// boolean isItem = ItemUtils.isItem(hitboxParent);//hitboxParent.containsKey(EntityDataStrings.ITEM_IS_ITEM);
|
||||||
|
// Entity hitboxAttachParent = AttachUtils.getParent(hitboxParent);
|
||||||
|
|
||||||
|
// if(isItem){
|
||||||
|
// if(hitboxAttachParent != hurtboxParent){
|
||||||
|
// Vector3d hurtboxPos = EntityUtils.getPosition(receiver);
|
||||||
|
// ParticleEffects.spawnBloodsplats(new Vector3f((float)hurtboxPos.x,(float)hurtboxPos.y,(float)hurtboxPos.z).add(0,0.1f,0), 20, 40);
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
|
||||||
|
// //client no longer manages damage; however, keeping this code around for the moment to show how we
|
||||||
|
// //might approach adding client-side effects as soon as impact occurs (ie play a sound, shoot sparks, etc)
|
||||||
|
// //before the server responds with a valid collision event or not
|
||||||
|
|
||||||
|
// // int damage = 0;
|
||||||
|
// // //for entities using attacktree
|
||||||
|
// // if(CreatureUtils.clientGetAttackTree(hitboxParent) != null){
|
||||||
|
// // damage = ItemUtils.getWeaponDataRaw(hitboxParent).getDamage();
|
||||||
|
// // } else {
|
||||||
|
// // //for entities using shooter tree
|
||||||
|
// // if(ProjectileTree.getProjectileTree(hitboxParent) != null){
|
||||||
|
// // damage = (int)ProjectileTree.getProjectileTree(hitboxParent).getDamage();
|
||||||
|
// // }
|
||||||
|
// // }
|
||||||
|
// // LifeUtils.getLifeState(hurtboxParent).damage(damage);
|
||||||
|
// // if(!LifeUtils.getLifeState(hurtboxParent).isIsAlive()){
|
||||||
|
// // EntityUtils.getPosition(hurtboxParent).set(Globals.spawnPoint);
|
||||||
|
// // LifeUtils.getLifeState(hurtboxParent).revive();
|
||||||
|
// // }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -13,7 +13,7 @@ import electrosphere.logger.LoggerInterface;
|
|||||||
/**
|
/**
|
||||||
* Client methods for handling hitbox collisions reported by the server
|
* Client methods for handling hitbox collisions reported by the server
|
||||||
*/
|
*/
|
||||||
public class ClientHitboxCollision {
|
public class ClientNetworkHitboxCollision {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Performs client logic for a collision that the server reports
|
* Performs client logic for a collision that the server reports
|
||||||
@ -29,11 +29,11 @@ public class ClientHitboxCollision {
|
|||||||
case HitboxData.HITBOX_TYPE_HURT:
|
case HitboxData.HITBOX_TYPE_HURT:
|
||||||
case HitboxData.HITBOX_TYPE_HURT_CONNECTED: {
|
case HitboxData.HITBOX_TYPE_HURT_CONNECTED: {
|
||||||
Globals.hitboxAudioService.playAudioPositional(senderEntity, receiverEntity, hitboxType, hurtboxType, position);
|
Globals.hitboxAudioService.playAudioPositional(senderEntity, receiverEntity, hitboxType, hurtboxType, position);
|
||||||
ClientHitboxCollision.conditionallySpawnParticles(senderEntity, receiverEntity, hitboxType, hurtboxType, position);
|
ClientNetworkHitboxCollision.conditionallySpawnParticles(senderEntity, receiverEntity, hitboxType, hurtboxType, position);
|
||||||
} break;
|
} break;
|
||||||
case HitboxData.HITBOX_TYPE_BLOCK_CONNECTED: {
|
case HitboxData.HITBOX_TYPE_BLOCK_CONNECTED: {
|
||||||
Globals.hitboxAudioService.playAudioPositional(senderEntity, receiverEntity, hitboxType, hurtboxType, position);
|
Globals.hitboxAudioService.playAudioPositional(senderEntity, receiverEntity, hitboxType, hurtboxType, position);
|
||||||
ClientHitboxCollision.conditionallySpawnParticles(senderEntity, receiverEntity, hitboxType, hurtboxType, position);
|
ClientNetworkHitboxCollision.conditionallySpawnParticles(senderEntity, receiverEntity, hitboxType, hurtboxType, position);
|
||||||
} break;
|
} break;
|
||||||
default: {
|
default: {
|
||||||
LoggerInterface.loggerEngine.WARNING("Client handling undefined hurtbox type: " + hurtboxType);
|
LoggerInterface.loggerEngine.WARNING("Client handling undefined hurtbox type: " + hurtboxType);
|
||||||
@ -7,11 +7,11 @@ import org.joml.Vector3d;
|
|||||||
import org.ode4j.ode.DContactGeom;
|
import org.ode4j.ode.DContactGeom;
|
||||||
import org.ode4j.ode.DGeom;
|
import org.ode4j.ode.DGeom;
|
||||||
|
|
||||||
|
import electrosphere.client.collision.ClientLocalHitboxCollision;
|
||||||
import electrosphere.collision.CollisionEngine;
|
import electrosphere.collision.CollisionEngine;
|
||||||
import electrosphere.collision.CollisionEngine.CollisionResolutionCallback;
|
import electrosphere.collision.CollisionEngine.CollisionResolutionCallback;
|
||||||
import electrosphere.collision.collidable.Collidable;
|
import electrosphere.collision.collidable.Collidable;
|
||||||
import electrosphere.collision.hitbox.HitboxManager;
|
import electrosphere.collision.hitbox.HitboxManager;
|
||||||
import electrosphere.collision.hitbox.HitboxUtils;
|
|
||||||
import electrosphere.engine.Globals;
|
import electrosphere.engine.Globals;
|
||||||
import electrosphere.entity.Entity;
|
import electrosphere.entity.Entity;
|
||||||
import electrosphere.entity.scene.Scene;
|
import electrosphere.entity.scene.Scene;
|
||||||
@ -225,7 +225,7 @@ public class ClientSceneWrapper {
|
|||||||
CollisionResolutionCallback resolutionCallback = new CollisionResolutionCallback() {
|
CollisionResolutionCallback resolutionCallback = new CollisionResolutionCallback() {
|
||||||
@Override
|
@Override
|
||||||
public void resolve(DContactGeom geom, DGeom impactorGeom, DGeom receiverGeom, Collidable impactor, Collidable receiver, Vector3d normal, Vector3d localPosition, Vector3d worldPos, float magnitude) {
|
public void resolve(DContactGeom geom, DGeom impactorGeom, DGeom receiverGeom, Collidable impactor, Collidable receiver, Vector3d normal, Vector3d localPosition, Vector3d worldPos, float magnitude) {
|
||||||
HitboxUtils.clientDamageHitboxColision(geom, impactorGeom, receiverGeom, impactor, receiver, normal, localPosition, worldPos, magnitude);
|
ClientLocalHitboxCollision.clientDamageHitboxColision(geom, impactorGeom, receiverGeom, impactor, receiver, normal, localPosition, worldPos, magnitude);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -1,9 +1,12 @@
|
|||||||
package electrosphere.client.ui.menu.ingame;
|
package electrosphere.client.ui.menu.ingame;
|
||||||
|
|
||||||
|
import electrosphere.audio.VirtualAudioSourceManager.VirtualAudioSourceType;
|
||||||
import electrosphere.client.ui.menu.WindowStrings;
|
import electrosphere.client.ui.menu.WindowStrings;
|
||||||
import electrosphere.client.ui.menu.WindowUtils;
|
import electrosphere.client.ui.menu.WindowUtils;
|
||||||
import electrosphere.engine.Globals;
|
import electrosphere.engine.Globals;
|
||||||
import electrosphere.entity.state.inventory.InventoryUtils;
|
import electrosphere.entity.state.inventory.InventoryUtils;
|
||||||
|
import electrosphere.entity.types.item.ItemUtils;
|
||||||
|
import electrosphere.game.data.item.type.Item;
|
||||||
import electrosphere.logger.LoggerInterface;
|
import electrosphere.logger.LoggerInterface;
|
||||||
import electrosphere.renderer.ui.components.PlayerInventoryWindow;
|
import electrosphere.renderer.ui.components.PlayerInventoryWindow;
|
||||||
import electrosphere.renderer.ui.elements.Div;
|
import electrosphere.renderer.ui.elements.Div;
|
||||||
@ -23,15 +26,23 @@ public class MenuGeneratorsInventory {
|
|||||||
if(Globals.draggedItem != null){
|
if(Globals.draggedItem != null){
|
||||||
//drop item
|
//drop item
|
||||||
InventoryUtils.clientAttemptEjectItem(Globals.playerEntity,Globals.draggedItem);
|
InventoryUtils.clientAttemptEjectItem(Globals.playerEntity,Globals.draggedItem);
|
||||||
|
//play sound effect
|
||||||
|
if(Globals.virtualAudioSourceManager != null){
|
||||||
|
Item itemData = Globals.gameConfigCurrent.getItemMap().getItem(ItemUtils.getType(Globals.draggedItem));
|
||||||
|
if(itemData.getItemAudio() != null && itemData.getItemAudio().getUIReleaseAudio() != null){
|
||||||
|
Globals.virtualAudioSourceManager.createVirtualAudioSource(itemData.getItemAudio().getUIReleaseAudio(), VirtualAudioSourceType.UI, false);
|
||||||
|
} else {
|
||||||
|
Globals.virtualAudioSourceManager.createVirtualAudioSource("/Audio/inventorySlotItem.ogg", VirtualAudioSourceType.UI, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
//clear ui
|
//clear ui
|
||||||
WindowUtils.cleanItemDraggingWindow();
|
WindowUtils.cleanItemDraggingWindow();
|
||||||
String sourceWindowId = WindowStrings.WINDOW_CHARACTER;
|
//re-render inventory
|
||||||
WindowUtils.replaceWindow(sourceWindowId,PlayerInventoryWindow.createPlayerInventoryWindow(Globals.playerEntity));
|
WindowUtils.replaceWindow(WindowStrings.WINDOW_CHARACTER, PlayerInventoryWindow.createPlayerInventoryWindow(Globals.playerEntity));
|
||||||
//null globals
|
//null globals
|
||||||
Globals.dragSourceInventory = null;
|
Globals.dragSourceInventory = null;
|
||||||
Globals.draggedItem = null;
|
Globals.draggedItem = null;
|
||||||
return false;
|
return false;
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}});
|
}});
|
||||||
|
|||||||
@ -1,96 +1,16 @@
|
|||||||
package electrosphere.collision.hitbox;
|
package electrosphere.collision.hitbox;
|
||||||
|
|
||||||
import electrosphere.collision.collidable.Collidable;
|
|
||||||
import electrosphere.entity.Entity;
|
import electrosphere.entity.Entity;
|
||||||
import electrosphere.entity.EntityDataStrings;
|
import electrosphere.entity.EntityDataStrings;
|
||||||
import electrosphere.entity.state.attach.AttachUtils;
|
|
||||||
import electrosphere.entity.state.hitbox.HitboxCollectionState;
|
|
||||||
import electrosphere.entity.state.hitbox.HitboxCollectionState.HitboxState;
|
|
||||||
import electrosphere.entity.state.hitbox.HitboxCollectionState.HitboxType;
|
|
||||||
import electrosphere.game.data.collidable.HitboxData;
|
import electrosphere.game.data.collidable.HitboxData;
|
||||||
|
|
||||||
import org.joml.Vector3d;
|
import org.joml.Vector3d;
|
||||||
import org.ode4j.ode.DContactGeom;
|
|
||||||
import org.ode4j.ode.DGeom;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utilities for working with hitboxes
|
* Utilities for working with hitboxes
|
||||||
*/
|
*/
|
||||||
public class HitboxUtils {
|
public class HitboxUtils {
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles a damage collision on the client
|
|
||||||
* @param impactor the entity initiating the collision
|
|
||||||
* @param receiver the entity receiving the collision
|
|
||||||
*/
|
|
||||||
public static void clientDamageHitboxColision(DContactGeom contactGeom, DGeom impactorGeom, DGeom receiverGeom, Collidable impactor, Collidable receiver, Vector3d normal, Vector3d localPosition, Vector3d worldPos, float magnitude){
|
|
||||||
|
|
||||||
Entity impactorParent = impactor.getParent();
|
|
||||||
Entity receiverParent = receiver.getParent();
|
|
||||||
HitboxCollectionState impactorState = HitboxCollectionState.getHitboxState(impactorParent);
|
|
||||||
HitboxCollectionState receiverState = HitboxCollectionState.getHitboxState(receiverParent);
|
|
||||||
HitboxState impactorShapeStatus = impactorState.getShapeStatus(impactorGeom);
|
|
||||||
HitboxState receiverShapeStatus = receiverState.getShapeStatus(receiverGeom);
|
|
||||||
|
|
||||||
|
|
||||||
//currently, impactor needs to be an item, and the receiver must not be an item
|
|
||||||
boolean isDamageEvent =
|
|
||||||
impactorShapeStatus != null &&
|
|
||||||
receiverShapeStatus != null &&
|
|
||||||
impactorShapeStatus.getType() == HitboxType.HIT &&
|
|
||||||
receiverShapeStatus.getType() == HitboxType.HURT &&
|
|
||||||
AttachUtils.getParent(impactorParent) != receiverParent
|
|
||||||
;
|
|
||||||
|
|
||||||
if(impactorShapeStatus != null){
|
|
||||||
impactorShapeStatus.setHadCollision(true);
|
|
||||||
}
|
|
||||||
if(receiverShapeStatus != null){
|
|
||||||
receiverShapeStatus.setHadCollision(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(isDamageEvent){
|
|
||||||
//TODO: client logic for audio etc
|
|
||||||
}
|
|
||||||
|
|
||||||
// Entity hitboxParent = (Entity)impactor.getData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT);
|
|
||||||
// Entity hurtboxParent = (Entity)receiver.getData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT);
|
|
||||||
|
|
||||||
//if the entity is attached to is an item, we need to compare with the parent of the item
|
|
||||||
//to make sure you don't stab yourself for instance
|
|
||||||
// boolean isItem = ItemUtils.isItem(hitboxParent);//hitboxParent.containsKey(EntityDataStrings.ITEM_IS_ITEM);
|
|
||||||
// Entity hitboxAttachParent = AttachUtils.getParent(hitboxParent);
|
|
||||||
|
|
||||||
// if(isItem){
|
|
||||||
// if(hitboxAttachParent != hurtboxParent){
|
|
||||||
// Vector3d hurtboxPos = EntityUtils.getPosition(receiver);
|
|
||||||
// ParticleEffects.spawnBloodsplats(new Vector3f((float)hurtboxPos.x,(float)hurtboxPos.y,(float)hurtboxPos.z).add(0,0.1f,0), 20, 40);
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
|
|
||||||
// //client no longer manages damage; however, keeping this code around for the moment to show how we
|
|
||||||
// //might approach adding client-side effects as soon as impact occurs (ie play a sound, shoot sparks, etc)
|
|
||||||
// //before the server responds with a valid collision event or not
|
|
||||||
|
|
||||||
// // int damage = 0;
|
|
||||||
// // //for entities using attacktree
|
|
||||||
// // if(CreatureUtils.clientGetAttackTree(hitboxParent) != null){
|
|
||||||
// // damage = ItemUtils.getWeaponDataRaw(hitboxParent).getDamage();
|
|
||||||
// // } else {
|
|
||||||
// // //for entities using shooter tree
|
|
||||||
// // if(ProjectileTree.getProjectileTree(hitboxParent) != null){
|
|
||||||
// // damage = (int)ProjectileTree.getProjectileTree(hitboxParent).getDamage();
|
|
||||||
// // }
|
|
||||||
// // }
|
|
||||||
// // LifeUtils.getLifeState(hurtboxParent).damage(damage);
|
|
||||||
// // if(!LifeUtils.getLifeState(hurtboxParent).isIsAlive()){
|
|
||||||
// // EntityUtils.getPosition(hurtboxParent).set(Globals.spawnPoint);
|
|
||||||
// // LifeUtils.getLifeState(hurtboxParent).revive();
|
|
||||||
// // }
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the data for a hitbox
|
* Gets the data for a hitbox
|
||||||
* @param e the entity encapsulating the hitbox
|
* @param e the entity encapsulating the hitbox
|
||||||
|
|||||||
@ -4,6 +4,7 @@ package electrosphere.entity.state.attack;
|
|||||||
import electrosphere.engine.Globals;
|
import electrosphere.engine.Globals;
|
||||||
import electrosphere.entity.Entity;
|
import electrosphere.entity.Entity;
|
||||||
import electrosphere.entity.EntityDataStrings;
|
import electrosphere.entity.EntityDataStrings;
|
||||||
|
import electrosphere.entity.EntityUtils;
|
||||||
import electrosphere.entity.btree.BehaviorTree;
|
import electrosphere.entity.btree.BehaviorTree;
|
||||||
import electrosphere.entity.btree.StateTransitionUtil;
|
import electrosphere.entity.btree.StateTransitionUtil;
|
||||||
import electrosphere.entity.btree.StateTransitionUtil.StateTransitionUtilItem;
|
import electrosphere.entity.btree.StateTransitionUtil.StateTransitionUtilItem;
|
||||||
@ -25,7 +26,9 @@ import electrosphere.net.synchronization.annotation.SyncedField;
|
|||||||
import electrosphere.net.synchronization.annotation.SynchronizableEnum;
|
import electrosphere.net.synchronization.annotation.SynchronizableEnum;
|
||||||
import electrosphere.net.synchronization.annotation.SynchronizedBehaviorTree;
|
import electrosphere.net.synchronization.annotation.SynchronizedBehaviorTree;
|
||||||
import electrosphere.net.synchronization.enums.BehaviorTreeIdEnums;
|
import electrosphere.net.synchronization.enums.BehaviorTreeIdEnums;
|
||||||
|
import electrosphere.renderer.actor.Actor;
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.joml.Vector3d;
|
import org.joml.Vector3d;
|
||||||
@ -93,6 +96,11 @@ public class ClientAttackTree implements BehaviorTree {
|
|||||||
String projectileToFire = null;
|
String projectileToFire = null;
|
||||||
String attackingPoint = null;
|
String attackingPoint = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The list of entities that have collided with the current attack
|
||||||
|
*/
|
||||||
|
List<Entity> collidedEntities = new LinkedList<Entity>();
|
||||||
|
|
||||||
//The state transition util
|
//The state transition util
|
||||||
StateTransitionUtil stateTransitionUtil;
|
StateTransitionUtil stateTransitionUtil;
|
||||||
|
|
||||||
@ -506,6 +514,39 @@ public class ClientAttackTree implements BehaviorTree {
|
|||||||
return 1.0;
|
return 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Freezes the animation for a frame or two when a collision occurs
|
||||||
|
*/
|
||||||
|
public void freezeFrame(){
|
||||||
|
Actor actor = EntityUtils.getActor(parent);
|
||||||
|
if(this.currentMove != null && this.currentMove.getHitstun() != null){
|
||||||
|
String animName = this.currentMove.getAttackState().getAnimation().getNameThirdPerson();
|
||||||
|
actor.setFreezeFrames(animName, this.currentMove.getHitstun());
|
||||||
|
if(parent == Globals.playerEntity && !Globals.controlHandler.cameraIsThirdPerson()){
|
||||||
|
Actor viewmodelActor = EntityUtils.getActor(Globals.firstPersonEntity);
|
||||||
|
animName = this.currentMove.getAttackState().getAnimation().getNameFirstPerson();
|
||||||
|
viewmodelActor.setFreezeFrames(animName, this.currentMove.getHitstun());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the target can be collided with
|
||||||
|
* @param target The target
|
||||||
|
* @return true if can be collided with, false otherwise (ie it has already collided)
|
||||||
|
*/
|
||||||
|
public boolean canCollideEntity(Entity target){
|
||||||
|
return !this.collidedEntities.contains(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets that the current attack has collided with the provided entity
|
||||||
|
* @param target The target entity
|
||||||
|
*/
|
||||||
|
public void collideEntity(Entity target){
|
||||||
|
this.collidedEntities.add(target);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p> Automatically generated </p>
|
* <p> Automatically generated </p>
|
||||||
* <p>
|
* <p>
|
||||||
@ -694,6 +735,9 @@ public class ClientAttackTree implements BehaviorTree {
|
|||||||
if(newState == AttackTreeState.BLOCK_RECOIL){
|
if(newState == AttackTreeState.BLOCK_RECOIL){
|
||||||
this.stateTransitionUtil.interrupt(AttackTreeState.ATTACK);
|
this.stateTransitionUtil.interrupt(AttackTreeState.ATTACK);
|
||||||
}
|
}
|
||||||
|
if(newState == AttackTreeState.ATTACK){
|
||||||
|
this.collidedEntities.clear();
|
||||||
|
}
|
||||||
this.setState(newState);
|
this.setState(newState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -46,6 +46,11 @@ public class AttackMove {
|
|||||||
int driftFrameStart; //when do we start drifting
|
int driftFrameStart; //when do we start drifting
|
||||||
int driftFrameEnd; //when do we stop drifting
|
int driftFrameEnd; //when do we stop drifting
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hitstun
|
||||||
|
*/
|
||||||
|
Integer hitstun;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the id of the attack move
|
* Gets the id of the attack move
|
||||||
* @return the id of the attack move
|
* @return the id of the attack move
|
||||||
@ -191,4 +196,13 @@ public class AttackMove {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The number of frames to freeze for on successfully landing this attack
|
||||||
|
* @return The number of frames or null
|
||||||
|
*/
|
||||||
|
public Integer getHitstun(){
|
||||||
|
return hitstun;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,7 @@ package electrosphere.net.client.protocol;
|
|||||||
|
|
||||||
import org.joml.Vector3d;
|
import org.joml.Vector3d;
|
||||||
|
|
||||||
import electrosphere.client.collision.ClientHitboxCollision;
|
import electrosphere.client.collision.ClientNetworkHitboxCollision;
|
||||||
import electrosphere.engine.Globals;
|
import electrosphere.engine.Globals;
|
||||||
import electrosphere.entity.Entity;
|
import electrosphere.entity.Entity;
|
||||||
import electrosphere.net.parser.net.message.CombatMessage;
|
import electrosphere.net.parser.net.message.CombatMessage;
|
||||||
@ -26,7 +26,7 @@ public class CombatProtocol implements ClientProtocolTemplate<CombatMessage> {
|
|||||||
Entity senderEntity = Globals.clientSceneWrapper.getEntityFromServerId(message.getentityID());
|
Entity senderEntity = Globals.clientSceneWrapper.getEntityFromServerId(message.getentityID());
|
||||||
Entity receiverEntity = Globals.clientSceneWrapper.getEntityFromServerId(message.getreceiverEntityID());
|
Entity receiverEntity = Globals.clientSceneWrapper.getEntityFromServerId(message.getreceiverEntityID());
|
||||||
if(senderEntity != null && receiverEntity != null){
|
if(senderEntity != null && receiverEntity != null){
|
||||||
ClientHitboxCollision.handleHitboxCollision(senderEntity, receiverEntity, position, message.gethitboxType(), message.gethurtboxType());
|
ClientNetworkHitboxCollision.handleHitboxCollision(senderEntity, receiverEntity, position, message.gethitboxType(), message.gethurtboxType());
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -98,11 +98,15 @@ public class Actor {
|
|||||||
public void incrementAnimationTime(double deltaTime){
|
public void incrementAnimationTime(double deltaTime){
|
||||||
toRemoveMasks.clear();
|
toRemoveMasks.clear();
|
||||||
for(ActorAnimationMask mask : animationQueue){
|
for(ActorAnimationMask mask : animationQueue){
|
||||||
|
if(mask.getFreezeFrames() > 0){
|
||||||
|
mask.setFreezeFrames(mask.getFreezeFrames() - 1);
|
||||||
|
} else {
|
||||||
mask.setTime(mask.getTime() + deltaTime * animationScalar);
|
mask.setTime(mask.getTime() + deltaTime * animationScalar);
|
||||||
if(mask.getTime() > mask.getDuration()){
|
if(mask.getTime() > mask.getDuration()){
|
||||||
toRemoveMasks.add(mask);
|
toRemoveMasks.add(mask);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
for(ActorAnimationMask mask : toRemoveMasks){
|
for(ActorAnimationMask mask : toRemoveMasks){
|
||||||
animationQueue.remove(mask);
|
animationQueue.remove(mask);
|
||||||
}
|
}
|
||||||
@ -673,6 +677,23 @@ public class Actor {
|
|||||||
this.boneGroups = boneGroups;
|
this.boneGroups = boneGroups;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the number of freeze frames for a given animation path if the animation is being played
|
||||||
|
* @param animationPath The path to the animation
|
||||||
|
* @param numFrames The number of frames to freeze for
|
||||||
|
*/
|
||||||
|
public void setFreezeFrames(String animationPath, int numFrames){
|
||||||
|
if(numFrames < 1){
|
||||||
|
throw new Error("Num frames less than 1 !" + numFrames);
|
||||||
|
}
|
||||||
|
for(ActorAnimationMask mask : this.animationQueue){
|
||||||
|
if(mask.getAnimationName().contains(animationPath)){
|
||||||
|
mask.setFreezeFrames(numFrames);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -23,6 +23,11 @@ public class ActorAnimationMask implements Comparable<ActorAnimationMask> {
|
|||||||
//The mask of bones to apply this animation to
|
//The mask of bones to apply this animation to
|
||||||
List<String> boneMask;
|
List<String> boneMask;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The number of frames to freeze this animation mask for
|
||||||
|
*/
|
||||||
|
int freezeFrames = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
* @param priority
|
* @param priority
|
||||||
@ -130,6 +135,22 @@ public class ActorAnimationMask implements Comparable<ActorAnimationMask> {
|
|||||||
return timeMax;
|
return timeMax;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the current freeze frame count
|
||||||
|
* @return The number of freeze frames
|
||||||
|
*/
|
||||||
|
public int getFreezeFrames(){
|
||||||
|
return freezeFrames;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the number of freeze frames remaining in the mask
|
||||||
|
* @param frameCount The number of frames
|
||||||
|
*/
|
||||||
|
public void setFreezeFrames(int frameCount){
|
||||||
|
this.freezeFrames = frameCount;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compareTo(ActorAnimationMask o) {
|
public int compareTo(ActorAnimationMask o) {
|
||||||
ActorAnimationMask otherMask = (ActorAnimationMask)o;
|
ActorAnimationMask otherMask = (ActorAnimationMask)o;
|
||||||
|
|||||||
@ -51,7 +51,13 @@ public class NaturalInventoryPanel {
|
|||||||
LoggerInterface.loggerUI.INFO("Natural inventory received drag release event");
|
LoggerInterface.loggerUI.INFO("Natural inventory received drag release event");
|
||||||
if(Globals.draggedItem != null){
|
if(Globals.draggedItem != null){
|
||||||
if(Globals.dragSourceInventory != inventory){
|
if(Globals.dragSourceInventory != inventory){
|
||||||
if(Globals.dragSourceInventory instanceof UnrelationalInventoryState){
|
if(Globals.dragSourceInventory instanceof RelationalInventoryState){
|
||||||
|
if(ClientEquipState.hasEquipState(entity) && InventoryUtils.hasEquipInventory(entity)){
|
||||||
|
RelationalInventoryState equipInventory = InventoryUtils.getEquipInventory(entity);
|
||||||
|
ClientEquipState equipState = ClientEquipState.getEquipState(entity);
|
||||||
|
equipState.commandAttemptUnequip(equipInventory.getItemSlot(Globals.draggedItem));
|
||||||
|
}
|
||||||
|
} if(Globals.dragSourceInventory instanceof UnrelationalInventoryState){
|
||||||
//transfer item
|
//transfer item
|
||||||
// sourceInventory.removeItem(Globals.draggedItem);
|
// sourceInventory.removeItem(Globals.draggedItem);
|
||||||
// inventory.addItem(Globals.draggedItem);
|
// inventory.addItem(Globals.draggedItem);
|
||||||
|
|||||||
@ -168,7 +168,7 @@ public class ServerHitboxResolutionCallback implements CollisionResolutionCallba
|
|||||||
|
|
||||||
//
|
//
|
||||||
//handle attacker
|
//handle attacker
|
||||||
this.handleAttackerCollision(impactorEntity,receiverEntity, isDamageEvent);
|
this.handleAttackerCollision(impactorEntity,receiverEntity, isBlockEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isBlockEvent){
|
if(isBlockEvent){
|
||||||
@ -211,7 +211,9 @@ public class ServerHitboxResolutionCallback implements CollisionResolutionCallba
|
|||||||
if(impactorEntity != null && ServerAttackTree.getServerAttackTree(impactorEntity) != null){
|
if(impactorEntity != null && ServerAttackTree.getServerAttackTree(impactorEntity) != null){
|
||||||
ServerAttackTree impactorAttackTree = ServerAttackTree.getServerAttackTree(impactorEntity);
|
ServerAttackTree impactorAttackTree = ServerAttackTree.getServerAttackTree(impactorEntity);
|
||||||
impactorAttackTree.collideEntity(receiverEntity);
|
impactorAttackTree.collideEntity(receiverEntity);
|
||||||
|
if(isBlock){
|
||||||
impactorAttackTree.recoilFromBlock();
|
impactorAttackTree.recoilFromBlock();
|
||||||
|
}
|
||||||
//if the receiver is an item that is equipped, collide with parent too
|
//if the receiver is an item that is equipped, collide with parent too
|
||||||
if(receiverIsItem && receiverHasParent){
|
if(receiverIsItem && receiverHasParent){
|
||||||
impactorAttackTree.collideEntity(AttachUtils.getParent(receiverEntity));
|
impactorAttackTree.collideEntity(AttachUtils.getParent(receiverEntity));
|
||||||
@ -224,7 +226,9 @@ public class ServerHitboxResolutionCallback implements CollisionResolutionCallba
|
|||||||
} else if(impactorEntity != null && AttachUtils.hasParent(impactorEntity) && AttachUtils.getParent(impactorEntity) != null && ServerAttackTree.getServerAttackTree(AttachUtils.getParent(impactorEntity)) != null){
|
} else if(impactorEntity != null && AttachUtils.hasParent(impactorEntity) && AttachUtils.getParent(impactorEntity) != null && ServerAttackTree.getServerAttackTree(AttachUtils.getParent(impactorEntity)) != null){
|
||||||
ServerAttackTree impactorAttackTree = ServerAttackTree.getServerAttackTree(AttachUtils.getParent(impactorEntity));
|
ServerAttackTree impactorAttackTree = ServerAttackTree.getServerAttackTree(AttachUtils.getParent(impactorEntity));
|
||||||
impactorAttackTree.collideEntity(receiverEntity);
|
impactorAttackTree.collideEntity(receiverEntity);
|
||||||
|
if(isBlock){
|
||||||
impactorAttackTree.recoilFromBlock();
|
impactorAttackTree.recoilFromBlock();
|
||||||
|
}
|
||||||
//if the receiver is an item that is equipped, collide with parent too
|
//if the receiver is an item that is equipped, collide with parent too
|
||||||
if(receiverIsItem && receiverHasParent){
|
if(receiverIsItem && receiverHasParent){
|
||||||
impactorAttackTree.collideEntity(AttachUtils.getParent(receiverEntity));
|
impactorAttackTree.collideEntity(AttachUtils.getParent(receiverEntity));
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user