implement crafting
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit
This commit is contained in:
parent
851875b62f
commit
9bd81242fc
@ -13,7 +13,7 @@
|
||||
"graphicsPerformanceEnableVSync" : false,
|
||||
"graphicsPerformanceDrawShadows" : true,
|
||||
"graphicsPerformanceOIT" : true,
|
||||
"graphicsPerformanceEnableFoliageManager" : true,
|
||||
"graphicsPerformanceEnableFoliageManager" : false,
|
||||
"graphicsViewRange" : 20000.0,
|
||||
|
||||
"renderResolutionX": 1920,
|
||||
|
||||
@ -43,7 +43,7 @@
|
||||
],
|
||||
"products": [
|
||||
{
|
||||
"itemType": "SPAWN_Workbench",
|
||||
"itemType": "Workbench",
|
||||
"count": 1
|
||||
}
|
||||
]
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
#maven.buildNumber.plugin properties file
|
||||
#Fri Nov 15 15:38:56 EST 2024
|
||||
buildNumber=385
|
||||
#Sat Nov 16 12:45:38 EST 2024
|
||||
buildNumber=387
|
||||
|
||||
@ -1052,6 +1052,10 @@ File watching scripts source dir
|
||||
Fix STBImage flipping bug (set flag statically)
|
||||
Update visuals on pine tree
|
||||
|
||||
(11/16/2024)
|
||||
Mountain generation work
|
||||
Implement crafting
|
||||
|
||||
|
||||
|
||||
# TODO
|
||||
@ -1077,10 +1081,6 @@ Implement gadgets
|
||||
- Decoy (creates a decoy)
|
||||
- Torch
|
||||
- Throwable potions
|
||||
Crafting
|
||||
- Crafting Menu
|
||||
- Recipe definitions
|
||||
- Reagent items
|
||||
|
||||
Ability to fully reload game engine state without exiting client
|
||||
- Back out to main menu and load a new level without any values persisting
|
||||
|
||||
@ -48,6 +48,14 @@
|
||||
{
|
||||
"name" : "viewTargetZ",
|
||||
"type" : "FIXED_DOUBLE"
|
||||
},
|
||||
{
|
||||
"name" : "stationId",
|
||||
"type" : "FIXED_INT"
|
||||
},
|
||||
{
|
||||
"name" : "recipeId",
|
||||
"type" : "FIXED_INT"
|
||||
}
|
||||
],
|
||||
"messageTypes" : [
|
||||
@ -142,6 +150,15 @@
|
||||
"viewTargetY",
|
||||
"viewTargetZ"
|
||||
]
|
||||
},
|
||||
{
|
||||
"messageName" : "clientRequestCraft",
|
||||
"description" : "Requests that the server craft an item",
|
||||
"data" : [
|
||||
"entityId",
|
||||
"stationId",
|
||||
"recipeId"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
2
pom.xml
2
pom.xml
@ -305,7 +305,7 @@
|
||||
<dependency>
|
||||
<groupId>io.github.studiorailgun</groupId>
|
||||
<artifactId>MathUtils</artifactId>
|
||||
<version>1.3.0</version>
|
||||
<version>1.4.0</version>
|
||||
</dependency>
|
||||
|
||||
<!--DataStructures-->
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
package electrosphere.client.ui.components;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import electrosphere.client.ui.menu.WindowStrings;
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.engine.signal.Signal.SignalType;
|
||||
@ -51,9 +53,10 @@ public class CraftingPanel {
|
||||
|
||||
/**
|
||||
* Creates the crafting panel component
|
||||
* @param onCraft Called when an item is crafted
|
||||
* @return The component
|
||||
*/
|
||||
public static Element createCraftingPanelComponent(){
|
||||
public static Element createCraftingPanelComponent(Consumer<RecipeData> onCraft){
|
||||
|
||||
//top level element
|
||||
Div rVal = Div.createCol();
|
||||
@ -83,6 +86,7 @@ public class CraftingPanel {
|
||||
Globals.gameConfigCurrent.getRecipeMap().getTypes().forEach((RecipeData recipe) -> {
|
||||
Button recipeButton = Button.createButton(recipe.getDisplayName(), () -> {
|
||||
CraftingPanel.setDetails(rVal, recipeDetailsSection, recipe);
|
||||
selectedRecipe = recipe;
|
||||
});
|
||||
recipeScrollable.addChild(recipeButton);
|
||||
});
|
||||
@ -91,7 +95,7 @@ public class CraftingPanel {
|
||||
|
||||
//the button to actually craft
|
||||
Button craftButton = Button.createButton("Craft", () -> {
|
||||
System.out.println("Craft an item here");
|
||||
onCraft.accept(selectedRecipe);
|
||||
});
|
||||
Div buttonRow = Div.createRow(
|
||||
craftButton
|
||||
|
||||
@ -17,6 +17,7 @@ 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.elements.Tooltip;
|
||||
import electrosphere.renderer.ui.elementtypes.ClickableElement.ClickEventCallback;
|
||||
import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaAlignment;
|
||||
import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaFlexDirection;
|
||||
@ -24,14 +25,21 @@ import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaJustification
|
||||
import electrosphere.renderer.ui.elementtypes.ContainerElement;
|
||||
import electrosphere.renderer.ui.elementtypes.DraggableElement.DragEventCallback;
|
||||
import electrosphere.renderer.ui.elementtypes.Element;
|
||||
import electrosphere.renderer.ui.elementtypes.HoverableElement.HoverEventCallback;
|
||||
import electrosphere.renderer.ui.events.ClickEvent;
|
||||
import electrosphere.renderer.ui.events.DragEvent;
|
||||
import electrosphere.renderer.ui.events.HoverEvent;
|
||||
|
||||
/**
|
||||
* An inventory panel showing a natural inventory
|
||||
*/
|
||||
public class NaturalInventoryPanel {
|
||||
|
||||
/**
|
||||
* The tooltip for the currently hovered item
|
||||
*/
|
||||
static Tooltip itemTooltip;
|
||||
|
||||
/**
|
||||
* Creates the natural inventory panel
|
||||
* @param entity The entity who has the inventory
|
||||
@ -179,6 +187,27 @@ public class NaturalInventoryPanel {
|
||||
}
|
||||
return false;
|
||||
}});
|
||||
panel.setOnHoverCallback(new HoverEventCallback() {public boolean execute(HoverEvent event){
|
||||
if(event.isHovered() && Globals.draggedItem == null){
|
||||
if(itemTooltip != null){
|
||||
Tooltip.destroy(itemTooltip);
|
||||
}
|
||||
Entity itemEntity = finalEnt;
|
||||
Item itemData = Globals.gameConfigCurrent.getItemMap().getItem(itemEntity);
|
||||
Globals.signalSystem.post(SignalType.UI_MODIFICATION,()->{
|
||||
itemTooltip = Tooltip.create(null,
|
||||
Div.createCol(Label.createLabel(itemData.getId()))
|
||||
);
|
||||
itemTooltip.setPositionX(panel.getAbsoluteX() + panelWidth);
|
||||
itemTooltip.setPositionY(panel.getAbsoluteY());
|
||||
});
|
||||
} else {
|
||||
if(itemTooltip != null){
|
||||
Tooltip.destroy(itemTooltip);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}});
|
||||
} else {
|
||||
panel.setOnDragRelease(new DragEventCallback(){public boolean execute(DragEvent event){
|
||||
if(Globals.dragSourceInventory instanceof RelationalInventoryState){
|
||||
|
||||
@ -8,6 +8,8 @@ import electrosphere.controls.ControlHandler.ControlsState;
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.engine.assetmanager.AssetDataStrings;
|
||||
import electrosphere.engine.signal.Signal.SignalType;
|
||||
import electrosphere.game.data.crafting.RecipeData;
|
||||
import electrosphere.net.parser.net.message.InventoryMessage;
|
||||
import electrosphere.renderer.ui.elements.Window;
|
||||
import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaAlignment;
|
||||
import electrosphere.renderer.ui.elementtypes.ContainerElement.YogaJustification;
|
||||
@ -61,7 +63,13 @@ public class CraftingWindow {
|
||||
//
|
||||
//contents
|
||||
//
|
||||
rVal.addChild(CraftingPanel.createCraftingPanelComponent());
|
||||
rVal.addChild(CraftingPanel.createCraftingPanelComponent((RecipeData recipe) -> {
|
||||
Globals.clientConnection.queueOutgoingMessage(InventoryMessage.constructclientRequestCraftMessage(
|
||||
Globals.clientSceneWrapper.mapClientToServerId(Globals.playerEntity.getId()),
|
||||
Globals.clientSceneWrapper.mapClientToServerId(Globals.interactionTarget.getId()),
|
||||
recipe.getId()
|
||||
));
|
||||
}));
|
||||
|
||||
//
|
||||
//Final setup
|
||||
|
||||
@ -24,6 +24,7 @@ import electrosphere.entity.state.inventory.RelationalInventoryState;
|
||||
import electrosphere.entity.state.inventory.UnrelationalInventoryState;
|
||||
import electrosphere.entity.types.creature.CreatureTemplate;
|
||||
import electrosphere.game.data.common.CommonEntityType;
|
||||
import electrosphere.game.data.crafting.RecipeData;
|
||||
import electrosphere.game.data.creature.type.equip.EquipPoint;
|
||||
import electrosphere.game.data.voxel.VoxelType;
|
||||
import electrosphere.renderer.actor.ActorUtils;
|
||||
@ -155,7 +156,9 @@ public class MenuGeneratorsUITesting {
|
||||
}));
|
||||
} break;
|
||||
case "CraftingPanel": {
|
||||
formEl.addChild(CraftingPanel.createCraftingPanelComponent());
|
||||
formEl.addChild(CraftingPanel.createCraftingPanelComponent((RecipeData recipe) -> {
|
||||
System.out.println("Craft " + recipe.getDisplayName());
|
||||
}));
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -618,6 +618,7 @@ public class ControlCategoryMainGame {
|
||||
Vector3d centerPos = new Vector3d(CameraEntityUtils.getCameraCenter(camera));
|
||||
Entity target = collisionEngine.rayCast(centerPos, eyePos, CollisionEngine.DEFAULT_INTERACT_DISTANCE, Collidable.MASK_NO_TERRAIN);
|
||||
if(target != null && CommonEntityFlags.isInteractable(target)){
|
||||
Globals.interactionTarget = target;
|
||||
InteractionData interactionData = CommonEntityUtils.getCommonData(target).getInteraction();
|
||||
switch(interactionData.getOnInteract()){
|
||||
case InteractionData.ON_INTERACT_TARGET: {
|
||||
|
||||
@ -395,6 +395,11 @@ public class Globals {
|
||||
//the entity for the first person modal (view model)
|
||||
public static Entity firstPersonEntity;
|
||||
|
||||
/**
|
||||
* The target of the interaction
|
||||
*/
|
||||
public static Entity interactionTarget = null;
|
||||
|
||||
//client current selected voxel type
|
||||
public static VoxelType clientSelectedVoxelType = null;
|
||||
//the selected type of entity to spawn
|
||||
|
||||
@ -61,6 +61,35 @@ public class EntityCreationUtils {
|
||||
return rVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a server entity in the given realm and position. This uses spatial entity as a server entity can't (currently) exist outside of a realm.
|
||||
* @param realm The realm to attach the entity to
|
||||
* @return The entity
|
||||
*/
|
||||
public static Entity createServerInventoryEntity(Realm realm){
|
||||
Entity rVal = EntityCreationUtils.spawnSpatialEntity();
|
||||
//register to global entity id lookup table
|
||||
EntityLookupUtils.registerServerEntity(rVal);
|
||||
//assign to realm
|
||||
Globals.realmManager.mapEntityToRealm(rVal, realm);
|
||||
//init data cell if it doesn't exist
|
||||
ServerDataCell cell = realm.getInventoryCell();
|
||||
//If a server data cell was not created, this is considered illegal state
|
||||
if(cell == null){
|
||||
throw new IllegalStateException("Realm inventory data cell undefined!");
|
||||
}
|
||||
//register to entity data cell mapper
|
||||
Globals.entityDataCellMapper.registerEntity(rVal, cell);
|
||||
//enable behavior tree tracking
|
||||
ServerBehaviorTreeUtils.registerEntity(rVal);
|
||||
|
||||
if(Globals.entityDataCellMapper.getEntityDataCell(rVal) == null){
|
||||
throw new Error("Failed to map entity to cell!");
|
||||
}
|
||||
|
||||
return rVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Spawns an entity that is not attached to a realm (for instance an item in an inventory)
|
||||
* @return The entity
|
||||
|
||||
@ -181,6 +181,7 @@ public class ClientInventoryState implements BehaviorTree {
|
||||
// throw new UnsupportedOperationException("TODO: in world item is null");
|
||||
}
|
||||
} break;
|
||||
case CLIENTREQUESTCRAFT:
|
||||
case CLIENTUPDATETOOLBAR:
|
||||
case CLIENTREQUESTADDNATURAL:
|
||||
case CLIENTREQUESTADDTOOLBAR:
|
||||
|
||||
@ -401,7 +401,7 @@ public class InventoryUtils {
|
||||
//need creature so we can figure out where to drop the item
|
||||
public static void serverAttemptEjectItem(Entity creature, Entity item){
|
||||
//if we're the server, immediately attempt the transform
|
||||
serverAttemptEjectItemTransform(creature,item);
|
||||
InventoryUtils.serverAttemptEjectItemTransform(creature,item);
|
||||
}
|
||||
|
||||
//need creature so we can figure out where to drop the item
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package electrosphere.entity.state.inventory;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
@ -86,6 +87,14 @@ public class RelationalInventoryState {
|
||||
return items.get(slot);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the collection of items in the inventory
|
||||
* @return The entities in the inventory
|
||||
*/
|
||||
public Collection<Entity> getItems(){
|
||||
return items.values();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the item slot for a given item
|
||||
* @param item The item
|
||||
|
||||
@ -16,14 +16,26 @@ import electrosphere.server.datacell.utils.ServerBehaviorTreeUtils;
|
||||
*/
|
||||
public class ServerInventoryState implements BehaviorTree {
|
||||
|
||||
/**
|
||||
* The queue of messages to handle
|
||||
*/
|
||||
CopyOnWriteArrayList<InventoryMessage> networkMessageQueue = new CopyOnWriteArrayList<InventoryMessage>();
|
||||
|
||||
/**
|
||||
* The parent of the state
|
||||
*/
|
||||
Entity parent;
|
||||
|
||||
ServerInventoryState() {
|
||||
|
||||
}
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
ServerInventoryState() {}
|
||||
|
||||
/**
|
||||
* Creates an inventory state
|
||||
* @param parent The parent entity
|
||||
* @return The inventory state
|
||||
*/
|
||||
public static ServerInventoryState serverCreateInventoryState(Entity parent){
|
||||
ServerInventoryState rVal = new ServerInventoryState();
|
||||
rVal.parent = parent;
|
||||
@ -57,7 +69,7 @@ public class ServerInventoryState implements BehaviorTree {
|
||||
//make sure can unequip
|
||||
if(InventoryUtils.hasEquipInventory(parent) && InventoryUtils.hasNaturalInventory(parent) && ServerEquipState.hasEquipState(parent)){
|
||||
ServerEquipState equipState = ServerEquipState.getEquipState(parent);
|
||||
EquipPoint point = equipState.getEquipPoint(message.getequipPointId());
|
||||
// EquipPoint point = equipState.getEquipPoint(message.getequipPointId());
|
||||
if(equipState.hasEquippedAtPoint(message.getequipPointId())){
|
||||
equipState.commandAttemptUnequip(message.getequipPointId());
|
||||
//tell player
|
||||
@ -76,6 +88,7 @@ public class ServerInventoryState implements BehaviorTree {
|
||||
ServerToolbarState serverToolbarState = ServerToolbarState.getServerToolbarState(parent);
|
||||
serverToolbarState.attemptChangeSelection(message.gettoolbarId());
|
||||
} break;
|
||||
case CLIENTREQUESTCRAFT:
|
||||
case CLIENTREQUESTPERFORMITEMACTION:
|
||||
case SERVERCOMMANDUNEQUIPITEM:
|
||||
case SERVERCOMMANDEQUIPITEM:
|
||||
@ -85,6 +98,10 @@ public class ServerInventoryState implements BehaviorTree {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a network message to be handled on the server
|
||||
* @param networkMessage The message
|
||||
*/
|
||||
public void addNetworkMessage(InventoryMessage networkMessage) {
|
||||
networkMessageQueue.add(networkMessage);
|
||||
}
|
||||
|
||||
@ -23,7 +23,16 @@ public class CommonEntityFlags {
|
||||
* @return true if should be synchronized, false otherwise
|
||||
*/
|
||||
public static boolean shouldBeSynchronized(Entity entity){
|
||||
return entity.containsKey(EntityDataStrings.SHOULD_SYNCHRONIZE);
|
||||
return !entity.containsKey(EntityDataStrings.SHOULD_SYNCHRONIZE) || (boolean)entity.getData(EntityDataStrings.SHOULD_SYNCHRONIZE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the synchronization status of the entity
|
||||
* @param entity The entity
|
||||
* @param shouldSynchronize true if it should be synchronized, false otherwise
|
||||
*/
|
||||
public static void setSynchronization(Entity entity, boolean shouldSynchronize){
|
||||
entity.putData(EntityDataStrings.SHOULD_SYNCHRONIZE, shouldSynchronize);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -20,8 +20,12 @@ import electrosphere.entity.state.AnimationPriorities;
|
||||
import electrosphere.entity.state.attach.AttachUtils;
|
||||
import electrosphere.entity.state.gravity.ServerGravityTree;
|
||||
import electrosphere.entity.state.hitbox.HitboxCollectionState;
|
||||
import electrosphere.entity.state.inventory.InventoryUtils;
|
||||
import electrosphere.entity.state.inventory.RelationalInventoryState;
|
||||
import electrosphere.entity.state.inventory.UnrelationalInventoryState;
|
||||
import electrosphere.entity.types.EntityTypes.EntityType;
|
||||
import electrosphere.entity.types.common.CommonEntityUtils;
|
||||
import electrosphere.entity.types.creature.CreatureUtils;
|
||||
import electrosphere.game.data.item.EquipData;
|
||||
import electrosphere.game.data.item.EquipWhitelist;
|
||||
import electrosphere.game.data.item.Item;
|
||||
@ -29,6 +33,7 @@ import electrosphere.game.data.item.ItemAudio;
|
||||
import electrosphere.game.data.item.WeaponData;
|
||||
import electrosphere.logger.LoggerInterface;
|
||||
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.renderer.actor.Actor;
|
||||
@ -108,19 +113,20 @@ public class ItemUtils {
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Spawns an item on the server
|
||||
* @param realm the realm to spawn in
|
||||
* @param position the position to spawn at
|
||||
* @param name the name of the item to spawn
|
||||
* @return The item entity
|
||||
* Applies transforms to an entity to make it an item entity
|
||||
* @param realm The realm of the entity
|
||||
* @param position The position of the entity
|
||||
* @param rVal The entity itself
|
||||
* @param item The item's type
|
||||
*/
|
||||
public static Entity serverSpawnBasicItem(Realm realm, Vector3d position, String name){
|
||||
Item item = Globals.gameConfigCurrent.getItemMap().getItem(name);
|
||||
//must correct the position such that it spawns inside the realm
|
||||
Vector3d correctedPosition = ServerEntityUtils.guaranteePositionIsInBounds(realm, position);
|
||||
Entity rVal = EntityCreationUtils.createServerEntity(realm, correctedPosition);
|
||||
public static void serverApplyItemEntityTransforms(Realm realm, Vector3d position, Entity rVal, Item item){
|
||||
|
||||
//error check inputs
|
||||
if(realm == null || position == null || rVal == null || item == null){
|
||||
throw new Error("Provided bad data to item transform! " + realm + " " + position + " " + rVal + " " + item);
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//Common entity transforms
|
||||
@ -184,7 +190,23 @@ public class ItemUtils {
|
||||
}
|
||||
}
|
||||
rVal.putData(EntityDataStrings.ITEM_IS_IN_INVENTORY, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Spawns an item on the server
|
||||
* @param realm the realm to spawn in
|
||||
* @param position the position to spawn at
|
||||
* @param name the name of the item to spawn
|
||||
* @return The item entity
|
||||
*/
|
||||
public static Entity serverSpawnBasicItem(Realm realm, Vector3d position, String name){
|
||||
Item item = Globals.gameConfigCurrent.getItemMap().getItem(name);
|
||||
//must correct the position such that it spawns inside the realm
|
||||
Vector3d correctedPosition = ServerEntityUtils.guaranteePositionIsInBounds(realm, position);
|
||||
Entity rVal = EntityCreationUtils.createServerEntity(realm, correctedPosition);
|
||||
|
||||
//apply item transforms to an entity
|
||||
ItemUtils.serverApplyItemEntityTransforms(realm, correctedPosition, rVal, item);
|
||||
|
||||
|
||||
//position entity
|
||||
@ -428,9 +450,9 @@ public class ItemUtils {
|
||||
* @param containingParent The parent that contains the item
|
||||
*/
|
||||
public static Entity serverRecreateContainerItem(Entity item, Entity containingParent){
|
||||
if(isItem(item)){
|
||||
if(ItemUtils.isItem(item)){
|
||||
Entity rVal = EntityCreationUtils.createRealmlessServerEntity();
|
||||
if(getEquipWhitelist(item) != null){
|
||||
if(ItemUtils.getEquipWhitelist(item) != null){
|
||||
rVal.putData(EntityDataStrings.ITEM_EQUIP_WHITELIST, getEquipWhitelist(item));
|
||||
}
|
||||
rVal.putData(EntityDataStrings.ITEM_ICON,ItemUtils.getItemIcon(item));
|
||||
@ -445,8 +467,51 @@ public class ItemUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new item in the parent's inventory
|
||||
* @param parent The parent that contains the item
|
||||
* @param itemData The item data
|
||||
*/
|
||||
public static void serverCreateContainerItem(Entity parent, Item itemData){
|
||||
if(parent == null || itemData == null){
|
||||
throw new Error("Provided bad data! " + parent + " " + itemData);
|
||||
}
|
||||
//make sure there's an item to store the item
|
||||
UnrelationalInventoryState naturalInventory = InventoryUtils.getNaturalInventory(parent);
|
||||
RelationalInventoryState toolbarInventory = InventoryUtils.getToolbarInventory(parent);
|
||||
if(naturalInventory == null && toolbarInventory == null){
|
||||
return;
|
||||
}
|
||||
Realm realm = Globals.realmManager.getEntityRealm(parent);
|
||||
Vector3d parentPos = EntityUtils.getPosition(parent);
|
||||
|
||||
|
||||
|
||||
//must correct the position such that it spawns inside the realm
|
||||
Entity rVal = EntityCreationUtils.createServerInventoryEntity(realm);
|
||||
|
||||
//apply item transforms to an entity
|
||||
ItemUtils.serverApplyItemEntityTransforms(realm, parentPos, rVal, itemData);
|
||||
|
||||
//error checking
|
||||
if(Globals.realmManager.getEntityRealm(rVal) == null){
|
||||
LoggerInterface.loggerEngine.ERROR(new IllegalStateException("Created item without it being assigned to a realm!"));
|
||||
}
|
||||
|
||||
//send entity to client
|
||||
if(CreatureUtils.hasControllerPlayerId(parent)){
|
||||
int playerId = CreatureUtils.getControllerPlayerId(parent);
|
||||
Player player = Globals.playerManager.getPlayerFromId(playerId);
|
||||
player.addMessage(InventoryMessage.constructaddItemToInventoryMessage(rVal.getId(), itemData.getId()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Try destroying a client item in the world
|
||||
* @param item The item to destroy
|
||||
*/
|
||||
public static void clientDestroyInWorldItem(Entity item){
|
||||
if(isItem(item)){
|
||||
if(ItemUtils.isItem(item)){
|
||||
//destroy physics
|
||||
if(PhysicsEntityUtils.containsDBody(item) && item.containsKey(EntityDataStrings.PHYSICS_COLLIDABLE)){
|
||||
//destroy physics
|
||||
|
||||
@ -66,6 +66,7 @@ public class InventoryProtocol implements ClientProtocolTemplate<InventoryMessag
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CLIENTREQUESTCRAFT:
|
||||
case CLIENTUPDATETOOLBAR:
|
||||
case CLIENTREQUESTADDNATURAL:
|
||||
case CLIENTREQUESTADDTOOLBAR:
|
||||
|
||||
@ -22,6 +22,7 @@ public class InventoryMessage extends NetworkMessage {
|
||||
CLIENTREQUESTADDNATURAL,
|
||||
CLIENTUPDATETOOLBAR,
|
||||
CLIENTREQUESTPERFORMITEMACTION,
|
||||
CLIENTREQUESTCRAFT,
|
||||
}
|
||||
|
||||
/**
|
||||
@ -39,6 +40,8 @@ public class InventoryMessage extends NetworkMessage {
|
||||
double viewTargetX;
|
||||
double viewTargetY;
|
||||
double viewTargetZ;
|
||||
int stationId;
|
||||
int recipeId;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
@ -207,6 +210,34 @@ public class InventoryMessage extends NetworkMessage {
|
||||
this.viewTargetZ = viewTargetZ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets stationId
|
||||
*/
|
||||
public int getstationId() {
|
||||
return stationId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets stationId
|
||||
*/
|
||||
public void setstationId(int stationId) {
|
||||
this.stationId = stationId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets recipeId
|
||||
*/
|
||||
public int getrecipeId() {
|
||||
return recipeId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets recipeId
|
||||
*/
|
||||
public void setrecipeId(int recipeId) {
|
||||
this.recipeId = recipeId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the packet header from the buffer
|
||||
* @param byteBuffer The buffer
|
||||
@ -261,6 +292,12 @@ public class InventoryMessage extends NetworkMessage {
|
||||
}
|
||||
case TypeBytes.INVENTORY_MESSAGE_TYPE_CLIENTREQUESTPERFORMITEMACTION:
|
||||
return InventoryMessage.canParseclientRequestPerformItemActionMessage(byteBuffer);
|
||||
case TypeBytes.INVENTORY_MESSAGE_TYPE_CLIENTREQUESTCRAFT:
|
||||
if(byteBuffer.getRemaining() >= TypeBytes.INVENTORY_MESSAGE_TYPE_CLIENTREQUESTCRAFT_SIZE){
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -726,6 +763,30 @@ public class InventoryMessage extends NetworkMessage {
|
||||
return rVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a message of type clientRequestCraft
|
||||
*/
|
||||
public static InventoryMessage parseclientRequestCraftMessage(CircularByteBuffer byteBuffer){
|
||||
InventoryMessage rVal = new InventoryMessage(InventoryMessageType.CLIENTREQUESTCRAFT);
|
||||
stripPacketHeader(byteBuffer);
|
||||
rVal.setentityId(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.setstationId(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.setrecipeId(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
return rVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a message of type clientRequestCraft
|
||||
*/
|
||||
public static InventoryMessage constructclientRequestCraftMessage(int entityId,int stationId,int recipeId){
|
||||
InventoryMessage rVal = new InventoryMessage(InventoryMessageType.CLIENTREQUESTCRAFT);
|
||||
rVal.setentityId(entityId);
|
||||
rVal.setstationId(stationId);
|
||||
rVal.setrecipeId(recipeId);
|
||||
rVal.serialize();
|
||||
return rVal;
|
||||
}
|
||||
|
||||
@Override
|
||||
void serialize(){
|
||||
byte[] intValues = new byte[8];
|
||||
@ -948,6 +1009,25 @@ public class InventoryMessage extends NetworkMessage {
|
||||
rawBytes[30+equipPointId.length()+i] = intValues[i];
|
||||
}
|
||||
break;
|
||||
case CLIENTREQUESTCRAFT:
|
||||
rawBytes = new byte[2+4+4+4];
|
||||
//message header
|
||||
rawBytes[0] = TypeBytes.MESSAGE_TYPE_INVENTORY;
|
||||
//entity messaage header
|
||||
rawBytes[1] = TypeBytes.INVENTORY_MESSAGE_TYPE_CLIENTREQUESTCRAFT;
|
||||
intValues = ByteStreamUtils.serializeIntToBytes(entityId);
|
||||
for(int i = 0; i < 4; i++){
|
||||
rawBytes[2+i] = intValues[i];
|
||||
}
|
||||
intValues = ByteStreamUtils.serializeIntToBytes(stationId);
|
||||
for(int i = 0; i < 4; i++){
|
||||
rawBytes[6+i] = intValues[i];
|
||||
}
|
||||
intValues = ByteStreamUtils.serializeIntToBytes(recipeId);
|
||||
for(int i = 0; i < 4; i++){
|
||||
rawBytes[10+i] = intValues[i];
|
||||
}
|
||||
break;
|
||||
}
|
||||
serialized = true;
|
||||
}
|
||||
|
||||
@ -364,6 +364,11 @@ public abstract class NetworkMessage {
|
||||
rVal = InventoryMessage.parseclientRequestPerformItemActionMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
case TypeBytes.INVENTORY_MESSAGE_TYPE_CLIENTREQUESTCRAFT:
|
||||
if(InventoryMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = InventoryMessage.parseclientRequestCraftMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case TypeBytes.MESSAGE_TYPE_SYNCHRONIZATION:
|
||||
|
||||
@ -151,6 +151,7 @@ public class TypeBytes {
|
||||
public static final byte INVENTORY_MESSAGE_TYPE_CLIENTREQUESTADDNATURAL = 8;
|
||||
public static final byte INVENTORY_MESSAGE_TYPE_CLIENTUPDATETOOLBAR = 9;
|
||||
public static final byte INVENTORY_MESSAGE_TYPE_CLIENTREQUESTPERFORMITEMACTION = 10;
|
||||
public static final byte INVENTORY_MESSAGE_TYPE_CLIENTREQUESTCRAFT = 11;
|
||||
/*
|
||||
Inventory packet sizes
|
||||
*/
|
||||
@ -158,6 +159,7 @@ public class TypeBytes {
|
||||
public static final byte INVENTORY_MESSAGE_TYPE_CLIENTREQUESTADDTOOLBAR_SIZE = 10;
|
||||
public static final byte INVENTORY_MESSAGE_TYPE_CLIENTREQUESTADDNATURAL_SIZE = 6;
|
||||
public static final byte INVENTORY_MESSAGE_TYPE_CLIENTUPDATETOOLBAR_SIZE = 6;
|
||||
public static final byte INVENTORY_MESSAGE_TYPE_CLIENTREQUESTCRAFT_SIZE = 14;
|
||||
|
||||
/*
|
||||
Synchronization subcategories
|
||||
|
||||
@ -1,11 +1,24 @@
|
||||
package electrosphere.net.server.protocol;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.entity.Entity;
|
||||
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.crafting.RecipeData;
|
||||
import electrosphere.game.data.crafting.RecipeIngredientData;
|
||||
import electrosphere.game.data.item.Item;
|
||||
import electrosphere.game.data.item.ItemDataMap;
|
||||
import electrosphere.logger.LoggerInterface;
|
||||
import electrosphere.net.parser.net.message.InventoryMessage;
|
||||
import electrosphere.net.server.ServerConnectionHandler;
|
||||
import electrosphere.net.template.ServerProtocolTemplate;
|
||||
import electrosphere.server.datacell.ServerDataCell;
|
||||
import electrosphere.server.datacell.utils.DataCellSearchUtils;
|
||||
import electrosphere.server.datacell.utils.EntityLookupUtils;
|
||||
import electrosphere.server.player.PlayerActions;
|
||||
|
||||
@ -80,6 +93,16 @@ public class InventoryProtocol implements ServerProtocolTemplate<InventoryMessag
|
||||
InventoryUtils.serverGetInventoryState(target).addNetworkMessage(message);
|
||||
}
|
||||
} break;
|
||||
case CLIENTREQUESTCRAFT: {
|
||||
target = EntityLookupUtils.getEntityById(connectionHandler.getPlayerEntityId());
|
||||
Entity workshopEntity = EntityLookupUtils.getEntityById(message.getstationId());
|
||||
RecipeData recipe = Globals.gameConfigCurrent.getRecipeMap().getType(message.getrecipeId());
|
||||
if(target != null && recipe != null){
|
||||
this.attemptCraft(target,workshopEntity,recipe);
|
||||
// System.out.println(message.getentityId() + " " + message.getstationId() + " " + message.getrecipeId());
|
||||
// InventoryUtils.serverGetInventoryState(target).addNetworkMessage(message);
|
||||
}
|
||||
} break;
|
||||
case SERVERCOMMANDUNEQUIPITEM:
|
||||
case SERVERCOMMANDMOVEITEMCONTAINER:
|
||||
case SERVERCOMMANDEQUIPITEM:
|
||||
@ -88,4 +111,98 @@ public class InventoryProtocol implements ServerProtocolTemplate<InventoryMessag
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Attempts to craft an item
|
||||
* @param crafter The entity performing the crafting
|
||||
* @param station The (optional) station for crafting
|
||||
* @param recipe The recipe to craft
|
||||
*/
|
||||
private void attemptCraft(Entity crafter, Entity station, RecipeData recipe){
|
||||
if(InventoryUtils.serverGetInventoryState(crafter) == null){
|
||||
return;
|
||||
}
|
||||
UnrelationalInventoryState naturalInventory = InventoryUtils.getNaturalInventory(crafter);
|
||||
RelationalInventoryState toolbarInventory = InventoryUtils.getToolbarInventory(crafter);
|
||||
|
||||
//get data obj
|
||||
ItemDataMap itemMap = Globals.gameConfigCurrent.getItemMap();
|
||||
|
||||
//get reagents
|
||||
List<Entity> reagentList = new LinkedList<Entity>();
|
||||
boolean hasReagents = true;
|
||||
//find the reagents we're going to use to craft
|
||||
for(RecipeIngredientData ingredient : recipe.getIngredients()){
|
||||
int found = 0;
|
||||
if(naturalInventory != null){
|
||||
for(Entity itemEnt : naturalInventory.getItems()){
|
||||
if(itemMap.getItem(itemEnt).getId().matches(ingredient.getItemType())){
|
||||
found++;
|
||||
reagentList.add(itemEnt);
|
||||
}
|
||||
if(found >= ingredient.getCount()){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(toolbarInventory != null){
|
||||
for(Entity itemEnt : toolbarInventory.getItems()){
|
||||
if(itemMap.getItem(itemEnt).getId().matches(ingredient.getItemType())){
|
||||
found++;
|
||||
reagentList.add(itemEnt);
|
||||
}
|
||||
if(found >= ingredient.getCount()){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(found < ingredient.getCount()){
|
||||
hasReagents = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(hasReagents){
|
||||
for(Entity reagentEnt : reagentList){
|
||||
if(naturalInventory != null){
|
||||
naturalInventory.removeItem(reagentEnt);
|
||||
}
|
||||
if(toolbarInventory != null){
|
||||
toolbarInventory.tryRemoveItem(reagentEnt);
|
||||
}
|
||||
this.deleteItemInInventory(crafter, reagentEnt);
|
||||
}
|
||||
for(RecipeIngredientData product : recipe.getProducts()){
|
||||
Item productType = itemMap.getItem(product.getItemType());
|
||||
if(productType == null){
|
||||
throw new Error("Could not locate product definition! " + productType + " " + product.getItemType());
|
||||
}
|
||||
for(int i = 0; i < product.getCount(); i++){
|
||||
ItemUtils.serverCreateContainerItem(crafter, productType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Delete an item that is in an inventory
|
||||
* @param parent The parent entity that contains the in-inventory item
|
||||
* @param itemEnt The item that is in an inventory
|
||||
*/
|
||||
private void deleteItemInInventory(Entity parent, Entity inInventory){
|
||||
//the parent entity's data cell
|
||||
ServerDataCell dataCell = DataCellSearchUtils.getEntityDataCell(parent);
|
||||
//broadcast destroy entity
|
||||
dataCell.broadcastNetworkMessage(InventoryMessage.constructremoveItemFromInventoryMessage(inInventory.getId()));
|
||||
//remove the inventories
|
||||
UnrelationalInventoryState naturalInventory = InventoryUtils.getNaturalInventory(parent);
|
||||
RelationalInventoryState toolbarInventory = InventoryUtils.getToolbarInventory(parent);
|
||||
if(naturalInventory != null){
|
||||
naturalInventory.removeItem(inInventory);
|
||||
}
|
||||
if(toolbarInventory != null){
|
||||
toolbarInventory.tryRemoveItem(inInventory);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -36,6 +36,11 @@ public class Realm {
|
||||
//this is the cell that all players loading into the game (via connection startup, death, etc) reside in
|
||||
ServerDataCell loadingCell = new ServerDataCell(new Scene());
|
||||
|
||||
/**
|
||||
* The data cell that will contain in-inventory items
|
||||
*/
|
||||
ServerDataCell inventoryCell = new ServerDataCell(new Scene());
|
||||
|
||||
//resolver for entity -> data cell within this realm
|
||||
EntityDataCellMapper entityDataCellMapper;
|
||||
|
||||
@ -261,6 +266,14 @@ public class Realm {
|
||||
this.spawnPoints.add(point);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the inventory data cell
|
||||
* @return The inventory data cell
|
||||
*/
|
||||
public ServerDataCell getInventoryCell(){
|
||||
return inventoryCell;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the script-engine side instance id for the scene that was loaded with this realm
|
||||
* @param sceneInstanceId The instance id
|
||||
|
||||
@ -132,7 +132,7 @@ public class ServerDataCell {
|
||||
* Sends the current state of the datacell to the player
|
||||
* Commonly, this should be called when a player is added to the cell
|
||||
*/
|
||||
void serializeStateToPlayer(Player player){
|
||||
private void serializeStateToPlayer(Player player){
|
||||
for(Entity entity : scene.getEntityList()){
|
||||
this.serializeEntityToPlayer(entity,player);
|
||||
}
|
||||
|
||||
@ -14,6 +14,7 @@ import electrosphere.game.server.world.ServerWorldData;
|
||||
import electrosphere.server.terrain.generation.heightmap.EmptySkyGen;
|
||||
import electrosphere.server.terrain.generation.heightmap.HeightmapGenerator;
|
||||
import electrosphere.server.terrain.generation.heightmap.HillsGen;
|
||||
import electrosphere.server.terrain.generation.heightmap.MountainGen;
|
||||
import electrosphere.server.terrain.generation.heightmap.PlainsGen;
|
||||
import electrosphere.server.terrain.generation.interfaces.ChunkGenerator;
|
||||
import electrosphere.server.terrain.generation.interfaces.GeneratedVoxel;
|
||||
@ -84,11 +85,12 @@ public class TestGenerationChunkGenerator implements ChunkGenerator {
|
||||
*/
|
||||
public TestGenerationChunkGenerator(ServerWorldData serverWorldData, boolean useJavascript){
|
||||
this.serverWorldData = serverWorldData;
|
||||
registerHeightmapGenerator(new EmptySkyGen());
|
||||
registerHeightmapGenerator(new HillsGen());
|
||||
registerHeightmapGenerator(new PlainsGen());
|
||||
registerVoxelGenerator(new HillsVoxelGen());
|
||||
registerVoxelGenerator(new AnimeMountainsGen());
|
||||
this.registerHeightmapGenerator(new EmptySkyGen());
|
||||
this.registerHeightmapGenerator(new HillsGen());
|
||||
this.registerHeightmapGenerator(new PlainsGen());
|
||||
this.registerHeightmapGenerator(new MountainGen());
|
||||
this.registerVoxelGenerator(new HillsVoxelGen());
|
||||
this.registerVoxelGenerator(new AnimeMountainsGen());
|
||||
this.useJavascript = useJavascript;
|
||||
}
|
||||
|
||||
@ -121,6 +123,7 @@ public class TestGenerationChunkGenerator implements ChunkGenerator {
|
||||
|
||||
BiomeSurfaceGenerationParams surfaceParams = surfaceBiome.getSurfaceGenerationParams();
|
||||
HeightmapGenerator heightmapGen = this.tagHeightmapMap.get(surfaceParams.getSurfaceGenTag());
|
||||
heightmapGen = this.tagHeightmapMap.get("mountains");
|
||||
if(heightmapGen == null){
|
||||
throw new Error("Undefined heightmap generator in biome! " + surfaceBiome.getId() + " " + surfaceBiome.getDisplayName() + " " + surfaceParams.getSurfaceGenTag());
|
||||
}
|
||||
|
||||
@ -0,0 +1,69 @@
|
||||
package electrosphere.server.terrain.generation.heightmap;
|
||||
|
||||
import io.github.studiorailgun.NoiseUtils;
|
||||
|
||||
public class MountainGen implements HeightmapGenerator {
|
||||
|
||||
/**
|
||||
* Offset from baseline to place the noisemap at
|
||||
*/
|
||||
static final float HEIGHT_OFFSET = 10;
|
||||
|
||||
/**
|
||||
* The falloff factor
|
||||
*/
|
||||
static final double FALLOFF_FACTOR = 10.0f;
|
||||
|
||||
/**
|
||||
* Vertical scale of the noise
|
||||
*/
|
||||
static final float VERTICAL_SCALE = 1024.0f;
|
||||
|
||||
/**
|
||||
* Horizontal scale of the noise
|
||||
*/
|
||||
static final float HORIZONTAL_SCALE = 1024.0f;
|
||||
|
||||
/**
|
||||
* The power applied to the noise
|
||||
*/
|
||||
static final float POWER_SCALE = 2;
|
||||
|
||||
/**
|
||||
* The scale to apply to the coordinates
|
||||
*/
|
||||
static final float GEN_SCALE = 1.0f / HORIZONTAL_SCALE;
|
||||
|
||||
//the different scales of noise to sample from
|
||||
static final double[][] NOISE_SCALES = new double[][]{
|
||||
{0.01, 3.0},
|
||||
{0.02, 2.0},
|
||||
{0.05, 0.8},
|
||||
{0.1, 0.3},
|
||||
{0.3, 0.2},
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Gets the height at a given position for this generation approach
|
||||
* @param SEED The seed
|
||||
* @param x The x position
|
||||
* @param y The y position
|
||||
* @return The height
|
||||
*/
|
||||
public float getHeight(long SEED, double x, double y){
|
||||
float rVal = 0.0f;
|
||||
double smoothVoronoiSample = NoiseUtils.smoothVoronoi(x * GEN_SCALE, y * GEN_SCALE, (double)SEED, FALLOFF_FACTOR);
|
||||
double inverted = 1.0 - smoothVoronoiSample;
|
||||
double minClamped = Math.max(inverted,0.0f);
|
||||
double powered = Math.pow(minClamped,POWER_SCALE);
|
||||
rVal = (float)powered * VERTICAL_SCALE;
|
||||
return rVal;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getTag() {
|
||||
return "mountains";
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user