play audio on client when server has collision
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
ab4b64942d
commit
ee44f76dcc
BIN
assets/Audio/weapons/collisions/Massive Punch A.wav
Normal file
BIN
assets/Audio/weapons/collisions/Massive Punch A.wav
Normal file
Binary file not shown.
BIN
assets/Audio/weapons/collisions/Massive Punch B.wav
Normal file
BIN
assets/Audio/weapons/collisions/Massive Punch B.wav
Normal file
Binary file not shown.
BIN
assets/Audio/weapons/collisions/Massive Punch C.wav
Normal file
BIN
assets/Audio/weapons/collisions/Massive Punch C.wav
Normal file
Binary file not shown.
@ -18,7 +18,6 @@ Things that feel bad:
|
||||
Part of this may be cylinder collidable instead of capsule
|
||||
|
||||
|
||||
Sound effect on hit
|
||||
Sound effect on block
|
||||
Allow block hotboxes to block damage
|
||||
Server packet on damage collision
|
||||
|
||||
@ -516,6 +516,7 @@ Sound effects on footstep
|
||||
New sound effects for movement
|
||||
Jump sound effects
|
||||
Don't play walking audio when entity is jumping
|
||||
Sound effect on sword hit
|
||||
|
||||
# TODO
|
||||
|
||||
|
||||
73
net/combat.json
Normal file
73
net/combat.json
Normal file
@ -0,0 +1,73 @@
|
||||
{
|
||||
"outputPath" : "./src/main/java/electrosphere/net/parser/",
|
||||
"packageName" : "electrosphere.net.parser",
|
||||
"categories":[
|
||||
{
|
||||
"categoryName" : "Combat",
|
||||
"data" : [
|
||||
{
|
||||
"name" : "entityID",
|
||||
"type" : "FIXED_INT"
|
||||
},
|
||||
{
|
||||
"name" : "receiverEntityID",
|
||||
"type" : "FIXED_INT"
|
||||
},
|
||||
{
|
||||
"name" : "positionX",
|
||||
"type" : "FIXED_DOUBLE"
|
||||
},
|
||||
{
|
||||
"name" : "positionY",
|
||||
"type" : "FIXED_DOUBLE"
|
||||
},
|
||||
{
|
||||
"name" : "positionZ",
|
||||
"type" : "FIXED_DOUBLE"
|
||||
},
|
||||
{
|
||||
"name" : "rotationX",
|
||||
"type" : "FIXED_DOUBLE"
|
||||
},
|
||||
{
|
||||
"name" : "rotationY",
|
||||
"type" : "FIXED_DOUBLE"
|
||||
},
|
||||
{
|
||||
"name" : "rotationZ",
|
||||
"type" : "FIXED_DOUBLE"
|
||||
},
|
||||
{
|
||||
"name" : "rotationW",
|
||||
"type" : "FIXED_DOUBLE"
|
||||
},
|
||||
{
|
||||
"name" : "time",
|
||||
"type" : "FIXED_LONG"
|
||||
},
|
||||
{
|
||||
"name" : "hitboxType",
|
||||
"type" : "VAR_STRING"
|
||||
},
|
||||
{
|
||||
"name" : "hurtboxType",
|
||||
"type" : "VAR_STRING"
|
||||
}
|
||||
],
|
||||
"messageTypes" : [
|
||||
{
|
||||
"messageName" : "serverReportHitboxCollision",
|
||||
"description" : "Reports to clients that a hitbox collision happened",
|
||||
"data" : [
|
||||
"entityID",
|
||||
"receiverEntityID",
|
||||
"time",
|
||||
"hitboxType",
|
||||
"hurtboxType"
|
||||
]
|
||||
}
|
||||
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -0,0 +1,89 @@
|
||||
package electrosphere.audio.collision;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
import org.joml.Vector3d;
|
||||
|
||||
import electrosphere.audio.VirtualAudioSourceManager.VirtualAudioSourceType;
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.entity.Entity;
|
||||
import electrosphere.entity.types.creature.CreatureUtils;
|
||||
import electrosphere.entity.types.item.ItemUtils;
|
||||
import electrosphere.logger.LoggerInterface;
|
||||
|
||||
/**
|
||||
* Client service to play audio when hitbox collisions happen
|
||||
*/
|
||||
public class HitboxAudioService {
|
||||
|
||||
/**
|
||||
* Default audio files to play. Eventually should probably refactor into service that determines audio based on materials
|
||||
*/
|
||||
static String[] defaultHitboxAudio = new String[]{
|
||||
"Audio/weapons/collisions/Massive Punch A.wav",
|
||||
"Audio/weapons/collisions/Massive Punch B.wav",
|
||||
"Audio/weapons/collisions/Massive Punch C.wav",
|
||||
};
|
||||
|
||||
/**
|
||||
* The random for selecting which file to play
|
||||
*/
|
||||
Random random = new Random();
|
||||
|
||||
/**
|
||||
* Plays an interaction
|
||||
* @param voxelType The voxel type
|
||||
* @param type The interaction type
|
||||
*/
|
||||
public void playAudio(Entity senderEntity, Entity receiverEntity, String hitboxType, String hurtboxType){
|
||||
String audioPath = this.getAudioPath(senderEntity, receiverEntity, hitboxType, hurtboxType);
|
||||
if(audioPath != null){
|
||||
Globals.virtualAudioSourceManager.createVirtualAudioSource(audioPath, VirtualAudioSourceType.CREATURE, false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Plays an interaction at a given position
|
||||
* @param voxelType The voxel type
|
||||
* @param type The interaction type
|
||||
* @param position The position of the audio
|
||||
*/
|
||||
public void playAudioPositional(Entity senderEntity, Entity receiverEntity, String hitboxType, String hurtboxType, Vector3d position){
|
||||
String audioPath = this.getAudioPath(senderEntity, receiverEntity, hitboxType, hurtboxType);
|
||||
if(audioPath != null){
|
||||
Globals.virtualAudioSourceManager.createVirtualAudioSource(audioPath, VirtualAudioSourceType.CREATURE, false, position);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the audio file to play when the given entities collide
|
||||
* @param senderEntity The entity with the hitbox
|
||||
* @param receiverEntity The entity with the hurtbox
|
||||
* @param hitboxType The hitbox type
|
||||
* @param hurtboxType The hurthox type
|
||||
* @return The audio file to play
|
||||
*/
|
||||
private String getAudioPath(Entity senderEntity, Entity receiverEntity, String hitboxType, String hurtboxType){
|
||||
if(ItemUtils.isWeapon(senderEntity)){
|
||||
if(CreatureUtils.isCreature(receiverEntity)){
|
||||
return this.getWeaponOnCreature();
|
||||
} else {
|
||||
LoggerInterface.loggerEngine.WARNING("Getting audio for unhandled hurtbox collision type!");
|
||||
}
|
||||
} else {
|
||||
LoggerInterface.loggerEngine.WARNING("Getting audio for unhandled hitbox collision type!");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the audio to play when a weapon collides with a creature
|
||||
* @return The audio file to play
|
||||
*/
|
||||
private String getWeaponOnCreature(){
|
||||
//return the audio
|
||||
int roll = random.nextInt(defaultHitboxAudio.length);
|
||||
return defaultHitboxAudio[roll];
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,41 @@
|
||||
package electrosphere.client.collision;
|
||||
|
||||
import org.joml.Vector3d;
|
||||
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.entity.Entity;
|
||||
import electrosphere.game.data.collidable.HitboxData;
|
||||
import electrosphere.logger.LoggerInterface;
|
||||
|
||||
/**
|
||||
* Client methods for handling hitbox collisions reported by the server
|
||||
*/
|
||||
public class ClientHitboxCollision {
|
||||
|
||||
/**
|
||||
* Performs client logic for a collision that the server reports
|
||||
* @param position The real-space position of the collision
|
||||
* @param hitboxType The type of hitbox
|
||||
* @param hurtboxType The type of hurtbox
|
||||
*/
|
||||
public static void handleHitboxCollision(Entity senderEntity, Entity receiverEntity, Vector3d position, String hitboxType, String hurtboxType){
|
||||
switch(hitboxType){
|
||||
case HitboxData.HITBOX_TYPE_HIT_CONNECTED:
|
||||
case HitboxData.HITBOX_TYPE_HIT: {
|
||||
switch(hurtboxType){
|
||||
case HitboxData.HITBOX_TYPE_HURT:
|
||||
case HitboxData.HITBOX_TYPE_HURT_CONNECTED: {
|
||||
Globals.hitboxAudioService.playAudio(senderEntity, receiverEntity, hitboxType, hurtboxType);
|
||||
} break;
|
||||
default: {
|
||||
LoggerInterface.loggerEngine.WARNING("Client handling undefined hurtbox type: " + hurtboxType);
|
||||
} break;
|
||||
}
|
||||
} break;
|
||||
default: {
|
||||
LoggerInterface.loggerEngine.WARNING("Client handling undefined hitbox type: " + hitboxType);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -9,6 +9,7 @@ import org.joml.Vector3f;
|
||||
|
||||
import electrosphere.audio.AudioEngine;
|
||||
import electrosphere.audio.VirtualAudioSourceManager;
|
||||
import electrosphere.audio.collision.HitboxAudioService;
|
||||
import electrosphere.audio.movement.MovementAudioService;
|
||||
import electrosphere.auth.AuthenticationManager;
|
||||
import electrosphere.client.fluid.cells.FluidCellManager;
|
||||
@ -106,6 +107,7 @@ public class Globals {
|
||||
public static AudioEngine audioEngine;
|
||||
public static VirtualAudioSourceManager virtualAudioSourceManager;
|
||||
public static MovementAudioService movementAudioService = new MovementAudioService();
|
||||
public static HitboxAudioService hitboxAudioService = new HitboxAudioService();
|
||||
|
||||
|
||||
//
|
||||
@ -473,7 +475,9 @@ public class Globals {
|
||||
"/Audio/weapons/swordUnsheath1.ogg",
|
||||
"/Audio/weapons/swoosh-03.ogg",
|
||||
"/Audio/movement/Equip A.wav",
|
||||
"/Audio/movement/landing-on-the-ground-4.wav",
|
||||
"/Audio/weapons/collisions/Massive Punch A.wav",
|
||||
"/Audio/weapons/collisions/Massive Punch B.wav",
|
||||
"/Audio/weapons/collisions/Massive Punch C.wav",
|
||||
};
|
||||
LoggerInterface.loggerStartup.INFO("Loading default audio resources");
|
||||
for(String path : audioToInit){
|
||||
|
||||
@ -7,6 +7,7 @@ import java.util.concurrent.Semaphore;
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.net.client.protocol.AuthProtocol;
|
||||
import electrosphere.net.client.protocol.CharacterProtocol;
|
||||
import electrosphere.net.client.protocol.CombatProtocol;
|
||||
import electrosphere.net.client.protocol.EntityProtocol;
|
||||
import electrosphere.net.client.protocol.InventoryProtocol;
|
||||
import electrosphere.net.client.protocol.LoreProtocol;
|
||||
@ -16,6 +17,7 @@ import electrosphere.net.client.protocol.SynchronizationProtocol;
|
||||
import electrosphere.net.client.protocol.TerrainProtocol;
|
||||
import electrosphere.net.parser.net.message.AuthMessage;
|
||||
import electrosphere.net.parser.net.message.CharacterMessage;
|
||||
import electrosphere.net.parser.net.message.CombatMessage;
|
||||
import electrosphere.net.parser.net.message.EntityMessage;
|
||||
import electrosphere.net.parser.net.message.InventoryMessage;
|
||||
import electrosphere.net.parser.net.message.LoreMessage;
|
||||
@ -45,6 +47,7 @@ public class MessageProtocol {
|
||||
//The individual protocols
|
||||
AuthProtocol authProtocol = new AuthProtocol();
|
||||
CharacterProtocol characterProtocol = new CharacterProtocol();
|
||||
CombatProtocol combatProtocol = new CombatProtocol();
|
||||
EntityProtocol entityProtocol = new EntityProtocol();
|
||||
InventoryProtocol inventoryProtocol = new InventoryProtocol();
|
||||
LoreProtocol loreProtocol = new LoreProtocol();
|
||||
@ -67,6 +70,9 @@ public class MessageProtocol {
|
||||
case CHARACTER_MESSAGE:
|
||||
result = this.characterProtocol.handleAsyncMessage((CharacterMessage)message);
|
||||
break;
|
||||
case COMBAT_MESSAGE: {
|
||||
result = this.combatProtocol.handleAsyncMessage((CombatMessage)message);
|
||||
} break;
|
||||
case ENTITY_MESSAGE:
|
||||
result = this.entityProtocol.handleAsyncMessage((EntityMessage)message);
|
||||
break;
|
||||
@ -109,6 +115,9 @@ public class MessageProtocol {
|
||||
case CHARACTER_MESSAGE:
|
||||
this.characterProtocol.handleSyncMessage((CharacterMessage)message);
|
||||
break;
|
||||
case COMBAT_MESSAGE: {
|
||||
this.combatProtocol.handleSyncMessage((CombatMessage)message);
|
||||
} break;
|
||||
case ENTITY_MESSAGE:
|
||||
this.entityProtocol.handleSyncMessage((EntityMessage)message);
|
||||
break;
|
||||
|
||||
@ -0,0 +1,33 @@
|
||||
package electrosphere.net.client.protocol;
|
||||
|
||||
import org.joml.Vector3d;
|
||||
|
||||
import electrosphere.client.collision.ClientHitboxCollision;
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.entity.Entity;
|
||||
import electrosphere.net.parser.net.message.CombatMessage;
|
||||
import electrosphere.net.template.ClientProtocolTemplate;
|
||||
|
||||
/**
|
||||
* Client protocl for dealing with combat messages
|
||||
*/
|
||||
public class CombatProtocol implements ClientProtocolTemplate<CombatMessage> {
|
||||
|
||||
@Override
|
||||
public CombatMessage handleAsyncMessage(CombatMessage message) {
|
||||
return message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleSyncMessage(CombatMessage message) {
|
||||
switch(message.getMessageSubtype()){
|
||||
case SERVERREPORTHITBOXCOLLISION: {
|
||||
Vector3d position = new Vector3d(message.getpositionX(),message.getpositionY(),message.getpositionZ());
|
||||
Entity senderEntity = Globals.clientSceneWrapper.getEntityFromServerId(message.getentityID());
|
||||
Entity receiverEntity = Globals.clientSceneWrapper.getEntityFromServerId(message.getreceiverEntityID());
|
||||
ClientHitboxCollision.handleHitboxCollision(senderEntity, receiverEntity, position, message.gethitboxType(), message.gethurtboxType());
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,252 @@
|
||||
package electrosphere.net.parser.net.message;
|
||||
|
||||
import electrosphere.net.parser.util.ByteStreamUtils;
|
||||
import electrosphere.net.parser.net.raw.CircularByteBuffer;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
public class CombatMessage extends NetworkMessage {
|
||||
|
||||
public enum CombatMessageType {
|
||||
SERVERREPORTHITBOXCOLLISION,
|
||||
}
|
||||
|
||||
CombatMessageType messageType;
|
||||
int entityID;
|
||||
int receiverEntityID;
|
||||
double positionX;
|
||||
double positionY;
|
||||
double positionZ;
|
||||
double rotationX;
|
||||
double rotationY;
|
||||
double rotationZ;
|
||||
double rotationW;
|
||||
long time;
|
||||
String hitboxType;
|
||||
String hurtboxType;
|
||||
|
||||
CombatMessage(CombatMessageType messageType){
|
||||
this.type = MessageType.COMBAT_MESSAGE;
|
||||
this.messageType = messageType;
|
||||
}
|
||||
|
||||
public CombatMessageType getMessageSubtype(){
|
||||
return this.messageType;
|
||||
}
|
||||
|
||||
public int getentityID() {
|
||||
return entityID;
|
||||
}
|
||||
|
||||
public void setentityID(int entityID) {
|
||||
this.entityID = entityID;
|
||||
}
|
||||
|
||||
public int getreceiverEntityID() {
|
||||
return receiverEntityID;
|
||||
}
|
||||
|
||||
public void setreceiverEntityID(int receiverEntityID) {
|
||||
this.receiverEntityID = receiverEntityID;
|
||||
}
|
||||
|
||||
public double getpositionX() {
|
||||
return positionX;
|
||||
}
|
||||
|
||||
public void setpositionX(double positionX) {
|
||||
this.positionX = positionX;
|
||||
}
|
||||
|
||||
public double getpositionY() {
|
||||
return positionY;
|
||||
}
|
||||
|
||||
public void setpositionY(double positionY) {
|
||||
this.positionY = positionY;
|
||||
}
|
||||
|
||||
public double getpositionZ() {
|
||||
return positionZ;
|
||||
}
|
||||
|
||||
public void setpositionZ(double positionZ) {
|
||||
this.positionZ = positionZ;
|
||||
}
|
||||
|
||||
public double getrotationX() {
|
||||
return rotationX;
|
||||
}
|
||||
|
||||
public void setrotationX(double rotationX) {
|
||||
this.rotationX = rotationX;
|
||||
}
|
||||
|
||||
public double getrotationY() {
|
||||
return rotationY;
|
||||
}
|
||||
|
||||
public void setrotationY(double rotationY) {
|
||||
this.rotationY = rotationY;
|
||||
}
|
||||
|
||||
public double getrotationZ() {
|
||||
return rotationZ;
|
||||
}
|
||||
|
||||
public void setrotationZ(double rotationZ) {
|
||||
this.rotationZ = rotationZ;
|
||||
}
|
||||
|
||||
public double getrotationW() {
|
||||
return rotationW;
|
||||
}
|
||||
|
||||
public void setrotationW(double rotationW) {
|
||||
this.rotationW = rotationW;
|
||||
}
|
||||
|
||||
public long gettime() {
|
||||
return time;
|
||||
}
|
||||
|
||||
public void settime(long time) {
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
public String gethitboxType() {
|
||||
return hitboxType;
|
||||
}
|
||||
|
||||
public void sethitboxType(String hitboxType) {
|
||||
this.hitboxType = hitboxType;
|
||||
}
|
||||
|
||||
public String gethurtboxType() {
|
||||
return hurtboxType;
|
||||
}
|
||||
|
||||
public void sethurtboxType(String hurtboxType) {
|
||||
this.hurtboxType = hurtboxType;
|
||||
}
|
||||
|
||||
static void stripPacketHeader(CircularByteBuffer byteBuffer){
|
||||
byteBuffer.read(2);
|
||||
}
|
||||
|
||||
public static boolean canParseMessage(CircularByteBuffer byteBuffer, byte secondByte){
|
||||
switch(secondByte){
|
||||
case TypeBytes.COMBAT_MESSAGE_TYPE_SERVERREPORTHITBOXCOLLISION:
|
||||
return CombatMessage.canParseserverReportHitboxCollisionMessage(byteBuffer);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean canParseserverReportHitboxCollisionMessage(CircularByteBuffer byteBuffer){
|
||||
int currentStreamLength = byteBuffer.getRemaining();
|
||||
List<Byte> temporaryByteQueue = new LinkedList<Byte>();
|
||||
if(currentStreamLength < 6){
|
||||
return false;
|
||||
}
|
||||
if(currentStreamLength < 10){
|
||||
return false;
|
||||
}
|
||||
if(currentStreamLength < 18){
|
||||
return false;
|
||||
}
|
||||
int hitboxTypeSize = 0;
|
||||
if(currentStreamLength < 22){
|
||||
return false;
|
||||
} else {
|
||||
temporaryByteQueue.add(byteBuffer.peek(18 + 0));
|
||||
temporaryByteQueue.add(byteBuffer.peek(18 + 1));
|
||||
temporaryByteQueue.add(byteBuffer.peek(18 + 2));
|
||||
temporaryByteQueue.add(byteBuffer.peek(18 + 3));
|
||||
hitboxTypeSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue);
|
||||
}
|
||||
if(currentStreamLength < 22 + hitboxTypeSize){
|
||||
return false;
|
||||
}
|
||||
int hurtboxTypeSize = 0;
|
||||
if(currentStreamLength < 26){
|
||||
return false;
|
||||
} else {
|
||||
temporaryByteQueue.add(byteBuffer.peek(22 + hitboxTypeSize + 0));
|
||||
temporaryByteQueue.add(byteBuffer.peek(22 + hitboxTypeSize + 1));
|
||||
temporaryByteQueue.add(byteBuffer.peek(22 + hitboxTypeSize + 2));
|
||||
temporaryByteQueue.add(byteBuffer.peek(22 + hitboxTypeSize + 3));
|
||||
hurtboxTypeSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue);
|
||||
}
|
||||
if(currentStreamLength < 26 + hitboxTypeSize + hurtboxTypeSize){
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static CombatMessage parseserverReportHitboxCollisionMessage(CircularByteBuffer byteBuffer){
|
||||
CombatMessage rVal = new CombatMessage(CombatMessageType.SERVERREPORTHITBOXCOLLISION);
|
||||
stripPacketHeader(byteBuffer);
|
||||
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.setreceiverEntityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteBuffer));
|
||||
rVal.sethitboxType(ByteStreamUtils.popStringFromByteQueue(byteBuffer));
|
||||
rVal.sethurtboxType(ByteStreamUtils.popStringFromByteQueue(byteBuffer));
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static CombatMessage constructserverReportHitboxCollisionMessage(int entityID,int receiverEntityID,long time,String hitboxType,String hurtboxType){
|
||||
CombatMessage rVal = new CombatMessage(CombatMessageType.SERVERREPORTHITBOXCOLLISION);
|
||||
rVal.setentityID(entityID);
|
||||
rVal.setreceiverEntityID(receiverEntityID);
|
||||
rVal.settime(time);
|
||||
rVal.sethitboxType(hitboxType);
|
||||
rVal.sethurtboxType(hurtboxType);
|
||||
rVal.serialize();
|
||||
return rVal;
|
||||
}
|
||||
|
||||
@Override
|
||||
void serialize(){
|
||||
byte[] intValues = new byte[8];
|
||||
byte[] stringBytes;
|
||||
switch(this.messageType){
|
||||
case SERVERREPORTHITBOXCOLLISION:
|
||||
rawBytes = new byte[2+4+4+8+4+hitboxType.length()+4+hurtboxType.length()];
|
||||
//message header
|
||||
rawBytes[0] = TypeBytes.MESSAGE_TYPE_COMBAT;
|
||||
//entity messaage header
|
||||
rawBytes[1] = TypeBytes.COMBAT_MESSAGE_TYPE_SERVERREPORTHITBOXCOLLISION;
|
||||
intValues = ByteStreamUtils.serializeIntToBytes(entityID);
|
||||
for(int i = 0; i < 4; i++){
|
||||
rawBytes[2+i] = intValues[i];
|
||||
}
|
||||
intValues = ByteStreamUtils.serializeIntToBytes(receiverEntityID);
|
||||
for(int i = 0; i < 4; i++){
|
||||
rawBytes[6+i] = intValues[i];
|
||||
}
|
||||
intValues = ByteStreamUtils.serializeLongToBytes(time);
|
||||
for(int i = 0; i < 8; i++){
|
||||
rawBytes[10+i] = intValues[i];
|
||||
}
|
||||
intValues = ByteStreamUtils.serializeIntToBytes(hitboxType.length());
|
||||
for(int i = 0; i < 4; i++){
|
||||
rawBytes[18+i] = intValues[i];
|
||||
}
|
||||
stringBytes = hitboxType.getBytes();
|
||||
for(int i = 0; i < hitboxType.length(); i++){
|
||||
rawBytes[22+i] = stringBytes[i];
|
||||
}
|
||||
intValues = ByteStreamUtils.serializeIntToBytes(hurtboxType.length());
|
||||
for(int i = 0; i < 4; i++){
|
||||
rawBytes[22+hitboxType.length()+i] = intValues[i];
|
||||
}
|
||||
stringBytes = hurtboxType.getBytes();
|
||||
for(int i = 0; i < hurtboxType.length(); i++){
|
||||
rawBytes[26+hitboxType.length()+i] = stringBytes[i];
|
||||
}
|
||||
break;
|
||||
}
|
||||
serialized = true;
|
||||
}
|
||||
|
||||
}
|
||||
@ -17,6 +17,7 @@ AUTH_MESSAGE,
|
||||
CHARACTER_MESSAGE,
|
||||
INVENTORY_MESSAGE,
|
||||
SYNCHRONIZATION_MESSAGE,
|
||||
COMBAT_MESSAGE,
|
||||
}
|
||||
|
||||
MessageType type;
|
||||
@ -393,6 +394,16 @@ SYNCHRONIZATION_MESSAGE,
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case TypeBytes.MESSAGE_TYPE_COMBAT:
|
||||
secondByte = byteBuffer.peek(1);
|
||||
switch(secondByte){
|
||||
case TypeBytes.COMBAT_MESSAGE_TYPE_SERVERREPORTHITBOXCOLLISION:
|
||||
if(CombatMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = CombatMessage.parseserverReportHitboxCollisionMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rVal;
|
||||
|
||||
@ -14,6 +14,7 @@ Message categories
|
||||
public static final byte MESSAGE_TYPE_CHARACTER = 6;
|
||||
public static final byte MESSAGE_TYPE_INVENTORY = 7;
|
||||
public static final byte MESSAGE_TYPE_SYNCHRONIZATION = 8;
|
||||
public static final byte MESSAGE_TYPE_COMBAT = 9;
|
||||
/*
|
||||
Entity subcategories
|
||||
*/
|
||||
@ -168,5 +169,12 @@ Message categories
|
||||
public static final byte SYNCHRONIZATION_MESSAGE_TYPE_SERVERNOTIFYBTREETRANSITION_SIZE = 18;
|
||||
public static final byte SYNCHRONIZATION_MESSAGE_TYPE_ATTACHTREE_SIZE = 10;
|
||||
public static final byte SYNCHRONIZATION_MESSAGE_TYPE_DETATCHTREE_SIZE = 10;
|
||||
/*
|
||||
Combat subcategories
|
||||
*/
|
||||
public static final byte COMBAT_MESSAGE_TYPE_SERVERREPORTHITBOXCOLLISION = 0;
|
||||
/*
|
||||
Combat packet sizes
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
@ -8,6 +8,7 @@ import electrosphere.engine.Globals;
|
||||
import electrosphere.logger.LoggerInterface;
|
||||
import electrosphere.net.parser.net.message.AuthMessage;
|
||||
import electrosphere.net.parser.net.message.CharacterMessage;
|
||||
import electrosphere.net.parser.net.message.CombatMessage;
|
||||
import electrosphere.net.parser.net.message.EntityMessage;
|
||||
import electrosphere.net.parser.net.message.InventoryMessage;
|
||||
import electrosphere.net.parser.net.message.LoreMessage;
|
||||
@ -18,6 +19,7 @@ import electrosphere.net.parser.net.message.SynchronizationMessage;
|
||||
import electrosphere.net.parser.net.message.TerrainMessage;
|
||||
import electrosphere.net.server.protocol.AuthProtocol;
|
||||
import electrosphere.net.server.protocol.CharacterProtocol;
|
||||
import electrosphere.net.server.protocol.CombatProtocol;
|
||||
import electrosphere.net.server.protocol.EntityProtocol;
|
||||
import electrosphere.net.server.protocol.InventoryProtocol;
|
||||
import electrosphere.net.server.protocol.LoreProtocol;
|
||||
@ -43,6 +45,7 @@ public class MessageProtocol {
|
||||
//The individual protocols
|
||||
AuthProtocol authProtocol = new AuthProtocol();
|
||||
CharacterProtocol characterProtocol = new CharacterProtocol();
|
||||
CombatProtocol combatProtocol = new CombatProtocol();
|
||||
EntityProtocol entityProtocol = new EntityProtocol();
|
||||
InventoryProtocol inventoryProtocol = new InventoryProtocol();
|
||||
LoreProtocol loreProtocol = new LoreProtocol();
|
||||
@ -74,6 +77,9 @@ public class MessageProtocol {
|
||||
case CHARACTER_MESSAGE:
|
||||
result = this.characterProtocol.handleAsyncMessage(serverConnectionHandler, (CharacterMessage)message);
|
||||
break;
|
||||
case COMBAT_MESSAGE: {
|
||||
result = this.combatProtocol.handleAsyncMessage(serverConnectionHandler, (CombatMessage)message);
|
||||
} break;
|
||||
case ENTITY_MESSAGE:
|
||||
result = this.entityProtocol.handleAsyncMessage(serverConnectionHandler, (EntityMessage)message);
|
||||
break;
|
||||
@ -116,6 +122,9 @@ public class MessageProtocol {
|
||||
case CHARACTER_MESSAGE:
|
||||
this.characterProtocol.handleSyncMessage(serverConnectionHandler, (CharacterMessage)message);
|
||||
break;
|
||||
case COMBAT_MESSAGE: {
|
||||
this.combatProtocol.handleSyncMessage(serverConnectionHandler, (CombatMessage)message);
|
||||
} break;
|
||||
case ENTITY_MESSAGE:
|
||||
this.entityProtocol.handleSyncMessage(serverConnectionHandler, (EntityMessage)message);
|
||||
break;
|
||||
|
||||
@ -0,0 +1,31 @@
|
||||
package electrosphere.net.server.protocol;
|
||||
|
||||
import electrosphere.net.parser.net.message.CombatMessage;
|
||||
import electrosphere.net.server.ServerConnectionHandler;
|
||||
import electrosphere.net.template.ServerProtocolTemplate;
|
||||
|
||||
/**
|
||||
* Server protocol for dealing with combat messages
|
||||
*/
|
||||
public class CombatProtocol implements ServerProtocolTemplate<CombatMessage> {
|
||||
|
||||
@Override
|
||||
public CombatMessage handleAsyncMessage(ServerConnectionHandler connectionHandler, CombatMessage message) {
|
||||
switch(message.getMessageSubtype()){
|
||||
case SERVERREPORTHITBOXCOLLISION: {
|
||||
//silently ignore
|
||||
} break;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleSyncMessage(ServerConnectionHandler connectionHandler, CombatMessage message) {
|
||||
switch(message.getMessageSubtype()){
|
||||
case SERVERREPORTHITBOXCOLLISION: {
|
||||
//silently ignore
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -6,6 +6,7 @@ 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.hitbox.HitboxCollectionState;
|
||||
import electrosphere.entity.state.hitbox.HitboxCollectionState.HitboxState;
|
||||
@ -15,6 +16,8 @@ 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.net.parser.net.message.CombatMessage;
|
||||
import electrosphere.server.datacell.utils.DataCellSearchUtils;
|
||||
|
||||
/**
|
||||
* Callback for managing collisions on the server
|
||||
@ -55,7 +58,18 @@ public class ServerHitboxResolutionCallback implements CollisionResolutionCallba
|
||||
//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);
|
||||
|
||||
|
||||
//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()
|
||||
)
|
||||
);
|
||||
|
||||
if(isItem){
|
||||
if(hitboxAttachParent != receiverParent){
|
||||
int damage = ItemUtils.getWeaponDataRaw(impactorParent).getDamage();
|
||||
|
||||
@ -14,7 +14,8 @@
|
||||
"./net/server.json",
|
||||
"./net/character.json",
|
||||
"./net/inventory.json",
|
||||
"./net/synchronization.json"
|
||||
"./net/synchronization.json",
|
||||
"./net/combat.json"
|
||||
]
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user