hitbox collision debounce work
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
4cf34d162c
commit
1ca9c60640
@ -553,6 +553,7 @@ Movement tweaks
|
||||
Hitbox support offsets now
|
||||
Multiple hitboxes per bone
|
||||
Potential fix for client concurrency issue
|
||||
Debounce attack collisions
|
||||
|
||||
|
||||
# TODO
|
||||
@ -561,6 +562,8 @@ Potential fix for client concurrency issue
|
||||
BIG BIG BIG BIG IMMEDIATE TO DO:
|
||||
always enforce opengl interface across all opengl calls jesus christ the bone uniform bug was impossible
|
||||
|
||||
Rename "BehaviorTree" to be "Component" (what it actually is)
|
||||
|
||||
Ability to fully reload game engine state without exiting client
|
||||
- Back out to main menu and load a new level without any values persisting
|
||||
- Receive a teleport packet from server and flush all game state before requesting state from server again
|
||||
|
||||
@ -119,7 +119,7 @@ public class HitboxAudioService {
|
||||
if(ItemUtils.isWeapon(senderEntity)){
|
||||
if(CreatureUtils.isCreature(receiverEntity)){
|
||||
if(isBlockSound){
|
||||
return this.getWeaponOnCreature();
|
||||
return this.getWeaponOnBlock();
|
||||
} else if(isDamageSound){
|
||||
return this.getWeaponOnCreature();
|
||||
}
|
||||
|
||||
@ -37,6 +37,7 @@ import electrosphere.renderer.actor.Actor;
|
||||
import electrosphere.server.datacell.Realm;
|
||||
import electrosphere.util.math.MathUtils;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
@ -82,6 +83,11 @@ public class ServerAttackTree implements BehaviorTree {
|
||||
String projectileToFire = 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
|
||||
StateTransitionUtil stateTransitionUtil;
|
||||
|
||||
@ -190,14 +196,14 @@ public class ServerAttackTree implements BehaviorTree {
|
||||
//figure out attack type we should be doing
|
||||
String attackType = getAttackType();
|
||||
//if we can attack, setup doing so
|
||||
if(canAttack(attackType)){
|
||||
setAttackMoveTypeActive(attackType);
|
||||
currentMoveset = getMoveset(attackType);
|
||||
if(this.canAttack(attackType)){
|
||||
this.setAttackMoveTypeActive(attackType);
|
||||
currentMoveset = this.getMoveset(attackType);
|
||||
if(currentMoveset != null){
|
||||
if(currentMove == null){
|
||||
currentMove = currentMoveset.get(0);
|
||||
} else {
|
||||
currentMove = getNextMove(currentMoveset,currentMove.getNextMoveId());
|
||||
currentMove = this.getNextMove(currentMoveset,currentMove.getNextMoveId());
|
||||
}
|
||||
if(currentMove != null){
|
||||
firesProjectile = currentMove.getFiresProjectile();
|
||||
@ -206,18 +212,20 @@ public class ServerAttackTree implements BehaviorTree {
|
||||
}
|
||||
|
||||
//set initial stuff (this alerts the client as well)
|
||||
setCurrentMoveId(currentMove.getAttackMoveId());
|
||||
this.setCurrentMoveId(currentMove.getAttackMoveId());
|
||||
|
||||
//start tree
|
||||
if(currentMove.getWindupState() != null){
|
||||
setState(AttackTreeState.WINDUP);
|
||||
this.setState(AttackTreeState.WINDUP);
|
||||
} else if(currentMove.getAttackState() != null){
|
||||
setState(AttackTreeState.ATTACK);
|
||||
this.setState(AttackTreeState.ATTACK);
|
||||
} else {
|
||||
LoggerInterface.loggerEngine.ERROR(new IllegalStateException("Trying to start attacking tree, but current move does not have windup or attack states defined!"));
|
||||
}
|
||||
//intuit can hold from presence of windup anim
|
||||
currentMoveCanHold = currentMove.getHoldState() != null;
|
||||
//clear collided list
|
||||
this.collidedEntities.clear();
|
||||
//stop movement tree
|
||||
if(parent.containsKey(EntityDataStrings.SERVER_MOVEMENT_BT)){
|
||||
BehaviorTree movementTree = CreatureUtils.serverGetEntityMovementTree(parent);
|
||||
@ -229,12 +237,15 @@ public class ServerAttackTree implements BehaviorTree {
|
||||
EntityUtils.getRotation(parent).rotationTo(MathUtils.getOriginVector(), new Vector3d(movementVector.x,movementVector.y,movementVector.z));
|
||||
frameCurrent = 0;
|
||||
} else {
|
||||
setState(AttackTreeState.IDLE);
|
||||
this.setState(AttackTreeState.IDLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Releases the tree from holding its animation
|
||||
*/
|
||||
public void release(){
|
||||
stillHold = false;
|
||||
}
|
||||
@ -429,10 +440,18 @@ public class ServerAttackTree implements BehaviorTree {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a network message to the tree
|
||||
* @param networkMessage The network message
|
||||
*/
|
||||
public void addNetworkMessage(EntityMessage networkMessage) {
|
||||
networkMessageQueue.add(networkMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current attack type
|
||||
* @return The current attack type
|
||||
*/
|
||||
String getAttackType(){
|
||||
String rVal = null;
|
||||
if(ServerEquipState.hasEquipState(parent)){
|
||||
@ -464,7 +483,7 @@ public class ServerAttackTree implements BehaviorTree {
|
||||
* @param attackType The type of attack to perform
|
||||
* @return true if it can attack, false otherwise
|
||||
*/
|
||||
boolean canAttack(String attackType){
|
||||
private boolean canAttack(String attackType){
|
||||
boolean rVal = true;
|
||||
if(attackType == null){
|
||||
return false;
|
||||
@ -503,7 +522,13 @@ public class ServerAttackTree implements BehaviorTree {
|
||||
return rVal;
|
||||
}
|
||||
|
||||
AttackMove getNextMove(List<AttackMove> moveset, String nextMoveId){
|
||||
/**
|
||||
* Gets the next attack move
|
||||
* @param moveset The moveset
|
||||
* @param nextMoveId The next move's id
|
||||
* @return The next move if it exists, null otherwise
|
||||
*/
|
||||
private AttackMove getNextMove(List<AttackMove> moveset, String nextMoveId){
|
||||
AttackMove rVal = null;
|
||||
for(AttackMove move : moveset){
|
||||
if(move.getAttackMoveId().equals(nextMoveId)){
|
||||
@ -538,6 +563,23 @@ public class ServerAttackTree implements BehaviorTree {
|
||||
public List<AttackMove> getMoveset(String attackType){
|
||||
return (List<AttackMove>)parent.getData(attackType);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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>
|
||||
|
||||
@ -7,12 +7,22 @@ import electrosphere.entity.btree.StateTransitionUtil.StateTransitionUtilItem;
|
||||
import electrosphere.entity.EntityDataStrings;
|
||||
import electrosphere.entity.Entity;
|
||||
import electrosphere.server.datacell.utils.ServerBehaviorTreeUtils;
|
||||
import electrosphere.net.parser.net.message.CombatMessage;
|
||||
import electrosphere.net.parser.net.message.SynchronizationMessage;
|
||||
import electrosphere.server.datacell.utils.DataCellSearchUtils;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.joml.Vector3d;
|
||||
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.entity.state.hitbox.HitboxCollectionState.HitboxState;
|
||||
import electrosphere.entity.state.life.ClientLifeTree.LifeStateEnum;
|
||||
import electrosphere.entity.types.item.ItemUtils;
|
||||
import electrosphere.game.data.collidable.HitboxData;
|
||||
import electrosphere.game.data.creature.type.HealthSystem;
|
||||
import electrosphere.logger.LoggerInterface;
|
||||
import electrosphere.net.synchronization.annotation.SyncedField;
|
||||
import electrosphere.net.synchronization.annotation.SynchronizedBehaviorTree;
|
||||
import electrosphere.net.synchronization.enums.BehaviorTreeIdEnums;
|
||||
@ -48,8 +58,12 @@ public class ServerLifeTree implements BehaviorTree {
|
||||
//the current iframe count
|
||||
int iFrameCurrent = 0;
|
||||
|
||||
//accumulates collisions and determines if the parent takes damage or blocks them
|
||||
List<CollisionEvent> collisionAccumulator = new LinkedList<CollisionEvent>();
|
||||
|
||||
@Override
|
||||
public void simulate(float deltaTime) {
|
||||
this.handleAccumulatedCollisions();
|
||||
switch(state){
|
||||
case ALIVE: {
|
||||
if(iFrameCurrent > 0){
|
||||
@ -101,6 +115,85 @@ public class ServerLifeTree implements BehaviorTree {
|
||||
return this.state == LifeStateEnum.ALIVE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the collisions that have been accumulated in this tree
|
||||
*/
|
||||
private void handleAccumulatedCollisions(){
|
||||
int numCollisions = 0;
|
||||
if(collisionAccumulator.size() > 0){
|
||||
//get the blocked entities
|
||||
List<Entity> blockedEntities = new LinkedList<Entity>();
|
||||
for(CollisionEvent event : collisionAccumulator){
|
||||
if(event.isBlock && !blockedEntities.contains(event.source)){
|
||||
//don't allow multiple hits per collision
|
||||
blockedEntities.add(event.source);
|
||||
|
||||
//tracking
|
||||
numCollisions++;
|
||||
|
||||
//tell clients an impact just happened
|
||||
DataCellSearchUtils.getEntityDataCell(parent).broadcastNetworkMessage(
|
||||
CombatMessage.constructserverReportHitboxCollisionMessage(
|
||||
event.source.getId(),
|
||||
parent.getId(),
|
||||
Globals.timekeeper.getNumberOfSimFramesElapsed(),
|
||||
event.sourceHitboxData.getHitboxData().getType(),
|
||||
HitboxData.HITBOX_TYPE_BLOCK_CONNECTED
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
for(CollisionEvent event : collisionAccumulator){
|
||||
if(event.isDamage && !blockedEntities.contains(event.source)){
|
||||
//don't allow multiple hits per collision
|
||||
blockedEntities.add(event.source);
|
||||
|
||||
//tracking
|
||||
numCollisions++;
|
||||
|
||||
//tell clients an impact just happened
|
||||
DataCellSearchUtils.getEntityDataCell(parent).broadcastNetworkMessage(
|
||||
CombatMessage.constructserverReportHitboxCollisionMessage(
|
||||
event.source.getId(),
|
||||
parent.getId(),
|
||||
Globals.timekeeper.getNumberOfSimFramesElapsed(),
|
||||
event.sourceHitboxData.getHitboxData().getType(),
|
||||
event.parentHitboxData.getHitboxData().getType()
|
||||
)
|
||||
);
|
||||
|
||||
//do damage calculation
|
||||
int damage = ItemUtils.getWeaponDataRaw(event.source).getDamage();
|
||||
this.damage(damage);
|
||||
if(!this.isAlive()){
|
||||
throw new UnsupportedOperationException("Reviving not implemented yet!");
|
||||
// Realm entityRealm = Globals.realmManager.getEntityRealm(receiverParent);
|
||||
// EntityUtils.getPosition(receiverParent).set(entityRealm.getSpawnPoint());
|
||||
// serverLifeTree.revive();
|
||||
}
|
||||
}
|
||||
}
|
||||
collisionAccumulator.clear();
|
||||
}
|
||||
if(numCollisions > 0){
|
||||
LoggerInterface.loggerEngine.DEBUG("Server life tree handled: " + numCollisions + " unique collisions");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a collision event to the life tree
|
||||
* @param collisionSource The collision source
|
||||
* @param position The position of the collision event
|
||||
* @param sourceHitboxData The hitbox data for the source of the collision
|
||||
* @param parentHitboxData The hitbox data for the parent of the tree
|
||||
* @param isDamage True if this is a damage event
|
||||
* @param isBlock True if this is a block event
|
||||
*/
|
||||
public void addCollisionEvent(Entity collisionSource, HitboxState sourceHitboxData, HitboxState parentHitboxData, Vector3d position, boolean isDamage, boolean isBlock){
|
||||
CollisionEvent collisionEvent = new CollisionEvent(collisionSource, sourceHitboxData, parentHitboxData, isDamage, isBlock);
|
||||
this.collisionAccumulator.add(collisionEvent);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p> Automatically generated </p>
|
||||
* <p>
|
||||
@ -192,4 +285,52 @@ public class ServerLifeTree implements BehaviorTree {
|
||||
return (ServerLifeTree)entity.getData(EntityDataStrings.TREE_SERVERLIFETREE);
|
||||
}
|
||||
|
||||
/**
|
||||
* A single collision event
|
||||
*/
|
||||
public static class CollisionEvent {
|
||||
|
||||
/**
|
||||
* The source of the collision event
|
||||
*/
|
||||
Entity source;
|
||||
|
||||
/**
|
||||
* The hitbox data for the source of the collision
|
||||
*/
|
||||
HitboxState sourceHitboxData;
|
||||
|
||||
/**
|
||||
* The hitbox data for the parent of the tree
|
||||
*/
|
||||
HitboxState parentHitboxData;
|
||||
|
||||
/**
|
||||
* True if this is a damage event
|
||||
*/
|
||||
boolean isDamage;
|
||||
|
||||
/**
|
||||
* True if this is a block event
|
||||
*/
|
||||
boolean isBlock;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param source The source of the collision
|
||||
* @param sourceHitboxData The hitbox data for the source of the collision
|
||||
* @param parentHitboxData The hitbox data for the parent of the tree
|
||||
* @param isDamage True if this is a damage event
|
||||
* @param isBlock True if this is a block event
|
||||
*/
|
||||
public CollisionEvent(Entity source, HitboxState sourceHitboxData, HitboxState parentHitboxData, boolean isDamage, boolean isBlock){
|
||||
this.source = source;
|
||||
this.sourceHitboxData = sourceHitboxData;
|
||||
this.parentHitboxData = parentHitboxData;
|
||||
this.isDamage = isDamage;
|
||||
this.isBlock = isBlock;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -6,19 +6,14 @@ import org.ode4j.ode.DGeom;
|
||||
|
||||
import electrosphere.collision.CollisionEngine.CollisionResolutionCallback;
|
||||
import electrosphere.collision.collidable.Collidable;
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.entity.Entity;
|
||||
import electrosphere.entity.state.attack.ServerAttackTree;
|
||||
import electrosphere.entity.state.hitbox.HitboxCollectionState;
|
||||
import electrosphere.entity.state.hitbox.HitboxCollectionState.HitboxState;
|
||||
import electrosphere.entity.state.hitbox.HitboxCollectionState.HitboxType;
|
||||
import electrosphere.entity.state.life.ServerLifeTree;
|
||||
import electrosphere.entity.state.movement.ProjectileTree;
|
||||
import electrosphere.entity.types.attach.AttachUtils;
|
||||
import electrosphere.entity.types.creature.CreatureUtils;
|
||||
import electrosphere.entity.types.item.ItemUtils;
|
||||
import electrosphere.game.data.collidable.HitboxData;
|
||||
import electrosphere.net.parser.net.message.CombatMessage;
|
||||
import electrosphere.server.datacell.utils.DataCellSearchUtils;
|
||||
|
||||
/**
|
||||
* Callback for managing collisions on the server
|
||||
@ -43,22 +38,49 @@ public class ServerHitboxResolutionCallback implements CollisionResolutionCallba
|
||||
boolean receiverIsHurt = receiverShapeStatus != null && receiverShapeStatus.getType() == HitboxType.HURT;
|
||||
boolean receiverIsBlock = receiverShapeStatus != null && (receiverShapeStatus.getType() == HitboxType.BLOCK || (receiverShapeStatus.getType() == HitboxType.HIT && receiverShapeStatus.isBlockOverride()));
|
||||
boolean parentsAreDifferent = AttachUtils.getParent(impactorParent) != receiverParent;
|
||||
boolean impactorCollisionBlocked = false;
|
||||
|
||||
//currently, impactor needs to be an item, and the receiver must not be an item
|
||||
//check if the impactor thinks it can collide with the receiver
|
||||
if(impactorParent != null && ServerAttackTree.getServerAttackTree(impactorParent) != null){
|
||||
ServerAttackTree impactorAttackTree = ServerAttackTree.getServerAttackTree(impactorParent);
|
||||
//if we collide with the creature directly
|
||||
if(!impactorAttackTree.canCollideEntity(receiverParent)){
|
||||
impactorCollisionBlocked = true;
|
||||
}
|
||||
//if we collide with an item attached to the creature
|
||||
if(AttachUtils.hasParent(receiverParent) && !impactorAttackTree.canCollideEntity(AttachUtils.getParent(receiverParent))){
|
||||
impactorCollisionBlocked = true;
|
||||
}
|
||||
} else if(impactorParent != null && AttachUtils.hasParent(impactorParent) && AttachUtils.getParent(impactorParent) != null && ServerAttackTree.getServerAttackTree(AttachUtils.getParent(impactorParent)) != null){
|
||||
ServerAttackTree impactorAttackTree = ServerAttackTree.getServerAttackTree(AttachUtils.getParent(impactorParent));
|
||||
//if we collide with the creature directly
|
||||
if(!impactorAttackTree.canCollideEntity(receiverParent)){
|
||||
impactorCollisionBlocked = true;
|
||||
}
|
||||
//if we collide with an item attached to the creature
|
||||
if(AttachUtils.hasParent(receiverParent) && !impactorAttackTree.canCollideEntity(AttachUtils.getParent(receiverParent))){
|
||||
impactorCollisionBlocked = true;
|
||||
}
|
||||
}
|
||||
|
||||
//check if is damage event
|
||||
boolean isDamageEvent =
|
||||
!impactorShapeStatusIsNull &&
|
||||
!receiverShapeStatusIsNull &&
|
||||
impactorIsHit &&
|
||||
receiverIsHurt &&
|
||||
parentsAreDifferent
|
||||
parentsAreDifferent &&
|
||||
!impactorCollisionBlocked
|
||||
;
|
||||
|
||||
//check if is block event
|
||||
boolean isBlockEvent =
|
||||
!impactorShapeStatusIsNull &&
|
||||
!receiverShapeStatusIsNull &&
|
||||
impactorIsHit &&
|
||||
receiverIsBlock &&
|
||||
parentsAreDifferent
|
||||
parentsAreDifferent &&
|
||||
!impactorCollisionBlocked
|
||||
;
|
||||
|
||||
|
||||
@ -75,62 +97,68 @@ public class ServerHitboxResolutionCallback implements CollisionResolutionCallba
|
||||
boolean isItem = ItemUtils.isItem(impactorParent);//hitboxParent.containsKey(EntityDataStrings.ITEM_IS_ITEM);
|
||||
Entity hitboxAttachParent = AttachUtils.getParent(impactorParent);
|
||||
|
||||
//tell clients an impact just happened
|
||||
DataCellSearchUtils.getEntityDataCell(receiverParent).broadcastNetworkMessage(
|
||||
CombatMessage.constructserverReportHitboxCollisionMessage(
|
||||
impactorParent.getId(),
|
||||
receiverParent.getId(),
|
||||
Globals.timekeeper.getNumberOfSimFramesElapsed(),
|
||||
impactorShapeStatus.getHitboxData().getType(),
|
||||
receiverShapeStatus.getHitboxData().getType()
|
||||
)
|
||||
);
|
||||
|
||||
//
|
||||
//handle receiver
|
||||
if(isItem){
|
||||
if(hitboxAttachParent != receiverParent){
|
||||
int damage = ItemUtils.getWeaponDataRaw(impactorParent).getDamage();
|
||||
ServerLifeTree serverLifeTree = ServerLifeTree.getServerLifeTree(receiverParent);
|
||||
serverLifeTree.damage(damage);
|
||||
if(!serverLifeTree.isAlive()){
|
||||
throw new UnsupportedOperationException("Reviving not implemented yet!");
|
||||
// Realm entityRealm = Globals.realmManager.getEntityRealm(receiverParent);
|
||||
// EntityUtils.getPosition(receiverParent).set(entityRealm.getSpawnPoint());
|
||||
// serverLifeTree.revive();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int damage = 0;
|
||||
//for entities using attacktree
|
||||
if(CreatureUtils.serverGetAttackTree(impactorParent) != null){
|
||||
damage = ItemUtils.getWeaponDataRaw(impactorParent).getDamage();
|
||||
} else {
|
||||
//for entities using shooter tree
|
||||
if(ProjectileTree.getProjectileTree(impactorParent) != null){
|
||||
damage = (int)ProjectileTree.getProjectileTree(impactorParent).getDamage();
|
||||
}
|
||||
}
|
||||
ServerLifeTree serverLifeTree = ServerLifeTree.getServerLifeTree(receiverParent);
|
||||
serverLifeTree.damage(damage);
|
||||
if(!serverLifeTree.isAlive()){
|
||||
throw new UnsupportedOperationException("Reviving not implemented yet!");
|
||||
// Realm entityRealm = Globals.realmManager.getEntityRealm(receiverParent);
|
||||
// EntityUtils.getPosition(receiverParent).set(entityRealm.getSpawnPoint());
|
||||
// serverLifeTree.revive();
|
||||
serverLifeTree.addCollisionEvent(impactorParent, impactorShapeStatus, receiverShapeStatus, localPosition, isDamageEvent, isBlockEvent);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//handle attacker
|
||||
this.handleAttackerCollision(impactorParent,receiverParent);
|
||||
}
|
||||
|
||||
if(isBlockEvent){
|
||||
//tell clients an impact just happened
|
||||
DataCellSearchUtils.getEntityDataCell(receiverParent).broadcastNetworkMessage(
|
||||
CombatMessage.constructserverReportHitboxCollisionMessage(
|
||||
impactorParent.getId(),
|
||||
receiverParent.getId(),
|
||||
Globals.timekeeper.getNumberOfSimFramesElapsed(),
|
||||
impactorShapeStatus.getHitboxData().getType(),
|
||||
HitboxData.HITBOX_TYPE_BLOCK_CONNECTED //TODO: more proper block override handling
|
||||
)
|
||||
);
|
||||
//
|
||||
//handle receiver
|
||||
boolean receiverIsItem = ItemUtils.isItem(receiverParent);
|
||||
boolean receiverHasParent = AttachUtils.hasParent(receiverParent);
|
||||
if(receiverIsItem && receiverHasParent){
|
||||
//item is equipped to something
|
||||
ServerLifeTree serverLifeTree = ServerLifeTree.getServerLifeTree(AttachUtils.getParent(receiverParent));
|
||||
if(serverLifeTree != null){
|
||||
serverLifeTree.addCollisionEvent(impactorParent, impactorShapeStatus, receiverShapeStatus, localPosition, isDamageEvent, isBlockEvent);
|
||||
}
|
||||
} else {
|
||||
//attacking an item that is not equipped to anything
|
||||
ServerLifeTree serverLifeTree = ServerLifeTree.getServerLifeTree(receiverParent);
|
||||
if(serverLifeTree != null){
|
||||
serverLifeTree.addCollisionEvent(impactorParent, impactorShapeStatus, receiverShapeStatus, localPosition, isDamageEvent, isBlockEvent);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//handle attacker
|
||||
this.handleAttackerCollision(impactorParent,receiverParent);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles collision tracking from the impactor's side
|
||||
* @param impactorParent The impactor hitbox's parent entity
|
||||
* @param receiverParent The receiver hitbox's parent entity
|
||||
*/
|
||||
private void handleAttackerCollision(Entity impactorParent, Entity receiverParent){
|
||||
boolean receiverIsItem = ItemUtils.isItem(receiverParent);
|
||||
boolean receiverHasParent = AttachUtils.hasParent(receiverParent);
|
||||
|
||||
if(impactorParent != null && ServerAttackTree.getServerAttackTree(impactorParent) != null){
|
||||
ServerAttackTree impactorAttackTree = ServerAttackTree.getServerAttackTree(impactorParent);
|
||||
impactorAttackTree.collideEntity(receiverParent);
|
||||
//if the receiver is an item that is equipped, collide with parent too
|
||||
if(receiverIsItem && receiverHasParent){
|
||||
impactorAttackTree.collideEntity(AttachUtils.getParent(receiverParent));
|
||||
}
|
||||
} else if(impactorParent != null && AttachUtils.hasParent(impactorParent) && AttachUtils.getParent(impactorParent) != null && ServerAttackTree.getServerAttackTree(AttachUtils.getParent(impactorParent)) != null){
|
||||
ServerAttackTree impactorAttackTree = ServerAttackTree.getServerAttackTree(AttachUtils.getParent(impactorParent));
|
||||
impactorAttackTree.collideEntity(receiverParent);
|
||||
//if the receiver is an item that is equipped, collide with parent too
|
||||
if(receiverIsItem && receiverHasParent){
|
||||
impactorAttackTree.collideEntity(AttachUtils.getParent(receiverParent));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user