toolbar state mostly working
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit

This commit is contained in:
austin 2024-09-27 18:23:55 -04:00
parent 95695188e3
commit b5e8c71545
43 changed files with 1696 additions and 202 deletions

View File

@ -267,7 +267,8 @@
"nameFirstPerson" : "Idle",
"priorityCategory" : "MODIFIER_HIGH",
"boneGroups" : ["handRight"]
}
},
"isToolbarSlot": true
},
{
"equipPointId" : "handsCombined",
@ -289,6 +290,7 @@
"priorityCategory" : "MODIFIER_HIGH",
"boneGroups" : ["armLeft", "armRight", "handLeft", "handRight"]
},
"isToolbarSlot": true,
"isCombinedPoint": true,
"subPoints" : ["handLeft","handRight"]
},
@ -317,6 +319,10 @@
]
}
],
"toolbarData" : {
"primarySlot" : "handRight",
"combinedSlot" : "handsCombined"
},
"blockSystem" : {
"variants": [
{

View File

@ -169,7 +169,8 @@
"nameFirstPerson" : "Idle",
"priorityCategory" : "MODIFIER_HIGH",
"boneGroups" : ["handRight"]
}
},
"isToolbarSlot": true
},
{
"equipPointId" : "handsCombined",
@ -191,6 +192,7 @@
"priorityCategory" : "MODIFIER_HIGH",
"boneGroups" : ["armLeft", "armRight", "handLeft", "handRight"]
},
"isToolbarSlot": true,
"isCombinedPoint": true,
"subPoints" : ["handLeft","handRight"]
},
@ -219,6 +221,10 @@
]
}
],
"toolbarData" : {
"primarySlot" : "handRight",
"combinedSlot" : "handsCombined"
},
"blockSystem" : {
"variants": [
{

View File

@ -845,6 +845,13 @@ Partially fix idle animations for human + skeleton
Directional lighting color control
Skysphere affected by directional lighting
(09/25/2024)
(09/26/2024)
Work on toolbar refactor
(09/27/2024)
Toolbar state mostly working
# TODO

View File

@ -25,6 +25,10 @@
"name" : "containerType",
"type" : "FIXED_INT"
},
{
"name" : "toolbarId",
"type" : "FIXED_INT"
},
{
"name" : "itemActionCode",
"type" : "FIXED_INT"
@ -37,6 +41,7 @@
"messageTypes" : [
{
"messageName" : "addItemToInventory",
"description" : "Requests that the server add the item to the client entity's appropriate inventory",
"data" : [
"entityId",
"itemTemplate"
@ -70,6 +75,7 @@
"description" : "Instructs the client to equip an item to an entity",
"data" : [
"equipperId",
"containerType",
"equipPointId",
"entityId",
"itemTemplate"
@ -80,6 +86,7 @@
"description" : "Instructs the client to unequip an item",
"data" : [
"equipperId",
"containerType",
"equipPointId"
]
},
@ -90,6 +97,21 @@
"equipPointId"
]
},
{
"messageName" : "clientRequestAddToolbar",
"description" : "Requests that the server add the item to the client entity's toolbar",
"data" : [
"entityId",
"toolbarId"
]
},
{
"messageName" : "clientRequestAddNatural",
"description" : "Requests that the server add the item to the client entity's natural inventory",
"data" : [
"entityId"
]
},
{
"messageName" : "clientRequestPerformItemAction",
"description" : "Requests that the server have the entity perform its equipped item's action for the given equip point",

View File

@ -7,6 +7,7 @@ import electrosphere.controls.ControlHandler.ControlsState;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.state.equip.ClientEquipState;
import electrosphere.entity.state.equip.ClientToolbarState;
import electrosphere.game.data.item.type.Item;
import electrosphere.net.parser.net.message.InventoryMessage;
@ -33,10 +34,10 @@ public class ItemActions {
//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)
ClientEquipState clientEquipState = ClientEquipState.getClientEquipState(Globals.playerEntity);
Entity rightHandItem = clientEquipState.getEquippedItemAtPoint("handRight");
if(rightHandItem != null && Globals.gameConfigCurrent.getItemMap().getItem(rightHandItem) != null){
Item data = Globals.gameConfigCurrent.getItemMap().getItem(rightHandItem);
ClientToolbarState clientToolbarState = ClientToolbarState.getClientToolbarState(Globals.playerEntity);
Entity primaryEntity = clientToolbarState.getCurrentPrimaryItem();
if(primaryEntity != null && Globals.gameConfigCurrent.getItemMap().getItem(primaryEntity) != null){
Item data = Globals.gameConfigCurrent.getItemMap().getItem(primaryEntity);
if(data.getClientSidePrimary() != null){
switch(data.getClientSidePrimary()){
case "OPEN_VOXEL": {

View File

@ -13,8 +13,8 @@ import org.joml.Vector3i;
import electrosphere.auth.AuthenticationManager;
import electrosphere.engine.Globals;
import electrosphere.engine.threads.LabeledThread.ThreadLabel;
import electrosphere.entity.types.creature.CreatureEquipData.EquippedItem;
import electrosphere.entity.types.creature.CreatureTemplate;
import electrosphere.entity.types.creature.CreatureToolbarData.ToolbarItem;
import electrosphere.game.data.creature.type.CreatureData;
import electrosphere.game.data.creature.type.visualattribute.VisualAttribute;
import electrosphere.game.server.world.MacroData;
@ -174,7 +174,7 @@ public class LoadingUtils {
template.putAttributeValue(attribute.getAttributeId(), attribute.getVariants().get(0).getId());
}
}
template.getCreatureEquipData().setSlotItem("handRight",new EquippedItem(71, "terrainTool"));
template.getCreatureToolbarData().setSlotItem("0", new ToolbarItem(71, "terrainTool"));
//set player character template
serverPlayerConnection.setCreatureTemplate(template);
Globals.clientConnection.queueOutgoingMessage(CharacterMessage.constructRequestSpawnCharacterMessage());

View File

@ -32,20 +32,22 @@ public class ClientEntityUtils {
*/
public static void destroyEntity(Entity entity){
//
//destroy the child entities, too
if(AttachUtils.hasChildren(entity)){
List<Entity> children = AttachUtils.getChildrenList(entity);
for(Entity child : children){
ClientEntityUtils.destroyEntity(child);
if(entity != null){
//
//destroy the child entities, too
if(AttachUtils.hasChildren(entity)){
List<Entity> children = AttachUtils.getChildrenList(entity);
for(Entity child : children){
ClientEntityUtils.destroyEntity(child);
}
}
//check for client-specific stuff
Globals.renderingEngine.getLightManager().destroyPointLight(entity);
//deregister all behavior trees
EntityUtils.cleanUpEntity(entity);
}
//check for client-specific stuff
Globals.renderingEngine.getLightManager().destroyPointLight(entity);
//deregister all behavior trees
EntityUtils.cleanUpEntity(entity);
}

View File

@ -259,6 +259,8 @@ public class EntityDataStrings {
public static final String TREE_CLIENTEQUIPSTATE = "treeClientEquipState";
public static final String EQUIP_INVENTORY = "equipInventory";
public static final String TREE_SERVEREQUIPSTATE = "treeServerEquipState";
public static final String TREE_CLIENTTOOLBARSTATE = "treeClientToolbarState";
public static final String TREE_SERVERTOOLBARSTATE = "treeServerToolbarState";
/*
Client-only components

View File

@ -85,11 +85,10 @@ public class ClientEquipState implements BehaviorTree {
public void commandAttemptEquip(Entity toEquip, EquipPoint point){
boolean hasEquipped = hasEquippedAtPoint(point.getEquipPointId());
boolean targetIsItem = ItemUtils.isItem(toEquip);
boolean targetIsAttached = AttachUtils.isAttached(toEquip);
String equipItemClass = ItemUtils.getEquipClass(toEquip);
List<String> pointEquipClassList = point.getEquipClassWhitelist();
boolean itemIsInPointWhitelist = pointEquipClassList.contains(equipItemClass);
if(!hasEquipped && targetIsItem && !targetIsAttached && itemIsInPointWhitelist){
if(!hasEquipped && targetIsItem && itemIsInPointWhitelist){
//send packet to server requesting to equip
String pointName = point.getEquipPointId();
int serverSideID = Globals.clientSceneWrapper.mapClientToServerId(toEquip.getId());

View File

@ -0,0 +1,323 @@
package electrosphere.entity.state.equip;
import electrosphere.entity.btree.BehaviorTree;
import electrosphere.entity.state.attach.AttachUtils;
import electrosphere.entity.state.client.firstPerson.FirstPersonTree;
import electrosphere.entity.state.gravity.GravityUtils;
import electrosphere.entity.state.inventory.InventoryUtils;
import electrosphere.entity.state.inventory.RelationalInventoryState;
import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.entity.types.item.ItemUtils;
import electrosphere.game.data.common.treedata.TreeDataAnimation;
import electrosphere.game.data.creature.type.equip.EquipPoint;
import electrosphere.game.data.creature.type.equip.ToolbarData;
import electrosphere.game.data.item.type.EquipWhitelist;
import electrosphere.game.data.item.type.Item;
import java.util.List;
import electrosphere.collision.PhysicsEntityUtils;
import electrosphere.engine.Globals;
import electrosphere.entity.ClientEntityUtils;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityCreationUtils;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityTags;
import electrosphere.entity.EntityUtils;
import electrosphere.net.synchronization.enums.BehaviorTreeIdEnums;
import electrosphere.renderer.actor.Actor;
import electrosphere.renderer.actor.ActorMeshMask;
import electrosphere.net.parser.net.message.InventoryMessage;
import electrosphere.net.parser.net.message.NetworkMessage;
import electrosphere.net.synchronization.annotation.SyncedField;
import electrosphere.net.synchronization.annotation.SynchronizedBehaviorTree;
/**
* The state of the toolbar on the client's side
*/
@SynchronizedBehaviorTree(name = "clientToolbarState", isServer = false, correspondingTree="serverToolbarState")
public class ClientToolbarState implements BehaviorTree {
/**
* The selected toolbar slot
*/
@SyncedField
int selectedSlot;
/**
* The parent entity
*/
Entity parent;
/**
* The toolbar data
*/
ToolbarData toolbarData;
/**
* The equipped entity
*/
Entity equippedEntity = null;
/**
* Attempts to add an item to the toolbar
* @param item The item
*/
public void attemptAddToToolbar(Entity item, int toolbarSlot){
if(item != null){
NetworkMessage requestUnequipMessage = InventoryMessage.constructclientRequestAddToolbarMessage(Globals.clientSceneWrapper.mapClientToServerId(item.getId()), toolbarSlot);
Globals.clientConnection.queueOutgoingMessage(requestUnequipMessage);
}
}
/**
* Performs the actual logic to term meshes on/off when equpping an item
* @param toEquip The entity to equip
*/
public void attemptEquip(Entity toEquip){
RelationalInventoryState equipInventoryState = InventoryUtils.getEquipInventory(parent);
boolean targetHasWhitelist = ItemUtils.hasEquipList(toEquip);
String equipItemClass = ItemUtils.getEquipClass(toEquip);
EquipPoint targetPoint = equipInventoryState.getEquipPointFromSlot(toolbarData.getPrimarySlot());
if(targetPoint.getEquipClassWhitelist() != null && !targetPoint.getEquipClassWhitelist().contains(equipItemClass)){
targetPoint = equipInventoryState.getEquipPointFromSlot(toolbarData.getCombinedSlot());
}
equippedEntity = toEquip;
//
//visual transforms
if(targetHasWhitelist){
//depends on the type of creature, must be replacing a mesh
String parentCreatureId = CreatureUtils.getType(parent);
List<EquipWhitelist> whitelist = ItemUtils.getEquipWhitelist(toEquip);
for(EquipWhitelist whitelistItem : whitelist){
if(whitelistItem.getCreatureId().equals(parentCreatureId)){
//put in map
String modelName = whitelistItem.getModel();
Globals.assetManager.addModelPathToQueue(modelName);
Actor parentActor = EntityUtils.getActor(parent);
//queue meshes from display model to parent actor
ActorMeshMask meshMask = parentActor.getMeshMask();
for(String toBlock : whitelistItem.getMeshMaskList()){
meshMask.blockMesh(modelName, toBlock);
}
for(String toDraw : whitelistItem.getMeshList()){
meshMask.queueMesh(modelName, toDraw);
}
//attach to parent bone
if(parent != Globals.firstPersonEntity || Globals.controlHandler.cameraIsThirdPerson()){
AttachUtils.clientAttachEntityToEntityAtBone(
parent,
toEquip,
targetPoint.getBone(),
AttachUtils.getEquipPointVectorOffset(targetPoint.getOffsetVectorThirdPerson()),
AttachUtils.getEquipPointRotationOffset(targetPoint.getOffsetRotationThirdPerson())
);
} else {
AttachUtils.clientAttachEntityToEntityAtBone(
Globals.firstPersonEntity,
toEquip,
targetPoint.getFirstPersonBone(),
AttachUtils.getEquipPointVectorOffset(targetPoint.getOffsetVectorFirstPerson()),
AttachUtils.getEquipPointRotationOffset(targetPoint.getOffsetRotationFirstPerson())
);
}
//make uncollidable
if(PhysicsEntityUtils.containsDBody(toEquip) && toEquip.containsKey(EntityDataStrings.PHYSICS_COLLIDABLE)){
Globals.clientSceneWrapper.getCollisionEngine().destroyPhysics(toEquip);
}
//make untargetable
Globals.clientSceneWrapper.getScene().removeEntityFromTag(toEquip, EntityTags.TARGETABLE);
break;
}
}
} else {
//does not depend on the type of creature, must be attaching to a bone
//make sure it's visible
if(EntityUtils.getActor(toEquip) == null){
Item itemData = Globals.gameConfigCurrent.getItemMap().getItem(ItemUtils.getType(toEquip));
EntityCreationUtils.makeEntityDrawable(toEquip, itemData.getGraphicsTemplate().getModel().getPath());
if(itemData.getIdleAnim() != null){
toEquip.putData(EntityDataStrings.ANIM_IDLE,itemData.getIdleAnim());
}
}
//actually equip
if(parent != Globals.firstPersonEntity || Globals.controlHandler.cameraIsThirdPerson()){
AttachUtils.clientAttachEntityToEntityAtBone(
parent,
toEquip,
targetPoint.getBone(),
AttachUtils.getEquipPointVectorOffset(targetPoint.getOffsetVectorThirdPerson()),
AttachUtils.getEquipPointRotationOffset(targetPoint.getOffsetRotationThirdPerson())
);
} else {
AttachUtils.clientAttachEntityToEntityAtBone(
Globals.firstPersonEntity,
toEquip,
targetPoint.getFirstPersonBone(),
AttachUtils.getEquipPointVectorOffset(targetPoint.getOffsetVectorFirstPerson()),
AttachUtils.getEquipPointRotationOffset(targetPoint.getOffsetRotationFirstPerson())
);
}
if(PhysicsEntityUtils.containsDBody(toEquip) && toEquip.containsKey(EntityDataStrings.PHYSICS_COLLIDABLE)){
Globals.clientSceneWrapper.getCollisionEngine().destroyPhysics(toEquip);
}
Globals.clientSceneWrapper.getScene().removeEntityFromTag(toEquip, EntityTags.TARGETABLE);
GravityUtils.clientAttemptDeactivateGravity(toEquip);
}
}
/**
* Performs the actual logic to turn meshes on/off when unequipping an item
* @param pointId The equipment point to unequip
*/
public void unequip(String pointId){
if(this.equippedEntity != null){
boolean targetHasWhitelist = ItemUtils.hasEquipList(this.equippedEntity);
RelationalInventoryState equipInventoryState = InventoryUtils.getEquipInventory(parent);
String equipItemClass = ItemUtils.getEquipClass(this.equippedEntity);
EquipPoint targetPoint = equipInventoryState.getEquipPointFromSlot(toolbarData.getPrimarySlot());
if(targetPoint.getEquipClassWhitelist() != null && !targetPoint.getEquipClassWhitelist().contains(equipItemClass)){
targetPoint = equipInventoryState.getEquipPointFromSlot(toolbarData.getCombinedSlot());
}
//
//visual transforms
if(targetHasWhitelist){
//depends on the type of creature, must be replacing meshes
String parentCreatureId = CreatureUtils.getType(parent);
List<EquipWhitelist> whitelist = ItemUtils.getEquipWhitelist(this.equippedEntity);
for(EquipWhitelist whitelistItem : whitelist){
if(whitelistItem.getCreatureId().equals(parentCreatureId)){
//put in map
Actor parentActor = EntityUtils.getActor(parent);
//queue meshes from display model to parent actor
ActorMeshMask meshMask = parentActor.getMeshMask();
for(String toUnblock : whitelistItem.getMeshMaskList()){
meshMask.unblockMesh(toUnblock);
}
for(String toDraw : whitelistItem.getMeshList()){
meshMask.removeAdditionalMesh(toDraw);
}
break;
}
}
} else {
//does not depend on the type of creature
AttachUtils.clientDetatchEntityFromEntityAtBone(parent, this.equippedEntity);
ClientEntityUtils.destroyEntity(this.equippedEntity);
}
//interrupt animation
if(targetPoint != null){
Actor thirdPersonActor = EntityUtils.getActor(parent);
if(targetPoint.getEquippedAnimation() != null){
TreeDataAnimation animation = targetPoint.getEquippedAnimation();
//play third person
if(thirdPersonActor.isPlayingAnimation() && thirdPersonActor.isPlayingAnimation(animation)){
if(animation != null){
thirdPersonActor.interruptAnimation(animation,true);
}
thirdPersonActor.incrementAnimationTime(0.0001);
}
//play first person
FirstPersonTree.conditionallyInterruptAnimation(parent, animation);
}
}
}
}
/**
* Gets the current primary item if it exists, null otherwise
* @return The item
*/
public Entity getCurrentPrimaryItem(){
return this.equippedEntity;
}
/**
* <p> (initially) Automatically generated </p>
* <p>
* Attaches this tree to the entity.
* </p>
* @param entity The entity to attach to
* @param tree The behavior tree to attach
* @param params Optional parameters that will be provided to the constructor
*/
public static ClientToolbarState attachTree(Entity parent, Object ... params){
ClientToolbarState rVal = new ClientToolbarState(parent,params);
//!!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_CLIENTTOOLBARSTATE, rVal);
Globals.clientSceneWrapper.getScene().registerBehaviorTree(rVal);
Globals.entityValueTrackingService.attachTreeToEntity(parent, BehaviorTreeIdEnums.BTREE_CLIENTTOOLBARSTATE_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_CLIENTTOOLBARSTATE_ID);
}
/**
* <p> (initially) Automatically generated </p>
* <p> Private constructor to enforce using the attach methods </p>
* <p>
* Constructor
* </p>
* @param parent The parent entity of this tree
* @param params Optional parameters that can be provided when attaching the tree. All custom data required for creating this tree should be passed in this varargs.
*/
private ClientToolbarState(Entity parent, Object ... params){
this.parent = parent;
this.toolbarData = (ToolbarData)params[0];
}
/**
* <p>
* Gets the ClientToolbarState of the entity
* </p>
* @param entity the entity
* @return The ClientToolbarState
*/
public static ClientToolbarState getClientToolbarState(Entity entity){
return (ClientToolbarState)entity.getData(EntityDataStrings.TREE_CLIENTTOOLBARSTATE);
}
/**
* <p> Automatically generated </p>
* <p>
* Sets selectedSlot and handles the synchronization logic for it.
* </p>
* @param selectedSlot The value to set selectedSlot to.
*/
public void setSelectedSlot(int selectedSlot){
this.selectedSlot = selectedSlot;
}
/**
* <p> Automatically generated </p>
* <p>
* Gets selectedSlot.
* </p>
*/
public int getSelectedSlot(){
return selectedSlot;
}
@Override
public void simulate(float deltaTime) {
}
}

View File

@ -74,11 +74,10 @@ public class ServerEquipState implements BehaviorTree {
public void commandAttemptEquip(Entity toEquip, EquipPoint point){
boolean hasEquipped = hasEquippedAtPoint(point.getEquipPointId());
boolean targetIsItem = ItemUtils.isItem(toEquip);
boolean targetIsAttached = AttachUtils.isAttached(toEquip);
String equipItemClass = ItemUtils.getEquipClass(toEquip);
List<String> pointEquipClassList = point.getEquipClassWhitelist();
boolean itemIsInPointWhitelist = pointEquipClassList.contains(equipItemClass);
if(!hasEquipped && targetIsItem && !targetIsAttached && itemIsInPointWhitelist){
if(!hasEquipped && targetIsItem && itemIsInPointWhitelist){
serverAttemptEquip(toEquip, point);
}
}
@ -162,14 +161,21 @@ public class ServerEquipState implements BehaviorTree {
//get the parent (typically creature) that contains the in-inventory item
Entity containingEntity = ItemUtils.getContainingParent(inInventoryEntity);
//actually switch containers
boolean parentHasNaturalInventory = InventoryUtils.hasNaturalInventory(parent);
boolean parentHasEquipInventory = InventoryUtils.hasEquipInventory(parent);
//make sure the switch is possible
if(parentHasEquipInventory && parentHasNaturalInventory){
//actually switch containers
if(InventoryUtils.hasNaturalInventory(parent)){
UnrelationalInventoryState naturalInventory = InventoryUtils.getNaturalInventory(parent);
RelationalInventoryState equipInventory = InventoryUtils.getEquipInventory(parent);
naturalInventory.removeItem(inInventoryEntity);
}
if(InventoryUtils.hasToolbarInventory(parent)){
RelationalInventoryState toolbarInventory = InventoryUtils.getToolbarInventory(parent);
if(ServerToolbarState.getServerToolbarState(parent) != null){
ServerToolbarState serverToolbarState = ServerToolbarState.getServerToolbarState(parent);
serverToolbarState.unequip(inWorldItem);
}
toolbarInventory.tryRemoveItem(inInventoryEntity);
}
if(InventoryUtils.hasEquipInventory(parent)){
RelationalInventoryState equipInventory = InventoryUtils.getEquipInventory(parent);
equipInventory.tryRemoveItem(inInventoryEntity);
equipInventory.addItem(point.getEquipPointId(), inInventoryEntity);
}
//if they're a player, let the player know that the item has moved container
@ -192,7 +198,13 @@ public class ServerEquipState implements BehaviorTree {
int equipperId = parent.getId();
String equipPointId = point.getEquipPointId();
int inWorldItemId = inWorldItem.getId();
NetworkMessage attachMessage = InventoryMessage.constructserverCommandEquipItemMessage(equipperId, equipPointId, inWorldItemId, itemType);
NetworkMessage attachMessage = InventoryMessage.constructserverCommandEquipItemMessage(
equipperId,
InventoryProtocol.INVENTORY_TYPE_EQUIP,
equipPointId,
inWorldItemId,
itemType
);
//actually send the packet
dataCell.broadcastNetworkMessage(attachMessage);
@ -282,7 +294,8 @@ public class ServerEquipState implements BehaviorTree {
public void serverAttemptUnequip(String pointId){
boolean hasNaturalInventory = InventoryUtils.hasNaturalInventory(parent);
boolean hasEquipInventory = InventoryUtils.hasEquipInventory(parent);
if(hasEquipInventory && hasNaturalInventory){
boolean hasEquipped = hasEquippedAtPoint(pointId);
if(hasEquipped && hasEquipInventory && hasNaturalInventory){
UnrelationalInventoryState naturalInventory = InventoryUtils.getNaturalInventory(parent);
RelationalInventoryState equipInventory = InventoryUtils.getEquipInventory(parent);
//switch the inventory it's under
@ -295,7 +308,7 @@ public class ServerEquipState implements BehaviorTree {
//get datacell
ServerDataCell dataCell = DataCellSearchUtils.getEntityDataCell(parent);
//broadcast attach entity
NetworkMessage unequipMessage = InventoryMessage.constructserverCommandUnequipItemMessage(parent.getId(), pointId);
NetworkMessage unequipMessage = InventoryMessage.constructserverCommandUnequipItemMessage(parent.getId(), InventoryProtocol.INVENTORY_TYPE_EQUIP, pointId);
//actually send the packet
dataCell.broadcastNetworkMessage(unequipMessage);
//if the parent is a player entity, tell the player about the updated inventory stuff
@ -312,14 +325,6 @@ public class ServerEquipState implements BehaviorTree {
controllerPlayer.addMessage(inventoryMessage);
}
}
// if(ItemUtils.getRealWorldEntity(item) != null){
// ItemUtils.destroyInWorldItem(ItemUtils.getRealWorldEntity(item));
// }
// // eject from equip state
// InventoryUtils.attemptDestroyItem(Globals.playerEntity,item);
// // add to unrelational
// sourceInventory.tryRemoveItem(item);
// inventory.addItem(item);
}
/**

View File

@ -0,0 +1,373 @@
package electrosphere.entity.state.equip;
import electrosphere.entity.btree.BehaviorTree;
import electrosphere.entity.state.attach.AttachUtils;
import electrosphere.entity.state.block.ServerBlockTree;
import electrosphere.entity.state.gravity.GravityUtils;
import electrosphere.entity.state.inventory.InventoryUtils;
import electrosphere.entity.state.inventory.RelationalInventoryState;
import electrosphere.entity.state.inventory.UnrelationalInventoryState;
import electrosphere.entity.types.creature.CreatureUtils;
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.ToolbarData;
import electrosphere.game.data.item.type.EquipWhitelist;
import electrosphere.logger.LoggerInterface;
import java.util.List;
import org.joml.Vector3d;
import electrosphere.collision.PhysicsEntityUtils;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityDataStrings;
import electrosphere.entity.EntityTags;
import electrosphere.entity.ServerEntityUtils;
import electrosphere.net.synchronization.enums.FieldIdEnums;
import electrosphere.server.datacell.Realm;
import electrosphere.server.datacell.ServerDataCell;
import electrosphere.server.datacell.utils.DataCellSearchUtils;
import electrosphere.net.parser.net.message.InventoryMessage;
import electrosphere.net.parser.net.message.NetworkMessage;
import electrosphere.net.parser.net.message.SynchronizationMessage;
import electrosphere.net.server.player.Player;
import electrosphere.net.server.protocol.InventoryProtocol;
import electrosphere.net.synchronization.enums.BehaviorTreeIdEnums;
import electrosphere.server.datacell.utils.ServerBehaviorTreeUtils;
import electrosphere.server.datacell.utils.ServerEntityTagUtils;
import electrosphere.server.utils.ServerScriptUtils;
import electrosphere.net.synchronization.annotation.SyncedField;
import electrosphere.net.synchronization.annotation.SynchronizedBehaviorTree;
/**
* The server's toolbar state
*/
@SynchronizedBehaviorTree(name = "serverToolbarState", isServer = true, correspondingTree="clientToolbarState")
public class ServerToolbarState implements BehaviorTree {
/**
* The selected toolbar slot
*/
@SyncedField
int selectedSlot;
/**
* The parent
*/
Entity parent;
/**
* The toolbar data
*/
ToolbarData toolbarData;
/**
* The real world item
*/
Entity realWorldItem = null;
/**
* Attempts to add item to toolbar
* @param inInventoryEntity The item to equip
* @param point The point to equip to
*/
public void attemptEquip(Entity inInventoryEntity, int slotId){
RelationalInventoryState toolbarInventory = InventoryUtils.getToolbarInventory(parent);
RelationalInventoryState equipInventory = InventoryUtils.getEquipInventory(parent);
ServerEquipState serverEquipState = ServerEquipState.getEquipState(parent);
boolean hasEquipped = toolbarInventory.hasItemInSlot(slotId + "");
boolean targetIsItem = ItemUtils.isItem(inInventoryEntity);
if(!hasEquipped && targetIsItem){
//remove from equip state
if(equipInventory != null && equipInventory.containsItem(inInventoryEntity)){
serverEquipState.serverAttemptUnequip(equipInventory.getItemSlot(inInventoryEntity));
equipInventory.tryRemoveItem(inInventoryEntity);
}
//add to toolbar
toolbarInventory.tryRemoveItem(inInventoryEntity);
toolbarInventory.addItem(slotId + "", inInventoryEntity);
if(slotId == selectedSlot){
visuallyEquipCurrentSlot();
}
//if they're a player, let the player know that the item has moved container
if(CreatureUtils.hasControllerPlayerId(parent)){
//get player
int playerId = CreatureUtils.getControllerPlayerId(parent);
Player controllerPlayer = Globals.playerManager.getPlayerFromId(playerId);
//tell the player they don't have the item anymore
NetworkMessage inventoryMessage = InventoryMessage.constructserverCommandMoveItemContainerMessage(
inInventoryEntity.getId(),
InventoryProtocol.INVENTORY_TYPE_TOOLBAR,
slotId + ""
);
controllerPlayer.addMessage(inventoryMessage);
}
}
}
/**
* Visually updates what is equipped at the current slot
*/
public void visuallyEquipCurrentSlot(){
RelationalInventoryState toolbarInventory = InventoryUtils.getToolbarInventory(parent);
RelationalInventoryState equipInventoryState = InventoryUtils.getEquipInventory(parent);
Entity inInventoryEntity = toolbarInventory.getItemSlot(selectedSlot + "");
if(inInventoryEntity != null){
boolean targetHasWhitelist = ItemUtils.hasEquipList(inInventoryEntity);
String equipItemClass = ItemUtils.getEquipClass(inInventoryEntity);
//hydrate inventory item
String itemType = ItemUtils.getType(inInventoryEntity);
Realm realm = Globals.realmManager.getEntityRealm(parent);
realWorldItem = ItemUtils.serverSpawnBasicItem(realm,new Vector3d(0,0,0),itemType);
//bind in world with in inventory
ItemUtils.setRealWorldEntity(inInventoryEntity, realWorldItem);
EquipPoint targetPoint = equipInventoryState.getEquipPointFromSlot(toolbarData.getPrimarySlot());
if(targetPoint.getEquipClassWhitelist() != null && !targetPoint.getEquipClassWhitelist().contains(equipItemClass)){
targetPoint = equipInventoryState.getEquipPointFromSlot(toolbarData.getCombinedSlot());
}
//
//Visual transforms
if(targetHasWhitelist){
//depends on the type of creature
String parentCreatureId = CreatureUtils.getType(parent);
List<EquipWhitelist> whitelist = ItemUtils.getEquipWhitelist(realWorldItem);
for(EquipWhitelist whitelistItem : whitelist){
if(whitelistItem.getCreatureId().equals(parentCreatureId)){
//put in map
String modelName = whitelistItem.getModel();
Globals.assetManager.addModelPathToQueue(modelName);
//attach to parent bone
AttachUtils.serverAttachEntityToEntityAtBone(
parent,
realWorldItem,
targetPoint.getBone(),
AttachUtils.getEquipPointVectorOffset(targetPoint.getOffsetVectorThirdPerson()),
AttachUtils.getEquipPointRotationOffset(targetPoint.getOffsetRotationThirdPerson())
);
//make uncollidable
if(PhysicsEntityUtils.containsDBody(realWorldItem) && realWorldItem.containsKey(EntityDataStrings.PHYSICS_COLLIDABLE)){
Realm inWorldRealm = Globals.realmManager.getEntityRealm(realWorldItem);
inWorldRealm.getCollisionEngine().destroyPhysics(realWorldItem);
}
//make untargetable
ServerEntityTagUtils.removeTagFromEntity(realWorldItem, EntityTags.TARGETABLE);
break;
}
}
} else {
//does not depend on the type of creature
AttachUtils.serverAttachEntityToEntityAtBone(
parent,
realWorldItem,
targetPoint.getBone(),
AttachUtils.getEquipPointVectorOffset(targetPoint.getOffsetVectorThirdPerson()),
AttachUtils.getEquipPointRotationOffset(targetPoint.getOffsetRotationThirdPerson())
);
if(PhysicsEntityUtils.containsDBody(realWorldItem) && realWorldItem.containsKey(EntityDataStrings.PHYSICS_COLLIDABLE)){
Realm inWorldRealm = Globals.realmManager.getEntityRealm(realWorldItem);
inWorldRealm.getCollisionEngine().destroyPhysics(realWorldItem);
}
ServerEntityTagUtils.removeTagFromEntity(realWorldItem, EntityTags.TARGETABLE);
GravityUtils.serverAttemptDeactivateGravity(realWorldItem);
}
//
//update block state based on what we have equipped
this.updateBlockVariant();
//actually switch containers
boolean parentHasNaturalInventory = InventoryUtils.hasNaturalInventory(parent);
boolean parentHasEquipInventory = InventoryUtils.hasEquipInventory(parent);
//make sure the switch is possible
if(parentHasNaturalInventory){
UnrelationalInventoryState naturalInventory = InventoryUtils.getNaturalInventory(parent);
naturalInventory.removeItem(inInventoryEntity);
}
if(parentHasEquipInventory){
//actually switch containers
RelationalInventoryState equipInventory = InventoryUtils.getEquipInventory(parent);
equipInventory.tryRemoveItem(inInventoryEntity);
}
//get the chunk the equipper is in, and broadcast to that chunk that they equipped the item
//get datacell
ServerDataCell dataCell = DataCellSearchUtils.getEntityDataCell(parent);
//broadcast attach entity
int equipperId = parent.getId();
int inWorldItemId = realWorldItem.getId();
NetworkMessage attachMessage = InventoryMessage.constructserverCommandEquipItemMessage(
equipperId,
InventoryProtocol.INVENTORY_TYPE_TOOLBAR,
this.selectedSlot + "",
inWorldItemId,
itemType
);
//actually send the packet
dataCell.broadcastNetworkMessage(attachMessage);
//Fire signal to script engine to equip
ServerScriptUtils.fireSignalOnEntity(parent, "equipItem");
}
}
/**
* Updates the server block variant based on what item is equipped
*/
private void updateBlockVariant(){
ServerBlockTree blockTree = ServerBlockTree.getServerBlockTree(parent);
RelationalInventoryState toolbarInventory = InventoryUtils.getToolbarInventory(parent);
RelationalInventoryState equipInventoryState = InventoryUtils.getEquipInventory(parent);
Entity selectedItemEntity = toolbarInventory.getItemSlot(this.selectedSlot + "");
if(blockTree != null && selectedItemEntity != null){
String equipItemClass = ItemUtils.getEquipClass(selectedItemEntity);
EquipPoint targetPoint = equipInventoryState.getEquipPointFromSlot(toolbarData.getPrimarySlot());
if(!targetPoint.getEquipClassWhitelist().contains(equipItemClass)){
targetPoint = equipInventoryState.getEquipPointFromSlot(toolbarData.getCombinedSlot());
}
BlockSystem blockData = blockTree.getBlockSystem();
if(selectedItemEntity != null && Globals.gameConfigCurrent.getItemMap().getItem(selectedItemEntity) != null && Globals.gameConfigCurrent.getItemMap().getItem(selectedItemEntity).getItemBlockData() != null){
BlockVariant blockVariant = blockData.getVariantForPointWithItem(targetPoint.getEquipPointId(),ItemUtils.getEquipClass(selectedItemEntity));
//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
if(blockVariant != null){
blockTree.setCurrentBlockVariant(blockVariant.getVariantId());
} else {
LoggerInterface.loggerEngine.ERROR(new IllegalStateException("Equipped item to equip point that does not have assigned block variant!!"));
}
}
}
}
/**
* The item to unequip
* @param item The item
*/
public void unequip(Entity item){
if(item == this.realWorldItem){
removeVisuals();
}
if(ItemUtils.getRealWorldEntity(item) != null && ItemUtils.getRealWorldEntity(item) == this.realWorldItem){
removeVisuals();
}
}
/**
* Removes visuals for the currently equipped item if they exist
*/
public void removeVisuals(){
//destroy in world item
boolean targetHasWhitelist = ItemUtils.hasEquipList(this.realWorldItem);
//
//Visual transforms
if(targetHasWhitelist){
} else {
ServerEntityUtils.destroyEntity(this.realWorldItem);
}
//
//update block state based on what we have equipped
this.updateBlockVariant();
//tell all clients to unequip the world item
//get datacell
ServerDataCell dataCell = DataCellSearchUtils.getEntityDataCell(parent);
//broadcast attach entity
NetworkMessage unequipMessage = InventoryMessage.constructserverCommandUnequipItemMessage(parent.getId(), InventoryProtocol.INVENTORY_TYPE_TOOLBAR, "");
//actually send the packet
dataCell.broadcastNetworkMessage(unequipMessage);
}
/**
* <p> (initially) Automatically generated </p>
* <p>
* Attaches this tree to the entity.
* </p>
* @param entity The entity to attach to
* @param tree The behavior tree to attach
* @param params Optional parameters that will be provided to the constructor
*/
public static ServerToolbarState attachTree(Entity parent, Object ... params){
ServerToolbarState rVal = new ServerToolbarState(parent,params);
//!!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_SERVERTOOLBARSTATE, rVal);
Globals.entityValueTrackingService.attachTreeToEntity(parent, BehaviorTreeIdEnums.BTREE_SERVERTOOLBARSTATE_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_SERVERTOOLBARSTATE_ID);
}
/**
* <p> (initially) Automatically generated </p>
* <p> Private constructor to enforce using the attach methods </p>
* <p>
* Constructor
* </p>
* @param parent The parent entity of this tree
* @param params Optional parameters that can be provided when attaching the tree. All custom data required for creating this tree should be passed in this varargs.
*/
private ServerToolbarState(Entity parent, Object ... params){
this.parent = parent;
this.toolbarData = (ToolbarData)params[0];
}
/**
* <p>
* Gets the ServerToolbarState of the entity
* </p>
* @param entity the entity
* @return The ServerToolbarState
*/
public static ServerToolbarState getServerToolbarState(Entity entity){
return (ServerToolbarState)entity.getData(EntityDataStrings.TREE_SERVERTOOLBARSTATE);
}
/**
* <p> Automatically generated </p>
* <p>
* Sets selectedSlot and handles the synchronization logic for it.
* </p>
* @param selectedSlot The value to set selectedSlot to.
*/
public void setSelectedSlot(int selectedSlot){
this.selectedSlot = selectedSlot;
if(DataCellSearchUtils.getEntityDataCell(parent) != null){
DataCellSearchUtils.getEntityDataCell(parent).broadcastNetworkMessage(SynchronizationMessage.constructUpdateClientIntStateMessage(parent.getId(), BehaviorTreeIdEnums.BTREE_SERVERTOOLBARSTATE_ID, FieldIdEnums.TREE_SERVERTOOLBARSTATE_SYNCEDFIELD_SELECTEDSLOT_ID, selectedSlot));
}
}
/**
* <p> Automatically generated </p>
* <p>
* Gets selectedSlot.
* </p>
*/
public int getSelectedSlot(){
return selectedSlot;
}
@Override
public void simulate(float deltaTime) {
}
}

View File

@ -8,7 +8,7 @@ import electrosphere.entity.ClientEntityUtils;
import electrosphere.entity.Entity;
import electrosphere.entity.btree.BehaviorTree;
import electrosphere.entity.state.equip.ClientEquipState;
import electrosphere.entity.types.item.ItemUtils;
import electrosphere.entity.state.equip.ClientToolbarState;
import electrosphere.net.parser.net.message.InventoryMessage;
import electrosphere.net.server.protocol.InventoryProtocol;
@ -57,51 +57,94 @@ public class ClientInventoryState implements BehaviorTree {
switch(message.getcontainerType()){
case InventoryProtocol.INVENTORY_TYPE_EQUIP: {
Entity target = Globals.clientSceneWrapper.getEntityFromServerId(message.getentityId());
boolean isInventoryItem = ItemUtils.itemIsInInventory(target);
boolean parentHasNaturalInventory = InventoryUtils.hasNaturalInventory(parent);
boolean parentHasEquipInventory = InventoryUtils.hasEquipInventory(parent);
String equipPointId = message.getequipPointId();
//check that we can do the transform
if(isInventoryItem && parentHasEquipInventory && parentHasNaturalInventory){
//switch containers
if(InventoryUtils.hasNaturalInventory(parent)){
UnrelationalInventoryState naturalInventory = InventoryUtils.getNaturalInventory(parent);
RelationalInventoryState equipInventory = InventoryUtils.getEquipInventory(parent);
naturalInventory.removeItem(target);
}
if(InventoryUtils.hasEquipInventory(parent)){
RelationalInventoryState equipInventory = InventoryUtils.getEquipInventory(parent);
equipInventory.tryRemoveItem(target);
equipInventory.addItem(equipPointId, target);
}
if(ClientEquipState.getClientEquipState(parent) != null){
ClientEquipState clientEquipState = ClientEquipState.getClientEquipState(parent);
clientEquipState.attemptEquip(target, clientEquipState.getEquipPoint(equipPointId));
}
if(InventoryUtils.hasToolbarInventory(parent)){
RelationalInventoryState toolbarInventory = InventoryUtils.getToolbarInventory(parent);
toolbarInventory.tryRemoveItem(target);
}
} break;
case InventoryProtocol.INVENTORY_TYPE_NATURAL: {
Entity target = Globals.clientSceneWrapper.getEntityFromServerId(message.getentityId());
boolean isInventoryItem = ItemUtils.itemIsInInventory(target);
boolean parentHasNaturalInventory = InventoryUtils.hasNaturalInventory(parent);
boolean parentHasEquipInventory = InventoryUtils.hasEquipInventory(parent);
String equipPointId = message.getequipPointId();
//check that we can do the transform
if(isInventoryItem && parentHasEquipInventory && parentHasNaturalInventory){
//switch containers
if(InventoryUtils.hasNaturalInventory(parent)){
UnrelationalInventoryState naturalInventory = InventoryUtils.getNaturalInventory(parent);
RelationalInventoryState equipInventory = InventoryUtils.getEquipInventory(parent);
naturalInventory.removeItem(target);
naturalInventory.addItem(target);
equipInventory.removeItemSlot(equipPointId);
}
if(InventoryUtils.hasEquipInventory(parent)){
RelationalInventoryState equipInventory = InventoryUtils.getEquipInventory(parent);
if(ClientEquipState.getClientEquipState(parent) != null){
ClientEquipState clientEquipState = ClientEquipState.getClientEquipState(parent);
clientEquipState.clientTransformUnequipPoint(equipInventory.getItemSlot(target));
}
equipInventory.tryRemoveItem(target);
}
if(InventoryUtils.hasToolbarInventory(parent)){
RelationalInventoryState toolbarInventory = InventoryUtils.getToolbarInventory(parent);
toolbarInventory.tryRemoveItem(target);
}
} break;
case InventoryProtocol.INVENTORY_TYPE_TOOLBAR: {
throw new UnsupportedOperationException("todo");
Entity target = Globals.clientSceneWrapper.getEntityFromServerId(message.getentityId());
if(InventoryUtils.hasNaturalInventory(parent)){
UnrelationalInventoryState naturalInventory = InventoryUtils.getNaturalInventory(parent);
naturalInventory.removeItem(target);
}
if(InventoryUtils.hasEquipInventory(parent)){
RelationalInventoryState equipInventory = InventoryUtils.getEquipInventory(parent);
if(ClientEquipState.getClientEquipState(parent) != null){
ClientEquipState clientEquipState = ClientEquipState.getClientEquipState(parent);
clientEquipState.clientTransformUnequipPoint(equipInventory.getItemSlot(target));
}
equipInventory.tryRemoveItem(target);
}
if(InventoryUtils.hasToolbarInventory(parent)){
RelationalInventoryState toolbarInventory = InventoryUtils.getToolbarInventory(parent);
toolbarInventory.tryRemoveItem(target);
toolbarInventory.addItem("" + message.getequipPointId(), target);
}
}
}
//once we've switched the items around, redraw the inventory to reflect the updated contents
WindowUtils.attemptRedrawInventoryWindows();
} break;
case SERVERCOMMANDUNEQUIPITEM: {
if(Globals.playerEntity != null && ClientEquipState.hasEquipState(Globals.playerEntity)){
//unequip the item
ClientEquipState equipState = ClientEquipState.getEquipState(Globals.playerEntity);
Entity entityInSlot = equipState.getEquippedItemAtPoint(message.getequipPointId());
equipState.clientTransformUnequipPoint(message.getequipPointId());
//destroy the in-world manifestation of said item
ClientEntityUtils.destroyEntity(entityInSlot);
switch(message.getcontainerType()){
case InventoryProtocol.INVENTORY_TYPE_NATURAL: {
throw new UnsupportedOperationException("unsupported!");
}
case InventoryProtocol.INVENTORY_TYPE_EQUIP: {
if(ClientEquipState.hasEquipState(parent)){
//unequip the item
ClientEquipState equipState = ClientEquipState.getEquipState(parent);
Entity entityInSlot = equipState.getEquippedItemAtPoint(message.getequipPointId());
equipState.clientTransformUnequipPoint(message.getequipPointId());
//destroy the in-world manifestation of said item
ClientEntityUtils.destroyEntity(entityInSlot);
}
} break;
case InventoryProtocol.INVENTORY_TYPE_TOOLBAR: {
if(ClientToolbarState.getClientToolbarState(parent) != null){
ClientToolbarState clientToolbarState = ClientToolbarState.getClientToolbarState(parent);
clientToolbarState.unequip(message.getequipPointId());
}
} break;
}
} break;
case CLIENTREQUESTADDNATURAL:
case CLIENTREQUESTADDTOOLBAR:
case CLIENTREQUESTEQUIPITEM:
case CLIENTREQUESTUNEQUIPITEM:
case CLIENTREQUESTPERFORMITEMACTION:

View File

@ -9,6 +9,7 @@ import electrosphere.entity.EntityUtils;
import electrosphere.entity.ServerEntityUtils;
import electrosphere.entity.state.equip.ClientEquipState;
import electrosphere.entity.state.equip.ServerEquipState;
import electrosphere.entity.state.equip.ServerToolbarState;
import electrosphere.entity.state.gravity.GravityUtils;
import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.entity.types.item.ItemUtils;
@ -17,6 +18,7 @@ import electrosphere.net.parser.net.message.EntityMessage;
import electrosphere.net.parser.net.message.InventoryMessage;
import electrosphere.net.parser.net.message.NetworkMessage;
import electrosphere.net.server.player.Player;
import electrosphere.net.server.protocol.InventoryProtocol;
import electrosphere.server.datacell.Realm;
import electrosphere.server.datacell.ServerDataCell;
import electrosphere.server.datacell.utils.DataCellSearchUtils;
@ -203,6 +205,77 @@ public class InventoryUtils {
return null;
}
/**
* Perform the entity transforms to actually store an item in an inventory, if server this has the side effect of also sending packets on success
* @param creature The creature to store the item in
* @param item The item to store
* @return The in-inventory item
*/
public static Entity serverAddToNatural(Entity creature, Entity item){
boolean creatureIsCreature = CreatureUtils.isCreature(creature);
boolean itemIsItem = ItemUtils.isItem(item);
boolean hasInventory = hasNaturalInventory(creature);
//check if the item is already in an inventory
boolean itemIsInInventory = ItemUtils.itemIsInInventory(item);
if(creatureIsCreature && itemIsItem && hasInventory){
//get inventory
//for the moment we're just gonna get natural inventory
//later we'll need to search through all creature inventories to find the item
UnrelationalInventoryState inventory = getNaturalInventory(creature);
//destroy in-world entity and create in-inventory item
//we're doing this so that we're not constantly sending networking messages for invisible entities attached to the player
Entity inventoryItem = item;
boolean sendCreatePacket = false;
if(!itemIsInInventory){
sendCreatePacket = true;
inventoryItem = ItemUtils.serverRecreateContainerItem(item, creature);
ServerEntityUtils.destroyEntity(item);
}
if(InventoryUtils.hasEquipInventory(creature) && InventoryUtils.getEquipInventory(creature).containsItem(item)){
InventoryUtils.getEquipInventory(creature).tryRemoveItem(item);
}
if(InventoryUtils.hasToolbarInventory(creature) && InventoryUtils.getToolbarInventory(creature).containsItem(item)){
if(ServerToolbarState.getServerToolbarState(creature) != null){
ServerToolbarState serverToolbarState = ServerToolbarState.getServerToolbarState(creature);
serverToolbarState.unequip(item);
}
InventoryUtils.getToolbarInventory(creature).tryRemoveItem(item);
}
//store item in inventory
inventory.addItem(inventoryItem);
//set item containing parent
ItemUtils.setContainingParent(inventoryItem, creature);
//tell controlling player that they have an item in their inventory
if(CreatureUtils.hasControllerPlayerId(creature)){
//get the player
int controllerPlayerID = CreatureUtils.getControllerPlayerId(creature);
Player controllerPlayer = Globals.playerManager.getPlayerFromId(controllerPlayerID);
//send message
if(sendCreatePacket){
controllerPlayer.addMessage(InventoryMessage.constructaddItemToInventoryMessage(inventoryItem.getId(), ItemUtils.getType(inventoryItem)));
} else {
controllerPlayer.addMessage(InventoryMessage.constructserverCommandMoveItemContainerMessage(inventoryItem.getId(), InventoryProtocol.INVENTORY_TYPE_NATURAL, ""));
}
}
//alert script engine
ServerScriptUtils.fireSignalOnEntity(creature, "itemAddToNatural", item.getId(), inventoryItem.getId());
return inventoryItem;
}
return null;
}
/**
* Asks the server to add the item to the player's natural inventory
* @param item The item to store
*/
public static void clientAddToNatural(Entity item){
//tell the server we want to try the transform
NetworkMessage requestPickupMessage = InventoryMessage.constructclientRequestAddNaturalMessage(
Globals.clientSceneWrapper.mapClientToServerId(item.getId())
);
Globals.clientConnection.queueOutgoingMessage(requestPickupMessage);
}
/**
* Attempts to store the in-world item entity in a creature inventory container
* @param creature the creature which has a natural inventory
@ -217,17 +290,6 @@ public class InventoryUtils {
Globals.clientConnection.queueOutgoingMessage(requestPickupMessage);
}
/**
* Attempts to store the in-world item entity in a creature inventory container
* @param creature the creature which has a natural inventory
* @param item the in-world item entity to store
* @return The in-inventory entity if it succeeded, null otherwise
*/
public static Entity serverAttemptStoreItem(Entity creature, Entity item){
//immediately attempt the transform
return serverAttemptStoreItemTransform(creature,item);
}
/**
* Places an item of provided type in the parent container's natural inventory
* @param parentContainer The entity (typically a creature) which will receive the item in their natural inventory
@ -300,7 +362,7 @@ public class InventoryUtils {
//get closest chunk
ServerDataCell dataCell = realm.getEntityDataCellMapper().getEntityDataCell(realWorldItem);
//broadcast destroy item
NetworkMessage unequipMessage = InventoryMessage.constructserverCommandUnequipItemMessage(creature.getId(), inventorySlot);
NetworkMessage unequipMessage = InventoryMessage.constructserverCommandUnequipItemMessage(creature.getId(), InventoryProtocol.INVENTORY_TYPE_EQUIP, inventorySlot);
dataCell.broadcastNetworkMessage(unequipMessage);
}
//drop item

View File

@ -213,4 +213,13 @@ public class RelationalInventoryState {
return null;
}
/**
* Checks if this inventory contains this item
* @param item The item
* @return true if it is inside this inventory, false otherwise
*/
public boolean containsItem(Entity item){
return this.items.values().contains(item);
}
}

View File

@ -5,6 +5,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
import electrosphere.entity.Entity;
import electrosphere.entity.btree.BehaviorTree;
import electrosphere.entity.state.equip.ServerEquipState;
import electrosphere.entity.state.equip.ServerToolbarState;
import electrosphere.game.data.creature.type.equip.EquipPoint;
import electrosphere.net.parser.net.message.InventoryMessage;
import electrosphere.server.datacell.utils.EntityLookupUtils;
@ -35,13 +36,13 @@ public class ServerInventoryState implements BehaviorTree {
for(InventoryMessage message : networkMessageQueue){
networkMessageQueue.remove(message);
switch(message.getMessageSubtype()){
case ADDITEMTOINVENTORY:
InventoryUtils.serverAttemptStoreItem(parent, EntityLookupUtils.getEntityById(message.getentityId()));
break;
case REMOVEITEMFROMINVENTORY:
case ADDITEMTOINVENTORY: {
InventoryUtils.serverAttemptStoreItemTransform(parent, EntityLookupUtils.getEntityById(message.getentityId()));
} break;
case REMOVEITEMFROMINVENTORY: {
InventoryUtils.serverAttemptEjectItem(parent, EntityLookupUtils.getEntityById(message.getentityId()));
break;
case CLIENTREQUESTEQUIPITEM:{
} break;
case CLIENTREQUESTEQUIPITEM: {
//item to equip
Entity target = EntityLookupUtils.getEntityById(message.getentityId());
//perform transform if it makes sense
@ -52,7 +53,7 @@ public class ServerInventoryState implements BehaviorTree {
}
}
break;
case CLIENTREQUESTUNEQUIPITEM:{
case CLIENTREQUESTUNEQUIPITEM: {
//make sure can unequip
if(InventoryUtils.hasEquipInventory(parent) && InventoryUtils.hasNaturalInventory(parent) && ServerEquipState.hasEquipState(parent)){
ServerEquipState equipState = ServerEquipState.getEquipState(parent);
@ -62,8 +63,15 @@ public class ServerInventoryState implements BehaviorTree {
//tell player
}
}
}
break;
} break;
case CLIENTREQUESTADDNATURAL: {
InventoryUtils.serverAddToNatural(parent, EntityLookupUtils.getEntityById(message.getentityId()));
} break;
case CLIENTREQUESTADDTOOLBAR: {
Entity itemEnt = EntityLookupUtils.getEntityById(message.getentityId());
ServerToolbarState serverToolbarState = ServerToolbarState.getServerToolbarState(parent);
serverToolbarState.attemptEquip(itemEnt, message.gettoolbarId());
} break;
case CLIENTREQUESTPERFORMITEMACTION:
case SERVERCOMMANDUNEQUIPITEM:
case SERVERCOMMANDEQUIPITEM:

View File

@ -22,7 +22,9 @@ import electrosphere.entity.state.block.ClientBlockTree;
import electrosphere.entity.state.block.ServerBlockTree;
import electrosphere.entity.state.client.particle.ClientParticleEmitterComponent;
import electrosphere.entity.state.equip.ClientEquipState;
import electrosphere.entity.state.equip.ClientToolbarState;
import electrosphere.entity.state.equip.ServerEquipState;
import electrosphere.entity.state.equip.ServerToolbarState;
import electrosphere.entity.state.gravity.ClientGravityTree;
import electrosphere.entity.state.gravity.ServerGravityTree;
import electrosphere.entity.state.hitbox.HitboxCollectionState;
@ -281,6 +283,9 @@ public class CommonEntityUtils {
if(rawType.getEquipPoints() != null && rawType.getEquipPoints().size() > 0){
ClientEquipState.attachTree(entity, rawType.getEquipPoints());
InventoryUtils.setEquipInventory(entity, RelationalInventoryState.buildRelationalInventoryStateFromEquipList(rawType.getEquipPoints()));
}
if(rawType.getToolbarData() != null){
ClientToolbarState.attachTree(entity, rawType.getToolbarData());
InventoryUtils.setToolbarInventory(entity, RelationalInventoryState.buildToolbarInventory());
}
if(rawType.getBlockSystem() != null){
@ -557,6 +562,9 @@ public class CommonEntityUtils {
if(rawType.getEquipPoints() != null && rawType.getEquipPoints().size() > 0){
ServerEquipState.attachTree(entity, rawType.getEquipPoints());
InventoryUtils.setEquipInventory(entity, RelationalInventoryState.buildRelationalInventoryStateFromEquipList(rawType.getEquipPoints()));
}
if(rawType.getToolbarData() != null){
ServerToolbarState.attachTree(entity, rawType.getToolbarData());
InventoryUtils.setToolbarInventory(entity, RelationalInventoryState.buildToolbarInventory());
}

View File

@ -28,6 +28,11 @@ public class CreatureTemplate {
*/
private CreatureEquipData equipData = new CreatureEquipData();
/**
* The toolbar data for the creature
*/
private CreatureToolbarData toolbarData = new CreatureToolbarData();
/**
* The collection of synchronized values
*/
@ -87,6 +92,14 @@ public class CreatureTemplate {
return this.equipData;
}
/**
* Gets the toolbar data for the template
* @return The toolbar data for the template
*/
public CreatureToolbarData getCreatureToolbarData(){
return this.toolbarData;
}
/**
* Gets the state collection for the creature
* @return The collection of synchronized values

View File

@ -0,0 +1,92 @@
package electrosphere.entity.types.creature;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* The data about what is in the creature's toolbar
*/
public class CreatureToolbarData {
//Map of equip slot -> item definition
Map<String,ToolbarItem> slotToItemMap = new HashMap<String,ToolbarItem>();
/**
* Gets the slots in the equip data
* @return The set of equip slot ids
*/
public Set<String> getSlots(){
return slotToItemMap.keySet();
}
/**
* Gets the item occupying a given slot
* @param slotId The id of the slot
* @return The item definition
*/
public ToolbarItem getSlotItem(String slotId){
return slotToItemMap.get(slotId);
}
/**
* Sets a slot as containing an item type
* @param slotId The slot
* @param itemType The item definition
*/
public void setSlotItem(String slotId, ToolbarItem itemType){
slotToItemMap.put(slotId, itemType);
}
/**
* Clears the equip data
*/
public void clear(){
slotToItemMap.clear();
}
/**
* An item that is equipped
*/
public static class ToolbarItem {
/**
* The type of the item
*/
String itemType;
/**
* The entity id of the item
*/
int entityId;
/**
* Constructor
* @param entityId The id of the item entity
* @param itemType The type of the item
*/
public ToolbarItem(int entityId, String itemType){
this.entityId = entityId;
this.itemType = itemType;
}
/**
* The type of the item
* @return The type
*/
public String getItemType(){
return itemType;
}
/**
* The id of the entity that is this item
* @return The id
*/
public int getEntityId(){
return entityId;
}
}
}

View File

@ -14,13 +14,18 @@ import electrosphere.entity.btree.BehaviorTree;
import electrosphere.entity.state.attack.ClientAttackTree;
import electrosphere.entity.state.attack.ServerAttackTree;
import electrosphere.entity.state.client.firstPerson.FirstPersonTree;
import electrosphere.entity.state.equip.ClientEquipState;
import electrosphere.entity.state.equip.ClientToolbarState;
import electrosphere.entity.state.equip.ServerEquipState;
import electrosphere.entity.state.equip.ServerToolbarState;
import electrosphere.entity.state.idle.ClientIdleTree;
import electrosphere.entity.state.inventory.InventoryUtils;
import electrosphere.entity.state.movement.groundmove.ClientGroundMovementTree;
import electrosphere.entity.state.movement.groundmove.ServerGroundMovementTree;
import electrosphere.entity.types.EntityTypes.EntityType;
import electrosphere.entity.types.common.CommonEntityUtils;
import electrosphere.entity.types.creature.CreatureEquipData.EquippedItem;
import electrosphere.entity.types.creature.CreatureToolbarData.ToolbarItem;
import electrosphere.entity.types.item.ItemUtils;
import electrosphere.game.data.creature.type.CreatureData;
import electrosphere.game.data.creature.type.visualattribute.AttributeVariant;
@ -34,6 +39,7 @@ import electrosphere.net.synchronization.transport.StateCollection;
import electrosphere.renderer.actor.Actor;
import electrosphere.renderer.actor.ActorStaticMorph;
import electrosphere.server.datacell.Realm;
import electrosphere.server.datacell.utils.EntityLookupUtils;
import electrosphere.server.poseactor.PoseActor;
import electrosphere.util.Utilities;
@ -137,6 +143,50 @@ public class CreatureUtils {
return rVal;
}
/**
* Applies a creature template's item transforms to the creature (ie attaches items that should be attached)
* @param realm The realm
* @param creature The creature
* @param template The template
*/
public static void clientApplyTemplate(Entity creature, CreatureTemplate template){
//
//must happen after the player is attached to the entity, or server won't send packet to add item to player's entity
//now that creature has been spawned, need to create all attached items
if(template != null){
if(template.getCreatureEquipData() != null && template.getCreatureEquipData().getSlots() != null){
for(String equipSlotId : template.getCreatureEquipData().getSlots()){
//add the item to the creature's inventory
EquippedItem itemDefinition = template.getCreatureEquipData().getSlotItem(equipSlotId);
Entity itemInInventory = InventoryUtils.clientConstructInInventoryItem(creature,itemDefinition.getItemType());
//equip the item to the slot defined in the template
ClientEquipState clientEquipState = ClientEquipState.getEquipState(creature);
clientEquipState.attemptEquip(itemInInventory, clientEquipState.getEquipPoint(equipSlotId));
//map the constructed item to its server id
Globals.clientSceneWrapper.mapIdToId(itemInInventory.getId(), itemDefinition.getEntityId());
}
}
if(template.getCreatureToolbarData() != null && template.getCreatureToolbarData().getSlots() != null){
for(String equipSlotId : template.getCreatureToolbarData().getSlots()){
//add the item to the creature's inventory
ToolbarItem itemDefinition = template.getCreatureToolbarData().getSlotItem(equipSlotId);
Entity itemInInventory = InventoryUtils.clientConstructInInventoryItem(creature,itemDefinition.getItemType());
//equip the item to the slot defined in the template
ClientToolbarState clientToolbarState = ClientToolbarState.getClientToolbarState(creature);
clientToolbarState.attemptAddToToolbar(itemInInventory, Integer.parseInt(equipSlotId));
//map the constructed item to its server id
Globals.clientSceneWrapper.mapIdToId(itemInInventory.getId(), itemDefinition.getEntityId());
}
}
}
}
/**
* Spawns a server-side creature
@ -250,6 +300,50 @@ public class CreatureUtils {
return rVal;
}
/**
* Applies a creature template's item transforms to the creature (ie attaches items that should be attached)
* @param realm The realm
* @param creature The creature
* @param template The template
*/
public static void serverApplyTemplate(Realm realm, Entity creature, CreatureTemplate template){
//
//must happen after the player is attached to the entity, or server won't send packet to add item to player's entity
//now that creature has been spawned, need to create all attached items
if(template != null){
if(template.getCreatureEquipData() != null && template.getCreatureEquipData().getSlots() != null){
for(String equipSlotId : template.getCreatureEquipData().getSlots()){
//spawn the item in the world
EquippedItem itemDefinition = template.getCreatureEquipData().getSlotItem(equipSlotId);
Entity itemInWorld = ItemUtils.serverSpawnBasicItem(realm, EntityUtils.getPosition(creature), itemDefinition.getItemType());
//add the item to the creature's inventory
Entity itemInInventory = InventoryUtils.serverAttemptStoreItemTransform(creature, EntityLookupUtils.getEntityById(itemInWorld.getId()));
//equip the item to the slot defined in the template
ServerEquipState serverEquipState = ServerEquipState.getEquipState(creature);
serverEquipState.commandAttemptEquip(itemInInventory,serverEquipState.getEquipPoint(equipSlotId));
}
}
if(template.getCreatureToolbarData() != null && template.getCreatureToolbarData().getSlots() != null){
for(String equipSlotId : template.getCreatureToolbarData().getSlots()){
//spawn the item in the world
ToolbarItem itemDefinition = template.getCreatureToolbarData().getSlotItem(equipSlotId);
Entity itemInWorld = ItemUtils.serverSpawnBasicItem(realm, EntityUtils.getPosition(creature), itemDefinition.getItemType());
//add the item to the creature's inventory
Entity itemInInventory = InventoryUtils.serverAttemptStoreItemTransform(creature, EntityLookupUtils.getEntityById(itemInWorld.getId()));
//equip the item to the slot defined in the template
ServerToolbarState serverToolbarState = ServerToolbarState.getServerToolbarState(creature);
serverToolbarState.attemptEquip(itemInInventory, Integer.parseInt(equipSlotId));
}
}
}
}
/**
* Creates a viewmodel entity on the client side
* @param type The type of creature

View File

@ -14,6 +14,7 @@ import electrosphere.game.data.creature.type.attack.AttackMoveResolver;
import electrosphere.game.data.creature.type.block.BlockSystem;
import electrosphere.game.data.creature.type.bonegroups.BoneGroup;
import electrosphere.game.data.creature.type.equip.EquipPoint;
import electrosphere.game.data.creature.type.equip.ToolbarData;
import electrosphere.game.data.creature.type.movement.MovementSystem;
import electrosphere.game.data.creature.type.rotator.RotatorSystem;
import electrosphere.game.data.foliage.type.AmbientAudio;
@ -56,6 +57,11 @@ public class CommonEntityType {
*/
List<EquipPoint> equipPoints;
/**
* The data for the toolbar
*/
ToolbarData toolbarData;
/**
* The collidable used for this creature type
*/
@ -206,6 +212,14 @@ public class CommonEntityType {
return equipPoints;
}
/**
* Gets the toolbar data
* @return The toolbar data
*/
public ToolbarData getToolbarData(){
return toolbarData;
}
/**
* Sets the attack move resolver for this creature type
* @param resolver The resolver

View File

@ -67,6 +67,11 @@ public class EquipPoint {
*/
List<String> subPoints;
/**
* Controls whether this is a toolbar slot or an equipment slot
*/
boolean isToolbarSlot;
@ -215,5 +220,13 @@ public class EquipPoint {
public List<String> getSubPoints(){
return this.subPoints;
}
/**
* Gets whether this is a toolbar slot or not
* @return true for toolbar slot, false otherwise
*/
public boolean isToolbarSlot(){
return this.isToolbarSlot;
}
}

View File

@ -0,0 +1,34 @@
package electrosphere.game.data.creature.type.equip;
/**
* Data about the toolbar
*/
public class ToolbarData {
/**
* The id for the primary toolbar equip point
*/
String primarySlot;
/**
* The id for the combined toolbar equip point
*/
String combinedSlot;
/**
* Gets the id for the primary toolbar equip point
* @return The id for the primary toolbar equip point
*/
public String getPrimarySlot(){
return primarySlot;
}
/**
* Gets the id for the combined toolbar equip point
* @return The id for the combined toolbar equip point
*/
public String getCombinedSlot(){
return combinedSlot;
}
}

View File

@ -10,13 +10,10 @@ import electrosphere.engine.Globals;
import electrosphere.entity.ClientEntityUtils;
import electrosphere.entity.Entity;
import electrosphere.entity.state.attach.AttachUtils;
import electrosphere.entity.state.equip.ClientEquipState;
import electrosphere.entity.state.inventory.InventoryUtils;
import electrosphere.entity.state.physicssync.ClientPhysicsSyncTree;
import electrosphere.entity.types.EntityTypes;
import electrosphere.entity.types.EntityTypes.EntityType;
import electrosphere.entity.types.common.CommonEntityUtils;
import electrosphere.entity.types.creature.CreatureEquipData.EquippedItem;
import electrosphere.entity.types.creature.CreatureTemplate;
import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.entity.types.foliage.FoliageUtils;
@ -211,21 +208,7 @@ public class EntityProtocol implements ClientProtocolTemplate<EntityMessage> {
);
Globals.clientSceneWrapper.mapIdToId(newlySpawnedEntity.getId(), message.getentityID());
//if the creature template includes an equip section, spawn all the equipped items
if(template != null && template.getCreatureEquipData() != null && template.getCreatureEquipData().getSlots() != null){
for(String equipSlotId : template.getCreatureEquipData().getSlots()){
//add the item to the creature's inventory
EquippedItem itemDefinition = template.getCreatureEquipData().getSlotItem(equipSlotId);
Entity itemInInventory = InventoryUtils.clientConstructInInventoryItem(newlySpawnedEntity,itemDefinition.getItemType());
//equip the item to the slot defined in the template
ClientEquipState clientEquipState = ClientEquipState.getEquipState(newlySpawnedEntity);
clientEquipState.attemptEquip(itemInInventory, clientEquipState.getEquipPoint(equipSlotId));
//map the constructed item to its server id
Globals.clientSceneWrapper.mapIdToId(itemInInventory.getId(), itemDefinition.getEntityId());
}
}
CreatureUtils.clientApplyTemplate(newlySpawnedEntity, template);
//apply state synchronization if present
if(template != null && template.getStateCollection() != null && template.getStateCollection().getValues() != null){
StateCollection.applyStateCollection(newlySpawnedEntity, template.getStateCollection());

View File

@ -3,6 +3,7 @@ package electrosphere.net.client.protocol;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.state.equip.ClientEquipState;
import electrosphere.entity.state.equip.ClientToolbarState;
import electrosphere.entity.state.inventory.ClientInventoryState;
import electrosphere.entity.state.inventory.InventoryUtils;
import electrosphere.game.data.creature.type.equip.EquipPoint;
@ -41,14 +42,27 @@ public class InventoryProtocol implements ClientProtocolTemplate<InventoryMessag
if(inWorldEntity != null){
//translate id
Globals.clientSceneWrapper.mapIdToId(inWorldEntity.getId(), message.getentityId());
//grab equip state
ClientEquipState equipState = ClientEquipState.getEquipState(equipper);
//create entity from template in message
//get equippoint
String equipPointName = message.getequipPointId();
EquipPoint equipPoint = equipState.getEquipPoint(equipPointName);
//attach
equipState.attemptEquip(inWorldEntity, equipPoint);
switch(message.getcontainerType()){
case electrosphere.net.server.protocol.InventoryProtocol.INVENTORY_TYPE_NATURAL: {
throw new UnsupportedOperationException("unsupported!");
}
case electrosphere.net.server.protocol.InventoryProtocol.INVENTORY_TYPE_EQUIP: {
//grab equip state
ClientEquipState equipState = ClientEquipState.getEquipState(equipper);
//create entity from template in message
//get equippoint
String equipPointName = message.getequipPointId();
EquipPoint equipPoint = equipState.getEquipPoint(equipPointName);
//attach
equipState.attemptEquip(inWorldEntity, equipPoint);
}
case electrosphere.net.server.protocol.InventoryProtocol.INVENTORY_TYPE_TOOLBAR: {
//grab toolbar state
ClientToolbarState toolbarState = ClientToolbarState.getClientToolbarState(equipper);
//attach
toolbarState.attemptEquip(inWorldEntity);
}
}
}
}
break;
@ -80,6 +94,8 @@ public class InventoryProtocol implements ClientProtocolTemplate<InventoryMessag
}
}
break;
case CLIENTREQUESTADDNATURAL:
case CLIENTREQUESTADDTOOLBAR:
case CLIENTREQUESTPERFORMITEMACTION:
case CLIENTREQUESTUNEQUIPITEM:
case CLIENTREQUESTEQUIPITEM:

View File

@ -15,6 +15,8 @@ public class InventoryMessage extends NetworkMessage {
SERVERCOMMANDEQUIPITEM,
SERVERCOMMANDUNEQUIPITEM,
CLIENTREQUESTUNEQUIPITEM,
CLIENTREQUESTADDTOOLBAR,
CLIENTREQUESTADDNATURAL,
CLIENTREQUESTPERFORMITEMACTION,
}
@ -24,6 +26,7 @@ public class InventoryMessage extends NetworkMessage {
int entityId;
int equipperId;
int containerType;
int toolbarId;
int itemActionCode;
int itemActionCodeState;
@ -76,6 +79,14 @@ public class InventoryMessage extends NetworkMessage {
this.containerType = containerType;
}
public int gettoolbarId() {
return toolbarId;
}
public void settoolbarId(int toolbarId) {
this.toolbarId = toolbarId;
}
public int getitemActionCode() {
return itemActionCode;
}
@ -116,6 +127,18 @@ public class InventoryMessage extends NetworkMessage {
return InventoryMessage.canParseserverCommandUnequipItemMessage(byteBuffer);
case TypeBytes.INVENTORY_MESSAGE_TYPE_CLIENTREQUESTUNEQUIPITEM:
return InventoryMessage.canParseclientRequestUnequipItemMessage(byteBuffer);
case TypeBytes.INVENTORY_MESSAGE_TYPE_CLIENTREQUESTADDTOOLBAR:
if(byteBuffer.getRemaining() >= TypeBytes.INVENTORY_MESSAGE_TYPE_CLIENTREQUESTADDTOOLBAR_SIZE){
return true;
} else {
return false;
}
case TypeBytes.INVENTORY_MESSAGE_TYPE_CLIENTREQUESTADDNATURAL:
if(byteBuffer.getRemaining() >= TypeBytes.INVENTORY_MESSAGE_TYPE_CLIENTREQUESTADDNATURAL_SIZE){
return true;
} else {
return false;
}
case TypeBytes.INVENTORY_MESSAGE_TYPE_CLIENTREQUESTPERFORMITEMACTION:
return InventoryMessage.canParseclientRequestPerformItemActionMessage(byteBuffer);
}
@ -261,33 +284,36 @@ public class InventoryMessage extends NetworkMessage {
if(currentStreamLength < 6){
return false;
}
int equipPointIdSize = 0;
if(currentStreamLength < 10){
return false;
} else {
temporaryByteQueue.add(byteBuffer.peek(6 + 0));
temporaryByteQueue.add(byteBuffer.peek(6 + 1));
temporaryByteQueue.add(byteBuffer.peek(6 + 2));
temporaryByteQueue.add(byteBuffer.peek(6 + 3));
equipPointIdSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue);
}
if(currentStreamLength < 10 + equipPointIdSize){
int equipPointIdSize = 0;
if(currentStreamLength < 14){
return false;
} else {
temporaryByteQueue.add(byteBuffer.peek(10 + 0));
temporaryByteQueue.add(byteBuffer.peek(10 + 1));
temporaryByteQueue.add(byteBuffer.peek(10 + 2));
temporaryByteQueue.add(byteBuffer.peek(10 + 3));
equipPointIdSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue);
}
if(currentStreamLength < 14 + equipPointIdSize){
return false;
}
if(currentStreamLength < 18 + equipPointIdSize){
return false;
}
int itemTemplateSize = 0;
if(currentStreamLength < 18){
if(currentStreamLength < 22){
return false;
} else {
temporaryByteQueue.add(byteBuffer.peek(14 + equipPointIdSize + 0));
temporaryByteQueue.add(byteBuffer.peek(14 + equipPointIdSize + 1));
temporaryByteQueue.add(byteBuffer.peek(14 + equipPointIdSize + 2));
temporaryByteQueue.add(byteBuffer.peek(14 + equipPointIdSize + 3));
temporaryByteQueue.add(byteBuffer.peek(18 + equipPointIdSize + 0));
temporaryByteQueue.add(byteBuffer.peek(18 + equipPointIdSize + 1));
temporaryByteQueue.add(byteBuffer.peek(18 + equipPointIdSize + 2));
temporaryByteQueue.add(byteBuffer.peek(18 + equipPointIdSize + 3));
itemTemplateSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue);
}
if(currentStreamLength < 18 + equipPointIdSize + itemTemplateSize){
if(currentStreamLength < 22 + equipPointIdSize + itemTemplateSize){
return false;
}
return true;
@ -297,15 +323,17 @@ public class InventoryMessage extends NetworkMessage {
InventoryMessage rVal = new InventoryMessage(InventoryMessageType.SERVERCOMMANDEQUIPITEM);
stripPacketHeader(byteBuffer);
rVal.setequipperId(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
rVal.setcontainerType(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
rVal.setequipPointId(ByteStreamUtils.popStringFromByteQueue(byteBuffer));
rVal.setentityId(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
rVal.setitemTemplate(ByteStreamUtils.popStringFromByteQueue(byteBuffer));
return rVal;
}
public static InventoryMessage constructserverCommandEquipItemMessage(int equipperId,String equipPointId,int entityId,String itemTemplate){
public static InventoryMessage constructserverCommandEquipItemMessage(int equipperId,int containerType,String equipPointId,int entityId,String itemTemplate){
InventoryMessage rVal = new InventoryMessage(InventoryMessageType.SERVERCOMMANDEQUIPITEM);
rVal.setequipperId(equipperId);
rVal.setcontainerType(containerType);
rVal.setequipPointId(equipPointId);
rVal.setentityId(entityId);
rVal.setitemTemplate(itemTemplate);
@ -319,17 +347,20 @@ public class InventoryMessage extends NetworkMessage {
if(currentStreamLength < 6){
return false;
}
int equipPointIdSize = 0;
if(currentStreamLength < 10){
return false;
}
int equipPointIdSize = 0;
if(currentStreamLength < 14){
return false;
} else {
temporaryByteQueue.add(byteBuffer.peek(6 + 0));
temporaryByteQueue.add(byteBuffer.peek(6 + 1));
temporaryByteQueue.add(byteBuffer.peek(6 + 2));
temporaryByteQueue.add(byteBuffer.peek(6 + 3));
temporaryByteQueue.add(byteBuffer.peek(10 + 0));
temporaryByteQueue.add(byteBuffer.peek(10 + 1));
temporaryByteQueue.add(byteBuffer.peek(10 + 2));
temporaryByteQueue.add(byteBuffer.peek(10 + 3));
equipPointIdSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue);
}
if(currentStreamLength < 10 + equipPointIdSize){
if(currentStreamLength < 14 + equipPointIdSize){
return false;
}
return true;
@ -339,13 +370,15 @@ public class InventoryMessage extends NetworkMessage {
InventoryMessage rVal = new InventoryMessage(InventoryMessageType.SERVERCOMMANDUNEQUIPITEM);
stripPacketHeader(byteBuffer);
rVal.setequipperId(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
rVal.setcontainerType(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
rVal.setequipPointId(ByteStreamUtils.popStringFromByteQueue(byteBuffer));
return rVal;
}
public static InventoryMessage constructserverCommandUnequipItemMessage(int equipperId,String equipPointId){
public static InventoryMessage constructserverCommandUnequipItemMessage(int equipperId,int containerType,String equipPointId){
InventoryMessage rVal = new InventoryMessage(InventoryMessageType.SERVERCOMMANDUNEQUIPITEM);
rVal.setequipperId(equipperId);
rVal.setcontainerType(containerType);
rVal.setequipPointId(equipPointId);
rVal.serialize();
return rVal;
@ -384,6 +417,36 @@ public class InventoryMessage extends NetworkMessage {
return rVal;
}
public static InventoryMessage parseclientRequestAddToolbarMessage(CircularByteBuffer byteBuffer){
InventoryMessage rVal = new InventoryMessage(InventoryMessageType.CLIENTREQUESTADDTOOLBAR);
stripPacketHeader(byteBuffer);
rVal.setentityId(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
rVal.settoolbarId(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
return rVal;
}
public static InventoryMessage constructclientRequestAddToolbarMessage(int entityId,int toolbarId){
InventoryMessage rVal = new InventoryMessage(InventoryMessageType.CLIENTREQUESTADDTOOLBAR);
rVal.setentityId(entityId);
rVal.settoolbarId(toolbarId);
rVal.serialize();
return rVal;
}
public static InventoryMessage parseclientRequestAddNaturalMessage(CircularByteBuffer byteBuffer){
InventoryMessage rVal = new InventoryMessage(InventoryMessageType.CLIENTREQUESTADDNATURAL);
stripPacketHeader(byteBuffer);
rVal.setentityId(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
return rVal;
}
public static InventoryMessage constructclientRequestAddNaturalMessage(int entityId){
InventoryMessage rVal = new InventoryMessage(InventoryMessageType.CLIENTREQUESTADDNATURAL);
rVal.setentityId(entityId);
rVal.serialize();
return rVal;
}
public static boolean canParseclientRequestPerformItemActionMessage(CircularByteBuffer byteBuffer){
int currentStreamLength = byteBuffer.getRemaining();
List<Byte> temporaryByteQueue = new LinkedList<Byte>();
@ -505,7 +568,7 @@ public class InventoryMessage extends NetworkMessage {
}
break;
case SERVERCOMMANDEQUIPITEM:
rawBytes = new byte[2+4+4+equipPointId.length()+4+4+itemTemplate.length()];
rawBytes = new byte[2+4+4+4+equipPointId.length()+4+4+itemTemplate.length()];
//message header
rawBytes[0] = TypeBytes.MESSAGE_TYPE_INVENTORY;
//entity messaage header
@ -514,29 +577,33 @@ public class InventoryMessage extends NetworkMessage {
for(int i = 0; i < 4; i++){
rawBytes[2+i] = intValues[i];
}
intValues = ByteStreamUtils.serializeIntToBytes(equipPointId.length());
intValues = ByteStreamUtils.serializeIntToBytes(containerType);
for(int i = 0; i < 4; i++){
rawBytes[6+i] = intValues[i];
}
intValues = ByteStreamUtils.serializeIntToBytes(equipPointId.length());
for(int i = 0; i < 4; i++){
rawBytes[10+i] = intValues[i];
}
stringBytes = equipPointId.getBytes();
for(int i = 0; i < equipPointId.length(); i++){
rawBytes[10+i] = stringBytes[i];
rawBytes[14+i] = stringBytes[i];
}
intValues = ByteStreamUtils.serializeIntToBytes(entityId);
for(int i = 0; i < 4; i++){
rawBytes[10+equipPointId.length()+i] = intValues[i];
rawBytes[14+equipPointId.length()+i] = intValues[i];
}
intValues = ByteStreamUtils.serializeIntToBytes(itemTemplate.length());
for(int i = 0; i < 4; i++){
rawBytes[14+equipPointId.length()+i] = intValues[i];
rawBytes[18+equipPointId.length()+i] = intValues[i];
}
stringBytes = itemTemplate.getBytes();
for(int i = 0; i < itemTemplate.length(); i++){
rawBytes[18+equipPointId.length()+i] = stringBytes[i];
rawBytes[22+equipPointId.length()+i] = stringBytes[i];
}
break;
case SERVERCOMMANDUNEQUIPITEM:
rawBytes = new byte[2+4+4+equipPointId.length()];
rawBytes = new byte[2+4+4+4+equipPointId.length()];
//message header
rawBytes[0] = TypeBytes.MESSAGE_TYPE_INVENTORY;
//entity messaage header
@ -545,13 +612,17 @@ public class InventoryMessage extends NetworkMessage {
for(int i = 0; i < 4; i++){
rawBytes[2+i] = intValues[i];
}
intValues = ByteStreamUtils.serializeIntToBytes(equipPointId.length());
intValues = ByteStreamUtils.serializeIntToBytes(containerType);
for(int i = 0; i < 4; i++){
rawBytes[6+i] = intValues[i];
}
intValues = ByteStreamUtils.serializeIntToBytes(equipPointId.length());
for(int i = 0; i < 4; i++){
rawBytes[10+i] = intValues[i];
}
stringBytes = equipPointId.getBytes();
for(int i = 0; i < equipPointId.length(); i++){
rawBytes[10+i] = stringBytes[i];
rawBytes[14+i] = stringBytes[i];
}
break;
case CLIENTREQUESTUNEQUIPITEM:
@ -569,6 +640,32 @@ public class InventoryMessage extends NetworkMessage {
rawBytes[6+i] = stringBytes[i];
}
break;
case CLIENTREQUESTADDTOOLBAR:
rawBytes = new byte[2+4+4];
//message header
rawBytes[0] = TypeBytes.MESSAGE_TYPE_INVENTORY;
//entity messaage header
rawBytes[1] = TypeBytes.INVENTORY_MESSAGE_TYPE_CLIENTREQUESTADDTOOLBAR;
intValues = ByteStreamUtils.serializeIntToBytes(entityId);
for(int i = 0; i < 4; i++){
rawBytes[2+i] = intValues[i];
}
intValues = ByteStreamUtils.serializeIntToBytes(toolbarId);
for(int i = 0; i < 4; i++){
rawBytes[6+i] = intValues[i];
}
break;
case CLIENTREQUESTADDNATURAL:
rawBytes = new byte[2+4];
//message header
rawBytes[0] = TypeBytes.MESSAGE_TYPE_INVENTORY;
//entity messaage header
rawBytes[1] = TypeBytes.INVENTORY_MESSAGE_TYPE_CLIENTREQUESTADDNATURAL;
intValues = ByteStreamUtils.serializeIntToBytes(entityId);
for(int i = 0; i < 4; i++){
rawBytes[2+i] = intValues[i];
}
break;
case CLIENTREQUESTPERFORMITEMACTION:
rawBytes = new byte[2+4+equipPointId.length()+4+4];
//message header

View File

@ -312,6 +312,16 @@ COMBAT_MESSAGE,
rVal = InventoryMessage.parseclientRequestUnequipItemMessage(byteBuffer);
}
break;
case TypeBytes.INVENTORY_MESSAGE_TYPE_CLIENTREQUESTADDTOOLBAR:
if(InventoryMessage.canParseMessage(byteBuffer,secondByte)){
rVal = InventoryMessage.parseclientRequestAddToolbarMessage(byteBuffer);
}
break;
case TypeBytes.INVENTORY_MESSAGE_TYPE_CLIENTREQUESTADDNATURAL:
if(InventoryMessage.canParseMessage(byteBuffer,secondByte)){
rVal = InventoryMessage.parseclientRequestAddNaturalMessage(byteBuffer);
}
break;
case TypeBytes.INVENTORY_MESSAGE_TYPE_CLIENTREQUESTPERFORMITEMACTION:
if(InventoryMessage.canParseMessage(byteBuffer,secondByte)){
rVal = InventoryMessage.parseclientRequestPerformItemActionMessage(byteBuffer);

View File

@ -136,11 +136,15 @@ Message categories
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_CLIENTREQUESTUNEQUIPITEM = 6;
public static final byte INVENTORY_MESSAGE_TYPE_CLIENTREQUESTPERFORMITEMACTION = 7;
public static final byte INVENTORY_MESSAGE_TYPE_CLIENTREQUESTADDTOOLBAR = 7;
public static final byte INVENTORY_MESSAGE_TYPE_CLIENTREQUESTADDNATURAL = 8;
public static final byte INVENTORY_MESSAGE_TYPE_CLIENTREQUESTPERFORMITEMACTION = 9;
/*
Inventory packet sizes
*/
public static final byte INVENTORY_MESSAGE_TYPE_REMOVEITEMFROMINVENTORY_SIZE = 6;
public static final byte INVENTORY_MESSAGE_TYPE_CLIENTREQUESTADDTOOLBAR_SIZE = 10;
public static final byte INVENTORY_MESSAGE_TYPE_CLIENTREQUESTADDNATURAL_SIZE = 6;
/*
Synchronization subcategories
*/

View File

@ -61,7 +61,19 @@ public class InventoryProtocol implements ServerProtocolTemplate<InventoryMessag
break;
case CLIENTREQUESTPERFORMITEMACTION: {
PlayerActions.attemptPlayerAction(connectionHandler, message);
}
} break;
case CLIENTREQUESTADDTOOLBAR: {
target = EntityLookupUtils.getEntityById(connectionHandler.getPlayerEntityId());
if(target != null && InventoryUtils.hasToolbarInventory(target)){
InventoryUtils.serverGetInventoryState(target).addNetworkMessage(message);
}
} break;
case CLIENTREQUESTADDNATURAL: {
target = EntityLookupUtils.getEntityById(connectionHandler.getPlayerEntityId());
if(target != null && InventoryUtils.hasNaturalInventory(target)){
InventoryUtils.serverGetInventoryState(target).addNetworkMessage(message);
}
} break;
case SERVERCOMMANDUNEQUIPITEM:
case SERVERCOMMANDMOVEITEMCONTAINER:
case SERVERCOMMANDEQUIPITEM:

View File

@ -1,6 +1,8 @@
package electrosphere.net.synchronization.client;
import electrosphere.util.Utilities;
import electrosphere.entity.state.equip.ClientToolbarState;
import electrosphere.entity.state.stance.ClientStanceComponent;
import electrosphere.entity.state.movement.sprint.ClientSprintTree;
import electrosphere.entity.state.movement.jump.ClientJumpTree;
@ -179,6 +181,14 @@ public class ClientSynchronizationManager {
switch(message.getfieldId()){
}
} break;
case BehaviorTreeIdEnums.BTREE_SERVERTOOLBARSTATE_ID: {
switch(message.getfieldId()){
case FieldIdEnums.TREE_SERVERTOOLBARSTATE_SYNCEDFIELD_SELECTEDSLOT_ID:{
ClientToolbarState tree = ClientToolbarState.getClientToolbarState(entity);
tree.setSelectedSlot(message.getintValue());
} break;
}
} break;
case BehaviorTreeIdEnums.BTREE_SERVERGRAVITY_ID: {
switch(message.getfieldId()){
case FieldIdEnums.TREE_SERVERGRAVITY_SYNCEDFIELD_STATE_ID:{

View File

@ -10,7 +10,9 @@ public class BehaviorTreeIdEnums {
public static final int BTREE_CLIENTBLOCKTREE_ID = 2;
public static final int BTREE_SERVERBLOCKTREE_ID = 3;
public static final int BTREE_CLIENTEQUIPSTATE_ID = 4;
public static final int BTREE_CLIENTTOOLBARSTATE_ID = 22;
public static final int BTREE_SERVEREQUIPSTATE_ID = 5;
public static final int BTREE_SERVERTOOLBARSTATE_ID = 23;
public static final int BTREE_CLIENTGRAVITY_ID = 12;
public static final int BTREE_SERVERGRAVITY_ID = 7;
public static final int BTREE_IDLE_ID = 8;

View File

@ -15,6 +15,8 @@ public class FieldIdEnums {
public static final int TREE_CLIENTBLOCKTREE_SYNCEDFIELD_CURRENTBLOCKVARIANT_ID = 7;
public static final int TREE_SERVERBLOCKTREE_SYNCEDFIELD_STATE_ID = 8;
public static final int TREE_SERVERBLOCKTREE_SYNCEDFIELD_CURRENTBLOCKVARIANT_ID = 9;
public static final int TREE_CLIENTTOOLBARSTATE_SYNCEDFIELD_SELECTEDSLOT_ID = 30;
public static final int TREE_SERVERTOOLBARSTATE_SYNCEDFIELD_SELECTEDSLOT_ID = 31;
public static final int TREE_CLIENTGRAVITY_SYNCEDFIELD_STATE_ID = 16;
public static final int TREE_SERVERGRAVITY_SYNCEDFIELD_STATE_ID = 11;
public static final int TREE_IDLE_SYNCEDFIELD_STATE_ID = 12;

View File

@ -1,6 +1,9 @@
package electrosphere.net.synchronization.transport;
import electrosphere.util.Utilities;
import electrosphere.entity.state.equip.ServerToolbarState;
import electrosphere.entity.state.equip.ClientToolbarState;
import electrosphere.entity.state.stance.ServerStanceComponent;
import electrosphere.entity.state.stance.ClientStanceComponent;
import electrosphere.entity.state.movement.sprint.ServerSprintTree;
@ -79,6 +82,10 @@ public class StateCollection {
collection.setValue(new SynchronizedFieldValue(BehaviorTreeIdEnums.BTREE_SERVERBLOCKTREE_ID,FieldIdEnums.TREE_SERVERBLOCKTREE_SYNCEDFIELD_STATE_ID,ClientBlockTree.getBlockStateEnumAsShort(tree.getState())));
collection.setValue(new SynchronizedFieldValue(BehaviorTreeIdEnums.BTREE_SERVERBLOCKTREE_ID,FieldIdEnums.TREE_SERVERBLOCKTREE_SYNCEDFIELD_CURRENTBLOCKVARIANT_ID,tree.getCurrentBlockVariant()));
} break;
case BehaviorTreeIdEnums.BTREE_SERVERTOOLBARSTATE_ID: {
ServerToolbarState tree = ServerToolbarState.getServerToolbarState(entity);
collection.setValue(new SynchronizedFieldValue(BehaviorTreeIdEnums.BTREE_SERVERTOOLBARSTATE_ID,FieldIdEnums.TREE_SERVERTOOLBARSTATE_SYNCEDFIELD_SELECTEDSLOT_ID,tree.getSelectedSlot()));
} break;
case BehaviorTreeIdEnums.BTREE_SERVERGRAVITY_ID: {
ServerGravityTree tree = ServerGravityTree.getServerGravityTree(entity);
collection.setValue(new SynchronizedFieldValue(BehaviorTreeIdEnums.BTREE_SERVERGRAVITY_ID,FieldIdEnums.TREE_SERVERGRAVITY_SYNCEDFIELD_STATE_ID,ClientGravityTree.getGravityTreeStateEnumAsShort(tree.getState())));
@ -155,6 +162,14 @@ public class StateCollection {
} break;
}
} break;
case BehaviorTreeIdEnums.BTREE_SERVERTOOLBARSTATE_ID: {
ClientToolbarState tree = ClientToolbarState.getClientToolbarState(entity);
switch(syncedValue.getFieldId()){
case(FieldIdEnums.TREE_SERVERTOOLBARSTATE_SYNCEDFIELD_SELECTEDSLOT_ID): {
tree.setSelectedSlot(((Double)syncedValue.getValue()).intValue());
} break;
}
} break;
case BehaviorTreeIdEnums.BTREE_SERVERGRAVITY_ID: {
ClientGravityTree tree = ClientGravityTree.getClientGravityTree(entity);
switch(syncedValue.getFieldId()){

View File

@ -184,7 +184,27 @@ public class EquipmentInventoryPanel {
int itemId = i;
panel.setOnDragRelease(new DragEventCallback(){public boolean execute(DragEvent event){
if(Globals.dragSourceInventory instanceof RelationalInventoryState){
if(ItemUtils.getContainingParent(Globals.draggedItem) != Globals.playerEntity){
if(Globals.dragSourceInventory == InventoryUtils.getToolbarInventory(entity)){
if(inventory.canEquipItemToSlot(Globals.draggedItem, slots.get(itemId))){
//fire equip event to equip state
ClientEquipState equipState = ClientEquipState.getEquipState(Globals.playerEntity);
equipState.commandAttemptEquip(Globals.draggedItem,inventory.getEquipPointFromSlot(slots.get(itemId)));
//play sound effect
if(Globals.virtualAudioSourceManager != null){
Item itemData = Globals.gameConfigCurrent.getItemMap().getItem(ItemUtils.getType(finalEnt));
if(itemData != null && itemData.getItemAudio() != null && itemData.getItemAudio().getUIReleaseAudio() != null){
Globals.virtualAudioSourceManager.createVirtualAudioSource(itemData.getItemAudio().getUIReleaseAudio(), VirtualAudioSourceType.UI, false);
} else {
Globals.virtualAudioSourceManager.createVirtualAudioSource(AssetDataStrings.UI_SFX_ITEM_RELEASE, VirtualAudioSourceType.UI, false);
}
}
} else if(inventory.canEquipItemToCombinedSlot(Globals.draggedItem, slots.get(itemId))){
EquipPoint combinedPoint = inventory.getCombinedPoint(slots.get(itemId));
//fire equip event to equip state
ClientEquipState equipState = ClientEquipState.getEquipState(Globals.playerEntity);
equipState.commandAttemptEquip(Globals.draggedItem,combinedPoint);
}
} else if(ItemUtils.getContainingParent(Globals.draggedItem) != Globals.playerEntity){
throw new UnsupportedOperationException("Unimplemented!");
}
} else if(Globals.dragSourceInventory instanceof UnrelationalInventoryState){

View File

@ -182,7 +182,9 @@ public class NaturalInventoryPanel {
} else {
panel.setOnDragRelease(new DragEventCallback(){public boolean execute(DragEvent event){
if(Globals.dragSourceInventory instanceof RelationalInventoryState){
if(ClientEquipState.hasEquipState(entity) && InventoryUtils.hasEquipInventory(entity)){
if(Globals.dragSourceInventory == InventoryUtils.getToolbarInventory(entity)){
InventoryUtils.clientAddToNatural(Globals.draggedItem);
} else if(Globals.dragSourceInventory == InventoryUtils.getEquipInventory(entity)){
RelationalInventoryState equipInventory = InventoryUtils.getEquipInventory(entity);
ClientEquipState equipState = ClientEquipState.getEquipState(entity);
equipState.commandAttemptUnequip(equipInventory.getItemSlot(Globals.draggedItem));

View File

@ -72,6 +72,10 @@ public class PlayerInventoryWindow {
rVal.addChild(NaturalInventoryPanel.createNaturalInventoryPanel(entity));
}
if(InventoryUtils.hasToolbarInventory(entity)){
rVal.addChild(ToolbarInventoryPanel.createToolbarInventoryPanel(entity));
}
//
//Final setup
//

View File

@ -0,0 +1,225 @@
package electrosphere.renderer.ui.components;
import electrosphere.audio.VirtualAudioSourceManager.VirtualAudioSourceType;
import electrosphere.client.ui.menu.WindowStrings;
import electrosphere.client.ui.menu.WindowUtils;
import electrosphere.engine.Globals;
import electrosphere.engine.assetmanager.AssetDataStrings;
import electrosphere.engine.signal.Signal.SignalType;
import electrosphere.entity.Entity;
import electrosphere.entity.state.equip.ClientEquipState;
import electrosphere.entity.state.equip.ClientToolbarState;
import electrosphere.entity.state.inventory.InventoryUtils;
import electrosphere.entity.state.inventory.RelationalInventoryState;
import electrosphere.entity.state.inventory.UnrelationalInventoryState;
import electrosphere.entity.types.item.ItemUtils;
import electrosphere.game.data.item.type.Item;
import electrosphere.logger.LoggerInterface;
import electrosphere.renderer.ui.elements.Div;
import electrosphere.renderer.ui.elements.ImagePanel;
import electrosphere.renderer.ui.elements.Label;
import electrosphere.renderer.ui.elementtypes.ClickableElement.ClickEventCallback;
import electrosphere.renderer.ui.elementtypes.ContainerElement;
import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaAlignment;
import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaFlexDirection;
import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaJustification;
import electrosphere.renderer.ui.elementtypes.DraggableElement.DragEventCallback;
import electrosphere.renderer.ui.elementtypes.Element;
import electrosphere.renderer.ui.events.ClickEvent;
import electrosphere.renderer.ui.events.DragEvent;
/**
* Toolbar inventory panel
*/
public class ToolbarInventoryPanel {
/**
* Creates the toolbar inventory panel
* @param entity The entity who has the inventory
* @return The panel element
*/
public static Element createToolbarInventoryPanel(Entity entity){
RelationalInventoryState inventory = InventoryUtils.getToolbarInventory(entity);
Div div = Div.createDiv();
div.setJustifyContent(YogaJustification.Center);
div.setMarginBottom(25);
div.setMarginLeft(25);
div.setMarginRight(25);
div.setMarginTop(25);
div.setOnDragRelease(new DragEventCallback() {public boolean execute(DragEvent event){
LoggerInterface.loggerUI.INFO("Toolbar inventory received drag release event");
if(Globals.draggedItem != null){
if(Globals.dragSourceInventory != inventory){
if(Globals.dragSourceInventory instanceof RelationalInventoryState){
if(ClientEquipState.hasEquipState(entity) && InventoryUtils.hasEquipInventory(entity)){
RelationalInventoryState equipInventory = InventoryUtils.getEquipInventory(entity);
ClientEquipState equipState = ClientEquipState.getEquipState(entity);
equipState.commandAttemptUnequip(equipInventory.getItemSlot(Globals.draggedItem));
}
} if(Globals.dragSourceInventory instanceof UnrelationalInventoryState){
//transfer item
// sourceInventory.removeItem(Globals.draggedItem);
// inventory.addItem(Globals.draggedItem);
// //null out global state
// Globals.dragSourceInventory = null;
// Globals.draggedItem = null;
Entity item = Globals.draggedItem;
if(ClientEquipState.hasEquipState(entity) && InventoryUtils.hasEquipInventory(entity)){
RelationalInventoryState equipInventory = InventoryUtils.getEquipInventory(entity);
ClientEquipState equipState = ClientEquipState.getEquipState(entity);
equipState.commandAttemptUnequip(equipInventory.getItemSlot(item));
}
//clear item container ui
WindowUtils.cleanItemDraggingWindow();
//re-render inventory
WindowUtils.replaceWindow(WindowStrings.WINDOW_CHARACTER, PlayerInventoryWindow.createPlayerInventoryWindow(Globals.playerEntity));
}
}
}
//play sound effect
if(Globals.virtualAudioSourceManager != null){
Item itemData = Globals.gameConfigCurrent.getItemMap().getItem(ItemUtils.getType(Globals.draggedItem));
if(itemData.getItemAudio() != null && itemData.getItemAudio().getUIReleaseAudio() != null){
Globals.virtualAudioSourceManager.createVirtualAudioSource(itemData.getItemAudio().getUIReleaseAudio(), VirtualAudioSourceType.UI, false);
} else {
Globals.virtualAudioSourceManager.createVirtualAudioSource(AssetDataStrings.UI_SFX_ITEM_RELEASE, VirtualAudioSourceType.UI, false);
}
}
//clear ui
WindowUtils.cleanItemDraggingWindow();
//re-render inventory
WindowUtils.replaceWindow(WindowStrings.WINDOW_CHARACTER, PlayerInventoryWindow.createPlayerInventoryWindow(Globals.playerEntity));
return true;
}});
div.setOnClick(new ClickEventCallback() {public boolean execute(ClickEvent event){
WindowUtils.focusWindow(WindowStrings.WINDOW_MENU_INVENTORY);
return false;
}});
//label 1 (inventory)
Label menuTitle = Label.createLabel("TOOLBAR");
menuTitle.setMarginBottom(10);
div.addChild(menuTitle);
{
//contains all the item panels
Div panelContainer = Div.createDiv();
panelContainer.setFlexDirection(YogaFlexDirection.Row);
for(int i = 0; i < inventory.getSlots().size(); i++){
String texturePath = "Textures/ui/uiFrame1.png";
boolean hasItem = false;
Entity currentItem = null;
if(inventory.getItemSlot("" + i) != Globals.draggedItem && inventory.getItemSlot("" + i) != null){
currentItem = inventory.getItemSlot("" + i);
//get texture path from item
texturePath = ItemUtils.getItemIcon(currentItem);
//flag that this isn't an empty slot
hasItem = true;
}
Entity finalEnt = currentItem;
if(!Globals.assetManager.hasLoadedTexture(texturePath)){
Globals.assetManager.addTexturePathtoQueue(texturePath);
}
int panelWidth = 50;
int panelHeight = 50;
ImagePanel panel = ImagePanel.createImagePanel(texturePath);
panel.setMinWidth(panelWidth);
panel.setMinHeight(panelHeight);
panel.setMarginRight(15);
panel.setMarginBottom(15);
panel.setMarginLeft(15);
panel.setMarginTop(15);
panel.setAlignSelf(YogaAlignment.Start);
panel.setAbsolutePosition(false);
if(hasItem == true && inventory.getItemSlot("" + i) != Globals.draggedItem){
int itemId = i;
panel.setOnDragStart(new DragEventCallback() {public boolean execute(DragEvent event){
// System.out.println("Drag start");
Globals.dragSourceInventory = inventory;
Globals.draggedItem = inventory.getItemSlot("" + itemId);
ContainerElement container = (ContainerElement)panel.getParent();
container.removeChild(panel);
WindowUtils.pushItemIconToItemWindow(panel);
//set new flex values now that its in this item dragging window
panel.setAbsolutePosition(true);
panel.setPositionX(panel.getAbsoluteX());
panel.setPositionY(panel.getAbsoluteY());
WindowUtils.replaceWindow(WindowStrings.WINDOW_CHARACTER, PlayerInventoryWindow.createPlayerInventoryWindow(Globals.playerEntity));
//play sound effect
if(Globals.virtualAudioSourceManager != null){
Item itemData = Globals.gameConfigCurrent.getItemMap().getItem(ItemUtils.getType(finalEnt));
if(itemData.getItemAudio() != null && itemData.getItemAudio().getUIGrabAudio() != null){
Globals.virtualAudioSourceManager.createVirtualAudioSource(itemData.getItemAudio().getUIGrabAudio(), VirtualAudioSourceType.UI, false);
} else {
Globals.virtualAudioSourceManager.createVirtualAudioSource(AssetDataStrings.UI_SFX_ITEM_GRAB, VirtualAudioSourceType.UI, false);
}
}
return false;
}});
panel.setOnDrag(new DragEventCallback() {public boolean execute(DragEvent event){
// System.out.println("Drag");
panel.setPositionX(event.getCurrentX() - panelWidth / 2);
panel.setPositionY(event.getCurrentY() - panelHeight / 2);
Globals.signalSystem.post(SignalType.YOGA_APPLY, Globals.elementService.getWindow(WindowStrings.WINDOW_ITEM_DRAG_CONTAINER));
return false;
}});
panel.setOnDragRelease(new DragEventCallback(){public boolean execute(DragEvent event){
if(panel.getParent() != div){
if(panel.getParent() != null){
ContainerElement container = (ContainerElement)panel.getParent();
container.removeChild(panel);
}
panel.setAbsolutePosition(false);
Globals.elementService.fireEvent(event, event.getCurrentX(), event.getCurrentY());
}
return false;
}});
} else {
int slotId = i;
panel.setOnDragRelease(new DragEventCallback(){public boolean execute(DragEvent event){
if(Globals.dragSourceInventory instanceof RelationalInventoryState){
if(Globals.dragSourceInventory == InventoryUtils.getToolbarInventory(Globals.playerEntity)){
ClientToolbarState clientToolbarState = ClientToolbarState.getClientToolbarState(entity);
clientToolbarState.attemptAddToToolbar(Globals.draggedItem, slotId);
} else if(Globals.dragSourceInventory == InventoryUtils.getEquipInventory(Globals.playerEntity)){
ClientToolbarState clientToolbarState = ClientToolbarState.getClientToolbarState(entity);
clientToolbarState.attemptAddToToolbar(Globals.draggedItem, slotId);
}
} else if(Globals.dragSourceInventory instanceof UnrelationalInventoryState){
if(ItemUtils.getContainingParent(Globals.draggedItem) != Globals.playerEntity){
throw new UnsupportedOperationException("Unimplemented!");
} else if(Globals.dragSourceInventory == InventoryUtils.getNaturalInventory(Globals.playerEntity)){
ClientToolbarState clientToolbarState = ClientToolbarState.getClientToolbarState(entity);
clientToolbarState.attemptAddToToolbar(Globals.draggedItem, slotId);
}
}
Item itemData = Globals.gameConfigCurrent.getItemMap().getItem(ItemUtils.getType(Globals.draggedItem));
if(itemData.getItemAudio() != null && itemData.getItemAudio().getUIReleaseAudio() != null){
Globals.virtualAudioSourceManager.createVirtualAudioSource(itemData.getItemAudio().getUIReleaseAudio(), VirtualAudioSourceType.UI, false);
} else {
Globals.virtualAudioSourceManager.createVirtualAudioSource(AssetDataStrings.UI_SFX_ITEM_RELEASE, VirtualAudioSourceType.UI, false);
}
//update ui
Globals.dragSourceInventory = null;
Globals.draggedItem = null;
//clear item container ui
WindowUtils.cleanItemDraggingWindow();
//rerender inventories
WindowUtils.replaceWindow(WindowStrings.WINDOW_CHARACTER, PlayerInventoryWindow.createPlayerInventoryWindow(Globals.playerEntity));
return false;
}});
}
panelContainer.addChild(panel);
}
div.addChild(panelContainer);
}
return div;
}
}

View File

@ -5,19 +5,13 @@ import org.joml.Vector3i;
import electrosphere.engine.Globals;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.state.equip.ServerEquipState;
import electrosphere.entity.state.inventory.InventoryUtils;
import electrosphere.entity.state.server.ServerPlayerViewDirTree;
import electrosphere.entity.types.creature.CreatureEquipData.EquippedItem;
import electrosphere.entity.types.creature.CreatureTemplate;
import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.entity.types.item.ItemUtils;
import electrosphere.logger.LoggerInterface;
import electrosphere.net.server.ServerConnectionHandler;
import electrosphere.net.server.player.Player;
import electrosphere.server.datacell.Realm;
import electrosphere.server.datacell.utils.EntityLookupUtils;
/**
* Deals with spawning player characters
@ -53,25 +47,8 @@ public class PlayerCharacterCreation {
));
realm.getDataCellManager().addPlayerToRealm(playerObject);
//
//must happen after the player is attached to the entity, or server won't send packet to add item to player's entity
//now that creature has been spawned, need to create all attached items
if(template != null && template.getCreatureEquipData() != null && template.getCreatureEquipData().getSlots() != null){
for(String equipSlotId : template.getCreatureEquipData().getSlots()){
//spawn the item in the world
EquippedItem itemDefinition = template.getCreatureEquipData().getSlotItem(equipSlotId);
Entity itemInWorld = ItemUtils.serverSpawnBasicItem(realm, EntityUtils.getPosition(newPlayerEntity), itemDefinition.getItemType());
//add the item to the creature's inventory
Entity itemInInventory = InventoryUtils.serverAttemptStoreItem(newPlayerEntity, EntityLookupUtils.getEntityById(itemInWorld.getId()));
//equip the item to the slot defined in the template
ServerEquipState serverEquipState = ServerEquipState.getEquipState(newPlayerEntity);
serverEquipState.commandAttemptEquip(itemInInventory,serverEquipState.getEquipPoint(equipSlotId));
}
}
//must come after the player is assigned, otherwise the player will not get the item attachment messages
CreatureUtils.serverApplyTemplate(realm, newPlayerEntity, template);
//
//error checking

View File

@ -6,19 +6,15 @@ import java.util.List;
import electrosphere.entity.Entity;
import electrosphere.entity.EntityUtils;
import electrosphere.entity.state.attach.AttachUtils;
import electrosphere.entity.state.equip.ServerEquipState;
import electrosphere.entity.state.inventory.InventoryUtils;
import electrosphere.entity.types.EntityTypes;
import electrosphere.entity.types.EntityTypes.EntityType;
import electrosphere.entity.types.common.CommonEntityUtils;
import electrosphere.entity.types.creature.CreatureEquipData.EquippedItem;
import electrosphere.entity.types.creature.CreatureTemplate;
import electrosphere.entity.types.creature.CreatureUtils;
import electrosphere.entity.types.foliage.FoliageUtils;
import electrosphere.entity.types.item.ItemUtils;
import electrosphere.server.datacell.Realm;
import electrosphere.server.datacell.ServerDataCell;
import electrosphere.server.datacell.utils.EntityLookupUtils;
import electrosphere.util.Utilities;
/**
@ -104,25 +100,8 @@ public class ContentSerialization {
//
//Spawn the creature itself
Entity creature = CreatureUtils.serverSpawnBasicCreature(realm, serializedEntity.getPosition(), serializedEntity.getSubtype(), template);
CreatureUtils.serverApplyTemplate(realm, creature, template);
EntityUtils.getRotation(creature).set(serializedEntity.getRotation());
//
//now that creature has been spawned, need to create all attached items
if(template != null && template.getCreatureEquipData() != null && template.getCreatureEquipData().getSlots() != null){
for(String equipSlotId : template.getCreatureEquipData().getSlots()){
//spawn the item in the world
EquippedItem itemDefinition = template.getCreatureEquipData().getSlotItem(equipSlotId);
Entity itemInWorld = ItemUtils.serverSpawnBasicItem(realm, serializedEntity.getPosition(), itemDefinition.getItemType());
//add the item to the creature's inventory
Entity itemInInventory = InventoryUtils.serverAttemptStoreItem(creature, EntityLookupUtils.getEntityById(itemInWorld.getId()));
//equip the item to the slot defined in the template
ServerEquipState serverEquipState = ServerEquipState.getEquipState(creature);
serverEquipState.commandAttemptEquip(itemInInventory,serverEquipState.getEquipPoint(equipSlotId));
}
}
} break;
case ITEM: {
Entity item = ItemUtils.serverSpawnBasicItem(realm, serializedEntity.getPosition(), serializedEntity.getSubtype());

View File

@ -60,7 +60,7 @@ public class UnitUtils {
Entity itemInWorld = ItemUtils.serverSpawnBasicItem(realm, position, equippedItem.getItemId());
//add the item to the creature's inventory
Entity itemInInventory = InventoryUtils.serverAttemptStoreItem(rVal, itemInWorld);
Entity itemInInventory = InventoryUtils.serverAttemptStoreItemTransform(rVal, itemInWorld);
//equip the item to the slot defined in the template
ServerEquipState serverEquipState = ServerEquipState.getEquipState(rVal);

View File

@ -39,7 +39,7 @@ public class ServerAttackTreeTests extends EntityTestTemplate {
Entity katana = ItemUtils.serverSpawnBasicItem(Globals.realmManager.first(), new Vector3d(0,0,0), "Katana2H");
//equip
Entity inInventoryItem = InventoryUtils.serverAttemptStoreItem(creature, katana);
Entity inInventoryItem = InventoryUtils.serverAttemptStoreItemTransform(creature, katana);
ServerEquipState serverEquipState = ServerEquipState.getServerEquipState(creature);
serverEquipState.commandAttemptEquip(inInventoryItem, serverEquipState.getEquipPoint("handsCombined"));
@ -74,7 +74,7 @@ public class ServerAttackTreeTests extends EntityTestTemplate {
Entity katana = ItemUtils.serverSpawnBasicItem(Globals.realmManager.first(), new Vector3d(0,0,0), "Katana2H");
//equip
Entity inInventoryItem = InventoryUtils.serverAttemptStoreItem(creature, katana);
Entity inInventoryItem = InventoryUtils.serverAttemptStoreItemTransform(creature, katana);
ServerEquipState serverEquipState = ServerEquipState.getServerEquipState(creature);
serverEquipState.commandAttemptEquip(inInventoryItem, serverEquipState.getEquipPoint("handsCombined"));

View File

@ -51,7 +51,7 @@ public class ClientEquipStateTests extends EntityTestTemplate {
assertEquals(1, clientSideItems.size());
//equip
Entity inInventoryItem = InventoryUtils.serverAttemptStoreItem(creature, katana);
Entity inInventoryItem = InventoryUtils.serverAttemptStoreItemTransform(creature, katana);
ServerEquipState serverEquipState = ServerEquipState.getServerEquipState(creature);
serverEquipState.commandAttemptEquip(inInventoryItem, serverEquipState.getEquipPoint("handsCombined"));

View File

@ -36,7 +36,7 @@ public class ServerEquipStateTests extends EntityTestTemplate {
Entity katana = ItemUtils.serverSpawnBasicItem(Globals.realmManager.first(), new Vector3d(0,0,0), "Katana2H");
//equip
Entity inInventoryItem = InventoryUtils.serverAttemptStoreItem(creature, katana);
Entity inInventoryItem = InventoryUtils.serverAttemptStoreItemTransform(creature, katana);
ServerEquipState serverEquipState = ServerEquipState.getServerEquipState(creature);
serverEquipState.commandAttemptEquip(inInventoryItem, serverEquipState.getEquipPoint("handsCombined"));
@ -69,7 +69,7 @@ public class ServerEquipStateTests extends EntityTestTemplate {
Entity katana2 = ItemUtils.serverSpawnBasicItem(Globals.realmManager.first(), new Vector3d(0,0,0), "Katana2H");
//equip
Entity inInventoryItem = InventoryUtils.serverAttemptStoreItem(creature, katana);
Entity inInventoryItem = InventoryUtils.serverAttemptStoreItemTransform(creature, katana);
ServerEquipState serverEquipState = ServerEquipState.getServerEquipState(creature);
serverEquipState.commandAttemptEquip(inInventoryItem, serverEquipState.getEquipPoint("handsCombined"));
@ -77,7 +77,7 @@ public class ServerEquipStateTests extends EntityTestTemplate {
TestEngineUtils.simulateFrames(1);
//attempt to equip second katana
Entity inInventoryItem2 = InventoryUtils.serverAttemptStoreItem(creature, katana2);
Entity inInventoryItem2 = InventoryUtils.serverAttemptStoreItemTransform(creature, katana2);
serverEquipState.commandAttemptEquip(inInventoryItem2, serverEquipState.getEquipPoint("handsCombined"));
//propagate to client