block synchronization
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
e671cda62d
commit
8c0a7697d0
@ -257,6 +257,7 @@
|
|||||||
"firstPersonBone" : "hand.R",
|
"firstPersonBone" : "hand.R",
|
||||||
"offsetVector" : [0,0,0],
|
"offsetVector" : [0,0,0],
|
||||||
"offsetRotation" : [-0.334,0.145,-0.28,0.89],
|
"offsetRotation" : [-0.334,0.145,-0.28,0.89],
|
||||||
|
"canBlock" : true,
|
||||||
"equipClassWhitelist" : [
|
"equipClassWhitelist" : [
|
||||||
"tool",
|
"tool",
|
||||||
"weapon",
|
"weapon",
|
||||||
@ -284,6 +285,22 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"blockSystem" : {
|
||||||
|
"variants": [
|
||||||
|
{
|
||||||
|
"variantId": "blockWeaponRight",
|
||||||
|
"windUpAnimation" : "Jump",
|
||||||
|
"mainAnimation" : "Fall",
|
||||||
|
"cooldownAnimation" : "Land",
|
||||||
|
"defaults" : [
|
||||||
|
{
|
||||||
|
"equipPoint" : "handRight",
|
||||||
|
"itemClassEquipped" : "weapon"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"collidable" : {
|
"collidable" : {
|
||||||
"type" : "CYLINDER",
|
"type" : "CYLINDER",
|
||||||
"dimension1" : 0.1,
|
"dimension1" : 0.1,
|
||||||
|
|||||||
@ -362,6 +362,9 @@ Fix equipping an item spawning two items
|
|||||||
Fix inventory ui not closing when you hit 'i' key (will need to update utility functions to manage input mode so you're not doing it in callback)
|
Fix inventory ui not closing when you hit 'i' key (will need to update utility functions to manage input mode so you're not doing it in callback)
|
||||||
Develop debug ui for equip points
|
Develop debug ui for equip points
|
||||||
|
|
||||||
|
(06/18/2024)
|
||||||
|
Block state synchronization between client and server
|
||||||
|
|
||||||
# TODO
|
# TODO
|
||||||
|
|
||||||
|
|
||||||
@ -375,15 +378,16 @@ Audio FX for everything
|
|||||||
|
|
||||||
|
|
||||||
= Coding =
|
= Coding =
|
||||||
|
Sour spot, sweet spot for damage hitboxes and hurtboxes
|
||||||
Fix items falling below the ground
|
Fix items falling below the ground
|
||||||
Control rebinding menu from title screen
|
Sub menu on title screen that allows changing control mappings
|
||||||
Redo hitboxes to have capsules and also chaining between frames (but not between swinging the camera around)
|
Redo hitboxes to have capsules and also chaining between frames (but not between swinging the camera around)
|
||||||
- Introduce block hitbox (blockbox) type
|
- Introduce block hitbox (blockbox) type
|
||||||
Enemy AI
|
Enemy AI
|
||||||
Probably some kind of tutorial text
|
Probably some kind of tutorial text
|
||||||
Network-able ui messages
|
Network-able ui messages
|
||||||
Ability to display video both on title screen as well as in game windows for tutorials
|
Ability to display video both on title screen as well as in game windows for tutorials
|
||||||
better scaffolding for scripting engine with hooks for equipping items, spawning entities, pausing/resuming play, etc
|
better scaffolding for scriptig engine with hooks for equipping items, spawning entities, pausing/resuming play, etc
|
||||||
Ability for private realms to have time start/stop based on the player's feedback <-- sync this up to tutorial ui via script
|
Ability for private realms to have time start/stop based on the player's feedback <-- sync this up to tutorial ui via script
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -24,6 +24,14 @@
|
|||||||
{
|
{
|
||||||
"name" : "containerType",
|
"name" : "containerType",
|
||||||
"type" : "FIXED_INT"
|
"type" : "FIXED_INT"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name" : "itemActionCode",
|
||||||
|
"type" : "FIXED_INT"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name" : "itemActionCodeState",
|
||||||
|
"type" : "FIXED_INT"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"messageTypes" : [
|
"messageTypes" : [
|
||||||
@ -81,6 +89,15 @@
|
|||||||
"data" : [
|
"data" : [
|
||||||
"equipPointId"
|
"equipPointId"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"messageName" : "clientRequestPerformItemAction",
|
||||||
|
"description" : "Requests that the server have the entity perform its equipped item's action for the given equip point",
|
||||||
|
"data" : [
|
||||||
|
"equipPointId",
|
||||||
|
"itemActionCode",
|
||||||
|
"itemActionCodeState"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
40
src/main/java/electrosphere/client/item/ItemActions.java
Normal file
40
src/main/java/electrosphere/client/item/ItemActions.java
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
package electrosphere.client.item;
|
||||||
|
|
||||||
|
import electrosphere.engine.Globals;
|
||||||
|
import electrosphere.net.parser.net.message.InventoryMessage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utilities for telling the server to perform actions with an item that the player has equipped
|
||||||
|
*/
|
||||||
|
public class ItemActions {
|
||||||
|
|
||||||
|
//the item action code for left clicking
|
||||||
|
public static final int ITEM_ACTION_CODE_PRIMARY = 0;
|
||||||
|
//the item action code for right clicking
|
||||||
|
public static final int ITEM_ACTION_CODE_SECONDARY = 1;
|
||||||
|
|
||||||
|
//the state for performing the item action code
|
||||||
|
public static final int ITEM_ACTION_CODE_STATE_ON = 1;
|
||||||
|
|
||||||
|
//the state for releasing the item action code
|
||||||
|
public static final int ITEM_ACTION_CODE_STATE_OFF = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempts to perform the secondary item action
|
||||||
|
*/
|
||||||
|
public static void attemptSecondaryItemAction(){
|
||||||
|
//tell the server we want the secondary hand item to START doing something
|
||||||
|
Globals.clientConnection.queueOutgoingMessage(InventoryMessage.constructclientRequestPerformItemActionMessage("handRight", ITEM_ACTION_CODE_SECONDARY, ITEM_ACTION_CODE_STATE_ON));
|
||||||
|
//TODO: do any immediate client side calculations here (ie start playing an animation until we get response from server)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Releases the secondary item action
|
||||||
|
*/
|
||||||
|
public static void releaseSecondaryItemAction(){
|
||||||
|
//tell the server we want the secondary hand item to STOP doing something
|
||||||
|
Globals.clientConnection.queueOutgoingMessage(InventoryMessage.constructclientRequestPerformItemActionMessage("handRight", ITEM_ACTION_CODE_SECONDARY, ITEM_ACTION_CODE_STATE_OFF));
|
||||||
|
//TODO: do any immediate client side calculations here (ie start playing an animation until we get response from server)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -71,6 +71,7 @@ import org.joml.Vector3d;
|
|||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
|
|
||||||
import electrosphere.audio.VirtualAudioSourceManager.VirtualAudioSourceType;
|
import electrosphere.audio.VirtualAudioSourceManager.VirtualAudioSourceType;
|
||||||
|
import electrosphere.client.item.ItemActions;
|
||||||
import electrosphere.client.targeting.crosshair.Crosshair;
|
import electrosphere.client.targeting.crosshair.Crosshair;
|
||||||
import electrosphere.client.terrain.editing.TerrainEditing;
|
import electrosphere.client.terrain.editing.TerrainEditing;
|
||||||
import electrosphere.collision.CollisionEngine;
|
import electrosphere.collision.CollisionEngine;
|
||||||
@ -85,7 +86,6 @@ import electrosphere.entity.state.attack.ShooterTree;
|
|||||||
import electrosphere.entity.state.equip.ClientEquipState;
|
import electrosphere.entity.state.equip.ClientEquipState;
|
||||||
import electrosphere.entity.state.inventory.InventoryUtils;
|
import electrosphere.entity.state.inventory.InventoryUtils;
|
||||||
import electrosphere.entity.state.inventory.UnrelationalInventoryState;
|
import electrosphere.entity.state.inventory.UnrelationalInventoryState;
|
||||||
import electrosphere.entity.state.ironsight.IronSightTree;
|
|
||||||
import electrosphere.entity.state.movement.JumpTree;
|
import electrosphere.entity.state.movement.JumpTree;
|
||||||
import electrosphere.entity.state.movement.SprintTree;
|
import electrosphere.entity.state.movement.SprintTree;
|
||||||
import electrosphere.entity.state.movement.groundmove.ClientGroundMovementTree;
|
import electrosphere.entity.state.movement.groundmove.ClientGroundMovementTree;
|
||||||
@ -130,7 +130,7 @@ public class ControlHandler {
|
|||||||
public static final String INPUT_CODE_DROP = "drop";
|
public static final String INPUT_CODE_DROP = "drop";
|
||||||
public static final String INPUT_CODE_INVENTORY_OPEN = "inventoryOpen";
|
public static final String INPUT_CODE_INVENTORY_OPEN = "inventoryOpen";
|
||||||
public static final String INPUT_CODE_CHARACTER_OPEN = "characterOpen";
|
public static final String INPUT_CODE_CHARACTER_OPEN = "characterOpen";
|
||||||
public static final String INPUT_CODE_IRON_SIGHT = "ironSight";
|
public static final String ITEM_SECONDARY = "actionItemSecondary";
|
||||||
public static final String INPUT_CODE_PLACE_TERRAIN = "placeTerrain";
|
public static final String INPUT_CODE_PLACE_TERRAIN = "placeTerrain";
|
||||||
public static final String INPUT_CODE_REMOVE_TERRAIN = "removeTerrain";
|
public static final String INPUT_CODE_REMOVE_TERRAIN = "removeTerrain";
|
||||||
|
|
||||||
@ -312,7 +312,7 @@ public class ControlHandler {
|
|||||||
handler.addControl(INPUT_CODE_DROP, new Control(ControlType.KEY,GLFW_KEY_Y));
|
handler.addControl(INPUT_CODE_DROP, new Control(ControlType.KEY,GLFW_KEY_Y));
|
||||||
handler.addControl(INPUT_CODE_INVENTORY_OPEN, new Control(ControlType.KEY,GLFW_KEY_I));
|
handler.addControl(INPUT_CODE_INVENTORY_OPEN, new Control(ControlType.KEY,GLFW_KEY_I));
|
||||||
handler.addControl(INPUT_CODE_CHARACTER_OPEN, new Control(ControlType.KEY,GLFW_KEY_C));
|
handler.addControl(INPUT_CODE_CHARACTER_OPEN, new Control(ControlType.KEY,GLFW_KEY_C));
|
||||||
handler.addControl(INPUT_CODE_IRON_SIGHT, new Control(ControlType.MOUSE_BUTTON,GLFW_MOUSE_BUTTON_RIGHT));
|
handler.addControl(ITEM_SECONDARY, new Control(ControlType.MOUSE_BUTTON,GLFW_MOUSE_BUTTON_RIGHT));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Map the menu navigation controls
|
Map the menu navigation controls
|
||||||
@ -837,22 +837,12 @@ public class ControlHandler {
|
|||||||
}
|
}
|
||||||
}});
|
}});
|
||||||
|
|
||||||
mainGameControlList.add(controls.get(INPUT_CODE_IRON_SIGHT));
|
mainGameControlList.add(controls.get(ITEM_SECONDARY));
|
||||||
controls.get(INPUT_CODE_IRON_SIGHT).setOnPress(new ControlMethod() {public void execute() {
|
controls.get(ITEM_SECONDARY).setOnPress(new ControlMethod() {public void execute() {
|
||||||
if(Globals.playerEntity != null){
|
ItemActions.attemptSecondaryItemAction();
|
||||||
IronSightTree ironSightTree = IronSightTree.getIronSightTree(Globals.playerEntity);
|
|
||||||
if(ironSightTree != null){
|
|
||||||
ironSightTree.start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}});
|
}});
|
||||||
controls.get(INPUT_CODE_IRON_SIGHT).setOnRelease(new ControlMethod() {public void execute() {
|
controls.get(ITEM_SECONDARY).setOnRelease(new ControlMethod() {public void execute() {
|
||||||
if(Globals.playerEntity != null){
|
ItemActions.releaseSecondaryItemAction();
|
||||||
IronSightTree ironSightTree = IronSightTree.getIronSightTree(Globals.playerEntity);
|
|
||||||
if(ironSightTree != null){
|
|
||||||
ironSightTree.release();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}});
|
}});
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@ -20,6 +20,7 @@ import electrosphere.game.server.world.MacroData;
|
|||||||
import electrosphere.logger.LoggerInterface;
|
import electrosphere.logger.LoggerInterface;
|
||||||
import electrosphere.menu.debug.ImGuiWindowMacros;
|
import electrosphere.menu.debug.ImGuiWindowMacros;
|
||||||
import electrosphere.renderer.RenderingEngine;
|
import electrosphere.renderer.RenderingEngine;
|
||||||
|
import electrosphere.server.MainServerFunctions;
|
||||||
import electrosphere.server.simulation.MacroSimulation;
|
import electrosphere.server.simulation.MacroSimulation;
|
||||||
|
|
||||||
|
|
||||||
@ -319,21 +320,10 @@ public class Main {
|
|||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// S E R V E R M I C R O S I M U L A T I O N
|
/// S E R V E R M A I N R O U T I N E S
|
||||||
///
|
///
|
||||||
Globals.profiler.beginCpuSample("Server simulation");
|
Globals.profiler.beginCpuSample("Main Server Functions");
|
||||||
LoggerInterface.loggerEngine.DEBUG("Begin server micro simulation");
|
MainServerFunctions.simulate();
|
||||||
if(Globals.realmManager != null){
|
|
||||||
Globals.realmManager.simulate();
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
/// M A C R O S I M U L A T I O N S T U F F
|
|
||||||
///
|
|
||||||
LoggerInterface.loggerEngine.DEBUG("Begin server macro simulation");
|
|
||||||
if(Globals.macroSimulation != null && Globals.macroSimulation.isReady()){
|
|
||||||
Globals.macroSimulation.simulate();
|
|
||||||
}
|
|
||||||
Globals.profiler.endCpuSample();
|
Globals.profiler.endCpuSample();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -272,6 +272,12 @@ public class EntityDataStrings {
|
|||||||
*/
|
*/
|
||||||
public static final String IRON_SIGHT_TREE = "ironSightTree";
|
public static final String IRON_SIGHT_TREE = "ironSightTree";
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Block trees
|
||||||
|
*/
|
||||||
|
public static final String TREE_CLIENTBLOCKTREE = "treeClientBlockTree";
|
||||||
|
public static final String TREE_SERVERBLOCKTREE = "treeServerBlockTree";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
AI stuff
|
AI stuff
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -1,27 +1,224 @@
|
|||||||
package electrosphere.entity.state.block;
|
package electrosphere.entity.state.block;
|
||||||
|
|
||||||
|
|
||||||
|
import electrosphere.engine.Globals;
|
||||||
|
import electrosphere.entity.Entity;
|
||||||
|
import electrosphere.entity.EntityDataStrings;
|
||||||
|
import electrosphere.entity.EntityUtils;
|
||||||
|
import electrosphere.entity.btree.BehaviorTree;
|
||||||
|
import electrosphere.game.data.creature.type.block.BlockSystem;
|
||||||
|
import electrosphere.net.synchronization.BehaviorTreeIdEnums;
|
||||||
|
|
||||||
import electrosphere.net.synchronization.annotation.SyncedField;
|
import electrosphere.net.synchronization.annotation.SyncedField;
|
||||||
import electrosphere.net.synchronization.annotation.SynchronizableEnum;
|
import electrosphere.net.synchronization.annotation.SynchronizableEnum;
|
||||||
import electrosphere.net.synchronization.annotation.SynchronizedBehaviorTree;
|
import electrosphere.net.synchronization.annotation.SynchronizedBehaviorTree;
|
||||||
|
import electrosphere.renderer.actor.Actor;
|
||||||
|
|
||||||
@SynchronizedBehaviorTree(name = "clientBlockTree", isServer = false, correspondingTree="serverBlockTree")
|
@SynchronizedBehaviorTree(name = "clientBlockTree", isServer = false, correspondingTree="serverBlockTree")
|
||||||
/**
|
/**
|
||||||
* Client block tree
|
* Client block tree
|
||||||
*/
|
*/
|
||||||
public class ClientBlockTree {
|
public class ClientBlockTree implements BehaviorTree {
|
||||||
|
|
||||||
@SynchronizableEnum
|
@SynchronizableEnum
|
||||||
/**
|
/**
|
||||||
* The state of the block tree
|
* The state of the block tree
|
||||||
*/
|
*/
|
||||||
public enum BlockState {
|
public enum BlockState {
|
||||||
|
WIND_UP,
|
||||||
BLOCKING,
|
BLOCKING,
|
||||||
|
COOLDOWN,
|
||||||
NOT_BLOCKING,
|
NOT_BLOCKING,
|
||||||
}
|
}
|
||||||
|
|
||||||
@SyncedField
|
@SyncedField
|
||||||
BlockState state;
|
BlockState state = BlockState.NOT_BLOCKING; //the current state
|
||||||
|
|
||||||
|
//the parent entity to this tree
|
||||||
|
Entity parent;
|
||||||
|
|
||||||
|
@SyncedField
|
||||||
|
String currentBlockVariant = null; //The current block variant (depends on equipped items)
|
||||||
|
|
||||||
|
//The data for block animations
|
||||||
|
BlockSystem blockSystem;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
private ClientBlockTree(Entity parent, BlockSystem blockSystem){
|
||||||
|
this.parent = parent;
|
||||||
|
this.blockSystem = blockSystem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void simulate(float deltaTime) {
|
||||||
|
Actor actor = EntityUtils.getActor(parent);
|
||||||
|
switch(state){
|
||||||
|
case WIND_UP: {
|
||||||
|
if(actor != null && blockSystem.getBlockVariant(currentBlockVariant) != null){
|
||||||
|
String animationToPlay = blockSystem.getBlockVariant(currentBlockVariant).getWindUpAnimation();
|
||||||
|
if(
|
||||||
|
!actor.isPlayingAnimation() || !actor.isPlayingAnimation(animationToPlay)
|
||||||
|
){
|
||||||
|
actor.playAnimation(animationToPlay,1);
|
||||||
|
actor.incrementAnimationTime(0.0001);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
case BLOCKING: {
|
||||||
|
if(actor != null && blockSystem.getBlockVariant(currentBlockVariant) != null){
|
||||||
|
String animationToPlay = blockSystem.getBlockVariant(currentBlockVariant).getMainAnimation();
|
||||||
|
if(
|
||||||
|
!actor.isPlayingAnimation() || !actor.isPlayingAnimation(animationToPlay)
|
||||||
|
){
|
||||||
|
actor.playAnimation(animationToPlay,1);
|
||||||
|
actor.incrementAnimationTime(0.0001);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
case COOLDOWN: {
|
||||||
|
if(actor != null && blockSystem.getBlockVariant(currentBlockVariant) != null){
|
||||||
|
String animationToPlay = blockSystem.getBlockVariant(currentBlockVariant).getCooldownAnimation();
|
||||||
|
if(
|
||||||
|
!actor.isPlayingAnimation() || !actor.isPlayingAnimation(animationToPlay)
|
||||||
|
){
|
||||||
|
actor.playAnimation(animationToPlay,1);
|
||||||
|
actor.incrementAnimationTime(0.0001);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
case NOT_BLOCKING: {
|
||||||
|
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p> Automatically generated </p>
|
||||||
|
* <p>
|
||||||
|
* Gets state.
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
public BlockState getState(){
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <p> Automatically generated </p>
|
||||||
|
* <p>
|
||||||
|
* Sets state and handles the synchronization logic for it.
|
||||||
|
* </p>
|
||||||
|
* @param state The value to set state to.
|
||||||
|
*/
|
||||||
|
public void setState(BlockState state){
|
||||||
|
this.state = state;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <p> (initially) Automatically generated </p>
|
||||||
|
* <p> More parameters can be safely added to this method</p>
|
||||||
|
* <p>
|
||||||
|
* Attaches this tree to the entity.
|
||||||
|
* </p>
|
||||||
|
* @param entity The entity to attach to
|
||||||
|
* @param tree The behavior tree to attach
|
||||||
|
*/
|
||||||
|
public static ClientBlockTree attachTree(Entity parent, BlockSystem blockSystem){
|
||||||
|
ClientBlockTree rVal = new ClientBlockTree(parent, blockSystem);
|
||||||
|
//put manual code here (setting params, etc)
|
||||||
|
|
||||||
|
|
||||||
|
//!!WARNING!! from here below should not be touched
|
||||||
|
//This was generated automatically to properly alert various systems that the btree exists and should be tracked
|
||||||
|
parent.putData(EntityDataStrings.TREE_CLIENTBLOCKTREE, rVal);
|
||||||
|
Globals.clientSceneWrapper.getScene().registerBehaviorTree(rVal);
|
||||||
|
Globals.entityValueTrackingService.attachTreeToEntity(parent, BehaviorTreeIdEnums.BTREE_CLIENTBLOCKTREE_ID);
|
||||||
|
return rVal;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <p> Automatically generated </p>
|
||||||
|
* <p>
|
||||||
|
* Detatches this tree from the entity.
|
||||||
|
* </p>
|
||||||
|
* @param entity The entity to detach to
|
||||||
|
* @param tree The behavior tree to detach
|
||||||
|
*/
|
||||||
|
public static void detachTree(Entity entity, BehaviorTree tree){
|
||||||
|
Globals.entityValueTrackingService.detatchTreeFromEntity(entity, BehaviorTreeIdEnums.BTREE_CLIENTBLOCKTREE_ID);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Gets the ClientBlockTree of the entity
|
||||||
|
* </p>
|
||||||
|
* @param entity the entity
|
||||||
|
* @return The ClientBlockTree
|
||||||
|
*/
|
||||||
|
public static ClientBlockTree getClientBlockTree(Entity entity){
|
||||||
|
return (ClientBlockTree)entity.getData(EntityDataStrings.TREE_CLIENTBLOCKTREE);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <p> Automatically generated </p>
|
||||||
|
* <p>
|
||||||
|
* Converts this enum type to an equivalent short value
|
||||||
|
* </p>
|
||||||
|
* @param enumVal The enum value
|
||||||
|
* @return The short value
|
||||||
|
*/
|
||||||
|
public static short getBlockStateEnumAsShort(BlockState enumVal){
|
||||||
|
switch(enumVal){
|
||||||
|
case WIND_UP:
|
||||||
|
return 0;
|
||||||
|
case BLOCKING:
|
||||||
|
return 1;
|
||||||
|
case COOLDOWN:
|
||||||
|
return 2;
|
||||||
|
case NOT_BLOCKING:
|
||||||
|
return 3;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <p> Automatically generated </p>
|
||||||
|
* <p>
|
||||||
|
* Converts a short to the equivalent enum value
|
||||||
|
* </p>
|
||||||
|
* @param shortVal The short value
|
||||||
|
* @return The enum value
|
||||||
|
*/
|
||||||
|
public static BlockState getBlockStateShortAsEnum(short shortVal){
|
||||||
|
switch(shortVal){
|
||||||
|
case 0:
|
||||||
|
return BlockState.WIND_UP;
|
||||||
|
case 1:
|
||||||
|
return BlockState.BLOCKING;
|
||||||
|
case 2:
|
||||||
|
return BlockState.COOLDOWN;
|
||||||
|
case 3:
|
||||||
|
return BlockState.NOT_BLOCKING;
|
||||||
|
default:
|
||||||
|
return BlockState.WIND_UP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p> Automatically generated </p>
|
||||||
|
* <p>
|
||||||
|
* Gets currentBlockVariant.
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
public String getCurrentBlockVariant(){
|
||||||
|
return currentBlockVariant;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <p> Automatically generated </p>
|
||||||
|
* <p>
|
||||||
|
* Sets currentBlockVariant and handles the synchronization logic for it.
|
||||||
|
* </p>
|
||||||
|
* @param currentBlockVariant The value to set currentBlockVariant to.
|
||||||
|
*/
|
||||||
|
public void setCurrentBlockVariant(String currentBlockVariant){
|
||||||
|
this.currentBlockVariant = currentBlockVariant;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,21 @@
|
|||||||
package electrosphere.entity.state.block;
|
package electrosphere.entity.state.block;
|
||||||
|
|
||||||
|
|
||||||
|
import electrosphere.engine.Globals;
|
||||||
|
import electrosphere.entity.Entity;
|
||||||
|
import electrosphere.entity.EntityDataStrings;
|
||||||
|
import electrosphere.entity.EntityUtils;
|
||||||
|
import electrosphere.entity.btree.BehaviorTree;
|
||||||
|
import electrosphere.net.synchronization.BehaviorTreeIdEnums;
|
||||||
|
|
||||||
|
import electrosphere.server.datacell.utils.ServerBehaviorTreeUtils;
|
||||||
|
import electrosphere.server.poseactor.PoseActor;
|
||||||
|
import electrosphere.net.parser.net.message.SynchronizationMessage;
|
||||||
|
|
||||||
|
import electrosphere.server.datacell.utils.DataCellSearchUtils;
|
||||||
|
|
||||||
import electrosphere.entity.state.block.ClientBlockTree.BlockState;
|
import electrosphere.entity.state.block.ClientBlockTree.BlockState;
|
||||||
|
import electrosphere.game.data.creature.type.block.BlockSystem;
|
||||||
import electrosphere.net.synchronization.annotation.SyncedField;
|
import electrosphere.net.synchronization.annotation.SyncedField;
|
||||||
import electrosphere.net.synchronization.annotation.SynchronizedBehaviorTree;
|
import electrosphere.net.synchronization.annotation.SynchronizedBehaviorTree;
|
||||||
|
|
||||||
@ -8,9 +23,175 @@ import electrosphere.net.synchronization.annotation.SynchronizedBehaviorTree;
|
|||||||
/**
|
/**
|
||||||
* Server block tree
|
* Server block tree
|
||||||
*/
|
*/
|
||||||
public class ServerBlockTree {
|
public class ServerBlockTree implements BehaviorTree {
|
||||||
|
|
||||||
@SyncedField
|
@SyncedField
|
||||||
BlockState state;
|
BlockState state = BlockState.NOT_BLOCKING; //the current state of the tree
|
||||||
|
|
||||||
|
//the parent entity to this tree
|
||||||
|
Entity parent;
|
||||||
|
|
||||||
|
@SyncedField
|
||||||
|
String currentBlockVariant = null; //The current block variant (depends on equipped items)
|
||||||
|
|
||||||
|
//The data for block animations
|
||||||
|
BlockSystem blockSystem;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
private ServerBlockTree(Entity parent, BlockSystem blockSystem){
|
||||||
|
this.parent = parent;
|
||||||
|
this.blockSystem = blockSystem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts the block tree
|
||||||
|
*/
|
||||||
|
public void start(){
|
||||||
|
setState(BlockState.WIND_UP);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stops the block tree
|
||||||
|
*/
|
||||||
|
public void stop(){
|
||||||
|
setState(BlockState.COOLDOWN);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void simulate(float deltaTime) {
|
||||||
|
PoseActor poseActor = EntityUtils.getPoseActor(parent);
|
||||||
|
switch(state){
|
||||||
|
case WIND_UP: {
|
||||||
|
if(poseActor != null && blockSystem.getBlockVariant(currentBlockVariant) != null){
|
||||||
|
String animationToPlay = blockSystem.getBlockVariant(currentBlockVariant).getWindUpAnimation();
|
||||||
|
if(
|
||||||
|
!poseActor.isPlayingAnimation() || !poseActor.isPlayingAnimation(animationToPlay)
|
||||||
|
){
|
||||||
|
poseActor.playAnimation(animationToPlay,1);
|
||||||
|
poseActor.incrementAnimationTime(0.0001);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
case BLOCKING: {
|
||||||
|
if(poseActor != null && blockSystem.getBlockVariant(currentBlockVariant) != null){
|
||||||
|
String animationToPlay = blockSystem.getBlockVariant(currentBlockVariant).getMainAnimation();
|
||||||
|
if(
|
||||||
|
!poseActor.isPlayingAnimation() || !poseActor.isPlayingAnimation(animationToPlay)
|
||||||
|
){
|
||||||
|
poseActor.playAnimation(animationToPlay,1);
|
||||||
|
poseActor.incrementAnimationTime(0.0001);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
case COOLDOWN: {
|
||||||
|
if(poseActor != null && blockSystem.getBlockVariant(currentBlockVariant) != null){
|
||||||
|
String animationToPlay = blockSystem.getBlockVariant(currentBlockVariant).getCooldownAnimation();
|
||||||
|
if(
|
||||||
|
!poseActor.isPlayingAnimation() || !poseActor.isPlayingAnimation(animationToPlay)
|
||||||
|
){
|
||||||
|
poseActor.playAnimation(animationToPlay,1);
|
||||||
|
poseActor.incrementAnimationTime(0.0001);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
case NOT_BLOCKING: {
|
||||||
|
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the block system data for this tree
|
||||||
|
* @return the data if it exists, otherwise null
|
||||||
|
*/
|
||||||
|
public BlockSystem getBlockSystem(){
|
||||||
|
return this.blockSystem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p> Automatically generated </p>
|
||||||
|
* <p>
|
||||||
|
* Gets state.
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
public BlockState getState(){
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <p> Automatically generated </p>
|
||||||
|
* <p>
|
||||||
|
* Sets state and handles the synchronization logic for it.
|
||||||
|
* </p>
|
||||||
|
* @param state The value to set state to.
|
||||||
|
*/
|
||||||
|
public void setState(BlockState state){
|
||||||
|
this.state = state;
|
||||||
|
int value = ClientBlockTree.getBlockStateEnumAsShort(state);
|
||||||
|
DataCellSearchUtils.getEntityDataCell(parent).broadcastNetworkMessage(SynchronizationMessage.constructUpdateClientStateMessage(parent.getId(), 3, 8, value));
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <p> (initially) Automatically generated </p>
|
||||||
|
* <p> More parameters can be safely added to this method</p>
|
||||||
|
* <p>
|
||||||
|
* Attaches this tree to the entity.
|
||||||
|
* </p>
|
||||||
|
* @param entity The entity to attach to
|
||||||
|
* @param tree The behavior tree to attach
|
||||||
|
*/
|
||||||
|
public static ServerBlockTree attachTree(Entity parent, BlockSystem blockSystem){
|
||||||
|
ServerBlockTree rVal = new ServerBlockTree(parent, blockSystem);
|
||||||
|
//put manual code here (setting params, etc)
|
||||||
|
|
||||||
|
|
||||||
|
//!!WARNING!! from here below should not be touched
|
||||||
|
//This was generated automatically to properly alert various systems that the btree exists and should be tracked
|
||||||
|
ServerBehaviorTreeUtils.attachBTreeToEntity(parent, rVal);
|
||||||
|
parent.putData(EntityDataStrings.TREE_SERVERBLOCKTREE, rVal);
|
||||||
|
Globals.entityValueTrackingService.attachTreeToEntity(parent, BehaviorTreeIdEnums.BTREE_SERVERBLOCKTREE_ID);
|
||||||
|
return rVal;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <p> Automatically generated </p>
|
||||||
|
* <p>
|
||||||
|
* Detatches this tree from the entity.
|
||||||
|
* </p>
|
||||||
|
* @param entity The entity to detach to
|
||||||
|
* @param tree The behavior tree to detach
|
||||||
|
*/
|
||||||
|
public static void detachTree(Entity entity, BehaviorTree tree){
|
||||||
|
Globals.entityValueTrackingService.detatchTreeFromEntity(entity, BehaviorTreeIdEnums.BTREE_SERVERBLOCKTREE_ID);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Gets the ServerBlockTree of the entity
|
||||||
|
* </p>
|
||||||
|
* @param entity the entity
|
||||||
|
* @return The ServerBlockTree
|
||||||
|
*/
|
||||||
|
public static ServerBlockTree getServerBlockTree(Entity entity){
|
||||||
|
return (ServerBlockTree)entity.getData(EntityDataStrings.TREE_SERVERBLOCKTREE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p> Automatically generated </p>
|
||||||
|
* <p>
|
||||||
|
* Gets currentBlockVariant.
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
public String getCurrentBlockVariant(){
|
||||||
|
return currentBlockVariant;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <p> Automatically generated </p>
|
||||||
|
* <p>
|
||||||
|
* Sets currentBlockVariant and handles the synchronization logic for it.
|
||||||
|
* </p>
|
||||||
|
* @param currentBlockVariant The value to set currentBlockVariant to.
|
||||||
|
*/
|
||||||
|
public void setCurrentBlockVariant(String currentBlockVariant){
|
||||||
|
this.currentBlockVariant = currentBlockVariant;
|
||||||
|
DataCellSearchUtils.getEntityDataCell(parent).broadcastNetworkMessage(SynchronizationMessage.constructUpdateClientStringStateMessage(parent.getId(), 3, 9, currentBlockVariant));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -107,8 +107,11 @@ public class ClientEquipState implements BehaviorTree {
|
|||||||
List<String> pointEquipClassList = point.getEquipClassWhitelist();
|
List<String> pointEquipClassList = point.getEquipClassWhitelist();
|
||||||
boolean itemIsInPointWhitelist = pointEquipClassList.contains(equipItemClass);
|
boolean itemIsInPointWhitelist = pointEquipClassList.contains(equipItemClass);
|
||||||
if(!hasEquipped && targetIsItem && !targetIsAttached && itemIsInPointWhitelist){
|
if(!hasEquipped && targetIsItem && !targetIsAttached && itemIsInPointWhitelist){
|
||||||
|
|
||||||
|
//
|
||||||
|
//visual transforms
|
||||||
if(targetHasWhitelist){
|
if(targetHasWhitelist){
|
||||||
//by attaching are we going to be replacing meshes?
|
//depends on the type of creature, must be replacing a mesh
|
||||||
String parentCreatureId = CreatureUtils.getType(parent);
|
String parentCreatureId = CreatureUtils.getType(parent);
|
||||||
List<EquipWhitelist> whitelist = ItemUtils.getEquipWhitelist(toEquip);
|
List<EquipWhitelist> whitelist = ItemUtils.getEquipWhitelist(toEquip);
|
||||||
for(EquipWhitelist whitelistItem : whitelist){
|
for(EquipWhitelist whitelistItem : whitelist){
|
||||||
@ -141,7 +144,7 @@ public class ClientEquipState implements BehaviorTree {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//since we're not replacing meshes we must be attaching to a bone
|
//does not depend on the type of creature, must be attaching to a bone
|
||||||
equipMap.put(point.getEquipPointId(),toEquip);
|
equipMap.put(point.getEquipPointId(),toEquip);
|
||||||
if(Globals.controlHandler.cameraIsThirdPerson()){
|
if(Globals.controlHandler.cameraIsThirdPerson()){
|
||||||
AttachUtils.clientAttachEntityToEntityAtBone(parent, toEquip, point.getBone(), AttachUtils.getEquipPointRotationOffset(point.getOffsetRotation()));
|
AttachUtils.clientAttachEntityToEntityAtBone(parent, toEquip, point.getBone(), AttachUtils.getEquipPointRotationOffset(point.getOffsetRotation()));
|
||||||
@ -284,8 +287,11 @@ public class ClientEquipState implements BehaviorTree {
|
|||||||
Entity equipped = equipMap.remove(pointId);
|
Entity equipped = equipMap.remove(pointId);
|
||||||
if(equipped != null){
|
if(equipped != null){
|
||||||
boolean targetHasWhitelist = ItemUtils.hasEquipList(equipped);
|
boolean targetHasWhitelist = ItemUtils.hasEquipList(equipped);
|
||||||
|
|
||||||
|
//
|
||||||
|
//visual transforms
|
||||||
if(targetHasWhitelist){
|
if(targetHasWhitelist){
|
||||||
//by attaching are we going to be replacing meshes?
|
//depends on the type of creature, must be replacing meshes
|
||||||
String parentCreatureId = CreatureUtils.getType(parent);
|
String parentCreatureId = CreatureUtils.getType(parent);
|
||||||
List<EquipWhitelist> whitelist = ItemUtils.getEquipWhitelist(equipped);
|
List<EquipWhitelist> whitelist = ItemUtils.getEquipWhitelist(equipped);
|
||||||
for(EquipWhitelist whitelistItem : whitelist){
|
for(EquipWhitelist whitelistItem : whitelist){
|
||||||
@ -304,6 +310,7 @@ public class ClientEquipState implements BehaviorTree {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
//does not depend on the type of creature
|
||||||
AttachUtils.clientDetatchEntityFromEntityAtBone(parent, equipped);
|
AttachUtils.clientDetatchEntityFromEntityAtBone(parent, equipped);
|
||||||
EntityUtils.cleanUpEntity(equipped);
|
EntityUtils.cleanUpEntity(equipped);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,6 +21,7 @@ import electrosphere.entity.EntityDataStrings;
|
|||||||
import electrosphere.entity.EntityTags;
|
import electrosphere.entity.EntityTags;
|
||||||
import electrosphere.entity.EntityUtils;
|
import electrosphere.entity.EntityUtils;
|
||||||
import electrosphere.entity.btree.BehaviorTree;
|
import electrosphere.entity.btree.BehaviorTree;
|
||||||
|
import electrosphere.entity.state.block.ServerBlockTree;
|
||||||
import electrosphere.entity.state.gravity.GravityUtils;
|
import electrosphere.entity.state.gravity.GravityUtils;
|
||||||
import electrosphere.entity.state.inventory.InventoryUtils;
|
import electrosphere.entity.state.inventory.InventoryUtils;
|
||||||
import electrosphere.entity.state.inventory.RelationalInventoryState;
|
import electrosphere.entity.state.inventory.RelationalInventoryState;
|
||||||
@ -28,6 +29,8 @@ import electrosphere.entity.state.inventory.UnrelationalInventoryState;
|
|||||||
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.creature.type.block.BlockSystem;
|
||||||
|
import electrosphere.game.data.creature.type.block.BlockVariant;
|
||||||
import electrosphere.game.data.creature.type.equip.EquipPoint;
|
import electrosphere.game.data.creature.type.equip.EquipPoint;
|
||||||
import electrosphere.game.data.item.type.EquipWhitelist;
|
import electrosphere.game.data.item.type.EquipWhitelist;
|
||||||
import electrosphere.net.parser.net.message.InventoryMessage;
|
import electrosphere.net.parser.net.message.InventoryMessage;
|
||||||
@ -46,9 +49,12 @@ import electrosphere.server.datacell.utils.ServerEntityTagUtils;
|
|||||||
*/
|
*/
|
||||||
public class ServerEquipState implements BehaviorTree {
|
public class ServerEquipState implements BehaviorTree {
|
||||||
|
|
||||||
|
//the parent entity of this equip state
|
||||||
Entity parent;
|
Entity parent;
|
||||||
|
|
||||||
|
//the list of available equip points
|
||||||
List<EquipPoint> equipPoints = new LinkedList<EquipPoint>();
|
List<EquipPoint> equipPoints = new LinkedList<EquipPoint>();
|
||||||
|
//the map of equip point id -> entity equipped at said point
|
||||||
Map<String,Entity> equipMap = new HashMap<String,Entity>();
|
Map<String,Entity> equipMap = new HashMap<String,Entity>();
|
||||||
|
|
||||||
public ServerEquipState(Entity parent, List<EquipPoint> equipPoints){
|
public ServerEquipState(Entity parent, List<EquipPoint> equipPoints){
|
||||||
@ -76,6 +82,11 @@ public class ServerEquipState implements BehaviorTree {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempts to equip an item
|
||||||
|
* @param inInventoryEntity The item to equip
|
||||||
|
* @param point The point to equip to
|
||||||
|
*/
|
||||||
public void serverAttemptEquip(Entity inInventoryEntity, EquipPoint point){
|
public void serverAttemptEquip(Entity inInventoryEntity, EquipPoint point){
|
||||||
boolean hasEquipped = hasEquippedAtPoint(point.getEquipPointId());
|
boolean hasEquipped = hasEquippedAtPoint(point.getEquipPointId());
|
||||||
boolean targetIsItem = ItemUtils.isItem(inInventoryEntity);
|
boolean targetIsItem = ItemUtils.isItem(inInventoryEntity);
|
||||||
@ -91,8 +102,10 @@ public class ServerEquipState implements BehaviorTree {
|
|||||||
//bind in world with in inventory
|
//bind in world with in inventory
|
||||||
ItemUtils.setRealWorldEntity(inInventoryEntity, inWorldItem);
|
ItemUtils.setRealWorldEntity(inInventoryEntity, inWorldItem);
|
||||||
|
|
||||||
|
//
|
||||||
|
//Visual transforms
|
||||||
if(targetHasWhitelist){
|
if(targetHasWhitelist){
|
||||||
//by attaching are we going to be replacing meshes?
|
//depends on the type of creature
|
||||||
String parentCreatureId = CreatureUtils.getType(parent);
|
String parentCreatureId = CreatureUtils.getType(parent);
|
||||||
List<EquipWhitelist> whitelist = ItemUtils.getEquipWhitelist(inWorldItem);
|
List<EquipWhitelist> whitelist = ItemUtils.getEquipWhitelist(inWorldItem);
|
||||||
for(EquipWhitelist whitelistItem : whitelist){
|
for(EquipWhitelist whitelistItem : whitelist){
|
||||||
@ -117,7 +130,7 @@ public class ServerEquipState implements BehaviorTree {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//since we're not replacing meshes we must be attaching to a bone
|
//does not depend on the type of creature
|
||||||
equipMap.put(point.getEquipPointId(),inWorldItem);
|
equipMap.put(point.getEquipPointId(),inWorldItem);
|
||||||
AttachUtils.serverAttachEntityToEntityAtBone(parent, inWorldItem, point.getBone(), AttachUtils.getEquipPointRotationOffset(point.getOffsetRotation()));
|
AttachUtils.serverAttachEntityToEntityAtBone(parent, inWorldItem, point.getBone(), AttachUtils.getEquipPointRotationOffset(point.getOffsetRotation()));
|
||||||
if(inWorldItem.containsKey(EntityDataStrings.PHYSICS_COLLISION_BODY) && inWorldItem.containsKey(EntityDataStrings.PHYSICS_COLLIDABLE)){
|
if(inWorldItem.containsKey(EntityDataStrings.PHYSICS_COLLISION_BODY) && inWorldItem.containsKey(EntityDataStrings.PHYSICS_COLLIDABLE)){
|
||||||
@ -128,6 +141,11 @@ public class ServerEquipState implements BehaviorTree {
|
|||||||
ServerEntityTagUtils.removeTagFromEntity(inWorldItem, EntityTags.TARGETABLE);
|
ServerEntityTagUtils.removeTagFromEntity(inWorldItem, EntityTags.TARGETABLE);
|
||||||
GravityUtils.serverAttemptDeactivateGravity(inWorldItem);
|
GravityUtils.serverAttemptDeactivateGravity(inWorldItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//update block state based on what we have equipped
|
||||||
|
this.updateBlockVariant();
|
||||||
|
|
||||||
//we need to send two packets
|
//we need to send two packets
|
||||||
//1) Remove item from original inventory
|
//1) Remove item from original inventory
|
||||||
//2) Add item with ID to "equipped" inventory
|
//2) Add item with ID to "equipped" inventory
|
||||||
@ -171,6 +189,11 @@ public class ServerEquipState implements BehaviorTree {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets an equip point by its name
|
||||||
|
* @param name The name of the equip point
|
||||||
|
* @return The equip point if it exists, null otherwise
|
||||||
|
*/
|
||||||
public EquipPoint getEquipPoint(String name){
|
public EquipPoint getEquipPoint(String name){
|
||||||
for(EquipPoint point : equipPoints){
|
for(EquipPoint point : equipPoints){
|
||||||
if(point.getEquipPointId().equals(name)){
|
if(point.getEquipPointId().equals(name)){
|
||||||
@ -180,6 +203,11 @@ public class ServerEquipState implements BehaviorTree {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the item equipped at a point
|
||||||
|
* @param point The point id
|
||||||
|
* @return The item if it exists, null otherwise
|
||||||
|
*/
|
||||||
public Entity getEquippedItemAtPoint(String point){
|
public Entity getEquippedItemAtPoint(String point){
|
||||||
return equipMap.get(point);
|
return equipMap.get(point);
|
||||||
}
|
}
|
||||||
@ -223,6 +251,10 @@ public class ServerEquipState implements BehaviorTree {
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Commands the equip state to unequip an item at a given equip point
|
||||||
|
* @param pointId The equip point
|
||||||
|
*/
|
||||||
public void commandAttemptUnequip(String pointId){
|
public void commandAttemptUnequip(String pointId){
|
||||||
boolean hasEquipped = hasEquippedAtPoint(pointId);
|
boolean hasEquipped = hasEquippedAtPoint(pointId);
|
||||||
if(hasEquipped){
|
if(hasEquipped){
|
||||||
@ -278,10 +310,17 @@ public class ServerEquipState implements BehaviorTree {
|
|||||||
// inventory.addItem(item);
|
// inventory.addItem(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs the transform to unequip an item from an equip point
|
||||||
|
* @param pointId The equip point id
|
||||||
|
*/
|
||||||
public void serverTransformUnequipPoint(String pointId){
|
public void serverTransformUnequipPoint(String pointId){
|
||||||
Entity equipped = equipMap.remove(pointId);
|
Entity equipped = equipMap.remove(pointId);
|
||||||
if(equipped != null){
|
if(equipped != null){
|
||||||
boolean targetHasWhitelist = ItemUtils.hasEquipList(equipped);
|
boolean targetHasWhitelist = ItemUtils.hasEquipList(equipped);
|
||||||
|
|
||||||
|
//
|
||||||
|
//Visual transforms
|
||||||
if(targetHasWhitelist){
|
if(targetHasWhitelist){
|
||||||
//have to do fancy mesh removal nonsense
|
//have to do fancy mesh removal nonsense
|
||||||
//basically the reverse of below
|
//basically the reverse of below
|
||||||
@ -319,13 +358,50 @@ public class ServerEquipState implements BehaviorTree {
|
|||||||
AttachUtils.serverDetatchEntityFromEntityAtBone(parent, equipped);
|
AttachUtils.serverDetatchEntityFromEntityAtBone(parent, equipped);
|
||||||
EntityUtils.cleanUpEntity(equipped);
|
EntityUtils.cleanUpEntity(equipped);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//update block state based on what we have equipped
|
||||||
|
this.updateBlockVariant();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets whether an item is equipped at a point or not
|
||||||
|
* @param point THe point to check
|
||||||
|
* @return true if an item is equipped at the point, false otherwise
|
||||||
|
*/
|
||||||
public boolean hasEquippedAtPoint(String point){
|
public boolean hasEquippedAtPoint(String point){
|
||||||
return equipMap.containsKey(point);
|
return equipMap.containsKey(point);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the server block variant based on what item is equipped
|
||||||
|
*/
|
||||||
|
private void updateBlockVariant(){
|
||||||
|
ServerBlockTree blockTree = ServerBlockTree.getServerBlockTree(parent);
|
||||||
|
if(blockTree != null){
|
||||||
|
|
||||||
|
List<EquipPoint> pointsThatCanBlock = new LinkedList<EquipPoint>();
|
||||||
|
for(EquipPoint point : equipPoints){
|
||||||
|
if(point.getCanBlock()){
|
||||||
|
pointsThatCanBlock.add(point);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BlockSystem blockData = blockTree.getBlockSystem();
|
||||||
|
for(EquipPoint point : pointsThatCanBlock){
|
||||||
|
Entity item = getEquippedItemAtPoint(point.getEquipPointId());
|
||||||
|
if(item != null){
|
||||||
|
BlockVariant blockVariant = blockData.getVariantForPointWithItem(point.getEquipPointId(),ItemUtils.getEquipClass(item));
|
||||||
|
|
||||||
|
//TODO: refactor to allow sending more than one variant at a time
|
||||||
|
//ie if you have two items equipped and you want to block with both
|
||||||
|
blockTree.setCurrentBlockVariant(blockVariant.getVariantId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void simulate(float deltaTime) {
|
public void simulate(float deltaTime) {
|
||||||
}
|
}
|
||||||
|
|||||||
@ -215,7 +215,7 @@ public class ServerGravityTree implements BehaviorTree {
|
|||||||
public void setState(GravityTreeState state){
|
public void setState(GravityTreeState state){
|
||||||
this.state = state;
|
this.state = state;
|
||||||
int value = ClientGravityTree.getGravityTreeStateEnumAsShort(state);
|
int value = ClientGravityTree.getGravityTreeStateEnumAsShort(state);
|
||||||
DataCellSearchUtils.getEntityDataCell(parent).broadcastNetworkMessage(SynchronizationMessage.constructUpdateClientStateMessage(parent.getId(), 5, 7, value));
|
DataCellSearchUtils.getEntityDataCell(parent).broadcastNetworkMessage(SynchronizationMessage.constructUpdateClientStateMessage(parent.getId(), 7, 11, value));
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* <p> (initially) Automatically generated </p>
|
* <p> (initially) Automatically generated </p>
|
||||||
|
|||||||
@ -215,4 +215,14 @@ public class ClientIdleTree implements BehaviorTree {
|
|||||||
public void setState(IdleTreeState state){
|
public void setState(IdleTreeState state){
|
||||||
this.state = state;
|
this.state = state;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Gets the ClientIdleTree of the entity
|
||||||
|
* </p>
|
||||||
|
* @param entity the entity
|
||||||
|
* @return The ClientIdleTree
|
||||||
|
*/
|
||||||
|
public static ClientIdleTree getClientIdleTree(Entity entity){
|
||||||
|
return (ClientIdleTree)entity.getData(EntityDataStrings.TREE_IDLE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -190,7 +190,7 @@ public class ServerIdleTree implements BehaviorTree {
|
|||||||
public void setState(IdleTreeState state){
|
public void setState(IdleTreeState state){
|
||||||
this.state = state;
|
this.state = state;
|
||||||
int value = ClientIdleTree.getIdleTreeStateEnumAsShort(state);
|
int value = ClientIdleTree.getIdleTreeStateEnumAsShort(state);
|
||||||
DataCellSearchUtils.getEntityDataCell(parent).broadcastNetworkMessage(SynchronizationMessage.constructUpdateClientStateMessage(parent.getId(), 7, 9, value));
|
DataCellSearchUtils.getEntityDataCell(parent).broadcastNetworkMessage(SynchronizationMessage.constructUpdateClientStateMessage(parent.getId(), 9, 13, value));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -1,70 +0,0 @@
|
|||||||
package electrosphere.entity.state.ironsight;
|
|
||||||
|
|
||||||
import org.joml.Vector3f;
|
|
||||||
|
|
||||||
import electrosphere.engine.Globals;
|
|
||||||
import electrosphere.entity.Entity;
|
|
||||||
import electrosphere.entity.EntityDataStrings;
|
|
||||||
import electrosphere.entity.btree.BehaviorTree;
|
|
||||||
import electrosphere.entity.types.camera.CameraEntityUtils;
|
|
||||||
|
|
||||||
public class IronSightTree implements BehaviorTree {
|
|
||||||
|
|
||||||
static enum IronSightTreeState {
|
|
||||||
ACTIVE,
|
|
||||||
INACTIVE,
|
|
||||||
}
|
|
||||||
|
|
||||||
IronSightTreeState state = IronSightTreeState.INACTIVE;
|
|
||||||
boolean cameraZoomedIn = false;
|
|
||||||
|
|
||||||
float regularRadius = 1.0f;
|
|
||||||
float zoomedInRadius = 0.1f;
|
|
||||||
Vector3f offcenterOffset = new Vector3f(-0.1f,1,0);
|
|
||||||
|
|
||||||
|
|
||||||
public void start(){
|
|
||||||
state = IronSightTreeState.ACTIVE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void release(){
|
|
||||||
state = IronSightTreeState.INACTIVE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void simulate(float deltaTime) {
|
|
||||||
switch(state){
|
|
||||||
case ACTIVE:
|
|
||||||
if(!cameraZoomedIn){
|
|
||||||
cameraZoomedIn = true;
|
|
||||||
CameraEntityUtils.setOrbitalCameraDistance(Globals.playerCamera, zoomedInRadius);
|
|
||||||
Globals.cameraHandler.updateRadialOffset(new Vector3f(0,1,0.5f));
|
|
||||||
Globals.cameraHandler.updateGlobalCamera();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case INACTIVE:
|
|
||||||
if(cameraZoomedIn){
|
|
||||||
cameraZoomedIn = false;
|
|
||||||
CameraEntityUtils.setOrbitalCameraDistance(Globals.playerCamera, regularRadius);
|
|
||||||
Globals.cameraHandler.updateRadialOffset(new Vector3f(0,1,0));
|
|
||||||
Globals.cameraHandler.updateGlobalCamera();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IronSightTree getIronSightTree(Entity creature){
|
|
||||||
Object rVal;
|
|
||||||
if((rVal = creature.getData(EntityDataStrings.IRON_SIGHT_TREE)) != null && rVal instanceof IronSightTree){
|
|
||||||
return (IronSightTree) rVal;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void attachIronSightTree(Entity player){
|
|
||||||
IronSightTree ironSightTree = new IronSightTree();
|
|
||||||
player.putData(EntityDataStrings.IRON_SIGHT_TREE, ironSightTree);
|
|
||||||
Globals.clientSceneWrapper.getScene().registerBehaviorTree(ironSightTree);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,6 +1,8 @@
|
|||||||
package electrosphere.entity.state.movement.groundmove;
|
package electrosphere.entity.state.movement.groundmove;
|
||||||
|
|
||||||
|
|
||||||
|
import electrosphere.server.datacell.utils.ServerBehaviorTreeUtils;
|
||||||
|
|
||||||
import electrosphere.net.parser.net.message.SynchronizationMessage;
|
import electrosphere.net.parser.net.message.SynchronizationMessage;
|
||||||
|
|
||||||
import electrosphere.net.synchronization.BehaviorTreeIdEnums;
|
import electrosphere.net.synchronization.BehaviorTreeIdEnums;
|
||||||
@ -676,7 +678,7 @@ public class ServerGroundMovementTree implements BehaviorTree {
|
|||||||
public void setFacing(MovementRelativeFacing facing){
|
public void setFacing(MovementRelativeFacing facing){
|
||||||
this.facing = facing;
|
this.facing = facing;
|
||||||
int value = ClientGroundMovementTree.getMovementRelativeFacingEnumAsShort(facing);
|
int value = ClientGroundMovementTree.getMovementRelativeFacingEnumAsShort(facing);
|
||||||
DataCellSearchUtils.getEntityDataCell(parent).broadcastNetworkMessage(SynchronizationMessage.constructUpdateClientStateMessage(parent.getId(), 9, 11, value));
|
DataCellSearchUtils.getEntityDataCell(parent).broadcastNetworkMessage(SynchronizationMessage.constructUpdateClientStateMessage(parent.getId(), 11, 15, value));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -540,18 +540,42 @@ public class AttachUtils {
|
|||||||
return (Matrix4f)e.getData(EntityDataStrings.ATTACH_TRANSFORM);
|
return (Matrix4f)e.getData(EntityDataStrings.ATTACH_TRANSFORM);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the parent entity has attached child entities
|
||||||
|
* @param e The parent entity
|
||||||
|
* @return true if there are attached child entities, false otherwise
|
||||||
|
*/
|
||||||
public static boolean hasChildren(Entity e){
|
public static boolean hasChildren(Entity e){
|
||||||
return e.containsKey(EntityDataStrings.ATTACH_CHILDREN_LIST) && !getChildrenList(e).isEmpty();
|
return e.containsKey(EntityDataStrings.ATTACH_CHILDREN_LIST) && !getChildrenList(e).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the attached entity's posiiton offset
|
||||||
|
* @param e The attached entity
|
||||||
|
* @return The position offset
|
||||||
|
*/
|
||||||
public static Vector3d getAttachPositionOffset(Entity e){
|
public static Vector3d getAttachPositionOffset(Entity e){
|
||||||
return (Vector3d)e.getData(EntityDataStrings.ATTACH_POSITION_OFFSET);
|
return (Vector3d)e.getData(EntityDataStrings.ATTACH_POSITION_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LinkedList<Entity> getChildrenList(Entity e){
|
/**
|
||||||
return (LinkedList<Entity>)e.getData(EntityDataStrings.ATTACH_CHILDREN_LIST);
|
* Gets the list of entities attached to this parent entity
|
||||||
|
* <p>
|
||||||
|
* NOTE: This can return an empty list of an entity has been attached to this one prior
|
||||||
|
* EVEN if it has since been unattached
|
||||||
|
* </p>
|
||||||
|
* @param parentEntity
|
||||||
|
* @return The list of entities that are attached to this parent entity, or null if undefined
|
||||||
|
*/
|
||||||
|
public static LinkedList<Entity> getChildrenList(Entity parentEntity){
|
||||||
|
return (LinkedList<Entity>)parentEntity.getData(EntityDataStrings.ATTACH_CHILDREN_LIST);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the equip point's rotation offset in quaterniond form
|
||||||
|
* @param values The list of raw float values
|
||||||
|
* @return The quaterniond containing those values or an identity quaterniond if no such values exist
|
||||||
|
*/
|
||||||
public static Quaterniond getEquipPointRotationOffset(List<Float> values){
|
public static Quaterniond getEquipPointRotationOffset(List<Float> values){
|
||||||
if(values.size() > 0){
|
if(values.size() > 0){
|
||||||
return new Quaterniond(values.get(0),values.get(1),values.get(2),values.get(3));
|
return new Quaterniond(values.get(0),values.get(1),values.get(2),values.get(3));
|
||||||
|
|||||||
@ -24,6 +24,8 @@ import electrosphere.entity.btree.BehaviorTree;
|
|||||||
import electrosphere.entity.state.attack.ClientAttackTree;
|
import electrosphere.entity.state.attack.ClientAttackTree;
|
||||||
import electrosphere.entity.state.attack.ServerAttackTree;
|
import electrosphere.entity.state.attack.ServerAttackTree;
|
||||||
import electrosphere.entity.state.attack.ShooterTree;
|
import electrosphere.entity.state.attack.ShooterTree;
|
||||||
|
import electrosphere.entity.state.block.ClientBlockTree;
|
||||||
|
import electrosphere.entity.state.block.ServerBlockTree;
|
||||||
import electrosphere.entity.state.collidable.ClientCollidableTree;
|
import electrosphere.entity.state.collidable.ClientCollidableTree;
|
||||||
import electrosphere.entity.state.collidable.ServerCollidableTree;
|
import electrosphere.entity.state.collidable.ServerCollidableTree;
|
||||||
import electrosphere.entity.state.equip.ClientEquipState;
|
import electrosphere.entity.state.equip.ClientEquipState;
|
||||||
@ -229,6 +231,9 @@ public class CreatureUtils {
|
|||||||
ClientEquipState.attachTree(rVal, rawType.getEquipPoints());
|
ClientEquipState.attachTree(rVal, rawType.getEquipPoints());
|
||||||
rVal.putData(EntityDataStrings.EQUIP_INVENTORY, RelationalInventoryState.buildRelationalInventoryStateFromEquipList(rawType.getEquipPoints()));
|
rVal.putData(EntityDataStrings.EQUIP_INVENTORY, RelationalInventoryState.buildRelationalInventoryStateFromEquipList(rawType.getEquipPoints()));
|
||||||
}
|
}
|
||||||
|
if(rawType.getBlockSystem() != null){
|
||||||
|
ClientBlockTree.attachTree(rVal, rawType.getBlockSystem());
|
||||||
|
}
|
||||||
for(String token : rawType.getTokens()){
|
for(String token : rawType.getTokens()){
|
||||||
switch(token){
|
switch(token){
|
||||||
case "BLENDER_TRANSFORM":
|
case "BLENDER_TRANSFORM":
|
||||||
@ -517,6 +522,9 @@ public class CreatureUtils {
|
|||||||
ServerEquipState.setEquipState(rVal, new ServerEquipState(rVal,rawType.getEquipPoints()));
|
ServerEquipState.setEquipState(rVal, new ServerEquipState(rVal,rawType.getEquipPoints()));
|
||||||
rVal.putData(EntityDataStrings.EQUIP_INVENTORY, RelationalInventoryState.buildRelationalInventoryStateFromEquipList(rawType.getEquipPoints()));
|
rVal.putData(EntityDataStrings.EQUIP_INVENTORY, RelationalInventoryState.buildRelationalInventoryStateFromEquipList(rawType.getEquipPoints()));
|
||||||
}
|
}
|
||||||
|
if(rawType.getBlockSystem() != null){
|
||||||
|
ServerBlockTree.attachTree(rVal, rawType.getBlockSystem());
|
||||||
|
}
|
||||||
for(String token : rawType.getTokens()){
|
for(String token : rawType.getTokens()){
|
||||||
switch(token){
|
switch(token){
|
||||||
case "BLENDER_TRANSFORM": {
|
case "BLENDER_TRANSFORM": {
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import electrosphere.game.data.collidable.CollidableTemplate;
|
|||||||
import electrosphere.game.data.collidable.HitboxData;
|
import electrosphere.game.data.collidable.HitboxData;
|
||||||
import electrosphere.game.data.creature.type.attack.AttackMove;
|
import electrosphere.game.data.creature.type.attack.AttackMove;
|
||||||
import electrosphere.game.data.creature.type.attack.AttackMoveResolver;
|
import electrosphere.game.data.creature.type.attack.AttackMoveResolver;
|
||||||
|
import electrosphere.game.data.creature.type.block.BlockSystem;
|
||||||
import electrosphere.game.data.creature.type.equip.EquipPoint;
|
import electrosphere.game.data.creature.type.equip.EquipPoint;
|
||||||
import electrosphere.game.data.creature.type.movement.MovementSystem;
|
import electrosphere.game.data.creature.type.movement.MovementSystem;
|
||||||
import electrosphere.game.data.creature.type.rotator.RotatorSystem;
|
import electrosphere.game.data.creature.type.rotator.RotatorSystem;
|
||||||
@ -29,6 +30,7 @@ public class CreatureType {
|
|||||||
String modelPath;
|
String modelPath;
|
||||||
ViewModelData viewModelData;
|
ViewModelData viewModelData;
|
||||||
IdleData idleData;
|
IdleData idleData;
|
||||||
|
BlockSystem blockSystem;
|
||||||
|
|
||||||
AttackMoveResolver attackMoveResolver;
|
AttackMoveResolver attackMoveResolver;
|
||||||
|
|
||||||
@ -95,6 +97,10 @@ public class CreatureType {
|
|||||||
public IdleData getIdleData(){
|
public IdleData getIdleData(){
|
||||||
return idleData;
|
return idleData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BlockSystem getBlockSystem(){
|
||||||
|
return blockSystem;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,56 @@
|
|||||||
|
package electrosphere.game.data.creature.type.block;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores data related to an entity blocking attacks
|
||||||
|
*/
|
||||||
|
public class BlockSystem {
|
||||||
|
|
||||||
|
//blocking with a weapon equipped in the right hand
|
||||||
|
//NOTE: the names provided here should line up with the actual field names on this object
|
||||||
|
public static final String BLOCK_VARIANT_WEAPON_RIGHT = "blockWeaponRight";
|
||||||
|
|
||||||
|
//the list of block variants
|
||||||
|
List<BlockVariant> variants;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the list of block variants
|
||||||
|
* @return the list
|
||||||
|
*/
|
||||||
|
public List<BlockVariant> getAllVariants(){
|
||||||
|
return variants;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a block variant from its variant string
|
||||||
|
* @param variantString The variant string
|
||||||
|
* @return The block variant if it exists, null otherwise
|
||||||
|
*/
|
||||||
|
public BlockVariant getBlockVariant(String variantString){
|
||||||
|
for(BlockVariant variant : variants){
|
||||||
|
if(variant.variantId.equals(variantString)){
|
||||||
|
return variant;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the block variant that is default for the provided equip point when the provided item class is equipped to that point
|
||||||
|
* @param equipPoint The equip point
|
||||||
|
* @param itemClass The item class
|
||||||
|
* @return The block variant if it exists, null otherwise
|
||||||
|
*/
|
||||||
|
public BlockVariant getVariantForPointWithItem(String equipPoint, String itemClass){
|
||||||
|
for(BlockVariant variant : variants){
|
||||||
|
for(VariantDefaults variantDefault : variant.getDefaults()){
|
||||||
|
if(variantDefault.equipPoint.equals(equipPoint) && variantDefault.itemClassEquipped.equals(itemClass)){
|
||||||
|
return variant;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,67 @@
|
|||||||
|
package electrosphere.game.data.creature.type.block;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A variant of data that can be loaded into the block system. Variants are for different types of equip states.
|
||||||
|
* IE: holding just a sword in your right hand will have a different block animation vs a shield in your right
|
||||||
|
* hand vs two handing a sword with your right hand.
|
||||||
|
*/
|
||||||
|
public class BlockVariant {
|
||||||
|
|
||||||
|
//The id of the block variant
|
||||||
|
String variantId;
|
||||||
|
|
||||||
|
//the animation to play when winding up
|
||||||
|
String windUpAnimation;
|
||||||
|
|
||||||
|
//the main animation to play while blocking
|
||||||
|
String mainAnimation;
|
||||||
|
|
||||||
|
//the animation to play when cooling down
|
||||||
|
String cooldownAnimation;
|
||||||
|
|
||||||
|
//the list of default equipment cases that this variant should be used for
|
||||||
|
List<VariantDefaults> defaults;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The id of the block variant
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String getVariantId(){
|
||||||
|
return variantId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The animation to play when winding up
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String getWindUpAnimation(){
|
||||||
|
return windUpAnimation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The main animation to play while blocking
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String getMainAnimation(){
|
||||||
|
return mainAnimation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The animation to play when cooling down
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String getCooldownAnimation(){
|
||||||
|
return cooldownAnimation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the list of default equipment cases that this variant should be used for
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public List<VariantDefaults> getDefaults(){
|
||||||
|
return defaults;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,34 @@
|
|||||||
|
package electrosphere.game.data.creature.type.block;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Equip point cases that this variant is used as the default for
|
||||||
|
* IE, if you create a variant default for "handRight, weapon",
|
||||||
|
* that means this should be used as the default variant for when
|
||||||
|
* the handRight equip point has a weapon equipped and the block
|
||||||
|
* tree is triggered
|
||||||
|
*/
|
||||||
|
public class VariantDefaults {
|
||||||
|
|
||||||
|
//the equip point
|
||||||
|
String equipPoint;
|
||||||
|
|
||||||
|
//the class of item equipped to that equip point
|
||||||
|
String itemClassEquipped;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the equip point
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String getEquipPoint(){
|
||||||
|
return equipPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the class of item equipped to that equip point
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String getItemClassEquipped(){
|
||||||
|
return itemClassEquipped;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -17,6 +17,8 @@ public class EquipPoint {
|
|||||||
List<Float> offsetVector;
|
List<Float> offsetVector;
|
||||||
//the rotation to apply to the items that are attached to the bone
|
//the rotation to apply to the items that are attached to the bone
|
||||||
List<Float> offsetRotation;
|
List<Float> offsetRotation;
|
||||||
|
//signals that this equip point can block
|
||||||
|
boolean canBlock;
|
||||||
//the equip classes that are whitelisted for this equip point
|
//the equip classes that are whitelisted for this equip point
|
||||||
List<String> equipClassWhitelist;
|
List<String> equipClassWhitelist;
|
||||||
|
|
||||||
@ -68,6 +70,14 @@ public class EquipPoint {
|
|||||||
this.offsetRotation = offsetRotation;
|
this.offsetRotation = offsetRotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Signals that this equip point can block
|
||||||
|
* @return true if can block, false otherwise
|
||||||
|
*/
|
||||||
|
public boolean getCanBlock(){
|
||||||
|
return canBlock;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the equip classes that are whitelisted for this equip point
|
* Gets the equip classes that are whitelisted for this equip point
|
||||||
* @return the classes
|
* @return the classes
|
||||||
|
|||||||
@ -4,50 +4,97 @@ import electrosphere.game.data.collidable.CollidableTemplate;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data on a given item
|
||||||
|
*/
|
||||||
public class Item {
|
public class Item {
|
||||||
|
|
||||||
|
//the id of the item
|
||||||
String itemId;
|
String itemId;
|
||||||
|
//the model path of the item
|
||||||
String modelPath;
|
String modelPath;
|
||||||
|
//tokens associated with this item type
|
||||||
List<String> tokens;
|
List<String> tokens;
|
||||||
|
//the collidable data for the item
|
||||||
CollidableTemplate collidable;
|
CollidableTemplate collidable;
|
||||||
|
//the equip whitelist for this item (what creatures can equip this item?)
|
||||||
List<EquipWhitelist> equipWhitelist;
|
List<EquipWhitelist> equipWhitelist;
|
||||||
|
//the idle animation for the item
|
||||||
String idleAnim;
|
String idleAnim;
|
||||||
|
//the path for the icon texture for this item
|
||||||
String iconPath;
|
String iconPath;
|
||||||
|
//the class of item
|
||||||
String equipClass;
|
String equipClass;
|
||||||
|
//weapon data for this item if it is an item
|
||||||
WeaponData weaponData;
|
WeaponData weaponData;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the id of the item
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
public String getItemId() {
|
public String getItemId() {
|
||||||
return itemId;
|
return itemId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the model path of the item
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
public String getModelPath() {
|
public String getModelPath() {
|
||||||
return modelPath;
|
return modelPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* tokens associated with this item type
|
||||||
|
*/
|
||||||
public List<String> getTokens() {
|
public List<String> getTokens() {
|
||||||
return tokens;
|
return tokens;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the collidable data for the item
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
public CollidableTemplate getCollidable(){
|
public CollidableTemplate getCollidable(){
|
||||||
return collidable;
|
return collidable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the equip whitelist for this item (what creatures can equip this item?)
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
public List<EquipWhitelist> getEquipWhitelist(){
|
public List<EquipWhitelist> getEquipWhitelist(){
|
||||||
return equipWhitelist;
|
return equipWhitelist;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the idle animation for the item
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
public String getIdleAnim(){
|
public String getIdleAnim(){
|
||||||
return idleAnim;
|
return idleAnim;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the path for the icon texture for this item
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
public String getIconPath(){
|
public String getIconPath(){
|
||||||
return iconPath;
|
return iconPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* the class of item
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
public String getEquipClass(){
|
public String getEquipClass(){
|
||||||
return equipClass;
|
return equipClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* weapon data for this item if it is an item
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
public WeaponData getWeaponData(){
|
public WeaponData getWeaponData(){
|
||||||
return weaponData;
|
return weaponData;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,14 +1,6 @@
|
|||||||
package electrosphere.net.client.protocol;
|
package electrosphere.net.client.protocol;
|
||||||
|
|
||||||
import electrosphere.client.scene.ClientWorldData;
|
|
||||||
import electrosphere.engine.Globals;
|
import electrosphere.engine.Globals;
|
||||||
import electrosphere.engine.Main;
|
|
||||||
import electrosphere.entity.Entity;
|
|
||||||
import electrosphere.entity.EntityUtils;
|
|
||||||
import electrosphere.entity.types.creature.CreatureUtils;
|
|
||||||
import electrosphere.entity.types.attach.AttachUtils;
|
|
||||||
import electrosphere.entity.types.item.ItemUtils;
|
|
||||||
import electrosphere.logger.LoggerInterface;
|
|
||||||
import electrosphere.net.parser.net.message.AuthMessage;
|
import electrosphere.net.parser.net.message.AuthMessage;
|
||||||
import electrosphere.net.parser.net.message.CharacterMessage;
|
import electrosphere.net.parser.net.message.CharacterMessage;
|
||||||
import electrosphere.net.parser.net.message.EntityMessage;
|
import electrosphere.net.parser.net.message.EntityMessage;
|
||||||
@ -19,8 +11,6 @@ import electrosphere.net.parser.net.message.PlayerMessage;
|
|||||||
import electrosphere.net.parser.net.message.ServerMessage;
|
import electrosphere.net.parser.net.message.ServerMessage;
|
||||||
import electrosphere.net.parser.net.message.SynchronizationMessage;
|
import electrosphere.net.parser.net.message.SynchronizationMessage;
|
||||||
import electrosphere.net.parser.net.message.TerrainMessage;
|
import electrosphere.net.parser.net.message.TerrainMessage;
|
||||||
import org.joml.Vector2f;
|
|
||||||
import org.joml.Vector3f;
|
|
||||||
|
|
||||||
public class ClientProtocol {
|
public class ClientProtocol {
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,6 @@ import electrosphere.entity.Entity;
|
|||||||
import electrosphere.entity.state.equip.ClientEquipState;
|
import electrosphere.entity.state.equip.ClientEquipState;
|
||||||
import electrosphere.entity.state.inventory.ClientInventoryState;
|
import electrosphere.entity.state.inventory.ClientInventoryState;
|
||||||
import electrosphere.entity.state.inventory.InventoryUtils;
|
import electrosphere.entity.state.inventory.InventoryUtils;
|
||||||
import electrosphere.entity.types.item.ItemUtils;
|
|
||||||
import electrosphere.game.data.creature.type.equip.EquipPoint;
|
import electrosphere.game.data.creature.type.equip.EquipPoint;
|
||||||
import electrosphere.logger.LoggerInterface;
|
import electrosphere.logger.LoggerInterface;
|
||||||
import electrosphere.net.parser.net.message.InventoryMessage;
|
import electrosphere.net.parser.net.message.InventoryMessage;
|
||||||
@ -70,6 +69,7 @@ public class InventoryProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case CLIENTREQUESTPERFORMITEMACTION:
|
||||||
case CLIENTREQUESTUNEQUIPITEM:
|
case CLIENTREQUESTUNEQUIPITEM:
|
||||||
case CLIENTREQUESTEQUIPITEM:
|
case CLIENTREQUESTEQUIPITEM:
|
||||||
//silently ignore
|
//silently ignore
|
||||||
|
|||||||
@ -15,6 +15,7 @@ public class InventoryMessage extends NetworkMessage {
|
|||||||
SERVERCOMMANDEQUIPITEM,
|
SERVERCOMMANDEQUIPITEM,
|
||||||
SERVERCOMMANDUNEQUIPITEM,
|
SERVERCOMMANDUNEQUIPITEM,
|
||||||
CLIENTREQUESTUNEQUIPITEM,
|
CLIENTREQUESTUNEQUIPITEM,
|
||||||
|
CLIENTREQUESTPERFORMITEMACTION,
|
||||||
}
|
}
|
||||||
|
|
||||||
InventoryMessageType messageType;
|
InventoryMessageType messageType;
|
||||||
@ -23,6 +24,8 @@ public class InventoryMessage extends NetworkMessage {
|
|||||||
int entityId;
|
int entityId;
|
||||||
int equipperId;
|
int equipperId;
|
||||||
int containerType;
|
int containerType;
|
||||||
|
int itemActionCode;
|
||||||
|
int itemActionCodeState;
|
||||||
|
|
||||||
InventoryMessage(InventoryMessageType messageType){
|
InventoryMessage(InventoryMessageType messageType){
|
||||||
this.type = MessageType.INVENTORY_MESSAGE;
|
this.type = MessageType.INVENTORY_MESSAGE;
|
||||||
@ -73,6 +76,22 @@ public class InventoryMessage extends NetworkMessage {
|
|||||||
this.containerType = containerType;
|
this.containerType = containerType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getitemActionCode() {
|
||||||
|
return itemActionCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setitemActionCode(int itemActionCode) {
|
||||||
|
this.itemActionCode = itemActionCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getitemActionCodeState() {
|
||||||
|
return itemActionCodeState;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setitemActionCodeState(int itemActionCodeState) {
|
||||||
|
this.itemActionCodeState = itemActionCodeState;
|
||||||
|
}
|
||||||
|
|
||||||
static void stripPacketHeader(CircularByteBuffer byteBuffer){
|
static void stripPacketHeader(CircularByteBuffer byteBuffer){
|
||||||
byteBuffer.read(2);
|
byteBuffer.read(2);
|
||||||
}
|
}
|
||||||
@ -97,6 +116,8 @@ public class InventoryMessage extends NetworkMessage {
|
|||||||
return InventoryMessage.canParseserverCommandUnequipItemMessage(byteBuffer);
|
return InventoryMessage.canParseserverCommandUnequipItemMessage(byteBuffer);
|
||||||
case TypeBytes.INVENTORY_MESSAGE_TYPE_CLIENTREQUESTUNEQUIPITEM:
|
case TypeBytes.INVENTORY_MESSAGE_TYPE_CLIENTREQUESTUNEQUIPITEM:
|
||||||
return InventoryMessage.canParseclientRequestUnequipItemMessage(byteBuffer);
|
return InventoryMessage.canParseclientRequestUnequipItemMessage(byteBuffer);
|
||||||
|
case TypeBytes.INVENTORY_MESSAGE_TYPE_CLIENTREQUESTPERFORMITEMACTION:
|
||||||
|
return InventoryMessage.canParseclientRequestPerformItemActionMessage(byteBuffer);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -363,6 +384,49 @@ public class InventoryMessage extends NetworkMessage {
|
|||||||
return rVal;
|
return rVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean canParseclientRequestPerformItemActionMessage(CircularByteBuffer byteBuffer){
|
||||||
|
int currentStreamLength = byteBuffer.getRemaining();
|
||||||
|
List<Byte> temporaryByteQueue = new LinkedList();
|
||||||
|
int equipPointIdSize = 0;
|
||||||
|
if(currentStreamLength < 6){
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
temporaryByteQueue.add(byteBuffer.peek(2 + 0));
|
||||||
|
temporaryByteQueue.add(byteBuffer.peek(2 + 1));
|
||||||
|
temporaryByteQueue.add(byteBuffer.peek(2 + 2));
|
||||||
|
temporaryByteQueue.add(byteBuffer.peek(2 + 3));
|
||||||
|
equipPointIdSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue);
|
||||||
|
}
|
||||||
|
if(currentStreamLength < 6 + equipPointIdSize){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(currentStreamLength < 10 + equipPointIdSize){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if(currentStreamLength < 14 + equipPointIdSize){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static InventoryMessage parseclientRequestPerformItemActionMessage(CircularByteBuffer byteBuffer){
|
||||||
|
InventoryMessage rVal = new InventoryMessage(InventoryMessageType.CLIENTREQUESTPERFORMITEMACTION);
|
||||||
|
stripPacketHeader(byteBuffer);
|
||||||
|
rVal.setequipPointId(ByteStreamUtils.popStringFromByteQueue(byteBuffer));
|
||||||
|
rVal.setitemActionCode(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||||
|
rVal.setitemActionCodeState(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||||
|
return rVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static InventoryMessage constructclientRequestPerformItemActionMessage(String equipPointId,int itemActionCode,int itemActionCodeState){
|
||||||
|
InventoryMessage rVal = new InventoryMessage(InventoryMessageType.CLIENTREQUESTPERFORMITEMACTION);
|
||||||
|
rVal.setequipPointId(equipPointId);
|
||||||
|
rVal.setitemActionCode(itemActionCode);
|
||||||
|
rVal.setitemActionCodeState(itemActionCodeState);
|
||||||
|
rVal.serialize();
|
||||||
|
return rVal;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void serialize(){
|
void serialize(){
|
||||||
byte[] intValues = new byte[8];
|
byte[] intValues = new byte[8];
|
||||||
@ -505,6 +569,29 @@ public class InventoryMessage extends NetworkMessage {
|
|||||||
rawBytes[6+i] = stringBytes[i];
|
rawBytes[6+i] = stringBytes[i];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case CLIENTREQUESTPERFORMITEMACTION:
|
||||||
|
rawBytes = new byte[2+4+equipPointId.length()+4+4];
|
||||||
|
//message header
|
||||||
|
rawBytes[0] = TypeBytes.MESSAGE_TYPE_INVENTORY;
|
||||||
|
//entity messaage header
|
||||||
|
rawBytes[1] = TypeBytes.INVENTORY_MESSAGE_TYPE_CLIENTREQUESTPERFORMITEMACTION;
|
||||||
|
intValues = ByteStreamUtils.serializeIntToBytes(equipPointId.length());
|
||||||
|
for(int i = 0; i < 4; i++){
|
||||||
|
rawBytes[2+i] = intValues[i];
|
||||||
|
}
|
||||||
|
stringBytes = equipPointId.getBytes();
|
||||||
|
for(int i = 0; i < equipPointId.length(); i++){
|
||||||
|
rawBytes[6+i] = stringBytes[i];
|
||||||
|
}
|
||||||
|
intValues = ByteStreamUtils.serializeIntToBytes(itemActionCode);
|
||||||
|
for(int i = 0; i < 4; i++){
|
||||||
|
rawBytes[6+equipPointId.length()+i] = intValues[i];
|
||||||
|
}
|
||||||
|
intValues = ByteStreamUtils.serializeIntToBytes(itemActionCodeState);
|
||||||
|
for(int i = 0; i < 4; i++){
|
||||||
|
rawBytes[10+equipPointId.length()+i] = intValues[i];
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
serialized = true;
|
serialized = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -311,6 +311,11 @@ SYNCHRONIZATION_MESSAGE,
|
|||||||
rVal = InventoryMessage.parseclientRequestUnequipItemMessage(byteBuffer);
|
rVal = InventoryMessage.parseclientRequestUnequipItemMessage(byteBuffer);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case TypeBytes.INVENTORY_MESSAGE_TYPE_CLIENTREQUESTPERFORMITEMACTION:
|
||||||
|
if(InventoryMessage.canParseMessage(byteBuffer,secondByte)){
|
||||||
|
rVal = InventoryMessage.parseclientRequestPerformItemActionMessage(byteBuffer);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TypeBytes.MESSAGE_TYPE_SYNCHRONIZATION:
|
case TypeBytes.MESSAGE_TYPE_SYNCHRONIZATION:
|
||||||
|
|||||||
@ -133,6 +133,7 @@ Message categories
|
|||||||
public static final byte INVENTORY_MESSAGE_TYPE_SERVERCOMMANDEQUIPITEM = 4;
|
public static final byte INVENTORY_MESSAGE_TYPE_SERVERCOMMANDEQUIPITEM = 4;
|
||||||
public static final byte INVENTORY_MESSAGE_TYPE_SERVERCOMMANDUNEQUIPITEM = 5;
|
public static final byte INVENTORY_MESSAGE_TYPE_SERVERCOMMANDUNEQUIPITEM = 5;
|
||||||
public static final byte INVENTORY_MESSAGE_TYPE_CLIENTREQUESTUNEQUIPITEM = 6;
|
public static final byte INVENTORY_MESSAGE_TYPE_CLIENTREQUESTUNEQUIPITEM = 6;
|
||||||
|
public static final byte INVENTORY_MESSAGE_TYPE_CLIENTREQUESTPERFORMITEMACTION = 7;
|
||||||
/*
|
/*
|
||||||
Inventory packet sizes
|
Inventory packet sizes
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -5,41 +5,45 @@ import electrosphere.engine.Main;
|
|||||||
import electrosphere.logger.LoggerInterface;
|
import electrosphere.logger.LoggerInterface;
|
||||||
import electrosphere.net.NetUtils;
|
import electrosphere.net.NetUtils;
|
||||||
import electrosphere.net.parser.net.message.NetworkMessage;
|
import electrosphere.net.parser.net.message.NetworkMessage;
|
||||||
import electrosphere.server.saves.SaveUtils;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.net.BindException;
|
import java.net.BindException;
|
||||||
import java.net.InetSocketAddress;
|
|
||||||
import java.net.ServerSocket;
|
import java.net.ServerSocket;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.net.SocketException;
|
import java.net.SocketException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Lowest level networking class for the server
|
||||||
* @author amaterasu
|
|
||||||
*/
|
*/
|
||||||
public class Server implements Runnable{
|
public class Server implements Runnable{
|
||||||
|
|
||||||
|
//the port the server is running on
|
||||||
int port;
|
int port;
|
||||||
|
|
||||||
|
//the socket for the server
|
||||||
ServerSocket serverSocket;
|
ServerSocket serverSocket;
|
||||||
|
|
||||||
|
//the map of ip->connection handler
|
||||||
Map<String,ServerConnectionHandler> clientMap = new HashMap<String,ServerConnectionHandler>();
|
Map<String,ServerConnectionHandler> clientMap = new HashMap<String,ServerConnectionHandler>();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inits the server
|
||||||
|
*/
|
||||||
void initServer(){
|
void initServer(){
|
||||||
// clientMap = new HashMap<String,ServerConnectionHandler>();
|
// clientMap = new HashMap<String,ServerConnectionHandler>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param port The port to run the server on
|
||||||
|
*/
|
||||||
public Server(int port){
|
public Server(int port){
|
||||||
this.port = port;
|
this.port = port;
|
||||||
}
|
}
|
||||||
@ -76,7 +80,19 @@ public class Server implements Runnable{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Synchronously handles queued packets for each client connection
|
||||||
|
*/
|
||||||
|
public void synchronousPacketHandling(){
|
||||||
|
for(ServerConnectionHandler connectionHandler : this.clientMap.values()){
|
||||||
|
connectionHandler.handleSynchronousPacketQueue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes the server socket
|
||||||
|
*/
|
||||||
public void close(){
|
public void close(){
|
||||||
try {
|
try {
|
||||||
if(serverSocket != null){
|
if(serverSocket != null){
|
||||||
@ -87,6 +103,10 @@ public class Server implements Runnable{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Broadcasts a message to all clients
|
||||||
|
* @param message The message to broadcast
|
||||||
|
*/
|
||||||
public void broadcastMessage(NetworkMessage message){
|
public void broadcastMessage(NetworkMessage message){
|
||||||
for(ServerConnectionHandler client : clientMap.values()){
|
for(ServerConnectionHandler client : clientMap.values()){
|
||||||
if(Globals.clientPlayer == null || client.playerID != Globals.clientPlayer.getId()){
|
if(Globals.clientPlayer == null || client.playerID != Globals.clientPlayer.getId()){
|
||||||
@ -95,6 +115,12 @@ public class Server implements Runnable{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a connection created manually by two streams instead of receiving the streams from the server socket
|
||||||
|
* @param serverInputStream The input stream
|
||||||
|
* @param serverOutputStream The output stream
|
||||||
|
* @return The connection object for the provided streams
|
||||||
|
*/
|
||||||
public ServerConnectionHandler addLocalPlayer(InputStream serverInputStream, OutputStream serverOutputStream){
|
public ServerConnectionHandler addLocalPlayer(InputStream serverInputStream, OutputStream serverOutputStream){
|
||||||
ServerConnectionHandler newClient = new ServerConnectionHandler(serverInputStream,serverOutputStream);
|
ServerConnectionHandler newClient = new ServerConnectionHandler(serverInputStream,serverOutputStream);
|
||||||
clientMap.put("127.0.0.1", newClient);
|
clientMap.put("127.0.0.1", newClient);
|
||||||
|
|||||||
@ -1,21 +1,12 @@
|
|||||||
package electrosphere.net.server;
|
package electrosphere.net.server;
|
||||||
|
|
||||||
import electrosphere.entity.types.creature.CreatureTemplate;
|
import electrosphere.entity.types.creature.CreatureTemplate;
|
||||||
import electrosphere.entity.types.creature.CreatureUtils;
|
|
||||||
import electrosphere.engine.Globals;
|
import electrosphere.engine.Globals;
|
||||||
import electrosphere.engine.Main;
|
import electrosphere.engine.Main;
|
||||||
import electrosphere.entity.Entity;
|
import electrosphere.entity.ServerEntityUtils;
|
||||||
import electrosphere.entity.EntityUtils;
|
|
||||||
import electrosphere.entity.state.ironsight.IronSightTree;
|
|
||||||
import electrosphere.entity.types.item.ItemUtils;
|
|
||||||
import electrosphere.entity.types.attach.AttachUtils;
|
|
||||||
import electrosphere.entity.types.collision.CollisionObjUtils;
|
|
||||||
import electrosphere.logger.LoggerInterface;
|
import electrosphere.logger.LoggerInterface;
|
||||||
import electrosphere.net.NetUtils;
|
|
||||||
import electrosphere.net.parser.net.message.AuthMessage;
|
import electrosphere.net.parser.net.message.AuthMessage;
|
||||||
import electrosphere.net.parser.net.message.EntityMessage;
|
|
||||||
import electrosphere.net.parser.net.message.NetworkMessage;
|
import electrosphere.net.parser.net.message.NetworkMessage;
|
||||||
import electrosphere.net.parser.net.message.PlayerMessage;
|
|
||||||
import electrosphere.net.parser.net.message.ServerMessage;
|
import electrosphere.net.parser.net.message.ServerMessage;
|
||||||
import electrosphere.net.parser.net.raw.NetworkParser;
|
import electrosphere.net.parser.net.raw.NetworkParser;
|
||||||
import electrosphere.net.server.player.Player;
|
import electrosphere.net.server.player.Player;
|
||||||
@ -24,30 +15,20 @@ import electrosphere.net.server.protocol.ServerProtocol;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.net.SocketException;
|
import java.net.SocketException;
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.security.spec.RSAKeyGenParameterSpec;
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Properties;
|
|
||||||
import java.util.Random;
|
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
import java.util.concurrent.Semaphore;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
import javax.crypto.spec.SecretKeySpec;
|
|
||||||
|
|
||||||
import org.joml.Vector3d;
|
|
||||||
import org.joml.Vector3f;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* A connection to the server
|
||||||
* @author satellite
|
|
||||||
*/
|
*/
|
||||||
public class ServerConnectionHandler implements Runnable {
|
public class ServerConnectionHandler implements Runnable {
|
||||||
|
|
||||||
|
//the player id associated with this connection
|
||||||
static int playerIdIncrementer = 0;
|
static int playerIdIncrementer = 0;
|
||||||
|
|
||||||
//local carrier variables
|
//local carrier variables
|
||||||
@ -55,17 +36,30 @@ public class ServerConnectionHandler implements Runnable {
|
|||||||
|
|
||||||
//socket carrier variables
|
//socket carrier variables
|
||||||
Socket socket;
|
Socket socket;
|
||||||
|
|
||||||
|
//the streams for the connection
|
||||||
// CryptoInputStream inputStream;
|
// CryptoInputStream inputStream;
|
||||||
// CryptoOutputStream outputStream;
|
// CryptoOutputStream outputStream;
|
||||||
InputStream inputStream;
|
InputStream inputStream;
|
||||||
OutputStream outputStream;
|
OutputStream outputStream;
|
||||||
boolean initialized;
|
|
||||||
boolean isAuthenticated = false;
|
//the network parser for the streams
|
||||||
NetworkParser networkParser;
|
NetworkParser networkParser;
|
||||||
|
|
||||||
|
//initialized status
|
||||||
|
boolean initialized;
|
||||||
|
//authentication status
|
||||||
|
boolean isAuthenticated = false;
|
||||||
|
|
||||||
|
//the player id
|
||||||
int playerID;
|
int playerID;
|
||||||
int playerCharacterID;
|
//the player's entity id
|
||||||
|
int playerEntityID;
|
||||||
|
|
||||||
|
//the creature template associated with this player
|
||||||
CreatureTemplate currentCreatureTemplate;
|
CreatureTemplate currentCreatureTemplate;
|
||||||
|
|
||||||
|
//the server protocol object associated with this player
|
||||||
ServerProtocol serverProtocol;
|
ServerProtocol serverProtocol;
|
||||||
|
|
||||||
//thresholds for determining when to send pings and when a client has disconnected
|
//thresholds for determining when to send pings and when a client has disconnected
|
||||||
@ -82,13 +76,27 @@ public class ServerConnectionHandler implements Runnable {
|
|||||||
String netMonitorHandle;
|
String netMonitorHandle;
|
||||||
//Used to copy messages from network parser to NetMonitor
|
//Used to copy messages from network parser to NetMonitor
|
||||||
List<NetworkMessage> netMonitorCache = new LinkedList<NetworkMessage>();
|
List<NetworkMessage> netMonitorCache = new LinkedList<NetworkMessage>();
|
||||||
|
|
||||||
|
//the lock used for synchronizing the synchronous message queue
|
||||||
|
Semaphore synchronousMessageLock = new Semaphore(1);
|
||||||
|
//the queue of synchonous network messages
|
||||||
|
List<NetworkMessage> synchronousMessageQueue = new CopyOnWriteArrayList<NetworkMessage>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a connection from a socket
|
||||||
|
* @param socket the socket
|
||||||
|
*/
|
||||||
public ServerConnectionHandler(Socket socket) {
|
public ServerConnectionHandler(Socket socket) {
|
||||||
this.socket = socket;
|
this.socket = socket;
|
||||||
playerID = getNewPlayerID();
|
playerID = getNewPlayerID();
|
||||||
LoggerInterface.loggerNetworking.INFO("Player ID: " + playerID);
|
LoggerInterface.loggerNetworking.INFO("Player ID: " + playerID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a connection from an arbitrary input and output stream
|
||||||
|
* @param serverInputStream the input stream
|
||||||
|
* @param serverOutputStream the output stream
|
||||||
|
*/
|
||||||
public ServerConnectionHandler(InputStream serverInputStream, OutputStream serverOutputStream){
|
public ServerConnectionHandler(InputStream serverInputStream, OutputStream serverOutputStream){
|
||||||
this.local = true;
|
this.local = true;
|
||||||
playerID = getNewPlayerID();
|
playerID = getNewPlayerID();
|
||||||
@ -114,6 +122,8 @@ public class ServerConnectionHandler implements Runnable {
|
|||||||
} catch (SocketException ex) {
|
} catch (SocketException ex) {
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: use this commented block of code as a reference for implementing encryption on top of the game connection
|
||||||
// final SecretKeySpec key = new SecretKeySpec(("1234567890123456").getBytes(),"AES");
|
// final SecretKeySpec key = new SecretKeySpec(("1234567890123456").getBytes(),"AES");
|
||||||
// final Properties properties = new Properties();
|
// final Properties properties = new Properties();
|
||||||
// final RSAKeyGenParameterSpec spec = new RSAKeyGenParameterSpec(4096, BigInteger.probablePrime(4000, new Random()));
|
// final RSAKeyGenParameterSpec spec = new RSAKeyGenParameterSpec(4096, BigInteger.probablePrime(4000, new Random()));
|
||||||
@ -210,7 +220,13 @@ public class ServerConnectionHandler implements Runnable {
|
|||||||
//ponder incoming messages
|
//ponder incoming messages
|
||||||
while(networkParser.hasIncomingMessaage()){
|
while(networkParser.hasIncomingMessaage()){
|
||||||
NetworkMessage message = networkParser.popIncomingMessage();
|
NetworkMessage message = networkParser.popIncomingMessage();
|
||||||
serverProtocol.handleMessage(message);
|
NetworkMessage bouncedMessage = serverProtocol.handleAsyncMessage(message);
|
||||||
|
//if the message bounces back from the async handle function, means we need to handle synchronously
|
||||||
|
if(bouncedMessage != null){
|
||||||
|
this.synchronousMessageLock.acquireUninterruptibly();
|
||||||
|
this.synchronousMessageQueue.add(bouncedMessage);
|
||||||
|
this.synchronousMessageLock.release();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Globals.netMonitor != null){
|
if(Globals.netMonitor != null){
|
||||||
@ -231,6 +247,18 @@ public class ServerConnectionHandler implements Runnable {
|
|||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles synchronous packets in the queue
|
||||||
|
*/
|
||||||
|
public void handleSynchronousPacketQueue(){
|
||||||
|
synchronousMessageLock.acquireUninterruptibly();
|
||||||
|
for(NetworkMessage message : synchronousMessageQueue){
|
||||||
|
this.serverProtocol.handleSynchronousMessage(message);
|
||||||
|
}
|
||||||
|
synchronousMessageQueue.clear();
|
||||||
|
synchronousMessageLock.release();
|
||||||
|
}
|
||||||
|
|
||||||
public void setPlayerId(int id){
|
public void setPlayerId(int id){
|
||||||
playerID = id;
|
playerID = id;
|
||||||
@ -245,12 +273,12 @@ public class ServerConnectionHandler implements Runnable {
|
|||||||
return playerIdIncrementer;
|
return playerIdIncrementer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPlayerCharacterId(int id){
|
public void setPlayerEntityId(int id){
|
||||||
playerCharacterID = id;
|
playerEntityID = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getPlayerCharacterId(){
|
public int getPlayerEntityId(){
|
||||||
return playerCharacterID;
|
return playerEntityID;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getIPAddress(){
|
public String getIPAddress(){
|
||||||
@ -266,7 +294,7 @@ public class ServerConnectionHandler implements Runnable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
boolean isConnectionPlayerEntity(int id){
|
boolean isConnectionPlayerEntity(int id){
|
||||||
return id == this.playerCharacterID;
|
return id == this.playerEntityID;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -303,13 +331,8 @@ public class ServerConnectionHandler implements Runnable {
|
|||||||
}
|
}
|
||||||
//figure out what player we are
|
//figure out what player we are
|
||||||
Player playerObject = Globals.playerManager.getPlayerFromId(getPlayerId());
|
Player playerObject = Globals.playerManager.getPlayerFromId(getPlayerId());
|
||||||
//get player entity & position
|
//tell all clients to destroy the entity
|
||||||
Entity playerEntity = playerObject.getPlayerEntity();
|
ServerEntityUtils.destroyEntity(playerObject.getPlayerEntity());
|
||||||
Vector3d position = EntityUtils.getPosition(playerEntity);
|
|
||||||
//deregister entity
|
|
||||||
EntityUtils.cleanUpEntity(playerObject.getPlayerEntity());
|
|
||||||
//TODO: tell all clients to destroy the entity
|
|
||||||
EntityUtils.cleanUpEntity(playerEntity);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -39,4 +39,20 @@ public class AuthProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the network message from the context of the main server simulation thread
|
||||||
|
* @param connectionHandler The connection handler
|
||||||
|
* @param message The network message
|
||||||
|
*/
|
||||||
|
protected static void handleSynchronousAuthMessage(ServerConnectionHandler connectionHandler, AuthMessage message){
|
||||||
|
switch(message.getMessageSubtype()){
|
||||||
|
case AUTHDETAILS:
|
||||||
|
case AUTHFAILURE:
|
||||||
|
case AUTHREQUEST:
|
||||||
|
case AUTHSUCCESS:
|
||||||
|
//silently ignore
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -37,6 +37,25 @@ public class CharacterProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the network message from the context of the main server simulation thread
|
||||||
|
* @param connectionHandler The connection handler
|
||||||
|
* @param message The network message
|
||||||
|
*/
|
||||||
|
protected static void handleSynchronousCharacterMessage(ServerConnectionHandler connectionHandler, CharacterMessage message){
|
||||||
|
switch(message.getMessageSubtype()){
|
||||||
|
case REQUESTCHARACTERLIST:
|
||||||
|
case REQUESTCREATECHARACTER:
|
||||||
|
case REQUESTSPAWNCHARACTER:
|
||||||
|
case RESPONSECHARACTERLIST:
|
||||||
|
case RESPONSECREATECHARACTERFAILURE:
|
||||||
|
case RESPONSECREATECHARACTERSUCCESS:
|
||||||
|
case RESPONSESPAWNCHARACTER:
|
||||||
|
//silently ignore
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Spawns the player's entity
|
* Spawns the player's entity
|
||||||
* @param connectionHandler The connection handler for the player
|
* @param connectionHandler The connection handler for the player
|
||||||
|
|||||||
@ -52,5 +52,29 @@ public class EntityProtocol {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the network message from the context of the main server simulation thread
|
||||||
|
* @param connectionHandler The connection handler
|
||||||
|
* @param message The network message
|
||||||
|
*/
|
||||||
|
protected static void handleSynchronousEntityMessage(ServerConnectionHandler connectionHandler, EntityMessage message){
|
||||||
|
switch(message.getMessageSubtype()){
|
||||||
|
case MOVEUPDATE:
|
||||||
|
case ATTACKUPDATE:
|
||||||
|
case STARTATTACK:
|
||||||
|
case UPDATEENTITYVIEWDIR:
|
||||||
|
case KILL:
|
||||||
|
case SPAWNCREATURE:
|
||||||
|
case DESTROY:
|
||||||
|
case CREATE:
|
||||||
|
case ATTACHENTITYTOENTITY:
|
||||||
|
case SETPROPERTY:
|
||||||
|
case SPAWNFOLIAGESEED:
|
||||||
|
case SPAWNITEM:
|
||||||
|
//silently ignore
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,54 +1,88 @@
|
|||||||
package electrosphere.net.server.protocol;
|
package electrosphere.net.server.protocol;
|
||||||
|
|
||||||
import electrosphere.engine.Globals;
|
|
||||||
import electrosphere.entity.Entity;
|
import electrosphere.entity.Entity;
|
||||||
import electrosphere.entity.state.equip.ClientEquipState;
|
|
||||||
import electrosphere.entity.state.inventory.InventoryUtils;
|
import electrosphere.entity.state.inventory.InventoryUtils;
|
||||||
import electrosphere.entity.state.inventory.UnrelationalInventoryState;
|
|
||||||
import electrosphere.entity.types.creature.CreatureUtils;
|
|
||||||
import electrosphere.game.data.creature.type.equip.EquipPoint;
|
|
||||||
import electrosphere.logger.LoggerInterface;
|
import electrosphere.logger.LoggerInterface;
|
||||||
import electrosphere.net.parser.net.message.InventoryMessage;
|
import electrosphere.net.parser.net.message.InventoryMessage;
|
||||||
import electrosphere.net.server.ServerConnectionHandler;
|
import electrosphere.net.server.ServerConnectionHandler;
|
||||||
import electrosphere.server.datacell.utils.EntityLookupUtils;
|
import electrosphere.server.datacell.utils.EntityLookupUtils;
|
||||||
|
import electrosphere.server.player.PlayerActions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Server protocol for dealing with inventory messages
|
||||||
|
*/
|
||||||
public class InventoryProtocol {
|
public class InventoryProtocol {
|
||||||
|
|
||||||
|
|
||||||
|
//the entity's equip inventory
|
||||||
public static final int INVENTORY_TYPE_EQUIP = 0;
|
public static final int INVENTORY_TYPE_EQUIP = 0;
|
||||||
|
//the natural inventory of the entity
|
||||||
public static final int INVENTORY_TYPE_NATURAL = 1;
|
public static final int INVENTORY_TYPE_NATURAL = 1;
|
||||||
|
|
||||||
protected static void handleInventoryMessage(ServerConnectionHandler connectionHandler, InventoryMessage message){
|
/**
|
||||||
Entity characterEntity;
|
* Handles asynchronous inventory messages
|
||||||
|
* @param connectionHandler The connection handler
|
||||||
|
* @param message The message to handle
|
||||||
|
* @return The network message if it should be handled synchronously, otherwise null
|
||||||
|
*/
|
||||||
|
protected static InventoryMessage handleAsyncInventoryMessage(ServerConnectionHandler connectionHandler, InventoryMessage message){
|
||||||
Entity target;
|
Entity target;
|
||||||
switch(message.getMessageSubtype()){
|
switch(message.getMessageSubtype()){
|
||||||
case ADDITEMTOINVENTORY:
|
case ADDITEMTOINVENTORY:
|
||||||
LoggerInterface.loggerNetworking.DEBUG("[SERVER] ADD ITEM TO INVENTORY " + message.getentityId());
|
LoggerInterface.loggerNetworking.DEBUG("[SERVER] ADD ITEM TO INVENTORY " + message.getentityId());
|
||||||
target = EntityLookupUtils.getEntityById(connectionHandler.getPlayerCharacterId());
|
target = EntityLookupUtils.getEntityById(connectionHandler.getPlayerEntityId());
|
||||||
if(InventoryUtils.hasNaturalInventory(target)){
|
if(InventoryUtils.hasNaturalInventory(target)){
|
||||||
InventoryUtils.serverGetInventoryState(target).addNetworkMessage(message);
|
InventoryUtils.serverGetInventoryState(target).addNetworkMessage(message);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case REMOVEITEMFROMINVENTORY:
|
case REMOVEITEMFROMINVENTORY:
|
||||||
LoggerInterface.loggerNetworking.DEBUG("[SERVER] REMOVE ITEM FROM INVENTORY " + message.getentityId());
|
LoggerInterface.loggerNetworking.DEBUG("[SERVER] REMOVE ITEM FROM INVENTORY " + message.getentityId());
|
||||||
target = EntityLookupUtils.getEntityById(connectionHandler.getPlayerCharacterId());
|
target = EntityLookupUtils.getEntityById(connectionHandler.getPlayerEntityId());
|
||||||
if(InventoryUtils.hasNaturalInventory(target)){
|
if(InventoryUtils.hasNaturalInventory(target)){
|
||||||
InventoryUtils.serverGetInventoryState(target).addNetworkMessage(message);
|
InventoryUtils.serverGetInventoryState(target).addNetworkMessage(message);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CLIENTREQUESTEQUIPITEM:
|
case CLIENTREQUESTEQUIPITEM:
|
||||||
LoggerInterface.loggerNetworking.DEBUG("[SERVER] REQUEST EQUIP ITEM " + message.getentityId());
|
LoggerInterface.loggerNetworking.DEBUG("[SERVER] REQUEST EQUIP ITEM " + message.getentityId());
|
||||||
target = EntityLookupUtils.getEntityById(connectionHandler.getPlayerCharacterId());
|
target = EntityLookupUtils.getEntityById(connectionHandler.getPlayerEntityId());
|
||||||
if(InventoryUtils.hasNaturalInventory(target)){
|
if(InventoryUtils.hasNaturalInventory(target)){
|
||||||
InventoryUtils.serverGetInventoryState(target).addNetworkMessage(message);
|
InventoryUtils.serverGetInventoryState(target).addNetworkMessage(message);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CLIENTREQUESTUNEQUIPITEM:
|
case CLIENTREQUESTUNEQUIPITEM:
|
||||||
LoggerInterface.loggerNetworking.DEBUG("[SERVER] REQUEST UNEQUIP ITEM " + message.getentityId());
|
LoggerInterface.loggerNetworking.DEBUG("[SERVER] REQUEST UNEQUIP ITEM " + message.getentityId());
|
||||||
target = EntityLookupUtils.getEntityById(connectionHandler.getPlayerCharacterId());
|
target = EntityLookupUtils.getEntityById(connectionHandler.getPlayerEntityId());
|
||||||
if(InventoryUtils.hasNaturalInventory(target)){
|
if(InventoryUtils.hasNaturalInventory(target)){
|
||||||
InventoryUtils.serverGetInventoryState(target).addNetworkMessage(message);
|
InventoryUtils.serverGetInventoryState(target).addNetworkMessage(message);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case CLIENTREQUESTPERFORMITEMACTION: {
|
||||||
|
//perform some action on the server based on what the client has equipped
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
case SERVERCOMMANDUNEQUIPITEM:
|
||||||
|
case SERVERCOMMANDMOVEITEMCONTAINER:
|
||||||
|
case SERVERCOMMANDEQUIPITEM:
|
||||||
|
//silently ignore
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the network message from the context of the main server simulation thread
|
||||||
|
* @param connectionHandler The connection handler
|
||||||
|
* @param message The network message
|
||||||
|
*/
|
||||||
|
protected static void handleSynchronousInventoryMessage(ServerConnectionHandler connectionHandler, InventoryMessage message){
|
||||||
|
switch(message.getMessageSubtype()){
|
||||||
|
case CLIENTREQUESTPERFORMITEMACTION: {
|
||||||
|
PlayerActions.attemptPlayerAction(connectionHandler, message);
|
||||||
|
} break;
|
||||||
|
case ADDITEMTOINVENTORY:
|
||||||
|
case REMOVEITEMFROMINVENTORY:
|
||||||
|
case CLIENTREQUESTEQUIPITEM:
|
||||||
|
case CLIENTREQUESTUNEQUIPITEM:
|
||||||
case SERVERCOMMANDUNEQUIPITEM:
|
case SERVERCOMMANDUNEQUIPITEM:
|
||||||
case SERVERCOMMANDMOVEITEMCONTAINER:
|
case SERVERCOMMANDMOVEITEMCONTAINER:
|
||||||
case SERVERCOMMANDEQUIPITEM:
|
case SERVERCOMMANDEQUIPITEM:
|
||||||
|
|||||||
@ -22,5 +22,19 @@ public class LoreProtocol {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the network message from the context of the main server simulation thread
|
||||||
|
* @param connectionHandler The connection handler
|
||||||
|
* @param message The network message
|
||||||
|
*/
|
||||||
|
protected static void handleSynchronousLoreMessage(ServerConnectionHandler connectionHandler, LoreMessage message){
|
||||||
|
switch(message.getMessageSubtype()){
|
||||||
|
case REQUESTRACES:
|
||||||
|
case RESPONSERACES:
|
||||||
|
//silently ignore
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,11 +3,36 @@ package electrosphere.net.server.protocol;
|
|||||||
import electrosphere.net.parser.net.message.PlayerMessage;
|
import electrosphere.net.parser.net.message.PlayerMessage;
|
||||||
import electrosphere.net.server.ServerConnectionHandler;
|
import electrosphere.net.server.ServerConnectionHandler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Player protocol handling
|
||||||
|
*/
|
||||||
public class PlayerProtocol {
|
public class PlayerProtocol {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles a player network message
|
||||||
|
* @param connectionHandler The connection handler
|
||||||
|
* @param message The player message
|
||||||
|
*/
|
||||||
protected static void handlePlayerMessage(ServerConnectionHandler connectionHandler, PlayerMessage message){
|
protected static void handlePlayerMessage(ServerConnectionHandler connectionHandler, PlayerMessage message){
|
||||||
switch(message.getMessageSubtype()){
|
switch(message.getMessageSubtype()){
|
||||||
|
case SETINITIALDISCRETEPOSITION:
|
||||||
|
case SET_ID:
|
||||||
|
//silently ignore
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the network message from the context of the main server simulation thread
|
||||||
|
* @param connectionHandler The connection handler
|
||||||
|
* @param message The network message
|
||||||
|
*/
|
||||||
|
protected static void handleSynchronousPlayerMessage(ServerConnectionHandler connectionHandler, PlayerMessage message){
|
||||||
|
switch(message.getMessageSubtype()){
|
||||||
|
case SETINITIALDISCRETEPOSITION:
|
||||||
|
case SET_ID:
|
||||||
|
//silently ignore
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,18 +1,6 @@
|
|||||||
package electrosphere.net.server.protocol;
|
package electrosphere.net.server.protocol;
|
||||||
|
|
||||||
import org.joml.Vector3f;
|
|
||||||
|
|
||||||
import electrosphere.engine.Globals;
|
|
||||||
import electrosphere.engine.Main;
|
|
||||||
import electrosphere.entity.Entity;
|
|
||||||
import electrosphere.entity.EntityUtils;
|
|
||||||
import electrosphere.entity.state.ironsight.IronSightTree;
|
|
||||||
import electrosphere.entity.types.attach.AttachUtils;
|
|
||||||
import electrosphere.entity.types.collision.CollisionObjUtils;
|
|
||||||
import electrosphere.entity.types.creature.CreatureUtils;
|
|
||||||
import electrosphere.entity.types.item.ItemUtils;
|
|
||||||
import electrosphere.logger.LoggerInterface;
|
import electrosphere.logger.LoggerInterface;
|
||||||
import electrosphere.net.NetUtils;
|
|
||||||
import electrosphere.net.parser.net.message.AuthMessage;
|
import electrosphere.net.parser.net.message.AuthMessage;
|
||||||
import electrosphere.net.parser.net.message.CharacterMessage;
|
import electrosphere.net.parser.net.message.CharacterMessage;
|
||||||
import electrosphere.net.parser.net.message.EntityMessage;
|
import electrosphere.net.parser.net.message.EntityMessage;
|
||||||
@ -25,53 +13,110 @@ import electrosphere.net.parser.net.message.TerrainMessage;
|
|||||||
import electrosphere.net.parser.net.message.NetworkMessage.MessageType;
|
import electrosphere.net.parser.net.message.NetworkMessage.MessageType;
|
||||||
import electrosphere.net.parser.net.message.ServerMessage.ServerMessageType;
|
import electrosphere.net.parser.net.message.ServerMessage.ServerMessageType;
|
||||||
import electrosphere.net.server.ServerConnectionHandler;
|
import electrosphere.net.server.ServerConnectionHandler;
|
||||||
import electrosphere.net.server.player.Player;
|
|
||||||
import electrosphere.server.terrain.manager.ServerTerrainChunk;
|
|
||||||
import electrosphere.server.terrain.models.TerrainModification;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The server's protocol for handling a message
|
||||||
|
*/
|
||||||
public class ServerProtocol {
|
public class ServerProtocol {
|
||||||
|
|
||||||
|
//the connection handler associated with this protocol object
|
||||||
ServerConnectionHandler connectionHandler;
|
ServerConnectionHandler connectionHandler;
|
||||||
|
//if set to true, will log ping messages
|
||||||
boolean echoPings = false;
|
boolean echoPings = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param connectionHandler the associated connection handler
|
||||||
|
*/
|
||||||
public ServerProtocol(ServerConnectionHandler connectionHandler){
|
public ServerProtocol(ServerConnectionHandler connectionHandler){
|
||||||
this.connectionHandler = connectionHandler;
|
this.connectionHandler = connectionHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleMessage(NetworkMessage message){
|
/**
|
||||||
|
* Handles a given network message
|
||||||
|
* @param message The network message to handle
|
||||||
|
* @return Returns the message if it should be synchronously handled with the main server thread instead
|
||||||
|
*/
|
||||||
|
public NetworkMessage handleAsyncMessage(NetworkMessage message){
|
||||||
//print out message
|
//print out message
|
||||||
printMessage(message);
|
printMessage(message);
|
||||||
//actually handle message
|
//actually handle message
|
||||||
switch(message.getType()){
|
switch(message.getType()){
|
||||||
case ENTITY_MESSAGE:
|
case ENTITY_MESSAGE: {
|
||||||
EntityProtocol.handleEntityMessage(connectionHandler, (EntityMessage)message);
|
EntityProtocol.handleEntityMessage(connectionHandler, (EntityMessage)message);
|
||||||
break;
|
} break;
|
||||||
case TERRAIN_MESSAGE:
|
case TERRAIN_MESSAGE: {
|
||||||
TerrainProtocol.handleTerrainMessage(connectionHandler, (TerrainMessage)message);
|
TerrainProtocol.handleTerrainMessage(connectionHandler, (TerrainMessage)message);
|
||||||
break;
|
} break;
|
||||||
case PLAYER_MESSAGE:
|
case PLAYER_MESSAGE: {
|
||||||
PlayerProtocol.handlePlayerMessage(connectionHandler, (PlayerMessage)message);
|
PlayerProtocol.handlePlayerMessage(connectionHandler, (PlayerMessage)message);
|
||||||
break;
|
} break;
|
||||||
case AUTH_MESSAGE:
|
case AUTH_MESSAGE: {
|
||||||
AuthProtocol.handleAuthenticationMessage(connectionHandler, (AuthMessage)message);
|
AuthProtocol.handleAuthenticationMessage(connectionHandler, (AuthMessage)message);
|
||||||
break;
|
} break;
|
||||||
case SERVER_MESSAGE:
|
case SERVER_MESSAGE: {
|
||||||
handleServerMessage((ServerMessage)message);
|
handleServerMessage((ServerMessage)message);
|
||||||
break;
|
} break;
|
||||||
case CHARACTER_MESSAGE:
|
case CHARACTER_MESSAGE: {
|
||||||
CharacterProtocol.handleCharacterMessage(connectionHandler, (CharacterMessage)message);
|
CharacterProtocol.handleCharacterMessage(connectionHandler, (CharacterMessage)message);
|
||||||
break;
|
} break;
|
||||||
case LORE_MESSAGE:
|
case LORE_MESSAGE: {
|
||||||
LoreProtocol.handleLoreMessage(connectionHandler, (LoreMessage)message);
|
LoreProtocol.handleLoreMessage(connectionHandler, (LoreMessage)message);
|
||||||
|
} break;
|
||||||
|
case INVENTORY_MESSAGE: {
|
||||||
|
return InventoryProtocol.handleAsyncInventoryMessage(connectionHandler, (InventoryMessage)message);
|
||||||
|
}
|
||||||
|
case SYNCHRONIZATION_MESSAGE:
|
||||||
|
//silently ignore sync messages from client
|
||||||
break;
|
break;
|
||||||
case INVENTORY_MESSAGE:
|
}
|
||||||
InventoryProtocol.handleInventoryMessage(connectionHandler, (InventoryMessage)message);
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Synchronously handles a network message
|
||||||
|
* @param message The network message
|
||||||
|
*/
|
||||||
|
public void handleSynchronousMessage(NetworkMessage message){
|
||||||
|
//print out message
|
||||||
|
printMessage(message);
|
||||||
|
//actually handle message
|
||||||
|
switch(message.getType()){
|
||||||
|
case ENTITY_MESSAGE: {
|
||||||
|
EntityProtocol.handleSynchronousEntityMessage(connectionHandler, (EntityMessage)message);
|
||||||
|
} break;
|
||||||
|
case TERRAIN_MESSAGE: {
|
||||||
|
TerrainProtocol.handleSynchronousServerMessage(connectionHandler, (TerrainMessage)message);
|
||||||
|
} break;
|
||||||
|
case PLAYER_MESSAGE: {
|
||||||
|
PlayerProtocol.handleSynchronousPlayerMessage(connectionHandler, (PlayerMessage)message);
|
||||||
|
} break;
|
||||||
|
case AUTH_MESSAGE: {
|
||||||
|
AuthProtocol.handleSynchronousAuthMessage(connectionHandler, (AuthMessage)message);
|
||||||
|
} break;
|
||||||
|
case SERVER_MESSAGE: {
|
||||||
|
ServerProtocol.handleSynchronousServerMessage(connectionHandler, (ServerMessage)message);
|
||||||
|
} break;
|
||||||
|
case CHARACTER_MESSAGE: {
|
||||||
|
CharacterProtocol.handleSynchronousCharacterMessage(connectionHandler, (CharacterMessage)message);
|
||||||
|
} break;
|
||||||
|
case LORE_MESSAGE: {
|
||||||
|
LoreProtocol.handleSynchronousLoreMessage(connectionHandler, (LoreMessage)message);
|
||||||
|
} break;
|
||||||
|
case INVENTORY_MESSAGE: {
|
||||||
|
InventoryProtocol.handleSynchronousInventoryMessage(connectionHandler, (InventoryMessage)message);
|
||||||
|
} break;
|
||||||
|
case SYNCHRONIZATION_MESSAGE:
|
||||||
|
//silently ignore sync messages from client
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles a server-type network message
|
||||||
|
* @param message The server message
|
||||||
|
*/
|
||||||
void handleServerMessage(ServerMessage message){
|
void handleServerMessage(ServerMessage message){
|
||||||
switch(message.getMessageSubtype()){
|
switch(message.getMessageSubtype()){
|
||||||
case PING:
|
case PING:
|
||||||
@ -83,6 +128,20 @@ public class ServerProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the network message from the context of the main server simulation thread
|
||||||
|
* @param connectionHandler The connection handler
|
||||||
|
* @param message The network message
|
||||||
|
*/
|
||||||
|
protected static void handleSynchronousServerMessage(ServerConnectionHandler connectionHandler, ServerMessage message){
|
||||||
|
switch(message.getMessageSubtype()){
|
||||||
|
case PING:
|
||||||
|
case PONG:
|
||||||
|
//silently ignore
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Print out the network message type, this only prints ping and pong if echoPings is true
|
* Print out the network message type, this only prints ping and pong if echoPings is true
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -6,20 +6,25 @@ import java.nio.IntBuffer;
|
|||||||
|
|
||||||
import org.joml.Vector3d;
|
import org.joml.Vector3d;
|
||||||
|
|
||||||
import electrosphere.client.terrain.cache.ChunkData;
|
|
||||||
import electrosphere.engine.Globals;
|
import electrosphere.engine.Globals;
|
||||||
import electrosphere.net.parser.net.message.TerrainMessage;
|
import electrosphere.net.parser.net.message.TerrainMessage;
|
||||||
import electrosphere.net.server.Server;
|
|
||||||
import electrosphere.net.server.ServerConnectionHandler;
|
import electrosphere.net.server.ServerConnectionHandler;
|
||||||
import electrosphere.net.server.player.Player;
|
import electrosphere.net.server.player.Player;
|
||||||
import electrosphere.server.datacell.Realm;
|
import electrosphere.server.datacell.Realm;
|
||||||
import electrosphere.server.fluid.manager.ServerFluidChunk;
|
import electrosphere.server.fluid.manager.ServerFluidChunk;
|
||||||
import electrosphere.server.terrain.editing.TerrainEditing;
|
import electrosphere.server.terrain.editing.TerrainEditing;
|
||||||
import electrosphere.server.terrain.manager.ServerTerrainChunk;
|
import electrosphere.server.terrain.manager.ServerTerrainChunk;
|
||||||
import electrosphere.server.terrain.models.TerrainModification;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Server handling for terrain network messages
|
||||||
|
*/
|
||||||
public class TerrainProtocol {
|
public class TerrainProtocol {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles a terrain message
|
||||||
|
* @param connectionHandler The connection handler
|
||||||
|
* @param message The terrain message
|
||||||
|
*/
|
||||||
protected static void handleTerrainMessage(ServerConnectionHandler connectionHandler, TerrainMessage message){
|
protected static void handleTerrainMessage(ServerConnectionHandler connectionHandler, TerrainMessage message){
|
||||||
switch(message.getMessageSubtype()){
|
switch(message.getMessageSubtype()){
|
||||||
case REQUESTMETADATA:
|
case REQUESTMETADATA:
|
||||||
@ -53,6 +58,36 @@ public class TerrainProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the network message from the context of the main server simulation thread
|
||||||
|
* @param connectionHandler The connection handler
|
||||||
|
* @param message The network message
|
||||||
|
*/
|
||||||
|
protected static void handleSynchronousServerMessage(ServerConnectionHandler connectionHandler, TerrainMessage message){
|
||||||
|
switch(message.getMessageSubtype()){
|
||||||
|
case REQUESTCHUNKDATA:
|
||||||
|
case REQUESTEDITVOXEL:
|
||||||
|
case REQUESTFLUIDDATA:
|
||||||
|
case REQUESTMETADATA:
|
||||||
|
case REQUESTUSETERRAINPALETTE:
|
||||||
|
case RESPONSEMETADATA:
|
||||||
|
case UPDATEFLUIDDATA:
|
||||||
|
case SPAWNPOSITION:
|
||||||
|
case UPDATEVOXEL:
|
||||||
|
case SENDCHUNKDATA:
|
||||||
|
case SENDFLUIDDATA:
|
||||||
|
//silently ignore
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a subchunk to the client
|
||||||
|
* @param connectionHandler The connection handler
|
||||||
|
* @param worldX the world x
|
||||||
|
* @param worldY the world y
|
||||||
|
* @param worldZ the world z
|
||||||
|
*/
|
||||||
static void sendWorldSubChunk(ServerConnectionHandler connectionHandler, int worldX, int worldY, int worldZ){
|
static void sendWorldSubChunk(ServerConnectionHandler connectionHandler, int worldX, int worldY, int worldZ){
|
||||||
/*
|
/*
|
||||||
int locationX,
|
int locationX,
|
||||||
@ -200,6 +235,13 @@ public class TerrainProtocol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends a fluid sub chunk to the client
|
||||||
|
* @param connectionHandler The connection handler
|
||||||
|
* @param worldX the world x
|
||||||
|
* @param worldY the world y
|
||||||
|
* @param worldZ the world z
|
||||||
|
*/
|
||||||
static void sendWorldFluidSubChunk(ServerConnectionHandler connectionHandler, int worldX, int worldY, int worldZ){
|
static void sendWorldFluidSubChunk(ServerConnectionHandler connectionHandler, int worldX, int worldY, int worldZ){
|
||||||
|
|
||||||
// System.out.println("Received request for chunk " + message.getworldX() + " " + message.getworldY());
|
// System.out.println("Received request for chunk " + message.getworldX() + " " + message.getworldY());
|
||||||
@ -213,6 +255,10 @@ public class TerrainProtocol {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends world metadata to the client
|
||||||
|
* @param connectionHandler The connection handler
|
||||||
|
*/
|
||||||
static void sendWorldMetadata(ServerConnectionHandler connectionHandler){
|
static void sendWorldMetadata(ServerConnectionHandler connectionHandler){
|
||||||
//world metadata
|
//world metadata
|
||||||
connectionHandler.addMessagetoOutgoingQueue(
|
connectionHandler.addMessagetoOutgoingQueue(
|
||||||
@ -233,7 +279,8 @@ public class TerrainProtocol {
|
|||||||
* @param message The message containing the edit request
|
* @param message The message containing the edit request
|
||||||
*/
|
*/
|
||||||
static void attemptTerrainEdit(ServerConnectionHandler connectionHandler, TerrainMessage message){
|
static void attemptTerrainEdit(ServerConnectionHandler connectionHandler, TerrainMessage message){
|
||||||
Player player = Globals.playerManager.getPlayerFromId(connectionHandler.getPlayerId());
|
// Player player = Globals.playerManager.getPlayerFromId(connectionHandler.getPlayerId());
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -7,13 +7,15 @@ public class BehaviorTreeIdEnums {
|
|||||||
|
|
||||||
public static final int BTREE_CLIENTATTACKTREE_ID = 0;
|
public static final int BTREE_CLIENTATTACKTREE_ID = 0;
|
||||||
public static final int BTREE_SERVERATTACKTREE_ID = 1;
|
public static final int BTREE_SERVERATTACKTREE_ID = 1;
|
||||||
public static final int BTREE_CLIENTEQUIPSTATE_ID = 2;
|
public static final int BTREE_CLIENTBLOCKTREE_ID = 2;
|
||||||
public static final int BTREE_SERVEREQUIPSTATE_ID = 3;
|
public static final int BTREE_SERVERBLOCKTREE_ID = 3;
|
||||||
public static final int BTREE_GRAVITY_ID = 4;
|
public static final int BTREE_CLIENTEQUIPSTATE_ID = 4;
|
||||||
public static final int BTREE_SERVERGRAVITY_ID = 5;
|
public static final int BTREE_SERVEREQUIPSTATE_ID = 5;
|
||||||
public static final int BTREE_IDLE_ID = 6;
|
public static final int BTREE_GRAVITY_ID = 6;
|
||||||
public static final int BTREE_SERVERIDLE_ID = 7;
|
public static final int BTREE_SERVERGRAVITY_ID = 7;
|
||||||
public static final int BTREE_CLIENTGROUNDMOVEMENTTREE_ID = 8;
|
public static final int BTREE_IDLE_ID = 8;
|
||||||
public static final int BTREE_SERVERGROUNDMOVEMENTTREE_ID = 9;
|
public static final int BTREE_SERVERIDLE_ID = 9;
|
||||||
|
public static final int BTREE_CLIENTGROUNDMOVEMENTTREE_ID = 10;
|
||||||
|
public static final int BTREE_SERVERGROUNDMOVEMENTTREE_ID = 11;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,10 @@
|
|||||||
package electrosphere.net.synchronization;
|
package electrosphere.net.synchronization;
|
||||||
|
|
||||||
|
|
||||||
|
import electrosphere.entity.state.block.ClientBlockTree;
|
||||||
|
|
||||||
|
import electrosphere.entity.state.block.ServerBlockTree;
|
||||||
|
|
||||||
import electrosphere.entity.state.movement.groundmove.ClientGroundMovementTree;
|
import electrosphere.entity.state.movement.groundmove.ClientGroundMovementTree;
|
||||||
|
|
||||||
import electrosphere.entity.state.movement.groundmove.ServerGroundMovementTree;
|
import electrosphere.entity.state.movement.groundmove.ServerGroundMovementTree;
|
||||||
@ -110,13 +114,25 @@ public class ClientSynchronizationManager {
|
|||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
case BehaviorTreeIdEnums.BTREE_SERVERBLOCKTREE_ID: {
|
||||||
|
switch(message.getfieldId()){
|
||||||
|
case 8:{
|
||||||
|
ClientBlockTree tree = ClientBlockTree.getClientBlockTree(entity);
|
||||||
|
tree.setState(ClientBlockTree.getBlockStateShortAsEnum((short)message.getbTreeValue()));
|
||||||
|
} break;
|
||||||
|
case 9:{
|
||||||
|
ClientBlockTree tree = ClientBlockTree.getClientBlockTree(entity);
|
||||||
|
tree.setCurrentBlockVariant(message.getstringValue());
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
} break;
|
||||||
case BehaviorTreeIdEnums.BTREE_SERVEREQUIPSTATE_ID: {
|
case BehaviorTreeIdEnums.BTREE_SERVEREQUIPSTATE_ID: {
|
||||||
switch(message.getfieldId()){
|
switch(message.getfieldId()){
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case BehaviorTreeIdEnums.BTREE_SERVERGRAVITY_ID: {
|
case BehaviorTreeIdEnums.BTREE_SERVERGRAVITY_ID: {
|
||||||
switch(message.getfieldId()){
|
switch(message.getfieldId()){
|
||||||
case 7:{
|
case 11:{
|
||||||
ClientGravityTree tree = ClientGravityTree.getClientGravityTree(entity);
|
ClientGravityTree tree = ClientGravityTree.getClientGravityTree(entity);
|
||||||
tree.setState(ClientGravityTree.getGravityTreeStateShortAsEnum((short)message.getbTreeValue()));
|
tree.setState(ClientGravityTree.getGravityTreeStateShortAsEnum((short)message.getbTreeValue()));
|
||||||
} break;
|
} break;
|
||||||
@ -124,15 +140,15 @@ public class ClientSynchronizationManager {
|
|||||||
} break;
|
} break;
|
||||||
case BehaviorTreeIdEnums.BTREE_SERVERIDLE_ID: {
|
case BehaviorTreeIdEnums.BTREE_SERVERIDLE_ID: {
|
||||||
switch(message.getfieldId()){
|
switch(message.getfieldId()){
|
||||||
case 9:{
|
case 13:{
|
||||||
ClientIdleTree tree = ClientIdleTree.getIdleTree(entity);
|
ClientIdleTree tree = ClientIdleTree.getClientIdleTree(entity);
|
||||||
tree.setState(ClientIdleTree.getIdleTreeStateShortAsEnum((short)message.getbTreeValue()));
|
tree.setState(ClientIdleTree.getIdleTreeStateShortAsEnum((short)message.getbTreeValue()));
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case BehaviorTreeIdEnums.BTREE_SERVERGROUNDMOVEMENTTREE_ID: {
|
case BehaviorTreeIdEnums.BTREE_SERVERGROUNDMOVEMENTTREE_ID: {
|
||||||
switch(message.getfieldId()){
|
switch(message.getfieldId()){
|
||||||
case 11:{
|
case 15:{
|
||||||
ClientGroundMovementTree tree = ClientGroundMovementTree.getClientGroundMovementTree(entity);
|
ClientGroundMovementTree tree = ClientGroundMovementTree.getClientGroundMovementTree(entity);
|
||||||
tree.setFacing(ClientGroundMovementTree.getMovementRelativeFacingShortAsEnum((short)message.getbTreeValue()));
|
tree.setFacing(ClientGroundMovementTree.getMovementRelativeFacingShortAsEnum((short)message.getbTreeValue()));
|
||||||
} break;
|
} break;
|
||||||
|
|||||||
@ -116,7 +116,12 @@ public class DebugContentPipeline implements RenderPipeline {
|
|||||||
modelTransformMatrix.translate(cameraModifiedPosition);
|
modelTransformMatrix.translate(cameraModifiedPosition);
|
||||||
//since you're directly accessing the quat from the body, need to adjust it to be in the correct orientation
|
//since you're directly accessing the quat from the body, need to adjust it to be in the correct orientation
|
||||||
modelTransformMatrix.rotate(PhysicsUtils.odeQuatToJomlQuat(capsuleView.getQuaternion()).mul(new Quaterniond(0.707,0,0,0.707)));
|
modelTransformMatrix.rotate(PhysicsUtils.odeQuatToJomlQuat(capsuleView.getQuaternion()).mul(new Quaterniond(0.707,0,0,0.707)));
|
||||||
modelTransformMatrix.scale(capsuleView.getRadius(),capsuleView.getLength(),capsuleView.getRadius());
|
//the ode4j capsule's end caps are always at least radius length, the length only controls the distance between the two caps.
|
||||||
|
//unfortunately that won't be easy to replicate with rendering tech currently; instead, run logic below
|
||||||
|
double radius = capsuleView.getRadius();
|
||||||
|
double length = capsuleView.getLength();
|
||||||
|
if(length < radius) length = radius;
|
||||||
|
modelTransformMatrix.scale(radius,length,radius);
|
||||||
hitboxModel.setModelMatrix(modelTransformMatrix);
|
hitboxModel.setModelMatrix(modelTransformMatrix);
|
||||||
hitboxModel.draw(renderPipelineState,openGLState);
|
hitboxModel.draw(renderPipelineState,openGLState);
|
||||||
}
|
}
|
||||||
@ -220,7 +225,12 @@ public class DebugContentPipeline implements RenderPipeline {
|
|||||||
modelTransformMatrix.translate(cameraModifiedPosition);
|
modelTransformMatrix.translate(cameraModifiedPosition);
|
||||||
//since you're directly accessing the quat from the body, need to adjust it to be in the correct orientation
|
//since you're directly accessing the quat from the body, need to adjust it to be in the correct orientation
|
||||||
modelTransformMatrix.rotate(PhysicsUtils.odeQuatToJomlQuat(capsuleView.getQuaternion()).mul(new Quaterniond(0.707,0,0,0.707)));
|
modelTransformMatrix.rotate(PhysicsUtils.odeQuatToJomlQuat(capsuleView.getQuaternion()).mul(new Quaterniond(0.707,0,0,0.707)));
|
||||||
modelTransformMatrix.scale(capsuleView.getRadius(),capsuleView.getLength(),capsuleView.getRadius());
|
//the ode4j capsule's end caps are always at least radius length, the length only controls the distance between the two caps.
|
||||||
|
//unfortunately that won't be easy to replicate with rendering tech currently; instead, run logic below
|
||||||
|
double radius = capsuleView.getRadius();
|
||||||
|
double length = capsuleView.getLength();
|
||||||
|
if(length < radius) length = radius;
|
||||||
|
modelTransformMatrix.scale(radius,length,radius);
|
||||||
hitboxModel.setModelMatrix(modelTransformMatrix);
|
hitboxModel.setModelMatrix(modelTransformMatrix);
|
||||||
hitboxModel.draw(renderPipelineState,openGLState);
|
hitboxModel.draw(renderPipelineState,openGLState);
|
||||||
}
|
}
|
||||||
|
|||||||
41
src/main/java/electrosphere/server/MainServerFunctions.java
Normal file
41
src/main/java/electrosphere/server/MainServerFunctions.java
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
package electrosphere.server;
|
||||||
|
|
||||||
|
import electrosphere.engine.Globals;
|
||||||
|
import electrosphere.logger.LoggerInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Functions that should be fired every server frame
|
||||||
|
*/
|
||||||
|
public class MainServerFunctions {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calls the main server routines that should fire each frame
|
||||||
|
*/
|
||||||
|
public static void simulate(){
|
||||||
|
|
||||||
|
//
|
||||||
|
//Synchronous player message parsing\
|
||||||
|
Globals.profiler.beginCpuSample("Server synchronous packet parsing");
|
||||||
|
if(Globals.server != null){
|
||||||
|
Globals.server.synchronousPacketHandling();
|
||||||
|
}
|
||||||
|
Globals.profiler.endCpuSample();
|
||||||
|
|
||||||
|
//
|
||||||
|
//Micro simulation (ie simulating each scene on the server)
|
||||||
|
Globals.profiler.beginCpuSample("Server micro simulation");
|
||||||
|
LoggerInterface.loggerEngine.DEBUG("Begin server micro simulation");
|
||||||
|
if(Globals.realmManager != null){
|
||||||
|
Globals.realmManager.simulate();
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//Macro simulation (ie simulating the larger world macro data)
|
||||||
|
LoggerInterface.loggerEngine.DEBUG("Server macro simulation");
|
||||||
|
if(Globals.macroSimulation != null && Globals.macroSimulation.isReady()){
|
||||||
|
Globals.macroSimulation.simulate();
|
||||||
|
}
|
||||||
|
Globals.profiler.endCpuSample();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -30,7 +30,7 @@ public class PlayerCharacterCreation {
|
|||||||
Realm realm = Globals.realmManager.getRealms().iterator().next();
|
Realm realm = Globals.realmManager.getRealms().iterator().next();
|
||||||
Entity newPlayerEntity = CreatureUtils.serverSpawnBasicCreature(realm,new Vector3d(Globals.spawnPoint.x,Globals.spawnPoint.y,Globals.spawnPoint.z),raceName,template);
|
Entity newPlayerEntity = CreatureUtils.serverSpawnBasicCreature(realm,new Vector3d(Globals.spawnPoint.x,Globals.spawnPoint.y,Globals.spawnPoint.z),raceName,template);
|
||||||
int playerCharacterId = newPlayerEntity.getId();
|
int playerCharacterId = newPlayerEntity.getId();
|
||||||
connectionHandler.setPlayerCharacterId(playerCharacterId);
|
connectionHandler.setPlayerEntityId(playerCharacterId);
|
||||||
CreatureUtils.setControllerPlayerId(newPlayerEntity, connectionHandler.getPlayerId());
|
CreatureUtils.setControllerPlayerId(newPlayerEntity, connectionHandler.getPlayerId());
|
||||||
//custom player btrees
|
//custom player btrees
|
||||||
addPlayerServerBTrees(newPlayerEntity);
|
addPlayerServerBTrees(newPlayerEntity);
|
||||||
|
|||||||
35
src/main/java/electrosphere/server/player/PlayerActions.java
Normal file
35
src/main/java/electrosphere/server/player/PlayerActions.java
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
package electrosphere.server.player;
|
||||||
|
|
||||||
|
import electrosphere.client.item.ItemActions;
|
||||||
|
import electrosphere.entity.Entity;
|
||||||
|
import electrosphere.entity.state.block.ServerBlockTree;
|
||||||
|
import electrosphere.net.parser.net.message.InventoryMessage;
|
||||||
|
import electrosphere.net.server.ServerConnectionHandler;
|
||||||
|
import electrosphere.server.datacell.utils.EntityLookupUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class for handling
|
||||||
|
*/
|
||||||
|
public class PlayerActions {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempts to perform an action a player requested
|
||||||
|
* @param connectionHandler The player's connection handler
|
||||||
|
* @param message The network message that encapsulates the requested action
|
||||||
|
*/
|
||||||
|
public static void attemptPlayerAction(ServerConnectionHandler connectionHandler, InventoryMessage message){
|
||||||
|
Entity playerEntity = EntityLookupUtils.getEntityById(connectionHandler.getPlayerEntityId());
|
||||||
|
|
||||||
|
if(message.getitemActionCode() == ItemActions.ITEM_ACTION_CODE_SECONDARY){
|
||||||
|
ServerBlockTree serverBlockTree = ServerBlockTree.getServerBlockTree(playerEntity);
|
||||||
|
if(serverBlockTree != null){
|
||||||
|
if(message.getitemActionCodeState() == ItemActions.ITEM_ACTION_CODE_STATE_ON){
|
||||||
|
serverBlockTree.start();
|
||||||
|
} else {
|
||||||
|
serverBlockTree.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user