From b1612cc9437ae1acfb8d80ab560a32780d820cd5 Mon Sep 17 00:00:00 2001 From: austin Date: Mon, 2 Sep 2024 18:30:26 -0400 Subject: [PATCH] hitbox collision debugging --- docs/src/progress/renderertodo.md | 18 +++ .../client/scene/ClientSceneWrapper.java | 5 +- .../collision/CollisionEngine.java | 8 +- .../collision/RayCastCallback.java | 18 ++- .../collision/hitbox/HitboxUtils.java | 4 +- .../state/hitbox/HitboxCollectionState.java | 44 +++-- .../ingame/MenuGeneratorsLevelEditor.java | 6 +- .../ServerHitboxResolutionCallback.java | 153 +++++++++++++----- .../server/datacell/RealmManager.java | 2 +- 9 files changed, 192 insertions(+), 66 deletions(-) rename src/main/java/electrosphere/server/{datacell/physics => collision}/ServerHitboxResolutionCallback.java (50%) diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md index 7bc810e4..78ddfba7 100644 --- a/docs/src/progress/renderertodo.md +++ b/docs/src/progress/renderertodo.md @@ -649,6 +649,24 @@ Fix Yoga double free bug Explicit error on setting uniform to unsupported type Methods for getting buffers from mesh +(08/29/2024) +use STBImage instead of ImageIO +Signal passing architecture +Services architecture + +(09/01/2024) +Lots of jenkins pipeline work (finally got it mostly consistent!) + +(09/02/2024) +Engine mostly building reproducibly/consistently/testably +Framebuffer fixes +Attack tree integration test +Shadowmap fixes +Shadowmap pipeline debug menu +Shader storage refactor +Unit definition/spawning +Hitbox updates for katana 2H + # TODO diff --git a/src/main/java/electrosphere/client/scene/ClientSceneWrapper.java b/src/main/java/electrosphere/client/scene/ClientSceneWrapper.java index b9374e93..b42b922a 100644 --- a/src/main/java/electrosphere/client/scene/ClientSceneWrapper.java +++ b/src/main/java/electrosphere/client/scene/ClientSceneWrapper.java @@ -5,6 +5,7 @@ import java.util.concurrent.ConcurrentHashMap; import org.joml.Vector3d; import org.ode4j.ode.DContactGeom; +import org.ode4j.ode.DGeom; import electrosphere.collision.CollisionEngine; import electrosphere.collision.CollisionEngine.CollisionResolutionCallback; @@ -220,8 +221,8 @@ public class ClientSceneWrapper { */ CollisionResolutionCallback resolutionCallback = new CollisionResolutionCallback() { @Override - public void resolve(DContactGeom geom, Collidable impactor, Collidable receiver, Vector3d normal, Vector3d localPosition, Vector3d worldPos, float magnitude) { - HitboxUtils.clientDamageHitboxColision(geom, impactor, receiver, normal, localPosition, worldPos, 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); } }; diff --git a/src/main/java/electrosphere/collision/CollisionEngine.java b/src/main/java/electrosphere/collision/CollisionEngine.java index 8d10a713..bf32c78d 100644 --- a/src/main/java/electrosphere/collision/CollisionEngine.java +++ b/src/main/java/electrosphere/collision/CollisionEngine.java @@ -353,6 +353,8 @@ public class CollisionEngine { //use custom collision resolution collisionResolutionCallback.resolve( contact.geom, + o1, + o2, bodyPointerMap.get(o1.getBody()), bodyPointerMap.get(o2.getBody()), PhysicsUtils.odeVecToJomlVec(contact.geom.normal).mul(-1.0), @@ -362,6 +364,8 @@ public class CollisionEngine { ); collisionResolutionCallback.resolve( contact.geom, + o2, + o1, bodyPointerMap.get(o2.getBody()), bodyPointerMap.get(o1.getBody()), PhysicsUtils.odeVecToJomlVec(contact.geom.normal), @@ -931,6 +935,8 @@ public class CollisionEngine { /** * Resolves a collision between two collidables in the engine * @param contactGeom the ode4j contact geom + * @param geom1 The first geometry + * @param geom2 The second geometry * @param impactor The collidable initiating the contact * @param receiver The collidable recieving the contact * @param normal The normal of the collision @@ -938,7 +944,7 @@ public class CollisionEngine { * @param worldPos The world position of the collision * @param magnitude The magnitude of the collision */ - public void resolve(DContactGeom contactGeom, Collidable impactor, Collidable receiver, Vector3d normal, Vector3d localPosition, Vector3d worldPos, float magnitude); + public void resolve(DContactGeom contactGeom, DGeom geom1, DGeom geom2, Collidable impactor, Collidable receiver, Vector3d normal, Vector3d localPosition, Vector3d worldPos, float magnitude); } } diff --git a/src/main/java/electrosphere/collision/RayCastCallback.java b/src/main/java/electrosphere/collision/RayCastCallback.java index b3092fa7..946df507 100644 --- a/src/main/java/electrosphere/collision/RayCastCallback.java +++ b/src/main/java/electrosphere/collision/RayCastCallback.java @@ -25,8 +25,16 @@ import electrosphere.logger.LoggerInterface; public class RayCastCallback implements DNearCallback { + /** + * Maximum number of contacts allowed + */ static final int MAX_CONTACTS = 5; + /** + * Really far away from the ray origin point + */ + static final double REALLY_LONG_DISTANCE = 1000000; + /** * // Check ray collision against a space void RayCallback(void *Data, dGeomID Geometry1, dGeomID Geometry2) { @@ -49,7 +57,7 @@ void RayCallback(void *Data, dGeomID Geometry1, dGeomID Geometry2) { //For the current execution, this stores the shortest length that has currently been encountered. //This is used to keep track of the closest body so that there doesn't need to be contact join creation. //This should be reset every time a ray cast is called in collision engine by calling setLength in this object. - double shortestLength = 1000000; + double shortestLength = REALLY_LONG_DISTANCE; @Override public void call(Object data, DGeom o1, DGeom o2) { @@ -111,6 +119,14 @@ void RayCallback(void *Data, dGeomID Geometry1, dGeomID Geometry2) { } } } + if(rayCastData.collisionPosition == null){ + String errorMessage = "Collision error!\n" + + "body1: " + b1 + "\n" + + "body2: " + b2 + "\n" + + "collidable1: " + collidable1 + "\n" + + "collidable2: " + collidable2 + "\n"; + LoggerInterface.loggerEngine.ERROR(new IllegalStateException(errorMessage)); + } } } } diff --git a/src/main/java/electrosphere/collision/hitbox/HitboxUtils.java b/src/main/java/electrosphere/collision/hitbox/HitboxUtils.java index 7d8d0efe..a7363974 100644 --- a/src/main/java/electrosphere/collision/hitbox/HitboxUtils.java +++ b/src/main/java/electrosphere/collision/hitbox/HitboxUtils.java @@ -24,14 +24,12 @@ public class HitboxUtils { * @param impactor the entity initiating the collision * @param receiver the entity receiving the collision */ - public static void clientDamageHitboxColision(DContactGeom contactGeom, Collidable impactor, Collidable receiver, Vector3d normal, Vector3d localPosition, Vector3d worldPos, float magnitude){ + 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); - DGeom impactorGeom = contactGeom.g1; - DGeom receiverGeom = contactGeom.g2; HitboxState impactorShapeStatus = impactorState.getShapeStatus(impactorGeom); HitboxState receiverShapeStatus = receiverState.getShapeStatus(receiverGeom); diff --git a/src/main/java/electrosphere/entity/state/hitbox/HitboxCollectionState.java b/src/main/java/electrosphere/entity/state/hitbox/HitboxCollectionState.java index 93016ce2..a4034a45 100644 --- a/src/main/java/electrosphere/entity/state/hitbox/HitboxCollectionState.java +++ b/src/main/java/electrosphere/entity/state/hitbox/HitboxCollectionState.java @@ -1,6 +1,5 @@ package electrosphere.entity.state.hitbox; -import java.util.Arrays; import java.util.HashMap; import java.util.LinkedList; import java.util.List; @@ -268,21 +267,27 @@ public class HitboxCollectionState { PhysicsEntityUtils.setGeometryPosition(collisionEngine, geom, worldPosition, rotation); } + + //update bone-attached hitboxes on server } else if(parent != null && isServer && EntityUtils.getPoseActor(parent) != null){ if(!this.geoms.isEmpty()){ Vector3d entityPosition = EntityUtils.getPosition(parent); this.body.setPosition(PhysicsUtils.jomlVecToOdeVec(entityPosition)); + // for(String boneName : this.boneHitboxMap.keySet()){ Vector3f bonePosition = EntityUtils.getPoseActor(parent).getBonePosition(boneName); + // for(HitboxState state : this.boneHitboxMap.get(boneName)){ - DGeom geom = this.stateGeomMap.get(state); - HitboxState shapeStatus = this.geomStateMap.get(geom); - switch(shapeStatus.shapeType){ + if(state == null){ + throw new IllegalStateException("Geometry not assigned to a hitbox state!"); + } + // + switch(state.shapeType){ case SPHERE: { - this.updateSphereShapePosition(collisionEngine,boneName,shapeStatus,bonePosition); + this.updateSphereShapePosition(collisionEngine,boneName,state,bonePosition); } break; case CAPSULE: { - this.updateCapsuleShapePosition(collisionEngine,boneName,shapeStatus,bonePosition); + this.updateCapsuleShapePosition(collisionEngine,boneName,state,bonePosition); } break; case STATIC_CAPSULE: { } break; @@ -387,9 +392,7 @@ public class HitboxCollectionState { //called all subsequent updates to hitbox position //destroy old capsule - this.geomStateMap.remove(geom); - this.geoms.remove(geom); - CollisionBodyCreation.destroyShape(collisionEngine, geom); + this.destroyGeom(collisionEngine, geom); //calculate position between new world point and old world point Vector3d bodyPosition = new Vector3d(worldPosition).lerp(previousWorldPos, 0.5); @@ -426,18 +429,14 @@ public class HitboxCollectionState { PhysicsEntityUtils.setGeometryPosition(collisionEngine, geom, bodyPosition, worldRotation); } else { //called first time the hitbox updates position - this.geomStateMap.remove(geom); - this.geoms.remove(geom); - CollisionBodyCreation.destroyShape(collisionEngine, geom); + this.destroyGeom(collisionEngine, geom); //create new capsule geom = CollisionBodyCreation.createCapsuleShape(manager.getCollisionEngine(), hitboxState.getHitboxData().getRadius(), length, Collidable.TYPE_OBJECT_BIT); CollisionBodyCreation.attachGeomToBody(collisionEngine,body,geom); } //update maps and other variables for next frame - this.stateGeomMap.put(hitboxState,geom); - this.geomStateMap.put(geom,hitboxState); - this.geoms.add(geom); + this.registerGeom(geom, hitboxState); hitboxState.setPreviousWorldPos(worldPosition); } @@ -560,11 +559,26 @@ public class HitboxCollectionState { * @param state The state associated with the geom */ private void registerGeom(DGeom geom, HitboxState state){ + if(state == null){ + throw new IllegalArgumentException("Null hitbox state provided to geometry register!"); + } this.geoms.add(geom); this.geomStateMap.put(geom,state); this.stateGeomMap.put(state,geom); } + /** + * Destroys a geometry + * @param collisionEngine The collision engine for the body + * @param geom The geometry + */ + private void destroyGeom(CollisionEngine collisionEngine, DGeom geom){ + HitboxState state = this.geomStateMap.remove(geom); + this.stateGeomMap.remove(state); + this.geoms.remove(geom); + CollisionBodyCreation.destroyShape(collisionEngine, geom); + } + /** * Gets the hitbox type of a given hitbox data * @param data The data diff --git a/src/main/java/electrosphere/menu/ingame/MenuGeneratorsLevelEditor.java b/src/main/java/electrosphere/menu/ingame/MenuGeneratorsLevelEditor.java index 5f2fbcc7..0d358504 100644 --- a/src/main/java/electrosphere/menu/ingame/MenuGeneratorsLevelEditor.java +++ b/src/main/java/electrosphere/menu/ingame/MenuGeneratorsLevelEditor.java @@ -203,7 +203,11 @@ public class MenuGeneratorsLevelEditor { Vector3d eyePos = new Vector3d(CameraEntityUtils.getCameraEye(Globals.playerCamera)); Vector3d centerPos = new Vector3d(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); Realm realm = Globals.realmManager.getRealms().iterator().next(); - Vector3d cursorPos = realm.getCollisionEngine().rayCastPosition(new Vector3d(centerPos), new Vector3d(eyePos).mul(-1.0), 5.0).add(cursorVerticalOffset); + Vector3d cursorPos = realm.getCollisionEngine().rayCastPosition(new Vector3d(centerPos), new Vector3d(eyePos).mul(-1.0), 5.0); + if(cursorPos == null){ + cursorPos = new Vector3d(centerPos).add(new Vector3d(eyePos).mul(-5.0)); + } + cursorPos = cursorPos.add(cursorVerticalOffset); UnitUtils.spawnUnit(realm, cursorPos, unitDefinition.getId()); })); } diff --git a/src/main/java/electrosphere/server/datacell/physics/ServerHitboxResolutionCallback.java b/src/main/java/electrosphere/server/collision/ServerHitboxResolutionCallback.java similarity index 50% rename from src/main/java/electrosphere/server/datacell/physics/ServerHitboxResolutionCallback.java rename to src/main/java/electrosphere/server/collision/ServerHitboxResolutionCallback.java index d8eca49b..ab24566b 100644 --- a/src/main/java/electrosphere/server/datacell/physics/ServerHitboxResolutionCallback.java +++ b/src/main/java/electrosphere/server/collision/ServerHitboxResolutionCallback.java @@ -1,4 +1,4 @@ -package electrosphere.server.datacell.physics; +package electrosphere.server.collision; import org.joml.Vector3d; import org.ode4j.ode.DContactGeom; @@ -14,6 +14,7 @@ import electrosphere.entity.state.hitbox.HitboxCollectionState.HitboxType; import electrosphere.entity.state.life.ServerLifeTree; import electrosphere.entity.types.attach.AttachUtils; import electrosphere.entity.types.item.ItemUtils; +import electrosphere.logger.LoggerInterface; /** * Callback for managing collisions on the server @@ -21,48 +22,106 @@ import electrosphere.entity.types.item.ItemUtils; public class ServerHitboxResolutionCallback implements CollisionResolutionCallback { @Override - public void resolve(DContactGeom contactGeom, 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); - DGeom impactorGeom = contactGeom.g1; - DGeom receiverGeom = contactGeom.g2; + public void resolve(DContactGeom contactGeom, DGeom impactorGeom, DGeom receiverGeom, Collidable impactor, Collidable receiver, Vector3d normal, Vector3d localPosition, Vector3d worldPos, float magnitude) { + Entity impactorEntity = impactor.getParent(); + Entity receiverEntity = receiver.getParent(); + HitboxCollectionState impactorState = HitboxCollectionState.getHitboxState(impactorEntity); + HitboxCollectionState receiverState = HitboxCollectionState.getHitboxState(receiverEntity); HitboxState impactorShapeStatus = impactorState.getShapeStatus(impactorGeom); HitboxState receiverShapeStatus = receiverState.getShapeStatus(receiverGeom); + //basic error checking + if(impactorEntity == null){ + throw new IllegalStateException("Impactor's entity is null"); + } + if(receiverEntity == null){ + throw new IllegalStateException("Receiver's entity is null"); + } + if(!HitboxCollectionState.hasHitboxState(impactorEntity)){ + throw new IllegalStateException("Impactor state is null"); + } + if(!HitboxCollectionState.hasHitboxState(receiverEntity)){ + throw new IllegalStateException("Receiver state is null"); + } + if(impactorGeom == null){ + throw new IllegalStateException("Impactor geom is null"); + } + if(receiverGeom == null){ + throw new IllegalStateException("Receiver geom is null"); + } + if(!impactorState.getGeometries().contains(impactorGeom)){ + String message = "Impactor geom has wrong parent assigned!\n" + + "Problem geom: " + impactorGeom + "\n" + + "All geometries tracked: " + impactorState.getGeometries() + "n\"" + ; + throw new IllegalStateException(message); + } + if(impactorShapeStatus == null){ + String message = "Impactor shape status is null\n" + + "Problem geom: " + impactorGeom + "\n" + + "All geometries tracked: " + impactorState.getGeometries() + "n\"" + ; + throw new IllegalStateException(message); + } + if(receiverShapeStatus == null){ + String message = "Receiver shape status is null\n" + + "Problem geom: " + receiverGeom + "\n" + + "All geometries tracked: " + receiverState.getGeometries() + "n\"" + ; + throw new IllegalStateException(message); + } + boolean impactorShapeStatusIsNull = impactorShapeStatus == null; boolean receiverShapeStatusIsNull = receiverShapeStatus == null; boolean impactorIsHit = impactorShapeStatus != null && impactorShapeStatus.getType() == HitboxType.HIT; 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 parentsAreDifferent = AttachUtils.getParent(impactorEntity) != receiverEntity; boolean impactorCollisionBlocked = false; //check if the impactor thinks it can collide with the receiver - if(impactorParent != null && ServerAttackTree.getServerAttackTree(impactorParent) != null){ - ServerAttackTree impactorAttackTree = ServerAttackTree.getServerAttackTree(impactorParent); + + // + //sword has attack tree + if(impactorEntity != null && ServerAttackTree.getServerAttackTree(impactorEntity) != null){ + ServerAttackTree impactorAttackTree = ServerAttackTree.getServerAttackTree(impactorEntity); + + // + //sword-on-sword check //if we collide with the creature directly - if(!impactorAttackTree.canCollideEntity(receiverParent)){ + if(!impactorAttackTree.canCollideEntity(receiverEntity)){ impactorCollisionBlocked = true; } + + // + //sword-on-creature check //if we collide with an item attached to the creature - if(AttachUtils.hasParent(receiverParent) && !impactorAttackTree.canCollideEntity(AttachUtils.getParent(receiverParent))){ + if(AttachUtils.hasParent(receiverEntity) && !impactorAttackTree.canCollideEntity(AttachUtils.getParent(receiverEntity))){ 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)); + + // + //creature has attack tree + } else if(impactorEntity != null && AttachUtils.hasParent(impactorEntity) && AttachUtils.getParent(impactorEntity) != null && ServerAttackTree.getServerAttackTree(AttachUtils.getParent(impactorEntity)) != null){ + ServerAttackTree impactorAttackTree = ServerAttackTree.getServerAttackTree(AttachUtils.getParent(impactorEntity)); + + // + //creature-on-sword check //if we collide with the creature directly - if(!impactorAttackTree.canCollideEntity(receiverParent)){ + if(!impactorAttackTree.canCollideEntity(receiverEntity)){ impactorCollisionBlocked = true; } + + // + //creature-on-creature check //if we collide with an item attached to the creature - if(AttachUtils.hasParent(receiverParent) && !impactorAttackTree.canCollideEntity(AttachUtils.getParent(receiverParent))){ + if(AttachUtils.hasParent(receiverEntity) && !impactorAttackTree.canCollideEntity(AttachUtils.getParent(receiverEntity))){ impactorCollisionBlocked = true; } } + // //check if is damage event boolean isDamageEvent = !impactorShapeStatusIsNull && @@ -73,6 +132,7 @@ public class ServerHitboxResolutionCallback implements CollisionResolutionCallba !impactorCollisionBlocked ; + // //check if is block event boolean isBlockEvent = !impactorShapeStatusIsNull && @@ -94,70 +154,79 @@ public class ServerHitboxResolutionCallback implements CollisionResolutionCallba if(isDamageEvent){ //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(impactorParent);//hitboxParent.containsKey(EntityDataStrings.ITEM_IS_ITEM); - Entity hitboxAttachParent = AttachUtils.getParent(impactorParent); + boolean isItem = ItemUtils.isItem(impactorEntity); + Entity hitboxAttachParent = AttachUtils.getParent(impactorEntity); // //handle receiver if(isItem){ - if(hitboxAttachParent != receiverParent){ - ServerLifeTree serverLifeTree = ServerLifeTree.getServerLifeTree(receiverParent); - serverLifeTree.addCollisionEvent(impactorParent, impactorShapeStatus, receiverShapeStatus, worldPos, isDamageEvent, isBlockEvent); + if(hitboxAttachParent != receiverEntity){ + ServerLifeTree serverLifeTree = ServerLifeTree.getServerLifeTree(receiverEntity); + serverLifeTree.addCollisionEvent(impactorEntity, impactorShapeStatus, receiverShapeStatus, worldPos, isDamageEvent, isBlockEvent); } } // //handle attacker - this.handleAttackerCollision(impactorParent,receiverParent); + this.handleAttackerCollision(impactorEntity,receiverEntity); } if(isBlockEvent){ // //handle receiver - boolean receiverIsItem = ItemUtils.isItem(receiverParent); - boolean receiverHasParent = AttachUtils.hasParent(receiverParent); + boolean receiverIsItem = ItemUtils.isItem(receiverEntity); + boolean receiverHasParent = AttachUtils.hasParent(receiverEntity); if(receiverIsItem && receiverHasParent){ //item is equipped to something - ServerLifeTree serverLifeTree = ServerLifeTree.getServerLifeTree(AttachUtils.getParent(receiverParent)); + ServerLifeTree serverLifeTree = ServerLifeTree.getServerLifeTree(AttachUtils.getParent(receiverEntity)); if(serverLifeTree != null){ - serverLifeTree.addCollisionEvent(impactorParent, impactorShapeStatus, receiverShapeStatus, worldPos, isDamageEvent, isBlockEvent); + serverLifeTree.addCollisionEvent(impactorEntity, impactorShapeStatus, receiverShapeStatus, worldPos, isDamageEvent, isBlockEvent); } } else { //attacking an item that is not equipped to anything - ServerLifeTree serverLifeTree = ServerLifeTree.getServerLifeTree(receiverParent); + ServerLifeTree serverLifeTree = ServerLifeTree.getServerLifeTree(receiverEntity); if(serverLifeTree != null){ - serverLifeTree.addCollisionEvent(impactorParent, impactorShapeStatus, receiverShapeStatus, worldPos, isDamageEvent, isBlockEvent); + serverLifeTree.addCollisionEvent(impactorEntity, impactorShapeStatus, receiverShapeStatus, worldPos, isDamageEvent, isBlockEvent); } } // //handle attacker - this.handleAttackerCollision(impactorParent,receiverParent); + this.handleAttackerCollision(impactorEntity,receiverEntity); } } /** * Handles collision tracking from the impactor's side - * @param impactorParent The impactor hitbox's parent entity + * @param impactorEntity 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); + private void handleAttackerCollision(Entity impactorEntity, Entity receiverEntity){ + boolean receiverIsItem = ItemUtils.isItem(receiverEntity); + boolean receiverHasParent = AttachUtils.hasParent(receiverEntity); - if(impactorParent != null && ServerAttackTree.getServerAttackTree(impactorParent) != null){ - ServerAttackTree impactorAttackTree = ServerAttackTree.getServerAttackTree(impactorParent); - impactorAttackTree.collideEntity(receiverParent); + // + //The sword has the attack tree + if(impactorEntity != null && ServerAttackTree.getServerAttackTree(impactorEntity) != null){ + ServerAttackTree impactorAttackTree = ServerAttackTree.getServerAttackTree(impactorEntity); + impactorAttackTree.collideEntity(receiverEntity); //if the receiver is an item that is equipped, collide with parent too if(receiverIsItem && receiverHasParent){ - impactorAttackTree.collideEntity(AttachUtils.getParent(receiverParent)); + impactorAttackTree.collideEntity(AttachUtils.getParent(receiverEntity)); + } else if(receiverHasParent){ + LoggerInterface.loggerEngine.WARNING("Potentially unhandled case with server collision!"); } - } 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); + + // + //The parent of the sword has the attack tree + } else if(impactorEntity != null && AttachUtils.hasParent(impactorEntity) && AttachUtils.getParent(impactorEntity) != null && ServerAttackTree.getServerAttackTree(AttachUtils.getParent(impactorEntity)) != null){ + ServerAttackTree impactorAttackTree = ServerAttackTree.getServerAttackTree(AttachUtils.getParent(impactorEntity)); + impactorAttackTree.collideEntity(receiverEntity); //if the receiver is an item that is equipped, collide with parent too if(receiverIsItem && receiverHasParent){ - impactorAttackTree.collideEntity(AttachUtils.getParent(receiverParent)); + impactorAttackTree.collideEntity(AttachUtils.getParent(receiverEntity)); + } else if(receiverHasParent){ + LoggerInterface.loggerEngine.WARNING("Potentially unhandled case with server collision!"); } } } diff --git a/src/main/java/electrosphere/server/datacell/RealmManager.java b/src/main/java/electrosphere/server/datacell/RealmManager.java index 354f4eb1..295de9e2 100644 --- a/src/main/java/electrosphere/server/datacell/RealmManager.java +++ b/src/main/java/electrosphere/server/datacell/RealmManager.java @@ -11,8 +11,8 @@ import electrosphere.collision.hitbox.HitboxManager; import electrosphere.entity.Entity; import electrosphere.game.server.world.ServerWorldData; import electrosphere.net.server.player.Player; +import electrosphere.server.collision.ServerHitboxResolutionCallback; import electrosphere.server.content.ServerContentManager; -import electrosphere.server.datacell.physics.ServerHitboxResolutionCallback; /** * Manages all realms for the engine. Should be a singleton