This commit is contained in:
parent
8e48250013
commit
8e6c9e97b0
BIN
assets/Audio/weapons/collisions/Sword Hit A.wav
Normal file
BIN
assets/Audio/weapons/collisions/Sword Hit A.wav
Normal file
Binary file not shown.
BIN
assets/Audio/weapons/collisions/Sword Hit B.wav
Normal file
BIN
assets/Audio/weapons/collisions/Sword Hit B.wav
Normal file
Binary file not shown.
BIN
assets/Audio/weapons/collisions/Sword Hit C.wav
Normal file
BIN
assets/Audio/weapons/collisions/Sword Hit C.wav
Normal file
Binary file not shown.
BIN
assets/Audio/weapons/collisions/Sword Hit D.wav
Normal file
BIN
assets/Audio/weapons/collisions/Sword Hit D.wav
Normal file
Binary file not shown.
BIN
assets/Audio/weapons/collisions/Sword Hit E.wav
Normal file
BIN
assets/Audio/weapons/collisions/Sword Hit E.wav
Normal file
Binary file not shown.
@ -9,7 +9,6 @@
|
|||||||
review combat code (lifestate, damage calculation, etc)
|
review combat code (lifestate, damage calculation, etc)
|
||||||
- Allow block hotboxxes to block damage
|
- Allow block hotboxxes to block damage
|
||||||
audio fx for everything
|
audio fx for everything
|
||||||
- Block SFX
|
|
||||||
|
|
||||||
+ rearchitecture
|
+ rearchitecture
|
||||||
|
|
||||||
@ -18,6 +17,4 @@
|
|||||||
Hitboxes between server and client feel wayyyy off
|
Hitboxes between server and client feel wayyyy off
|
||||||
|
|
||||||
+ bug fixes
|
+ bug fixes
|
||||||
On attack, the server weapon does not swing (it instead stops aligning)
|
|
||||||
The server does not interrupt attack on animation end
|
|
||||||
|
|
||||||
|
|||||||
@ -539,6 +539,8 @@ Pass at client-server physics synchronization
|
|||||||
|
|
||||||
(08/12/2024)
|
(08/12/2024)
|
||||||
Fix server animation playing at reduced timescale
|
Fix server animation playing at reduced timescale
|
||||||
|
Block override concept for hitboxes
|
||||||
|
Block sfx
|
||||||
|
|
||||||
|
|
||||||
# TODO
|
# TODO
|
||||||
|
|||||||
@ -9,6 +9,8 @@ import electrosphere.engine.Globals;
|
|||||||
import electrosphere.entity.Entity;
|
import electrosphere.entity.Entity;
|
||||||
import electrosphere.entity.types.creature.CreatureUtils;
|
import electrosphere.entity.types.creature.CreatureUtils;
|
||||||
import electrosphere.entity.types.item.ItemUtils;
|
import electrosphere.entity.types.item.ItemUtils;
|
||||||
|
import electrosphere.entity.types.object.ObjectUtils;
|
||||||
|
import electrosphere.game.data.collidable.HitboxData;
|
||||||
import electrosphere.logger.LoggerInterface;
|
import electrosphere.logger.LoggerInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -25,6 +27,17 @@ public class HitboxAudioService {
|
|||||||
"Audio/weapons/collisions/Massive Punch C.wav",
|
"Audio/weapons/collisions/Massive Punch C.wav",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default audio files to play. Eventually should probably refactor into service that determines audio based on materials
|
||||||
|
*/
|
||||||
|
static String[] defaultBlockboxAudio = new String[]{
|
||||||
|
"Audio/weapons/collisions/Sword Hit A.wav",
|
||||||
|
"Audio/weapons/collisions/Sword Hit B.wav",
|
||||||
|
"Audio/weapons/collisions/Sword Hit C.wav",
|
||||||
|
"Audio/weapons/collisions/Sword Hit D.wav",
|
||||||
|
"Audio/weapons/collisions/Sword Hit E.wav",
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The random for selecting which file to play
|
* The random for selecting which file to play
|
||||||
*/
|
*/
|
||||||
@ -64,11 +77,66 @@ public class HitboxAudioService {
|
|||||||
* @return The audio file to play
|
* @return The audio file to play
|
||||||
*/
|
*/
|
||||||
private String getAudioPath(Entity senderEntity, Entity receiverEntity, String hitboxType, String hurtboxType){
|
private String getAudioPath(Entity senderEntity, Entity receiverEntity, String hitboxType, String hurtboxType){
|
||||||
|
boolean isBlockSound = false;
|
||||||
|
boolean isDamageSound = false;
|
||||||
|
switch(hitboxType){
|
||||||
|
case HitboxData.HITBOX_TYPE_HIT:
|
||||||
|
case HitboxData.HITBOX_TYPE_HIT_CONNECTED: {
|
||||||
|
switch(hurtboxType){
|
||||||
|
case HitboxData.HITBOX_TYPE_HIT:
|
||||||
|
case HitboxData.HITBOX_TYPE_HIT_CONNECTED: {
|
||||||
|
isBlockSound = true;
|
||||||
|
} break;
|
||||||
|
case HitboxData.HITBOX_TYPE_BLOCK_CONNECTED: {
|
||||||
|
isBlockSound = true;
|
||||||
|
} break;
|
||||||
|
case HitboxData.HITBOX_TYPE_HURT:
|
||||||
|
case HitboxData.HITBOX_TYPE_HURT_CONNECTED: {
|
||||||
|
isDamageSound = true;
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
case HitboxData.HITBOX_TYPE_BLOCK_CONNECTED: {
|
||||||
|
switch(hurtboxType){
|
||||||
|
case HitboxData.HITBOX_TYPE_HIT:
|
||||||
|
case HitboxData.HITBOX_TYPE_HIT_CONNECTED: {
|
||||||
|
isBlockSound = true;
|
||||||
|
} break;
|
||||||
|
case HitboxData.HITBOX_TYPE_BLOCK_CONNECTED: {
|
||||||
|
isBlockSound = true;
|
||||||
|
} break;
|
||||||
|
case HitboxData.HITBOX_TYPE_HURT:
|
||||||
|
case HitboxData.HITBOX_TYPE_HURT_CONNECTED: {
|
||||||
|
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
case HitboxData.HITBOX_TYPE_HURT:
|
||||||
|
case HitboxData.HITBOX_TYPE_HURT_CONNECTED: {
|
||||||
|
|
||||||
|
} break;
|
||||||
|
}
|
||||||
if(ItemUtils.isWeapon(senderEntity)){
|
if(ItemUtils.isWeapon(senderEntity)){
|
||||||
if(CreatureUtils.isCreature(receiverEntity)){
|
if(CreatureUtils.isCreature(receiverEntity)){
|
||||||
return this.getWeaponOnCreature();
|
if(isBlockSound){
|
||||||
|
return this.getWeaponOnCreature();
|
||||||
|
} else if(isDamageSound){
|
||||||
|
return this.getWeaponOnCreature();
|
||||||
|
}
|
||||||
|
} else if(ItemUtils.isWeapon(receiverEntity)){
|
||||||
|
if(isBlockSound){
|
||||||
|
return this.getWeaponOnBlock();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
LoggerInterface.loggerEngine.WARNING("Getting audio for unhandled hurtbox collision type!");
|
String message = "Getting audio for unhandled hurtbox collision type!\n" +
|
||||||
|
"Is creature: " + CreatureUtils.isCreature(receiverEntity) + "\n" +
|
||||||
|
"Is item: " + ItemUtils.isItem(receiverEntity) + "\n" +
|
||||||
|
"Is weapon: " + ItemUtils.isWeapon(receiverEntity) + "\n" +
|
||||||
|
"Is object: " + ObjectUtils.isObject(receiverEntity);
|
||||||
|
if(ItemUtils.isItem(receiverEntity)){
|
||||||
|
message = message + "\nItem Type: " + ItemUtils.getType(receiverEntity);
|
||||||
|
}
|
||||||
|
LoggerInterface.loggerEngine.WARNING(message);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LoggerInterface.loggerEngine.WARNING("Getting audio for unhandled hitbox collision type!");
|
LoggerInterface.loggerEngine.WARNING("Getting audio for unhandled hitbox collision type!");
|
||||||
@ -86,4 +154,13 @@ public class HitboxAudioService {
|
|||||||
return defaultHitboxAudio[roll];
|
return defaultHitboxAudio[roll];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the audio to play when a weapon collides with a block box
|
||||||
|
* @return The audio file to play
|
||||||
|
*/
|
||||||
|
private String getWeaponOnBlock(){
|
||||||
|
int roll = random.nextInt(defaultBlockboxAudio.length);
|
||||||
|
return defaultBlockboxAudio[roll];
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,7 +25,10 @@ public class ClientHitboxCollision {
|
|||||||
switch(hurtboxType){
|
switch(hurtboxType){
|
||||||
case HitboxData.HITBOX_TYPE_HURT:
|
case HitboxData.HITBOX_TYPE_HURT:
|
||||||
case HitboxData.HITBOX_TYPE_HURT_CONNECTED: {
|
case HitboxData.HITBOX_TYPE_HURT_CONNECTED: {
|
||||||
Globals.hitboxAudioService.playAudio(senderEntity, receiverEntity, hitboxType, hurtboxType);
|
Globals.hitboxAudioService.playAudioPositional(senderEntity, receiverEntity, hitboxType, hurtboxType, position);
|
||||||
|
} break;
|
||||||
|
case HitboxData.HITBOX_TYPE_BLOCK_CONNECTED: {
|
||||||
|
Globals.hitboxAudioService.playAudioPositional(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);
|
||||||
|
|||||||
@ -478,6 +478,11 @@ public class Globals {
|
|||||||
"/Audio/weapons/collisions/Massive Punch A.wav",
|
"/Audio/weapons/collisions/Massive Punch A.wav",
|
||||||
"/Audio/weapons/collisions/Massive Punch B.wav",
|
"/Audio/weapons/collisions/Massive Punch B.wav",
|
||||||
"/Audio/weapons/collisions/Massive Punch C.wav",
|
"/Audio/weapons/collisions/Massive Punch C.wav",
|
||||||
|
"Audio/weapons/collisions/Sword Hit A.wav",
|
||||||
|
"Audio/weapons/collisions/Sword Hit B.wav",
|
||||||
|
"Audio/weapons/collisions/Sword Hit C.wav",
|
||||||
|
"Audio/weapons/collisions/Sword Hit D.wav",
|
||||||
|
"Audio/weapons/collisions/Sword Hit E.wav",
|
||||||
};
|
};
|
||||||
LoggerInterface.loggerStartup.INFO("Loading default audio resources");
|
LoggerInterface.loggerStartup.INFO("Loading default audio resources");
|
||||||
for(String path : audioToInit){
|
for(String path : audioToInit){
|
||||||
|
|||||||
@ -20,6 +20,15 @@ public class ClientEntityUtils {
|
|||||||
//reposition entity
|
//reposition entity
|
||||||
CollisionObjUtils.clientPositionCharacter(entity, position);
|
CollisionObjUtils.clientPositionCharacter(entity, position);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroys an entity on the client
|
||||||
|
* @param entity the entity to destroy
|
||||||
|
*/
|
||||||
|
public static void destroyEntity(Entity entity){
|
||||||
|
//deregister all behavior trees
|
||||||
|
EntityUtils.cleanUpEntity(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -239,12 +239,19 @@ public class ServerAttackTree implements BehaviorTree {
|
|||||||
stillHold = false;
|
stillHold = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interrupts the tree
|
||||||
|
*/
|
||||||
public void interrupt(){
|
public void interrupt(){
|
||||||
setState(AttackTreeState.IDLE);
|
setState(AttackTreeState.IDLE);
|
||||||
}
|
//activate hitboxes
|
||||||
|
List<Entity> attachedEntities = AttachUtils.getChildrenList(parent);
|
||||||
public void slowdown(){
|
for(Entity currentAttached : attachedEntities){
|
||||||
setState(AttackTreeState.COOLDOWN);
|
if(HitboxCollectionState.hasHitboxState(currentAttached)){
|
||||||
|
HitboxCollectionState currentState = HitboxCollectionState.getHitboxState(currentAttached);
|
||||||
|
currentState.setActive(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
package electrosphere.entity.state.block;
|
package electrosphere.entity.state.block;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import electrosphere.engine.Globals;
|
import electrosphere.engine.Globals;
|
||||||
import electrosphere.entity.Entity;
|
import electrosphere.entity.Entity;
|
||||||
import electrosphere.entity.EntityDataStrings;
|
import electrosphere.entity.EntityDataStrings;
|
||||||
@ -12,6 +14,8 @@ import electrosphere.net.parser.net.message.SynchronizationMessage;
|
|||||||
|
|
||||||
import electrosphere.server.datacell.utils.DataCellSearchUtils;
|
import electrosphere.server.datacell.utils.DataCellSearchUtils;
|
||||||
import electrosphere.entity.state.block.ClientBlockTree.BlockState;
|
import electrosphere.entity.state.block.ClientBlockTree.BlockState;
|
||||||
|
import electrosphere.entity.state.hitbox.HitboxCollectionState;
|
||||||
|
import electrosphere.entity.types.attach.AttachUtils;
|
||||||
import electrosphere.game.data.creature.type.block.BlockSystem;
|
import electrosphere.game.data.creature.type.block.BlockSystem;
|
||||||
import electrosphere.game.data.creature.type.block.BlockVariant;
|
import electrosphere.game.data.creature.type.block.BlockVariant;
|
||||||
import electrosphere.net.synchronization.annotation.SyncedField;
|
import electrosphere.net.synchronization.annotation.SyncedField;
|
||||||
@ -96,6 +100,15 @@ public class ServerBlockTree implements BehaviorTree {
|
|||||||
public void stop(){
|
public void stop(){
|
||||||
this.stateTransitionUtil.reset();
|
this.stateTransitionUtil.reset();
|
||||||
setState(BlockState.COOLDOWN);
|
setState(BlockState.COOLDOWN);
|
||||||
|
//activate hitboxes
|
||||||
|
List<Entity> attachedEntities = AttachUtils.getChildrenList(parent);
|
||||||
|
for(Entity currentAttached : attachedEntities){
|
||||||
|
if(HitboxCollectionState.hasHitboxState(currentAttached)){
|
||||||
|
HitboxCollectionState currentState = HitboxCollectionState.getHitboxState(currentAttached);
|
||||||
|
currentState.setActive(false);
|
||||||
|
currentState.setBlockOverride(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -105,9 +118,27 @@ public class ServerBlockTree implements BehaviorTree {
|
|||||||
this.stateTransitionUtil.simulate(BlockState.WIND_UP);
|
this.stateTransitionUtil.simulate(BlockState.WIND_UP);
|
||||||
} break;
|
} break;
|
||||||
case BLOCKING: {
|
case BLOCKING: {
|
||||||
|
//activate hitboxes
|
||||||
|
List<Entity> attachedEntities = AttachUtils.getChildrenList(parent);
|
||||||
|
for(Entity currentAttached : attachedEntities){
|
||||||
|
if(HitboxCollectionState.hasHitboxState(currentAttached)){
|
||||||
|
HitboxCollectionState currentState = HitboxCollectionState.getHitboxState(currentAttached);
|
||||||
|
currentState.setActive(true);
|
||||||
|
currentState.setBlockOverride(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
this.stateTransitionUtil.simulate(BlockState.BLOCKING);
|
this.stateTransitionUtil.simulate(BlockState.BLOCKING);
|
||||||
} break;
|
} break;
|
||||||
case COOLDOWN: {
|
case COOLDOWN: {
|
||||||
|
//activate hitboxes
|
||||||
|
List<Entity> attachedEntities = AttachUtils.getChildrenList(parent);
|
||||||
|
for(Entity currentAttached : attachedEntities){
|
||||||
|
if(HitboxCollectionState.hasHitboxState(currentAttached)){
|
||||||
|
HitboxCollectionState currentState = HitboxCollectionState.getHitboxState(currentAttached);
|
||||||
|
currentState.setActive(false);
|
||||||
|
currentState.setBlockOverride(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
this.stateTransitionUtil.simulate(BlockState.COOLDOWN);
|
this.stateTransitionUtil.simulate(BlockState.COOLDOWN);
|
||||||
} break;
|
} break;
|
||||||
case NOT_BLOCKING: {
|
case NOT_BLOCKING: {
|
||||||
|
|||||||
@ -73,6 +73,9 @@ public class HitboxCollectionState {
|
|||||||
//controls whether the hitbox state is active or not
|
//controls whether the hitbox state is active or not
|
||||||
boolean active = true;
|
boolean active = true;
|
||||||
|
|
||||||
|
//controls whether active hitboxes should be overwritten with block boxes
|
||||||
|
boolean blockOverride = false;
|
||||||
|
|
||||||
//the associated manager
|
//the associated manager
|
||||||
HitboxManager manager;
|
HitboxManager manager;
|
||||||
|
|
||||||
@ -153,7 +156,7 @@ public class HitboxCollectionState {
|
|||||||
rVal.hitboxGeomMap.put(hitboxDataRaw.getBone(),geom);
|
rVal.hitboxGeomMap.put(hitboxDataRaw.getBone(),geom);
|
||||||
}
|
}
|
||||||
rVal.geoms.add(geom);
|
rVal.geoms.add(geom);
|
||||||
rVal.geomStateMap.put(geom,new HitboxState(hitboxDataRaw.getBone(), hitboxDataRaw, type, subType, shapeType, true));
|
rVal.geomStateMap.put(geom,new HitboxState(hitboxDataRaw.getBone(), hitboxDataRaw, type, subType, shapeType, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
//create body with all the shapes
|
//create body with all the shapes
|
||||||
@ -467,6 +470,26 @@ public class HitboxCollectionState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the block override status
|
||||||
|
* @return true if should override hitboxes with blockboxes, false otherwise
|
||||||
|
*/
|
||||||
|
public boolean isBlockOverride(){
|
||||||
|
return this.blockOverride;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the block override of the hitbox
|
||||||
|
* @param state true to override attack hitboxes with block boxes, false otherwise
|
||||||
|
*/
|
||||||
|
public void setBlockOverride(boolean state){
|
||||||
|
this.blockOverride = state;
|
||||||
|
for(DGeom geom : this.geoms){
|
||||||
|
HitboxState shapeState = this.getShapeStatus(geom);
|
||||||
|
shapeState.setBlockOverride(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the list of all DGeoms in the data
|
* Gets the list of all DGeoms in the data
|
||||||
* @return the list of all DGeoms
|
* @return the list of all DGeoms
|
||||||
@ -526,6 +549,10 @@ public class HitboxCollectionState {
|
|||||||
//controls whether the hitbox is active
|
//controls whether the hitbox is active
|
||||||
boolean isActive;
|
boolean isActive;
|
||||||
|
|
||||||
|
//controls whether the block override is active or not
|
||||||
|
//if it is active, hitboxes should behave like block boxes
|
||||||
|
boolean blockOverride = false;
|
||||||
|
|
||||||
//the previous position of this hitbox shape
|
//the previous position of this hitbox shape
|
||||||
Vector3d previousWorldPos = null;
|
Vector3d previousWorldPos = null;
|
||||||
|
|
||||||
@ -633,6 +660,22 @@ public class HitboxCollectionState {
|
|||||||
this.isActive = active;
|
this.isActive = active;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets whether the block override is active or not
|
||||||
|
* @return true if the block override is active, false otherwise
|
||||||
|
*/
|
||||||
|
public boolean isBlockOverride(){
|
||||||
|
return blockOverride;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether the block override is active or not
|
||||||
|
* @param blockOverride true if the block override is active, false otherwise
|
||||||
|
*/
|
||||||
|
public void setBlockOverride(boolean blockOverride){
|
||||||
|
this.blockOverride = blockOverride;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the previous world position of this hitbox
|
* Gets the previous world position of this hitbox
|
||||||
* @return The previous world position
|
* @return The previous world position
|
||||||
|
|||||||
@ -376,10 +376,17 @@ public class ItemUtils {
|
|||||||
*/
|
*/
|
||||||
public static Entity clientRecreateContainerItem(Entity item, Entity containingParent){
|
public static Entity clientRecreateContainerItem(Entity item, Entity containingParent){
|
||||||
if(isItem(item)){
|
if(isItem(item)){
|
||||||
|
Item itemData = Globals.gameConfigCurrent.getItemMap().getItem(ItemUtils.getType(item));
|
||||||
Entity rVal = EntityCreationUtils.createClientNonSpatialEntity();
|
Entity rVal = EntityCreationUtils.createClientNonSpatialEntity();
|
||||||
if(getEquipWhitelist(item) != null){
|
if(getEquipWhitelist(item) != null){
|
||||||
rVal.putData(EntityDataStrings.ITEM_EQUIP_WHITELIST, getEquipWhitelist(item));
|
rVal.putData(EntityDataStrings.ITEM_EQUIP_WHITELIST, getEquipWhitelist(item));
|
||||||
}
|
}
|
||||||
|
if(itemData.getWeaponData() != null){
|
||||||
|
rVal.putData(EntityDataStrings.ITEM_IS_WEAPON, true);
|
||||||
|
WeaponData weaponData = itemData.getWeaponData();
|
||||||
|
rVal.putData(EntityDataStrings.ITEM_WEAPON_CLASS,weaponData.getWeaponClass());
|
||||||
|
rVal.putData(EntityDataStrings.ITEM_WEAPON_DATA_RAW,weaponData);
|
||||||
|
}
|
||||||
rVal.putData(EntityDataStrings.ITEM_ICON,ItemUtils.getItemIcon(item));
|
rVal.putData(EntityDataStrings.ITEM_ICON,ItemUtils.getItemIcon(item));
|
||||||
rVal.putData(EntityDataStrings.ITEM_EQUIP_CLASS, item.getData(EntityDataStrings.ITEM_EQUIP_CLASS));
|
rVal.putData(EntityDataStrings.ITEM_EQUIP_CLASS, item.getData(EntityDataStrings.ITEM_EQUIP_CLASS));
|
||||||
EntityUtils.setEntityType(rVal, ENTITY_TYPE_ITEM);
|
EntityUtils.setEntityType(rVal, ENTITY_TYPE_ITEM);
|
||||||
|
|||||||
@ -50,6 +50,9 @@ public class HitboxData {
|
|||||||
//controls whether the hitbox is active or not
|
//controls whether the hitbox is active or not
|
||||||
boolean active = false;
|
boolean active = false;
|
||||||
|
|
||||||
|
//override when block state is active. Used to make hitboxes function as blockboxes while blocking
|
||||||
|
boolean blockOverride = false;
|
||||||
|
|
||||||
//used for more advanced hitbox spawning to find hitbox position on frame update
|
//used for more advanced hitbox spawning to find hitbox position on frame update
|
||||||
HitboxPositionCallback positionCallback;
|
HitboxPositionCallback positionCallback;
|
||||||
|
|
||||||
@ -112,6 +115,22 @@ public class HitboxData {
|
|||||||
this.active = active;
|
this.active = active;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the block override status
|
||||||
|
* @return true if should override hitboxes with block, false otherwise
|
||||||
|
*/
|
||||||
|
public boolean isBlockOverride(){
|
||||||
|
return blockOverride;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the status of the block override
|
||||||
|
* @param blockOverride true if should override hitboxes with block, false otherwise
|
||||||
|
*/
|
||||||
|
public void setBlockOverride(boolean blockOverride){
|
||||||
|
this.blockOverride = blockOverride;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the bone this hitbox is attached to
|
* Sets the bone this hitbox is attached to
|
||||||
* @param bone the bone to attach the hitbox to
|
* @param bone the bone to attach the hitbox to
|
||||||
|
|||||||
@ -358,6 +358,9 @@ public class DebugContentPipeline implements RenderPipeline {
|
|||||||
return "Textures/color/transparent_yellow.png";
|
return "Textures/color/transparent_yellow.png";
|
||||||
}
|
}
|
||||||
if(shapeStatus.isActive()){
|
if(shapeStatus.isActive()){
|
||||||
|
if(shapeStatus.isBlockOverride()){
|
||||||
|
return "Textures/transparent_blue.png";
|
||||||
|
}
|
||||||
return "Textures/transparent_red.png";
|
return "Textures/transparent_red.png";
|
||||||
}
|
}
|
||||||
return "Textures/transparent_grey.png";
|
return "Textures/transparent_grey.png";
|
||||||
|
|||||||
@ -16,6 +16,7 @@ import electrosphere.entity.state.movement.ProjectileTree;
|
|||||||
import electrosphere.entity.types.attach.AttachUtils;
|
import electrosphere.entity.types.attach.AttachUtils;
|
||||||
import electrosphere.entity.types.creature.CreatureUtils;
|
import electrosphere.entity.types.creature.CreatureUtils;
|
||||||
import electrosphere.entity.types.item.ItemUtils;
|
import electrosphere.entity.types.item.ItemUtils;
|
||||||
|
import electrosphere.game.data.collidable.HitboxData;
|
||||||
import electrosphere.net.parser.net.message.CombatMessage;
|
import electrosphere.net.parser.net.message.CombatMessage;
|
||||||
import electrosphere.server.datacell.utils.DataCellSearchUtils;
|
import electrosphere.server.datacell.utils.DataCellSearchUtils;
|
||||||
|
|
||||||
@ -44,6 +45,14 @@ public class ServerHitboxResolutionCallback implements CollisionResolutionCallba
|
|||||||
receiverShapeStatus.getType() == HitboxType.HURT &&
|
receiverShapeStatus.getType() == HitboxType.HURT &&
|
||||||
AttachUtils.getParent(impactorParent) != receiverParent
|
AttachUtils.getParent(impactorParent) != receiverParent
|
||||||
;
|
;
|
||||||
|
|
||||||
|
boolean isBlockEvent =
|
||||||
|
impactorShapeStatus != null &&
|
||||||
|
receiverShapeStatus != null &&
|
||||||
|
impactorShapeStatus.getType() == HitboxType.HIT &&
|
||||||
|
(receiverShapeStatus.getType() == HitboxType.BLOCK || (receiverShapeStatus.getType() == HitboxType.HIT && receiverShapeStatus.isBlockOverride())) &&
|
||||||
|
AttachUtils.getParent(impactorParent) != receiverParent
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
if(impactorShapeStatus != null){
|
if(impactorShapeStatus != null){
|
||||||
@ -103,6 +112,19 @@ public class ServerHitboxResolutionCallback implements CollisionResolutionCallba
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user