From 784279e13fc75a091be4ddd27862445c93abf7ca Mon Sep 17 00:00:00 2001 From: austin Date: Mon, 21 Feb 2022 17:54:06 -0500 Subject: [PATCH] uninteractable menu --- assets/Data/creatures/human.json | 47 ++++++- assets/Data/items.json | 53 ++++---- assets/Textures/icons/itemIconEmpty.png | Bin 0 -> 7261 bytes assets/Textures/icons/itemIconItemGeneric.png | Bin 0 -> 11510 bytes assets/Textures/icons/itemIconWeapon.png | Bin 0 -> 12451 bytes .../controls/ControlHandler.java | 69 +++++++++- .../engine/assetmanager/AssetManager.java | 4 + .../entity/EntityDataStrings.java | 9 ++ .../entity/state/AttackTree.java | 54 ++++---- .../state/collidable/CollidableTree.java | 2 +- .../entity/state/equip/EquipState.java | 123 +++++++++++++----- .../state/{ => gravity}/GravityTree.java | 2 +- .../entity/state/gravity/GravityUtils.java | 15 +++ .../state/inventory/InventoryUtils.java | 67 ++++++++++ .../inventory/RelationalInventoryState.java | 23 +++- .../inventory/UnrelationalInventoryState.java | 8 +- .../state/movement/GroundMovementTree.java | 23 ++-- .../entity/types/creature/CreatureUtils.java | 30 ++++- .../entity/types/hitbox/HitboxManager.java | 6 +- .../entity/types/hitbox/HitboxUtils.java | 11 ++ .../entity/types/item/ItemUtils.java | 72 ++++++++-- .../game/collision/CollisionEngine.java | 14 ++ .../game/data/creature/type/CreatureType.java | 6 + .../data/creature/type/equip/EquipPoint.java | 33 +++++ .../game/data/item/type/Item.java | 4 + .../ai/creature/OpportunisticAttacker.java | 12 +- .../game/simulation/MicroSimulation.java | 2 +- src/main/java/electrosphere/main/Globals.java | 4 + src/main/java/electrosphere/main/Main.java | 16 ++- src/main/java/electrosphere/menu/Menu.java | 5 +- .../electrosphere/menu/MenuTransition.java | 6 + .../java/electrosphere/menu/MenuUtils.java | 60 ++++++++- .../renderer/ui/WindowManager.java | 38 ++++++ .../renderer/ui/widgets/ImagePanel.java | 21 ++- 34 files changed, 688 insertions(+), 151 deletions(-) create mode 100644 assets/Textures/icons/itemIconEmpty.png create mode 100644 assets/Textures/icons/itemIconItemGeneric.png create mode 100644 assets/Textures/icons/itemIconWeapon.png rename src/main/java/electrosphere/entity/state/{ => gravity}/GravityTree.java (99%) create mode 100644 src/main/java/electrosphere/entity/state/gravity/GravityUtils.java create mode 100644 src/main/java/electrosphere/entity/state/inventory/InventoryUtils.java create mode 100644 src/main/java/electrosphere/game/data/creature/type/equip/EquipPoint.java create mode 100644 src/main/java/electrosphere/renderer/ui/WindowManager.java diff --git a/assets/Data/creatures/human.json b/assets/Data/creatures/human.json index 826735db..3e0b7e8e 100644 --- a/assets/Data/creatures/human.json +++ b/assets/Data/creatures/human.json @@ -55,7 +55,8 @@ "ATTACKER", "GRAVITY", "TARGETABLE", - "CAN_EQUIP" + "CAN_EQUIP", + "INVENTORY" ], "visualAttributes" : [], "movementSystems" : [ @@ -131,6 +132,50 @@ } ] }, + "equipPoints" : [ + { + "equipPointId" : "handLeft", + "bone" : "MiddleLower.L", + "offsetVector" : [], + "offsetRotation" : [], + "equipClassWhitelist" : [ + "tool", + "shield", + "item" + ] + }, + { + "equipPointId" : "handRight", + "bone" : "MiddleLower.R", + "offsetVector" : [], + "offsetRotation" : [], + "equipClassWhitelist" : [ + "tool", + "weapon", + "item" + ] + }, + { + "equipPointId" : "Torso", + "bone" : "Bone", + "offsetVector" : [], + "offsetRotation" : [], + "equipClassWhitelist" : [ + "armor", + "clothing" + ] + }, + { + "equipPointId" : "Legs", + "bone" : "Bone", + "offsetVector" : [], + "offsetRotation" : [], + "equipClassWhitelist" : [ + "armor", + "clothing" + ] + } + ], "collidable" : { "type" : "CYLINDER", "dimension1" : 0.1, diff --git a/assets/Data/items.json b/assets/Data/items.json index d022a782..e3513492 100644 --- a/assets/Data/items.json +++ b/assets/Data/items.json @@ -26,10 +26,10 @@ "tokens" : [ "GRAVITY", "BLENDER_TRANSFORM", - "WEAPON", "MELEE", "TARGETABLE" ], + "equipClass" : "weapon", "idleAnim" : "Sword|Idle", "collidable": { "type" : "CUBE", @@ -39,36 +39,18 @@ "offsetX" : 0, "offsetY" : 0.05, "offsetZ" : 0 - } + }, + "iconPath" : "Textures/icons/itemIconWeapon.png" }, { "itemId" : "Bow", "modelPath": "Models/bow1.fbx", "tokens" : [ "GRAVITY", - "WEAPON", "RANGED", "TARGETABLE" ], - "collidable": { - "type" : "CUBE", - "dimension1" : 0.1, - "dimension2" : 0.1, - "dimension3" : 0.35, - "offsetX" : 0, - "offsetY" : 0.05, - "offsetZ" : 0 - } - }, - - { - "itemId" : "shorts1", - "modelPath": "Models/itemEntityShorts.fbx", - "tokens" : [ - "GRAVITY", - "ARMOR", - "TARGETABLE" - ], + "equipClass" : "weapon", "collidable": { "type" : "CUBE", "dimension1" : 0.1, @@ -78,6 +60,27 @@ "offsetY" : 0.05, "offsetZ" : 0 }, + "iconPath" : "Textures/icons/itemIconWeapon.png" + }, + + { + "itemId" : "shorts1", + "modelPath": "Models/itemEntityShorts.fbx", + "tokens" : [ + "GRAVITY", + "TARGETABLE" + ], + "equipClass" : "clothing", + "collidable": { + "type" : "CUBE", + "dimension1" : 0.1, + "dimension2" : 0.1, + "dimension3" : 0.35, + "offsetX" : 0, + "offsetY" : 0.05, + "offsetZ" : 0 + }, + "iconPath" : "Textures/icons/itemIconItemGeneric.png", "equipWhitelist" : [ { "creatureId" : "human", @@ -100,6 +103,7 @@ "ARMOR", "TARGETABLE" ], + "equipClass" : "trait", "collidable": { "type" : "CUBE", "dimension1" : 0.1, @@ -109,6 +113,7 @@ "offsetY" : 0.05, "offsetZ" : 0 }, + "iconPath" : "Textures/icons/itemIconItemGeneric.png", "equipWhitelist" : [ { "creatureId" : "human", @@ -129,6 +134,7 @@ "ARMOR", "TARGETABLE" ], + "equipClass" : "clothing", "collidable": { "type" : "CUBE", "dimension1" : 0.1, @@ -138,6 +144,7 @@ "offsetY" : 0.05, "offsetZ" : 0 }, + "iconPath" : "Textures/icons/itemIconItemGeneric.png", "equipWhitelist" : [ { "creatureId" : "human", @@ -164,6 +171,7 @@ "ARMOR", "TARGETABLE" ], + "equipClass" : "clothing", "collidable": { "type" : "CUBE", "dimension1" : 0.1, @@ -173,6 +181,7 @@ "offsetY" : 0.05, "offsetZ" : 0 }, + "iconPath" : "Textures/icons/itemIconItemGeneric.png", "equipWhitelist" : [ { "creatureId" : "human", diff --git a/assets/Textures/icons/itemIconEmpty.png b/assets/Textures/icons/itemIconEmpty.png new file mode 100644 index 0000000000000000000000000000000000000000..19e4625ed2ee14af217e4c7e2acec92003b834bc GIT binary patch literal 7261 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 Tyx0kNJC8L~9w^r++JycObC~gK literal 0 HcmV?d00001 diff --git a/assets/Textures/icons/itemIconWeapon.png b/assets/Textures/icons/itemIconWeapon.png new file mode 100644 index 0000000000000000000000000000000000000000..c60fc50fc6ee202b89079a0326d0fa914ee61eab GIT binary patch literal 12451 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 ZL4$C1#z{mHUH;x7mE_c9E2NG5{|}fbp*{cr literal 0 HcmV?d00001 diff --git a/src/main/java/electrosphere/controls/ControlHandler.java b/src/main/java/electrosphere/controls/ControlHandler.java index d7862e53..c3a80db4 100644 --- a/src/main/java/electrosphere/controls/ControlHandler.java +++ b/src/main/java/electrosphere/controls/ControlHandler.java @@ -8,6 +8,8 @@ import electrosphere.entity.types.creature.CreatureUtils; import electrosphere.entity.EntityUtils; import electrosphere.entity.state.AttackTree; import electrosphere.entity.state.equip.EquipState; +import electrosphere.entity.state.inventory.InventoryUtils; +import electrosphere.entity.state.inventory.UnrelationalInventoryState; import electrosphere.entity.state.movement.GroundMovementTree; import electrosphere.entity.state.movement.GroundMovementTree.MovementRelativeFacing; import electrosphere.entity.state.movement.GroundMovementTree.MovementTreeState; @@ -51,6 +53,7 @@ public class ControlHandler { public static final String INPUT_CODE_SPRINT = "sprint"; public static final String INPUT_CODE_INTERACT = "interact"; public static final String INPUT_CODE_DROP = "drop"; + public static final String INPUT_CODE_INVENTORY_OPEN = "inventoryOpen"; public static final String DATA_STRING_INPUT_CODE_MENU_INCREMENT = "menuIncrement"; public static final String DATA_STRING_INPUT_CODE_MENU_DECREMENT = "menuDecrement"; @@ -97,6 +100,9 @@ public class ControlHandler { public static final String DATA_STRING_INPUT_CODE_MENU_TYPE_X = "menuTypeX"; public static final String DATA_STRING_INPUT_CODE_MENU_TYPE_Y = "menuTypeY"; public static final String DATA_STRING_INPUT_CODE_MENU_TYPE_Z = "menuTypeZ"; + + public static final String INPUT_CODE_INVENTORY_CLOSE = "inventoryClose"; + public static final String INPUT_CODE_INVENTORY_ITEM_MANIPULATE = "inventoryItemManipulate"; public static enum ControlsState { @@ -104,6 +110,7 @@ public class ControlHandler { TITLE_MENU, MAIN_GAME, IN_GAME_MAIN_MENU, + INVENTORY, NO_INPUT, } @@ -117,6 +124,7 @@ public class ControlHandler { List mainGameDebugControlList = new LinkedList(); List menuNavigationControlList = new LinkedList(); List typingControlList = new LinkedList(); + List inventoryControlList = new LinkedList(); ControlHandler(){ controls = new HashMap(); @@ -145,6 +153,7 @@ public class ControlHandler { handler.addControl(INPUT_CODE_SPRINT, new Control(true,false,GLFW_KEY_LEFT_SHIFT)); handler.addControl(INPUT_CODE_INTERACT, new Control(true,false,GLFW_KEY_E)); handler.addControl(INPUT_CODE_DROP, new Control(true,false,GLFW_KEY_Y)); + handler.addControl(INPUT_CODE_INVENTORY_OPEN, new Control(true,false,GLFW_KEY_I)); /* Map the menu navigation controls @@ -195,6 +204,12 @@ public class ControlHandler { handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_X, new Control(true,false,GLFW_KEY_X)); handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_Y, new Control(true,false,GLFW_KEY_Y)); handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_Z, new Control(true,false,GLFW_KEY_Z)); + + /* + Inventory controls + */ + handler.addControl(INPUT_CODE_INVENTORY_CLOSE, new Control(true,false,GLFW_KEY_I)); + handler.addControl(INPUT_CODE_INVENTORY_ITEM_MANIPULATE, new Control(false,true,GLFW_MOUSE_BUTTON_1)); /* set state @@ -248,6 +263,10 @@ public class ControlHandler { runHandlers(menuNavigationControlList); // pollMenuNavigationControls(); break; + + case INVENTORY: + runHandlers(inventoryControlList); + break; case NO_INPUT: break; @@ -261,6 +280,7 @@ public class ControlHandler { setInGameDebugControls(); setMenuNavigationControls(); setTypingControls(); + setInventoryControls(); } void setMainGameControls(){ @@ -541,8 +561,13 @@ public class ControlHandler { controls.get(INPUT_CODE_INTERACT).setOnPress(new ControlMethod(){public void execute(){ if(Globals.playerCharacter != null){ if(Globals.playerCharacter.getDataKeys().contains(EntityDataStrings.EQUIP_STATE) && Crosshair.hasTarget()){ - EquipState equipState = (EquipState)Globals.playerCharacter.getData(EntityDataStrings.EQUIP_STATE); - equipState.attemptEquip(Crosshair.getTarget()); + if(InventoryUtils.hasNaturalInventory(Globals.playerCharacter)){ + InventoryUtils.attemptStoreItem(Globals.playerCharacter, Crosshair.getTarget()); + // UnrelationalInventoryState inventory = InventoryUtils.getNaturalInventory(Globals.playerCharacter); + // inventory.addItem(Crosshair.getTarget()); + } + // EquipState equipState = (EquipState)Globals.playerCharacter.getData(EntityDataStrings.EQUIP_STATE); + // // equipState.attemptEquip(Crosshair.getTarget()); } } }}); @@ -554,8 +579,13 @@ public class ControlHandler { controls.get(INPUT_CODE_DROP).setOnPress(new ControlMethod(){public void execute(){ if(Globals.playerCharacter != null){ if(Globals.playerCharacter.getDataKeys().contains(EntityDataStrings.EQUIP_STATE)){ - EquipState equipState = (EquipState)Globals.playerCharacter.getData(EntityDataStrings.EQUIP_STATE); - equipState.drop(); + // EquipState equipState = (EquipState)Globals.playerCharacter.getData(EntityDataStrings.EQUIP_STATE); + // equipState.drop(); + UnrelationalInventoryState inventory = InventoryUtils.getNaturalInventory(Globals.playerCharacter); + if(inventory.getItems().size() > 0){ + Entity itemToDrop = inventory.getItems().get(0); + InventoryUtils.attemptEjectItem(Globals.playerCharacter,itemToDrop); + } } } }}); @@ -602,6 +632,20 @@ public class ControlHandler { Globals.controlHandler.setHandlerState(ControlsState.IN_GAME_MAIN_MENU); }}); + /* + Open inventory + */ + mainGameControlList.add(controls.get(INPUT_CODE_INVENTORY_OPEN)); + controls.get(INPUT_CODE_INVENTORY_OPEN).setOnPress(new ControlMethod(){public void execute(){ + if(InventoryUtils.hasNaturalInventory(Globals.playerCharacter)){ + UnrelationalInventoryState inventory = InventoryUtils.getNaturalInventory(Globals.playerCharacter); + Globals.currentMenu = MenuUtils.createNaturalInventoryMenu(inventory); + MenuUtils.makeMenuDrawable(Globals.currentMenu); + Globals.controlHandler.setHandlerState(ControlsState.INVENTORY); + Globals.controlHandler.showMouse(); + } + }}); + } void setInGameDebugControls(){ @@ -734,6 +778,23 @@ public class ControlHandler { // } } } + + void setInventoryControls(){ + /* + Close inventory + */ + inventoryControlList.add(controls.get(INPUT_CODE_INVENTORY_CLOSE)); + controls.get(INPUT_CODE_INVENTORY_CLOSE).setOnPress(new ControlMethod(){public void execute(){ + MenuTransition.backout(Globals.currentMenu); + }}); + /* + Item manipulation + */ + inventoryControlList.add(controls.get(INPUT_CODE_INVENTORY_ITEM_MANIPULATE)); + controls.get(INPUT_CODE_INVENTORY_ITEM_MANIPULATE).setOnPress(new ControlMethod(){public void execute(){ + + }}); + } public Control getControl(String controlName){ return controls.get(controlName); diff --git a/src/main/java/electrosphere/engine/assetmanager/AssetManager.java b/src/main/java/electrosphere/engine/assetmanager/AssetManager.java index 128f3461..44d89f43 100644 --- a/src/main/java/electrosphere/engine/assetmanager/AssetManager.java +++ b/src/main/java/electrosphere/engine/assetmanager/AssetManager.java @@ -160,6 +160,10 @@ public class AssetManager { texturesLoadedIntoMemory.put(rVal,t); return rVal; } + + public boolean hasLoadedTexture(String path){ + return texturesLoadedIntoMemory.containsKey(path); + } diff --git a/src/main/java/electrosphere/entity/EntityDataStrings.java b/src/main/java/electrosphere/entity/EntityDataStrings.java index 3707fd9a..091fabc6 100644 --- a/src/main/java/electrosphere/entity/EntityDataStrings.java +++ b/src/main/java/electrosphere/entity/EntityDataStrings.java @@ -125,6 +125,8 @@ public class EntityDataStrings { public static final String COLLIDABLE_TREE = "collidableTree"; public static final String HITBOX_DATA = "hitboxData"; + public static final String HITBOX_ASSOCIATED_LIST = "hitboxAssociatedList"; + public static final String HURTBOX_ASSOCIATED_LIST = "hurtboxAssociatedList"; /* @@ -143,6 +145,7 @@ public class EntityDataStrings { public static final String ITEM_IS_WEAPON = "itemIsWeapon"; public static final String ITEM_IS_ARMOR = "itemIsArmor"; public static final String ITEM_EQUIP_WHITELIST = "itemEquipWhitelist"; + public static final String ITEM_ICON = "itemIcon"; /* @@ -186,6 +189,12 @@ public class EntityDataStrings { Equip state */ public static final String EQUIP_STATE = "equipState"; + public static final String EQUIP_INVENTORY = "equipInventory"; + + /* + Inventory in general + */ + public static final String NATURAL_INVENTORY = "inventoryNatural"; /* Entity categories diff --git a/src/main/java/electrosphere/entity/state/AttackTree.java b/src/main/java/electrosphere/entity/state/AttackTree.java index 21e46372..4cb9581c 100644 --- a/src/main/java/electrosphere/entity/state/AttackTree.java +++ b/src/main/java/electrosphere/entity/state/AttackTree.java @@ -190,11 +190,10 @@ public class AttackTree { if(parent.getDataKeys().contains(EntityDataStrings.ATTACH_CHILDREN_LIST)){ List attachedEntities = (List)parent.getData(EntityDataStrings.ATTACH_CHILDREN_LIST); for(Entity currentAttached : attachedEntities){ - if(currentAttached.getDataKeys().contains(EntityDataStrings.ITEM_IS_ITEM)){ - for(Entity hitbox : Globals.hitboxManager.getAllHitboxes()){ - if(hitbox.getData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT) == currentAttached){ - HitboxUtils.getHitboxData(hitbox).setActive(true); - } + if(currentAttached.getDataKeys().contains(EntityDataStrings.HITBOX_ASSOCIATED_LIST)){ + List hitboxes = HitboxUtils.getHitboxAssociatedList(currentAttached); + for(Entity hitbox : hitboxes){ + HitboxUtils.getHitboxData(hitbox).setActive(true); } } } @@ -239,11 +238,10 @@ public class AttackTree { if(parent.getDataKeys().contains(EntityDataStrings.ATTACH_CHILDREN_LIST)){ List attachedEntities = (List)parent.getData(EntityDataStrings.ATTACH_CHILDREN_LIST); for(Entity currentAttached : attachedEntities){ - if(currentAttached.getDataKeys().contains(EntityDataStrings.ITEM_IS_ITEM)){ - for(Entity hitbox : Globals.hitboxManager.getAllHitboxes()){ - if(hitbox.getData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT) == currentAttached){ - HitboxUtils.getHitboxData(hitbox).setActive(false); - } + if(currentAttached.getDataKeys().contains(EntityDataStrings.HITBOX_ASSOCIATED_LIST)){ + List hitboxes = HitboxUtils.getHitboxAssociatedList(currentAttached); + for(Entity hitbox : hitboxes){ + HitboxUtils.getHitboxData(hitbox).setActive(false); } } } @@ -305,24 +303,24 @@ public class AttackTree { } else { if(parent.getDataKeys().contains(EntityDataStrings.EQUIP_STATE)){ EquipState equipState = (EquipState)parent.getData(EntityDataStrings.EQUIP_STATE); - if(equipState.hasEquipPrimary()){ - switch(attackType){ - case EntityDataStrings.ATTACK_MOVE_TYPE_MELEE_SWING_ONE_HAND: - break; - default: - rVal = false; - break; - } - } else { - switch(attackType){ - case EntityDataStrings.ATTACK_MOVE_TYPE_MELEE_SWING_ONE_HAND: - rVal = false; - break; - default: - rVal = false; - break; - } - } + // if(equipState.hasEquipPrimary()){ + // switch(attackType){ + // case EntityDataStrings.ATTACK_MOVE_TYPE_MELEE_SWING_ONE_HAND: + // break; + // default: + // rVal = false; + // break; + // } + // } else { + // switch(attackType){ + // case EntityDataStrings.ATTACK_MOVE_TYPE_MELEE_SWING_ONE_HAND: + // rVal = false; + // break; + // default: + // rVal = false; + // break; + // } + // } } } return rVal; diff --git a/src/main/java/electrosphere/entity/state/collidable/CollidableTree.java b/src/main/java/electrosphere/entity/state/collidable/CollidableTree.java index c2d98a38..0fe28b2a 100644 --- a/src/main/java/electrosphere/entity/state/collidable/CollidableTree.java +++ b/src/main/java/electrosphere/entity/state/collidable/CollidableTree.java @@ -4,7 +4,7 @@ import electrosphere.collision.dispatch.CollisionObject; import electrosphere.entity.Entity; import electrosphere.entity.EntityDataStrings; import electrosphere.entity.EntityUtils; -import electrosphere.entity.state.GravityTree; +import electrosphere.entity.state.gravity.GravityTree; import electrosphere.game.collision.PhysicsUtils; import electrosphere.game.collision.collidable.Collidable; import electrosphere.game.data.creature.type.CollidableTemplate; diff --git a/src/main/java/electrosphere/entity/state/equip/EquipState.java b/src/main/java/electrosphere/entity/state/equip/EquipState.java index 1fd82422..fff9ab5f 100644 --- a/src/main/java/electrosphere/entity/state/equip/EquipState.java +++ b/src/main/java/electrosphere/entity/state/equip/EquipState.java @@ -1,6 +1,9 @@ package electrosphere.entity.state.equip; +import java.util.HashMap; +import java.util.LinkedList; import java.util.List; +import java.util.Map; import electrosphere.collision.dispatch.CollisionObject; import electrosphere.dynamics.RigidBody; @@ -12,6 +15,7 @@ import electrosphere.entity.types.creature.CreatureUtils; import electrosphere.entity.types.item.ItemUtils; import electrosphere.game.client.targeting.crosshair.Crosshair; import electrosphere.game.collision.collidable.Collidable; +import electrosphere.game.data.creature.type.equip.EquipPoint; import electrosphere.game.data.item.type.EquipWhitelist; import electrosphere.main.Globals; import electrosphere.renderer.actor.Actor; @@ -24,36 +28,38 @@ import electrosphere.renderer.actor.ActorMeshMask; public class EquipState { Entity parent; + + List equipPoints = new LinkedList(); + Map equipMap = new HashMap(); - Entity equipPrimary; - - String equipPrimaryBoneName; - - public EquipState(Entity parent, String equipPrimaryBoneName){ + public EquipState(Entity parent, List equipPoints){ this.parent = parent; - this.equipPrimaryBoneName = equipPrimaryBoneName; - } - - public boolean hasEquipPrimary(){ - return equipPrimary != null; + for(EquipPoint point : equipPoints){ + this.equipPoints.add(point); + } } - public Entity getEquipPrimary() { - return equipPrimary; - } - - public void setEquipPrimary(Entity equipPrimary) { - this.equipPrimary = equipPrimary; + public List equippedPoints(){ + return new LinkedList(equipMap.keySet()); } - public void attemptEquip(Entity toEquip){ - if(!hasEquipPrimary() && ItemUtils.isItem(toEquip) && !AttachUtils.isAttached(toEquip)){ - if(ItemUtils.hasEquipList(toEquip)){ + public void attemptEquip(Entity toEquip, EquipPoint point){ + boolean hasEquipped = equipMap.containsKey(point.getEquipPointId()); + boolean targetIsItem = ItemUtils.isItem(toEquip); + boolean targetIsAttached = AttachUtils.isAttached(toEquip); + boolean targetHasWhitelist = ItemUtils.hasEquipList(toEquip); + String equipItemClass = "";//somehow resolve from toEquip + List pointEquipClassList = point.getEquipClassWhitelist(); + boolean itemIsInPointWhitelist = pointEquipClassList.contains(equipItemClass); + if(!hasEquipped && targetIsItem && !targetIsAttached && itemIsInPointWhitelist){ + if(targetHasWhitelist){ + //by attaching are we going to be replacing meshes? String parentCreatureId = CreatureUtils.getType(parent); List whitelist = ItemUtils.getEquipWhitelist(toEquip); for(EquipWhitelist whitelistItem : whitelist){ if(whitelistItem.getCreatureId().equals(parentCreatureId)){ - equipPrimary = toEquip; + //put in map + equipMap.put(point.getEquipPointId(),toEquip); String modelName = whitelistItem.getModel(); Globals.assetManager.addModelPathToQueue(modelName); Actor parentActor = EntityUtils.getActor(parent); @@ -66,7 +72,7 @@ public class EquipState { meshMask.queueMesh(modelName, toDraw); } //attach to parent bone - AttachUtils.attachEntityToEntityAtBone(parent, toEquip, equipPrimaryBoneName); + AttachUtils.attachEntityToEntityAtBone(parent, toEquip, point.getBone()); //make uncollidable if(toEquip.getDataKeys().contains(EntityDataStrings.PHYSICS_COLLISION_BODY) && toEquip.getDataKeys().contains(EntityDataStrings.PHYSICS_COLLIDABLE)){ CollisionObject rigidBody = (CollisionObject)toEquip.getData(EntityDataStrings.PHYSICS_COLLISION_BODY); @@ -75,32 +81,79 @@ public class EquipState { //hide toEquip actor EntityUtils.setDraw(toEquip, false); //make untargetable - Globals.entityManager.setTargetable(equipPrimary, false); + Globals.entityManager.setTargetable(toEquip, false); break; } } } else { - equipPrimary = toEquip; - AttachUtils.attachEntityToEntityAtBone(parent, toEquip, equipPrimaryBoneName); + //since we're not replacing meshes we must be attaching to a bone + equipMap.put(point.getEquipPointId(),toEquip); + AttachUtils.attachEntityToEntityAtBone(parent, toEquip, point.getBone()); if(toEquip.getDataKeys().contains(EntityDataStrings.PHYSICS_COLLISION_BODY) && toEquip.getDataKeys().contains(EntityDataStrings.PHYSICS_COLLIDABLE)){ CollisionObject rigidBody = (CollisionObject)toEquip.getData(EntityDataStrings.PHYSICS_COLLISION_BODY); Globals.collisionEngine.deregisterPhysicsObject(rigidBody); } - Globals.entityManager.setTargetable(equipPrimary, false); + Globals.entityManager.setTargetable(toEquip, false); } } + // if(!hasEquipPrimary() && ItemUtils.isItem(toEquip) && !AttachUtils.isAttached(toEquip)){ + // if(ItemUtils.hasEquipList(toEquip)){ + // String parentCreatureId = CreatureUtils.getType(parent); + // List whitelist = ItemUtils.getEquipWhitelist(toEquip); + // for(EquipWhitelist whitelistItem : whitelist){ + // if(whitelistItem.getCreatureId().equals(parentCreatureId)){ + // equipPrimary = toEquip; + // 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 + // AttachUtils.attachEntityToEntityAtBone(parent, toEquip, equipPrimaryBoneName); + // //make uncollidable + // if(toEquip.getDataKeys().contains(EntityDataStrings.PHYSICS_COLLISION_BODY) && toEquip.getDataKeys().contains(EntityDataStrings.PHYSICS_COLLIDABLE)){ + // CollisionObject rigidBody = (CollisionObject)toEquip.getData(EntityDataStrings.PHYSICS_COLLISION_BODY); + // Globals.collisionEngine.deregisterPhysicsObject(rigidBody); + // } + // //hide toEquip actor + // EntityUtils.setDraw(toEquip, false); + // //make untargetable + // Globals.entityManager.setTargetable(equipPrimary, false); + // break; + // } + // } + // } else { + // equipPrimary = toEquip; + // AttachUtils.attachEntityToEntityAtBone(parent, toEquip, equipPrimaryBoneName); + // if(toEquip.getDataKeys().contains(EntityDataStrings.PHYSICS_COLLISION_BODY) && toEquip.getDataKeys().contains(EntityDataStrings.PHYSICS_COLLIDABLE)){ + // CollisionObject rigidBody = (CollisionObject)toEquip.getData(EntityDataStrings.PHYSICS_COLLISION_BODY); + // Globals.collisionEngine.deregisterPhysicsObject(rigidBody); + // } + // Globals.entityManager.setTargetable(equipPrimary, false); + // } + // } } - public void drop(){ - if(hasEquipPrimary()){ - AttachUtils.detatchEntityFromEntityAtBone(parent,equipPrimary); - if(equipPrimary.getDataKeys().contains(EntityDataStrings.PHYSICS_COLLISION_BODY) && equipPrimary.getDataKeys().contains(EntityDataStrings.PHYSICS_COLLIDABLE)){ - CollisionObject rigidBody = (CollisionObject)equipPrimary.getData(EntityDataStrings.PHYSICS_COLLISION_BODY); - Globals.collisionEngine.registerPhysicsObject(rigidBody); - } - Globals.entityManager.setTargetable(equipPrimary, true); - equipPrimary = null; - } + // public void drop(Entity entity){ + // if(hasEquipPrimary()){ + // AttachUtils.detatchEntityFromEntityAtBone(parent,equipPrimary); + // if(equipPrimary.getDataKeys().contains(EntityDataStrings.PHYSICS_COLLISION_BODY) && equipPrimary.getDataKeys().contains(EntityDataStrings.PHYSICS_COLLIDABLE)){ + // CollisionObject rigidBody = (CollisionObject)equipPrimary.getData(EntityDataStrings.PHYSICS_COLLISION_BODY); + // Globals.collisionEngine.registerPhysicsObject(rigidBody); + // } + // Globals.entityManager.setTargetable(equipPrimary, true); + // equipPrimary = null; + // } + // } + + public void unequipPoint(String pointId){ + equipMap.remove(pointId); } diff --git a/src/main/java/electrosphere/entity/state/GravityTree.java b/src/main/java/electrosphere/entity/state/gravity/GravityTree.java similarity index 99% rename from src/main/java/electrosphere/entity/state/GravityTree.java rename to src/main/java/electrosphere/entity/state/gravity/GravityTree.java index db2b3dbb..4faecbcc 100644 --- a/src/main/java/electrosphere/entity/state/GravityTree.java +++ b/src/main/java/electrosphere/entity/state/gravity/GravityTree.java @@ -1,4 +1,4 @@ -package electrosphere.entity.state; +package electrosphere.entity.state.gravity; import electrosphere.collision.dispatch.CollisionObject; import electrosphere.entity.Entity; diff --git a/src/main/java/electrosphere/entity/state/gravity/GravityUtils.java b/src/main/java/electrosphere/entity/state/gravity/GravityUtils.java new file mode 100644 index 00000000..0ee72b5c --- /dev/null +++ b/src/main/java/electrosphere/entity/state/gravity/GravityUtils.java @@ -0,0 +1,15 @@ +package electrosphere.entity.state.gravity; + +import electrosphere.entity.Entity; +import electrosphere.entity.EntityDataStrings; + +public class GravityUtils { + + public static void attemptActivateGravity(Entity target){ + if(target.getDataKeys().contains(EntityDataStrings.GRAVITY_ENTITY)){ + GravityTree tree = (GravityTree)target.getData(EntityDataStrings.GRAVITY_TREE); + tree.start(); + } + } + +} \ No newline at end of file diff --git a/src/main/java/electrosphere/entity/state/inventory/InventoryUtils.java b/src/main/java/electrosphere/entity/state/inventory/InventoryUtils.java new file mode 100644 index 00000000..e28afd36 --- /dev/null +++ b/src/main/java/electrosphere/entity/state/inventory/InventoryUtils.java @@ -0,0 +1,67 @@ +package electrosphere.entity.state.inventory; + +import org.joml.Vector3d; +import org.joml.Vector3f; + +import electrosphere.entity.Entity; +import electrosphere.entity.EntityDataStrings; +import electrosphere.entity.EntityUtils; +import electrosphere.entity.state.gravity.GravityUtils; +import electrosphere.entity.types.creature.CreatureUtils; +import electrosphere.entity.types.item.ItemUtils; + +public class InventoryUtils { + + + public static boolean hasNaturalInventory(Entity target){ + return target.getDataKeys().contains(EntityDataStrings.NATURAL_INVENTORY); + } + + public static UnrelationalInventoryState getNaturalInventory(Entity target){ + return (UnrelationalInventoryState)target.getData(EntityDataStrings.NATURAL_INVENTORY); + } + + public static void attemptStoreItem(Entity creature, Entity item){ + boolean creatureIsCreature = CreatureUtils.isCreature(creature); + boolean itemIsItem = ItemUtils.isItem(item); + boolean hasInventory = hasNaturalInventory(creature); + 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 = ItemUtils.recreateContainerItem(item); + //destroy the item that was left over + ItemUtils.destroyInWorldItem(item); + //store item in inventory + inventory.addItem(inventoryItem); + } + } + + //need creature so we can figure out where to drop the item + public static void attemptEjectItem(Entity creature, Entity item){ + //verify creature is creature, item is item, inventory exists, and item is in inventory + boolean creatureIsCreature = CreatureUtils.isCreature(creature); + boolean itemIsItem = ItemUtils.isItem(item); + boolean hasInventory = hasNaturalInventory(creature); + if(creatureIsCreature && itemIsItem && hasInventory){ + //get inventory + UnrelationalInventoryState inventory = getNaturalInventory(creature); + //remove item from inventory + inventory.removeItem(item); + //compose item into in-world entity + Entity inWorldItem = ItemUtils.spawnBasicItem(ItemUtils.getType(item)); + //delete in container item + ItemUtils.destroyInInventoryItem(item); + //find "in front of creature" + Vector3d dropSpot = new Vector3d(EntityUtils.getPosition(creature)).add(CreatureUtils.getFacingVector(creature)); + //move in-world entity to in front of creature + EntityUtils.getPosition(inWorldItem).set(dropSpot); + //activate gravity + GravityUtils.attemptActivateGravity(inWorldItem); + } + } + +} diff --git a/src/main/java/electrosphere/entity/state/inventory/RelationalInventoryState.java b/src/main/java/electrosphere/entity/state/inventory/RelationalInventoryState.java index e729f7b0..250e2fed 100644 --- a/src/main/java/electrosphere/entity/state/inventory/RelationalInventoryState.java +++ b/src/main/java/electrosphere/entity/state/inventory/RelationalInventoryState.java @@ -1,22 +1,31 @@ package electrosphere.entity.state.inventory; import java.util.HashMap; +import java.util.LinkedList; import java.util.List; import java.util.Map; -import java.util.Set; import electrosphere.entity.Entity; +import electrosphere.game.data.creature.type.equip.EquipPoint; public class RelationalInventoryState { - int capacity; - Map items = new HashMap(); - public RelationalInventoryState(List slots){ + public static RelationalInventoryState buildRelationalInventoryStateFromStringList(List slots){ + RelationalInventoryState rVal = new RelationalInventoryState(); for(String slot : slots){ - items.put(slot,null); + rVal.items.put(slot,null); } + return rVal; + } + + public static RelationalInventoryState buildRelationalInventoryStateFromEquipList(List points){ + RelationalInventoryState rVal = new RelationalInventoryState(); + for(EquipPoint point : points){ + rVal.items.put(point.getEquipPointId(),null); + } + return rVal; } public void addItem(String slot, Entity item){ @@ -38,8 +47,8 @@ public class RelationalInventoryState { return items.containsKey(slot) ? items.get(slot) != null : false; } - public Set getSlots(){ - return items.keySet(); + public List getSlots(){ + return new LinkedList(items.keySet()); } } diff --git a/src/main/java/electrosphere/entity/state/inventory/UnrelationalInventoryState.java b/src/main/java/electrosphere/entity/state/inventory/UnrelationalInventoryState.java index 1b6ae14c..8bdfbf37 100644 --- a/src/main/java/electrosphere/entity/state/inventory/UnrelationalInventoryState.java +++ b/src/main/java/electrosphere/entity/state/inventory/UnrelationalInventoryState.java @@ -11,6 +11,10 @@ public class UnrelationalInventoryState { List items = new LinkedList(); + public UnrelationalInventoryState(int capacity){ + this.capacity = capacity; + } + public void addItem(Entity item){ items.add(item); } @@ -23,7 +27,9 @@ public class UnrelationalInventoryState { return items; } - + public int getCapacity(){ + return capacity; + } } diff --git a/src/main/java/electrosphere/entity/state/movement/GroundMovementTree.java b/src/main/java/electrosphere/entity/state/movement/GroundMovementTree.java index bea4b644..c8301598 100644 --- a/src/main/java/electrosphere/entity/state/movement/GroundMovementTree.java +++ b/src/main/java/electrosphere/entity/state/movement/GroundMovementTree.java @@ -1,6 +1,8 @@ package electrosphere.entity.state.movement; import electrosphere.entity.state.collidable.Impulse; +import electrosphere.entity.state.gravity.GravityTree; +import electrosphere.entity.state.gravity.GravityUtils; import electrosphere.collision.dispatch.CollisionObject; import electrosphere.dynamics.RigidBody; import electrosphere.entity.CameraEntityUtils; @@ -10,8 +12,6 @@ import electrosphere.entity.EntityDataStrings; import electrosphere.entity.EntityUtils; import electrosphere.entity.state.AttackTree; import electrosphere.entity.state.AttackTree.AttackTreeState; -import electrosphere.entity.state.GravityTree; -import electrosphere.entity.state.GravityTree; import electrosphere.entity.state.movement.SprintTree.SprintTreeState; import electrosphere.game.collision.CollisionEngine; import electrosphere.game.collision.PhysicsUtils; @@ -179,17 +179,17 @@ public class GroundMovementTree { case 0: state = MovementTreeState.STARTUP; // System.out.println("Set state STARTUP"); - activateGravityTree(); + GravityUtils.attemptActivateGravity(parent); break; case 1: state = MovementTreeState.MOVE; // System.out.println("Set state MOVE"); - activateGravityTree(); + GravityUtils.attemptActivateGravity(parent); break; case 2: state = MovementTreeState.SLOWDOWN; // System.out.println("Set state SLOWDOWN"); - activateGravityTree(); + GravityUtils.attemptActivateGravity(parent); break; case 3: state = MovementTreeState.IDLE; @@ -247,7 +247,7 @@ public class GroundMovementTree { // position.set(newPosition); rotation.set(movementQuaternion); - activateGravityTree(); + GravityUtils.attemptActivateGravity(parent); if(Globals.RUN_SERVER){ // Globals.server.broadcastMessage( @@ -323,7 +323,7 @@ public class GroundMovementTree { // position.set(newPosition); rotation.set(movementQuaternion); - activateGravityTree(); + GravityUtils.attemptActivateGravity(parent); if(Globals.RUN_SERVER){ // Globals.server.broadcastMessage( @@ -407,7 +407,7 @@ public class GroundMovementTree { // position.set(newPosition); rotation.set(movementQuaternion); - activateGravityTree(); + GravityUtils.attemptActivateGravity(parent); if(Globals.RUN_SERVER){ // Globals.server.broadcastMessage( @@ -474,13 +474,6 @@ public class GroundMovementTree { networkMessageQueue.add(networkMessage); } - public void activateGravityTree(){ - if(parent.getDataKeys().contains(EntityDataStrings.GRAVITY_ENTITY)){ - GravityTree tree = (GravityTree)parent.getData(EntityDataStrings.GRAVITY_TREE); - tree.start(); - } - } - public boolean canStartMoving(){ boolean rVal = true; if(parent.getDataKeys().contains(EntityDataStrings.ATTACK_TREE) && ((AttackTree)parent.getData(EntityDataStrings.ATTACK_TREE)).getState() != AttackTreeState.IDLE){ diff --git a/src/main/java/electrosphere/entity/types/creature/CreatureUtils.java b/src/main/java/electrosphere/entity/types/creature/CreatureUtils.java index c7b2b77e..d0e75c33 100644 --- a/src/main/java/electrosphere/entity/types/creature/CreatureUtils.java +++ b/src/main/java/electrosphere/entity/types/creature/CreatureUtils.java @@ -11,10 +11,12 @@ import electrosphere.entity.types.hitbox.HitboxUtils; import electrosphere.game.data.creature.type.CreatureType; import electrosphere.game.data.creature.type.MovementSystem; import electrosphere.entity.state.AttackTree; -import electrosphere.entity.state.GravityTree; import electrosphere.entity.state.IdleTree; import electrosphere.entity.state.collidable.CollidableTree; import electrosphere.entity.state.equip.EquipState; +import electrosphere.entity.state.gravity.GravityTree; +import electrosphere.entity.state.inventory.RelationalInventoryState; +import electrosphere.entity.state.inventory.UnrelationalInventoryState; import electrosphere.entity.types.collision.CollisionObjUtils; import electrosphere.entity.state.life.LifeState; import electrosphere.entity.state.movement.SprintTree; @@ -23,6 +25,7 @@ import electrosphere.game.collision.collidable.Collidable; import electrosphere.game.data.creature.type.CollidableTemplate; import electrosphere.game.data.creature.type.SprintSystem; import electrosphere.game.data.creature.type.attack.AttackMove; +import electrosphere.game.data.creature.type.equip.EquipPoint; import electrosphere.game.data.creature.type.visualattribute.AttributeVariant; import electrosphere.game.data.creature.type.visualattribute.VisualAttribute; import electrosphere.logger.LoggerInterface; @@ -36,6 +39,10 @@ import electrosphere.renderer.Model; import electrosphere.renderer.actor.Actor; import electrosphere.renderer.actor.ActorUtils; import electrosphere.util.ModelLoader; + +import java.util.LinkedList; +import java.util.List; + import org.joml.Quaternionf; import org.joml.Vector3d; import org.joml.Vector3f; @@ -70,11 +77,19 @@ public class CreatureUtils { Entity rVal = EntityUtils.spawnDrawableEntity(rawType.getModelPath()); Actor creatureActor = EntityUtils.getActor(rVal); for(HitboxData hitboxdata : rawType.getHitboxes()){ + List hitboxList = new LinkedList(); + List hurtboxList = new LinkedList(); if(hitboxdata.getType().equals("hit")){ - Globals.hitboxManager.registerHitbox(HitboxUtils.spawnRegularHitbox(rVal, hitboxdata.getBone(), hitboxdata.getRadius())); + Entity hitbox = HitboxUtils.spawnRegularHitbox(rVal, hitboxdata.getBone(), hitboxdata.getRadius()); + Globals.hitboxManager.registerHitbox(hitbox); + hitboxList.add(hitbox); } else if(hitboxdata.getType().equals("hurt")){ - Globals.hitboxManager.registerHitbox(HitboxUtils.spawnRegularHurtbox(rVal, hitboxdata.getBone(), hitboxdata.getRadius())); + Entity hurtbox = HitboxUtils.spawnRegularHurtbox(rVal, hitboxdata.getBone(), hitboxdata.getRadius()); + Globals.hitboxManager.registerHitbox(hurtbox); + hurtboxList.add(hurtbox); } + rVal.putData(EntityDataStrings.HITBOX_ASSOCIATED_LIST, hitboxList); + rVal.putData(EntityDataStrings.HURTBOX_ASSOCIATED_LIST, hurtboxList); } if(rawType.getCollidable() != null){ CollidableTemplate physicsTemplate = rawType.getCollidable(); @@ -136,6 +151,10 @@ public class CreatureUtils { break; } } + if(rawType.getEquipPoints() != null && rawType.getEquipPoints().size() > 0){ + rVal.putData(EntityDataStrings.EQUIP_STATE, new EquipState(rVal,rawType.getEquipPoints())); + rVal.putData(EntityDataStrings.EQUIP_INVENTORY, RelationalInventoryState.buildRelationalInventoryStateFromEquipList(rawType.getEquipPoints())); + } for(String token : rawType.getTokens()){ switch(token){ case "BLENDER_TRANSFORM": @@ -170,8 +189,11 @@ public class CreatureUtils { Globals.entityManager.registerTargetableEntity(rVal); break; case "CAN_EQUIP": - rVal.putData(EntityDataStrings.EQUIP_STATE, new EquipState(rVal,"MiddleLower.R")); + // rVal.putData(EntityDataStrings.EQUIP_STATE, new EquipState(rVal,"MiddleLower.R")); break; + case "INVENTORY": + rVal.putData(EntityDataStrings.NATURAL_INVENTORY,new UnrelationalInventoryState(10)); + break; } } //variants diff --git a/src/main/java/electrosphere/entity/types/hitbox/HitboxManager.java b/src/main/java/electrosphere/entity/types/hitbox/HitboxManager.java index e29a6dc0..dfe96211 100644 --- a/src/main/java/electrosphere/entity/types/hitbox/HitboxManager.java +++ b/src/main/java/electrosphere/entity/types/hitbox/HitboxManager.java @@ -12,7 +12,7 @@ import java.util.concurrent.CopyOnWriteArrayList; */ public class HitboxManager { - CopyOnWriteArrayList hitboxes = new CopyOnWriteArrayList(); + CopyOnWriteArrayList hitboxes = new CopyOnWriteArrayList(); long idIncrementer = 0; public HitboxManager(){ @@ -28,4 +28,8 @@ public class HitboxManager { public CopyOnWriteArrayList getAllHitboxes(){ return hitboxes; } + + public void deregisterHitbox(Entity hitbox){ + hitboxes.remove(hitbox); + } } diff --git a/src/main/java/electrosphere/entity/types/hitbox/HitboxUtils.java b/src/main/java/electrosphere/entity/types/hitbox/HitboxUtils.java index 4074dbea..e2e81b33 100644 --- a/src/main/java/electrosphere/entity/types/hitbox/HitboxUtils.java +++ b/src/main/java/electrosphere/entity/types/hitbox/HitboxUtils.java @@ -9,6 +9,9 @@ import electrosphere.entity.state.life.LifeState; import electrosphere.entity.state.life.LifeUtils; import electrosphere.game.server.effects.ParticleEffects; import electrosphere.main.Globals; + +import java.util.List; + import org.joml.Matrix4f; import org.joml.Quaternionf; import org.joml.Vector3d; @@ -148,5 +151,13 @@ public class HitboxUtils { public static HitboxData getHitboxData(Entity e){ return (HitboxData)e.getData(EntityDataStrings.HITBOX_DATA); } + + public static List getHitboxAssociatedList(Entity e){ + return (List)e.getData(EntityDataStrings.HITBOX_ASSOCIATED_LIST); + } + + public static List getHurtboxAssociatedList(Entity e){ + return (List)e.getData(EntityDataStrings.HURTBOX_ASSOCIATED_LIST); + } } diff --git a/src/main/java/electrosphere/entity/types/item/ItemUtils.java b/src/main/java/electrosphere/entity/types/item/ItemUtils.java index 417e12c5..8303f055 100644 --- a/src/main/java/electrosphere/entity/types/item/ItemUtils.java +++ b/src/main/java/electrosphere/entity/types/item/ItemUtils.java @@ -4,10 +4,11 @@ import electrosphere.collision.dispatch.CollisionObject; import electrosphere.entity.Entity; import electrosphere.entity.EntityDataStrings; import electrosphere.entity.EntityUtils; -import electrosphere.entity.state.GravityTree; import electrosphere.entity.state.collidable.CollidableTree; +import electrosphere.entity.state.gravity.GravityTree; import electrosphere.entity.state.movement.GroundMovementTree; import electrosphere.entity.types.attach.AttachUtils; +import electrosphere.entity.types.collision.CollisionObjUtils; import electrosphere.entity.types.hitbox.HitboxData; import electrosphere.entity.types.hitbox.HitboxUtils; import electrosphere.game.collision.PhysicsUtils; @@ -24,6 +25,7 @@ import electrosphere.renderer.Model; import electrosphere.renderer.actor.Actor; import electrosphere.renderer.actor.ActorUtils; +import java.util.LinkedList; import java.util.List; import org.joml.Quaternionf; @@ -35,13 +37,20 @@ import org.joml.Vector3f; * @author amaterasu */ public class ItemUtils { + + static final String genericItemIconPath = "Textures/icons/itemIconItemGeneric.png"; + public static Entity spawnBasicItem(String name){ Item item = Globals.gameConfigCurrent.getItemMap().getItem(name); Entity rVal = EntityUtils.spawnDrawableEntity(item.getModelPath()); if(item.getHitboxes() != null){ + List hitboxList = new LinkedList(); for(HitboxData hitboxdata : item.getHitboxes()){ - Globals.hitboxManager.registerHitbox(HitboxUtils.spawnRegularHitbox(rVal, hitboxdata.getBone(), hitboxdata.getRadius())); + Entity hitbox = HitboxUtils.spawnRegularHitbox(rVal, hitboxdata.getBone(), hitboxdata.getRadius()); + Globals.hitboxManager.registerHitbox(hitbox); + hitboxList.add(hitbox); } + rVal.putData(EntityDataStrings.HITBOX_ASSOCIATED_LIST,hitboxList); } if(item.getCollidable() != null){ CollidableTemplate physicsTemplate = item.getCollidable(); @@ -93,12 +102,6 @@ public class ItemUtils { case "TARGETABLE": Globals.entityManager.registerTargetableEntity(rVal); break; - case "WEAPON": - rVal.putData(EntityDataStrings.ITEM_IS_WEAPON, true); - break; - case "ARMOR": - rVal.putData(EntityDataStrings.ITEM_IS_ARMOR, true); - break; } } if(item.getEquipWhitelist() != null){ @@ -107,6 +110,11 @@ public class ItemUtils { if(item.getIdleAnim() != null){ rVal.putData(EntityDataStrings.ANIM_IDLE,item.getIdleAnim()); } + if(item.getIconPath() != null && !item.getIconPath().equals("")){ + rVal.putData(EntityDataStrings.ITEM_ICON,item.getIconPath()); + } else { + rVal.putData(EntityDataStrings.ITEM_ICON,genericItemIconPath); + } rVal.putData(EntityDataStrings.DRAW_CAST_SHADOW, true); rVal.putData(EntityDataStrings.ITEM_IS_ITEM, true); rVal.putData(EntityDataStrings.ITEM_TYPE, name); @@ -192,4 +200,52 @@ public class ItemUtils { return (List)item.getData(EntityDataStrings.ITEM_EQUIP_WHITELIST); } + /** + * Emits an entity which represents the item inside a container + */ + public static Entity recreateContainerItem(Entity item){ + if(isItem(item)){ + Entity rVal = new Entity(); + if(getEquipWhitelist(item) != null){ + rVal.putData(EntityDataStrings.ITEM_EQUIP_WHITELIST, getEquipWhitelist(item)); + } + rVal.putData(EntityDataStrings.ITEM_ICON,ItemUtils.getItemIcon(item)); + rVal.putData(EntityDataStrings.ITEM_IS_ITEM, true); + rVal.putData(EntityDataStrings.ITEM_TYPE, item.getData(EntityDataStrings.ITEM_TYPE)); + Globals.entityManager.registerEntity(rVal); + return rVal; + } else { + return null; + } + } + + public static void destroyInWorldItem(Entity item){ + if(isItem(item)){ + //destroy physics + if(item.getDataKeys().contains(EntityDataStrings.PHYSICS_COLLISION_BODY) && item.getDataKeys().contains(EntityDataStrings.PHYSICS_COLLIDABLE)){ + //destroy physics + //this deregisters from all four & unhooks rigid bodies from the physics runtime + Globals.collisionEngine.destroyEntityThatHasPhysics(item); + //destroy hitboxes + List hitboxes = HitboxUtils.getHitboxAssociatedList(item); + if(hitboxes != null){ + for(Entity hitbox : hitboxes){ + Globals.hitboxManager.deregisterHitbox(hitbox); + HitboxUtils.getHitboxData(hitbox).setActive(false); + } + } + //destroy graphics + EntityUtils.cleanUpDrawableEntity(item); + } + } + } + + public static void destroyInInventoryItem(Entity item){ + Globals.entityManager.deregisterEntity(item); + } + + public static String getItemIcon(Entity item){ + return (String)item.getData(EntityDataStrings.ITEM_ICON); + } + } diff --git a/src/main/java/electrosphere/game/collision/CollisionEngine.java b/src/main/java/electrosphere/game/collision/CollisionEngine.java index d972ac25..4b9c8c25 100644 --- a/src/main/java/electrosphere/game/collision/CollisionEngine.java +++ b/src/main/java/electrosphere/game/collision/CollisionEngine.java @@ -28,6 +28,7 @@ import electrosphere.entity.EntityUtils; import electrosphere.entity.state.collidable.Impulse; import electrosphere.entity.types.hitbox.HitboxData; import electrosphere.game.collision.collidable.Collidable; + import static electrosphere.main.Main.deltaTime; import java.util.ArrayList; import java.util.List; @@ -278,6 +279,10 @@ public class CollisionEngine { public List getPhysicsEntities(){ return physicsEntities; } + + public void deregisterPhysicsEntity(Entity physicsEntity){ + physicsEntities.remove(physicsEntity); + } public void registerDynamicPhysicsEntity(Entity dynamicEntity){ dynamicPhysicsEntities.add(dynamicEntity); @@ -466,5 +471,14 @@ public class CollisionEngine { structurePhysicsEntities.remove(e); } } + + public void destroyEntityThatHasPhysics(Entity e){ + //make uncollidable + if(e.getDataKeys().contains(EntityDataStrings.PHYSICS_COLLISION_BODY) && e.getDataKeys().contains(EntityDataStrings.PHYSICS_COLLIDABLE)){ + CollisionObject rigidBody = (CollisionObject)e.getData(EntityDataStrings.PHYSICS_COLLISION_BODY); + deregisterPhysicsObject(rigidBody); + } + deregisterCollidableEntity(e); + } } diff --git a/src/main/java/electrosphere/game/data/creature/type/CreatureType.java b/src/main/java/electrosphere/game/data/creature/type/CreatureType.java index c9a06d4e..17337ea8 100644 --- a/src/main/java/electrosphere/game/data/creature/type/CreatureType.java +++ b/src/main/java/electrosphere/game/data/creature/type/CreatureType.java @@ -3,6 +3,7 @@ package electrosphere.game.data.creature.type; import electrosphere.entity.types.hitbox.HitboxData; import electrosphere.game.data.creature.type.attack.AttackMove; import electrosphere.game.data.creature.type.attack.AttackMoveResolver; +import electrosphere.game.data.creature.type.equip.EquipPoint; import electrosphere.game.data.creature.type.rotator.RotatorSystem; import electrosphere.game.data.creature.type.visualattribute.VisualAttribute; @@ -15,6 +16,7 @@ public class CreatureType { List visualAttributes; List movementSystems; RotatorSystem rotatorSystem; + List equipPoints; CollidableTemplate collidable; List attackMoves; HealthSystem healthSystem; @@ -67,6 +69,10 @@ public class CreatureType { return rotatorSystem; } + public List getEquipPoints(){ + return equipPoints; + } + public void setAttackMoveResolver(AttackMoveResolver resolver){ attackMoveResolver = resolver; } diff --git a/src/main/java/electrosphere/game/data/creature/type/equip/EquipPoint.java b/src/main/java/electrosphere/game/data/creature/type/equip/EquipPoint.java new file mode 100644 index 00000000..34ab1d7a --- /dev/null +++ b/src/main/java/electrosphere/game/data/creature/type/equip/EquipPoint.java @@ -0,0 +1,33 @@ +package electrosphere.game.data.creature.type.equip; + +import java.util.List; + +public class EquipPoint { + + String equipPointId; + String bone; + List offsetVector; + List offsetRotation; + List equipClassWhitelist; + + public String getEquipPointId(){ + return equipPointId; + } + + public String getBone(){ + return bone; + } + + public List getOffsetVector(){ + return offsetVector; + } + + public List getOffsetRotation(){ + return offsetRotation; + } + + public List getEquipClassWhitelist(){ + return equipClassWhitelist; + } + +} diff --git a/src/main/java/electrosphere/game/data/item/type/Item.java b/src/main/java/electrosphere/game/data/item/type/Item.java index 8ff8d26d..392f49e5 100644 --- a/src/main/java/electrosphere/game/data/item/type/Item.java +++ b/src/main/java/electrosphere/game/data/item/type/Item.java @@ -13,6 +13,7 @@ public class Item { CollidableTemplate collidable; List equipWhitelist; String idleAnim; + String iconPath; public String getItemId() { return itemId; @@ -42,5 +43,8 @@ public class Item { return idleAnim; } + public String getIconPath(){ + return iconPath; + } } diff --git a/src/main/java/electrosphere/game/server/ai/creature/OpportunisticAttacker.java b/src/main/java/electrosphere/game/server/ai/creature/OpportunisticAttacker.java index c6fed489..8184e30a 100644 --- a/src/main/java/electrosphere/game/server/ai/creature/OpportunisticAttacker.java +++ b/src/main/java/electrosphere/game/server/ai/creature/OpportunisticAttacker.java @@ -208,9 +208,9 @@ public class OpportunisticAttacker extends AI { boolean rVal = false; if(character.getDataKeys().contains(EntityDataStrings.EQUIP_STATE)){ EquipState equipState = (EquipState)character.getData(EntityDataStrings.EQUIP_STATE); - if(equipState.hasEquipPrimary()){ - rVal = true; - } + // if(equipState.hasEquipPrimary()){ + // rVal = true; + // } } return rVal; } @@ -244,9 +244,9 @@ public class OpportunisticAttacker extends AI { void pickupWeapon(){ if(character.getDataKeys().contains(EntityDataStrings.EQUIP_STATE)){ EquipState equipState = (EquipState)character.getData(EntityDataStrings.EQUIP_STATE); - if(!equipState.hasEquipPrimary()){ - equipState.attemptEquip(target); - } + // if(!equipState.hasEquipPrimary()){ + // equipState.attemptEquip(target); + // } } } diff --git a/src/main/java/electrosphere/game/simulation/MicroSimulation.java b/src/main/java/electrosphere/game/simulation/MicroSimulation.java index cdcbd7d5..d22ce1e2 100644 --- a/src/main/java/electrosphere/game/simulation/MicroSimulation.java +++ b/src/main/java/electrosphere/game/simulation/MicroSimulation.java @@ -5,11 +5,11 @@ import electrosphere.entity.Entity; import electrosphere.entity.EntityDataStrings; import electrosphere.entity.EntityUtils; import electrosphere.entity.state.AttackTree; -import electrosphere.entity.state.GravityTree; import electrosphere.entity.state.IdleTree; import electrosphere.entity.state.movement.GroundMovementTree; import electrosphere.entity.state.ParticleTree; import electrosphere.entity.state.collidable.CollidableTree; +import electrosphere.entity.state.gravity.GravityTree; import electrosphere.entity.types.creature.CreatureUtils; import electrosphere.entity.types.hitbox.HitboxUtils; import electrosphere.entity.types.item.ItemUtils; diff --git a/src/main/java/electrosphere/main/Globals.java b/src/main/java/electrosphere/main/Globals.java index 87c3beb8..8c2143b6 100644 --- a/src/main/java/electrosphere/main/Globals.java +++ b/src/main/java/electrosphere/main/Globals.java @@ -53,6 +53,7 @@ import electrosphere.game.server.pathfinding.NavMeshManager; import electrosphere.renderer.ui.Widget; import electrosphere.renderer.ui.WidgetManager; import electrosphere.renderer.ui.WidgetUtils; +import electrosphere.renderer.ui.WindowManager; import electrosphere.renderer.ui.font.FontUtils; import electrosphere.renderer.ui.font.RawFontMap; import electrosphere.renderer.ui.font.TextBox; @@ -275,6 +276,9 @@ public class Globals { //thread for loading different game states public static LoadingThread loadingThread; + //manages all windows to be drawn to the screen + public static WindowManager windowManager; + //manager for all widgets currently being drawn to screen public static WidgetManager widgetManager; diff --git a/src/main/java/electrosphere/main/Main.java b/src/main/java/electrosphere/main/Main.java index a4a60c86..61e29a7b 100644 --- a/src/main/java/electrosphere/main/Main.java +++ b/src/main/java/electrosphere/main/Main.java @@ -435,15 +435,17 @@ public class Main { mouse_lastX = (float) xpos; mouse_lastY = (float) ypos; - yaw = yaw + xoffset; - pitch = pitch - yoffset; + if(Globals.controlHandler != null && !Globals.controlHandler.isMouseVisible()){ + yaw = yaw + xoffset; + pitch = pitch - yoffset; - if (pitch > 100.0f) { - pitch = 100.0f; + if (pitch > 100.0f) { + pitch = 100.0f; + } + if (pitch < -99.0f) { + pitch = -99.0f; + } } - if (pitch < -99.0f) { - pitch = -99.0f; - } } diff --git a/src/main/java/electrosphere/menu/Menu.java b/src/main/java/electrosphere/menu/Menu.java index 15431ded..3023a605 100644 --- a/src/main/java/electrosphere/menu/Menu.java +++ b/src/main/java/electrosphere/menu/Menu.java @@ -27,6 +27,7 @@ public class Menu { OPTIONS_MAIN_MENU, IN_GAME_MAIN_MENU, TEST, + INVENTORY_NATURAL, } MenuType type; @@ -34,8 +35,8 @@ public class Menu { int option = 0; int optionMax = 0; - List widgetList = new ArrayList(); - List optionList = new ArrayList(); + List widgetList = new ArrayList(); + List optionList = new ArrayList(); public Menu(MenuType type){ this.type = type; diff --git a/src/main/java/electrosphere/menu/MenuTransition.java b/src/main/java/electrosphere/menu/MenuTransition.java index 348d50b2..dce34934 100644 --- a/src/main/java/electrosphere/menu/MenuTransition.java +++ b/src/main/java/electrosphere/menu/MenuTransition.java @@ -206,6 +206,12 @@ public class MenuTransition { Globals.currentMenu.dispose(); Globals.controlHandler.setHandlerState(ControlsState.MAIN_GAME); break; + case INVENTORY_NATURAL: + MenuUtils.makeMenuUndrawable(Globals.currentMenu); + Globals.currentMenu.dispose(); + Globals.controlHandler.setHandlerState(ControlsState.MAIN_GAME); + Globals.controlHandler.hideMouse(); + break; } } diff --git a/src/main/java/electrosphere/menu/MenuUtils.java b/src/main/java/electrosphere/menu/MenuUtils.java index d046d20d..296ee25b 100644 --- a/src/main/java/electrosphere/menu/MenuUtils.java +++ b/src/main/java/electrosphere/menu/MenuUtils.java @@ -1,5 +1,8 @@ package electrosphere.menu; +import electrosphere.entity.Entity; +import electrosphere.entity.state.inventory.UnrelationalInventoryState; +import electrosphere.entity.types.item.ItemUtils; import electrosphere.game.server.saves.SaveUtils; import electrosphere.main.Globals; import electrosphere.menu.Menu.MenuType; @@ -128,10 +131,10 @@ public class MenuUtils { Window menuWindow = new Window(100, 100, 500, 500); //black texture background - ImagePanel imagePanel = new ImagePanel(0,0,width,height); - imagePanel.setWidth(width); - imagePanel.setHeight(height); - imagePanel.setTexture(Globals.assetManager.fetchTexture(Globals.blackTexture)); + ImagePanel imagePanel = new ImagePanel(0,0,width,height,Globals.blackTexture); + // imagePanel.setWidth(width); + // imagePanel.setHeight(height); + // imagePanel.setTexture(Globals.assetManager.fetchTexture(Globals.blackTexture)); menuWindow.addWidget(imagePanel); //label 1 (back) @@ -160,6 +163,55 @@ public class MenuUtils { rVal.addElement(WidgetUtils.createWindowTEST()); return rVal; } + + public static Menu createNaturalInventoryMenu(UnrelationalInventoryState inventory){ + Menu rVal = new Menu(MenuType.INVENTORY_NATURAL); + int screenTop = Globals.WINDOW_HEIGHT - 150; + int width = 500; + int height = 500; + int screenLeft = (Globals.WINDOW_WIDTH - width)/2; + Window menuWindow = new Window(100, 100, 500, 500); + + //black texture background + ImagePanel imagePanel = new ImagePanel(0,0,width,height,Globals.blackTexture); + // imagePanel.setWidth(width); + // imagePanel.setHeight(height); + // imagePanel.setTexture(Globals.assetManager.fetchTexture(Globals.blackTexture)); + menuWindow.addWidget(imagePanel); + + //label 1 (inventory) + Label inventoryLabel = new Label(10,10,1.0f); + inventoryLabel.setText("INVENTORY"); + menuWindow.addWidget(inventoryLabel); + rVal.addOption(inventoryLabel); + + int columns = 8; + int columnWidth = 60; + int rowHeight = 60; + for(int i = 0; i < inventory.getCapacity(); i++){ + String texturePath = "Textures/icons/itemIconEmpty.png"; + if(i < inventory.getItems().size()){ + Entity currentItem = inventory.getItems().get(i); + //get texture path from item + texturePath = ItemUtils.getItemIcon(currentItem); + } + if(!Globals.assetManager.hasLoadedTexture(texturePath)){ + Globals.assetManager.addTexturePathtoQueue(texturePath); + } + ImagePanel panel = new ImagePanel((10 + i % columns * columnWidth),height - (110 + i / columns * rowHeight),50,50,texturePath); + // imagePanel.setWidth(width); + // imagePanel.setHeight(height); + // imagePanel.setTexture(Globals.assetManager.fetchTexture(Globals.blackTexture)); + menuWindow.addWidget(panel); + } + + + rVal.addElement(menuWindow); + Globals.widgetManager.registerWidget(menuWindow); +// rVal.addElement(WidgetUtils.createVerticallyAlignedMinSizeTextBoxFromCharCount(40, 40, screenTop - 50, "BACK", true)); +// rVal.addOption( WidgetUtils.createVerticallyAlignedMinSizeTextBoxFromCharCount(40, 40, screenTop - 275, "QUIT", true)); + return rVal; + } public static void makeMenuDrawable(Menu m){ for(Widget w : m.widgetList){ diff --git a/src/main/java/electrosphere/renderer/ui/WindowManager.java b/src/main/java/electrosphere/renderer/ui/WindowManager.java new file mode 100644 index 00000000..64f31101 --- /dev/null +++ b/src/main/java/electrosphere/renderer/ui/WindowManager.java @@ -0,0 +1,38 @@ +package electrosphere.renderer.ui; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +public class WindowManager { + + + Map windowManager = new HashMap(); + List windowPriorityList = new LinkedList(); + + public void registerWindow(String windowName, Window window){ + windowManager.put(windowName,window); + windowPriorityList.add(window); + } + + public Window getWindow(String windowName){ + return windowManager.get(windowName); + } + + public void unregisterWindow(String windowName){ + Window toRemove = windowManager.remove(windowName); + if(toRemove != null){ + windowPriorityList.remove(toRemove); + } + } + + /** + * windows should be drawn in this order + * @return + */ + public List getWindowPriorityList(){ + return windowPriorityList; + } + +} diff --git a/src/main/java/electrosphere/renderer/ui/widgets/ImagePanel.java b/src/main/java/electrosphere/renderer/ui/widgets/ImagePanel.java index bf92dd67..730c75b6 100644 --- a/src/main/java/electrosphere/renderer/ui/widgets/ImagePanel.java +++ b/src/main/java/electrosphere/renderer/ui/widgets/ImagePanel.java @@ -21,16 +21,24 @@ import static org.lwjgl.opengl.GL30.glBindFramebuffer; */ public class ImagePanel extends Widget { + String texturePath; Material customMat = new Material(); + boolean hasLoadedTexture = false; Texture texture = null; Vector3f texPosition = new Vector3f(0,0,0); Vector3f texScale = new Vector3f(1,1,0); - public ImagePanel(int x, int y, int width, int height){ - texture = Globals.assetManager.fetchTexture("Textures/default_diffuse.png"); - customMat.setTexturePointer(texture.getTexturePointer()); + public ImagePanel(int x, int y, int width, int height, String texturePath){ + this.texturePath = texturePath; + texture = Globals.assetManager.fetchTexture(this.texturePath); + if(texture != null){ + customMat.setTexturePointer(texture.getTexturePointer()); + hasLoadedTexture = true; + } else { + customMat.setTexturePointer(Globals.assetManager.fetchTexture(Globals.blackTexture).getTexturePointer()); + } this.positionX = x; this.positionY = y; this.width = width; @@ -49,6 +57,13 @@ public class ImagePanel extends Widget { @Override public void draw(int parentFramebufferPointer, int parentWidth, int parentHeight) { + if(!hasLoadedTexture){ + texture = Globals.assetManager.fetchTexture(this.texturePath); + if(texture != null){ + customMat.setTexturePointer(texture.getTexturePointer()); + hasLoadedTexture = true; + } + } //this call binds the screen as the "texture" we're rendering to //have to call before actually rendering glBindFramebuffer(GL_FRAMEBUFFER, parentFramebufferPointer);