hitbox collision debugging
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
bff1b62659
commit
b1612cc943
@ -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
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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());
|
||||
}));
|
||||
}
|
||||
|
||||
@ -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!");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
|
||||
Loading…
Reference in New Issue
Block a user