diff --git a/assets/Data/creatures/elf.json b/assets/Data/creatures/elf.json index 12ea52e0..419c2828 100644 --- a/assets/Data/creatures/elf.json +++ b/assets/Data/creatures/elf.json @@ -116,7 +116,7 @@ "variants" : [ { "id" : "hairshort1", - "model" : "Models/hairshort1meshed.fbx", + "model" : "Models/creatures/person2/hair/hairshort1meshed.fbx", "meshes" : [ "Hair" ] diff --git a/assets/Data/creatures/human.json b/assets/Data/creatures/human.json index 3abe5b36..a959b91e 100644 --- a/assets/Data/creatures/human.json +++ b/assets/Data/creatures/human.json @@ -116,7 +116,7 @@ "variants" : [ { "id" : "hairshort1", - "model" : "Models/hairshort1meshed.fbx", + "model" : "Models/creatures/person2/hair/hairshort1meshed.fbx", "meshes" : [ "Hair" ] @@ -334,7 +334,7 @@ "maxHealth" : 100, "onDamageIFrames" : 30 }, - "modelPath" : "Models/person2_1.glb" + "modelPath" : "Models/creatures/person2/person2_1.glb" } ], "files" : [] diff --git a/assets/Data/foliage.json b/assets/Data/foliage.json index 771b2435..ff274204 100644 --- a/assets/Data/foliage.json +++ b/assets/Data/foliage.json @@ -29,7 +29,7 @@ "growthModel": { "growthRate" : 0.001 }, - "modelPath" : "Models/grass2.fbx" + "modelPath" : "Models/foliage/grass2.fbx" }, { "name" : "oak", diff --git a/assets/Data/items.json b/assets/Data/items.json index 9037fbad..d54f9065 100644 --- a/assets/Data/items.json +++ b/assets/Data/items.json @@ -84,7 +84,7 @@ { "itemId" : "shorts1", - "modelPath": "Models/itemEntityShorts.fbx", + "modelPath": "Models/items/itemEntityShorts.fbx", "tokens" : [ "GRAVITY", "TARGETABLE" @@ -107,7 +107,7 @@ "equipWhitelist" : [ { "creatureId" : "human", - "model" : "Models/shorts1.fbx", + "model" : "Models/creatures/person2/clothing/shorts1.fbx", "meshList" : [ "ClothingItem" ], @@ -155,7 +155,7 @@ { "itemId" : "boots1", - "modelPath": "Models/itemEntityShorts.fbx", + "modelPath": "Models/boots1.glb", "tokens" : [ "GRAVITY", "ARMOR", @@ -179,16 +179,12 @@ "equipWhitelist" : [ { "creatureId" : "human", - "model" : "Models/boots1.fbx", + "model" : "Models/boots1.glb", "meshList" : [ "BootLeft", "BootRight" ], "meshMaskList" : [ - "FootLeft", - "FootRight", - "LowerLegLeft", - "LowerLegRight" ] } ] diff --git a/assets/Models/Wheat1.fbx b/assets/Models/Wheat1.fbx deleted file mode 100644 index 91ced733..00000000 Binary files a/assets/Models/Wheat1.fbx and /dev/null differ diff --git a/assets/Models/baseman.fbx b/assets/Models/baseman.fbx deleted file mode 100644 index 2f586c97..00000000 Binary files a/assets/Models/baseman.fbx and /dev/null differ diff --git a/assets/Models/baseman2.fbx b/assets/Models/baseman2.fbx deleted file mode 100644 index a8304a14..00000000 Binary files a/assets/Models/baseman2.fbx and /dev/null differ diff --git a/assets/Models/baseman4.fbx b/assets/Models/baseman4.fbx deleted file mode 100644 index 4d039445..00000000 Binary files a/assets/Models/baseman4.fbx and /dev/null differ diff --git a/assets/Models/baseman5.fbx b/assets/Models/baseman5.fbx deleted file mode 100644 index 596746d6..00000000 Binary files a/assets/Models/baseman5.fbx and /dev/null differ diff --git a/assets/Models/SmallCube.fbx b/assets/Models/basic/geometry/SmallCube.fbx similarity index 100% rename from assets/Models/SmallCube.fbx rename to assets/Models/basic/geometry/SmallCube.fbx diff --git a/assets/Models/geometry1.fbx b/assets/Models/basic/geometry/geometry1.fbx similarity index 100% rename from assets/Models/geometry1.fbx rename to assets/Models/basic/geometry/geometry1.fbx diff --git a/assets/Models/test3.fbx b/assets/Models/basic/geometry/test3.fbx similarity index 100% rename from assets/Models/test3.fbx rename to assets/Models/basic/geometry/test3.fbx diff --git a/assets/Models/test5.fbx b/assets/Models/basic/geometry/test5.fbx similarity index 100% rename from assets/Models/test5.fbx rename to assets/Models/basic/geometry/test5.fbx diff --git a/assets/Models/unitcube.fbx b/assets/Models/basic/geometry/unitcube.fbx similarity index 100% rename from assets/Models/unitcube.fbx rename to assets/Models/basic/geometry/unitcube.fbx diff --git a/assets/Models/unitcylinder.fbx b/assets/Models/basic/geometry/unitcylinder.fbx similarity index 100% rename from assets/Models/unitcylinder.fbx rename to assets/Models/basic/geometry/unitcylinder.fbx diff --git a/assets/Models/unitplane.fbx b/assets/Models/basic/geometry/unitplane.fbx similarity index 100% rename from assets/Models/unitplane.fbx rename to assets/Models/basic/geometry/unitplane.fbx diff --git a/assets/Models/unitsphere.fbx b/assets/Models/basic/geometry/unitsphere.fbx similarity index 100% rename from assets/Models/unitsphere.fbx rename to assets/Models/basic/geometry/unitsphere.fbx diff --git a/assets/Models/unitsphere_1.fbx b/assets/Models/basic/geometry/unitsphere_1.fbx similarity index 100% rename from assets/Models/unitsphere_1.fbx rename to assets/Models/basic/geometry/unitsphere_1.fbx diff --git a/assets/Models/unitsphere_grey.fbx b/assets/Models/basic/geometry/unitsphere_grey.fbx similarity index 100% rename from assets/Models/unitsphere_grey.fbx rename to assets/Models/basic/geometry/unitsphere_grey.fbx diff --git a/assets/Models/watercube1.fbx b/assets/Models/basic/geometry/watercube1.fbx similarity index 100% rename from assets/Models/watercube1.fbx rename to assets/Models/basic/geometry/watercube1.fbx diff --git a/assets/Models/building1.fbx b/assets/Models/buildings/building1.fbx similarity index 100% rename from assets/Models/building1.fbx rename to assets/Models/buildings/building1.fbx diff --git a/assets/Models/deer1.fbx b/assets/Models/creatures/animals/deer1.fbx similarity index 100% rename from assets/Models/deer1.fbx rename to assets/Models/creatures/animals/deer1.fbx diff --git a/assets/Models/elf1.fbx b/assets/Models/creatures/elf/elf1.fbx similarity index 100% rename from assets/Models/elf1.fbx rename to assets/Models/creatures/elf/elf1.fbx diff --git a/assets/Models/goblin1.fbx b/assets/Models/creatures/goblin/goblin1.fbx similarity index 100% rename from assets/Models/goblin1.fbx rename to assets/Models/creatures/goblin/goblin1.fbx diff --git a/assets/Models/baseman5.glb b/assets/Models/creatures/person2/baseman5.glb similarity index 100% rename from assets/Models/baseman5.glb rename to assets/Models/creatures/person2/baseman5.glb diff --git a/assets/Models/creatures/person2/clothing/belt1.glb b/assets/Models/creatures/person2/clothing/belt1.glb new file mode 100644 index 00000000..a4a6ea96 Binary files /dev/null and b/assets/Models/creatures/person2/clothing/belt1.glb differ diff --git a/assets/Models/boots1.fbx b/assets/Models/creatures/person2/clothing/boots1.fbx similarity index 100% rename from assets/Models/boots1.fbx rename to assets/Models/creatures/person2/clothing/boots1.fbx diff --git a/assets/Models/creatures/person2/clothing/boots1.glb b/assets/Models/creatures/person2/clothing/boots1.glb new file mode 100644 index 00000000..517274c2 Binary files /dev/null and b/assets/Models/creatures/person2/clothing/boots1.glb differ diff --git a/assets/Models/shirt1.fbx b/assets/Models/creatures/person2/clothing/shirt1.fbx similarity index 100% rename from assets/Models/shirt1.fbx rename to assets/Models/creatures/person2/clothing/shirt1.fbx diff --git a/assets/Models/shorts.glb b/assets/Models/creatures/person2/clothing/shorts.glb similarity index 100% rename from assets/Models/shorts.glb rename to assets/Models/creatures/person2/clothing/shorts.glb diff --git a/assets/Models/shorts1.fbx b/assets/Models/creatures/person2/clothing/shorts1.fbx similarity index 100% rename from assets/Models/shorts1.fbx rename to assets/Models/creatures/person2/clothing/shorts1.fbx diff --git a/assets/Models/hairshort1.fbx b/assets/Models/creatures/person2/hair/hairshort1.fbx similarity index 100% rename from assets/Models/hairshort1.fbx rename to assets/Models/creatures/person2/hair/hairshort1.fbx diff --git a/assets/Models/hairshort1meshed.fbx b/assets/Models/creatures/person2/hair/hairshort1meshed.fbx similarity index 100% rename from assets/Models/hairshort1meshed.fbx rename to assets/Models/creatures/person2/hair/hairshort1meshed.fbx diff --git a/assets/Models/person2_1.glb b/assets/Models/creatures/person2/person2_1.glb similarity index 100% rename from assets/Models/person2_1.glb rename to assets/Models/creatures/person2/person2_1.glb diff --git a/assets/Models/groundplanemassiveuv.fbx b/assets/Models/engine/groundplanemassiveuv.fbx similarity index 100% rename from assets/Models/groundplanemassiveuv.fbx rename to assets/Models/engine/groundplanemassiveuv.fbx diff --git a/assets/Models/lockoncrosshair1.fbx b/assets/Models/engine/lockoncrosshair1.fbx similarity index 100% rename from assets/Models/lockoncrosshair1.fbx rename to assets/Models/engine/lockoncrosshair1.fbx diff --git a/assets/Models/waypoint1.fbx b/assets/Models/engine/waypoint1.fbx similarity index 100% rename from assets/Models/waypoint1.fbx rename to assets/Models/engine/waypoint1.fbx diff --git a/assets/Models/cloudRing.fbx b/assets/Models/environment/cloudRing.fbx similarity index 100% rename from assets/Models/cloudRing.fbx rename to assets/Models/environment/cloudRing.fbx diff --git a/assets/Models/skyboxSphere.fbx b/assets/Models/environment/skyboxSphere.fbx similarity index 100% rename from assets/Models/skyboxSphere.fbx rename to assets/Models/environment/skyboxSphere.fbx diff --git a/assets/Models/f15.fbx b/assets/Models/f15.fbx deleted file mode 100644 index 35968334..00000000 Binary files a/assets/Models/f15.fbx and /dev/null differ diff --git a/assets/Models/floatingisland1.fbx b/assets/Models/floatingisland1.fbx deleted file mode 100644 index 44ec9366..00000000 Binary files a/assets/Models/floatingisland1.fbx and /dev/null differ diff --git a/assets/Models/falloak1.fbx b/assets/Models/foliage/falloak1.fbx similarity index 100% rename from assets/Models/falloak1.fbx rename to assets/Models/foliage/falloak1.fbx diff --git a/assets/Models/foliageBlockTemplate1Test1.fbx b/assets/Models/foliage/foliageBlockTemplate1Test1.fbx similarity index 100% rename from assets/Models/foliageBlockTemplate1Test1.fbx rename to assets/Models/foliage/foliageBlockTemplate1Test1.fbx diff --git a/assets/Models/grass1.fbx b/assets/Models/foliage/grass1.fbx similarity index 100% rename from assets/Models/grass1.fbx rename to assets/Models/foliage/grass1.fbx diff --git a/assets/Models/grass2.fbx b/assets/Models/foliage/grass2.fbx similarity index 100% rename from assets/Models/grass2.fbx rename to assets/Models/foliage/grass2.fbx diff --git a/assets/Models/proceduralTree1/proceduralLeafBlob1.fbx b/assets/Models/foliage/proceduralTree1/proceduralLeafBlob1.fbx similarity index 100% rename from assets/Models/proceduralTree1/proceduralLeafBlob1.fbx rename to assets/Models/foliage/proceduralTree1/proceduralLeafBlob1.fbx diff --git a/assets/Models/proceduralTree1/proceduralTrunk1.fbx b/assets/Models/foliage/proceduralTree1/proceduralTrunk1.fbx similarity index 100% rename from assets/Models/proceduralTree1/proceduralTrunk1.fbx rename to assets/Models/foliage/proceduralTree1/proceduralTrunk1.fbx diff --git a/assets/Models/proceduralTree1/proceduralTrunk1.png b/assets/Models/foliage/proceduralTree1/proceduralTrunk1.png similarity index 100% rename from assets/Models/proceduralTree1/proceduralTrunk1.png rename to assets/Models/foliage/proceduralTree1/proceduralTrunk1.png diff --git a/assets/Models/proceduralTree2/Trunk.png b/assets/Models/foliage/proceduralTree2/Trunk.png similarity index 100% rename from assets/Models/proceduralTree2/Trunk.png rename to assets/Models/foliage/proceduralTree2/Trunk.png diff --git a/assets/Models/proceduralTree2/proceduralTree2.fbx b/assets/Models/foliage/proceduralTree2/proceduralTree2.fbx similarity index 100% rename from assets/Models/proceduralTree2/proceduralTree2.fbx rename to assets/Models/foliage/proceduralTree2/proceduralTree2.fbx diff --git a/assets/Models/proceduralTree2/proceduralTree2v2.fbx b/assets/Models/foliage/proceduralTree2/proceduralTree2v2.fbx similarity index 100% rename from assets/Models/proceduralTree2/proceduralTree2v2.fbx rename to assets/Models/foliage/proceduralTree2/proceduralTree2v2.fbx diff --git a/assets/Models/tree1.fbx b/assets/Models/foliage/tree1.fbx similarity index 100% rename from assets/Models/tree1.fbx rename to assets/Models/foliage/tree1.fbx diff --git a/assets/Models/itemEntityShorts.fbx b/assets/Models/items/itemEntityShorts.fbx similarity index 100% rename from assets/Models/itemEntityShorts.fbx rename to assets/Models/items/itemEntityShorts.fbx diff --git a/assets/Models/arrow1.fbx b/assets/Models/items/weapons/arrow1.fbx similarity index 100% rename from assets/Models/arrow1.fbx rename to assets/Models/items/weapons/arrow1.fbx diff --git a/assets/Models/bow1.fbx b/assets/Models/items/weapons/bow1.fbx similarity index 100% rename from assets/Models/bow1.fbx rename to assets/Models/items/weapons/bow1.fbx diff --git a/assets/Models/katana1.fbx b/assets/Models/items/weapons/katana1.fbx similarity index 100% rename from assets/Models/katana1.fbx rename to assets/Models/items/weapons/katana1.fbx diff --git a/assets/Models/katana1alt.fbx b/assets/Models/items/weapons/katana1alt.fbx similarity index 100% rename from assets/Models/katana1alt.fbx rename to assets/Models/items/weapons/katana1alt.fbx diff --git a/assets/Models/modelPretransforms.json b/assets/Models/modelPretransforms.json index b2fe37bf..7cd4ee8d 100644 --- a/assets/Models/modelPretransforms.json +++ b/assets/Models/modelPretransforms.json @@ -67,7 +67,7 @@ ] }, { - "path" : "Models/person2_1.glb", + "path" : "Models/creatures/person2/person2_1.glb", "globalTransform": { "rotation" : [0,0,0,1], "offset" : [0.0, 0.0, 0.0], @@ -77,7 +77,7 @@ ] }, { - "path" : "Models/grass2.fbx", + "path" : "Models/foliage/grass2.fbx", "globalTransform": { "rotation" : [0.0, 0.0, 0.0, 1.0], "offset" : [0.0, 0.0, 0.0], diff --git a/assets/Models/campfire1.fbx b/assets/Models/objects/campfire1.fbx similarity index 100% rename from assets/Models/campfire1.fbx rename to assets/Models/objects/campfire1.fbx diff --git a/assets/Models/crate2.fbx b/assets/Models/objects/crate2.fbx similarity index 100% rename from assets/Models/crate2.fbx rename to assets/Models/objects/crate2.fbx diff --git a/assets/Models/flame1.fbx b/assets/Models/objects/flame1.fbx similarity index 100% rename from assets/Models/flame1.fbx rename to assets/Models/objects/flame1.fbx diff --git a/assets/Models/shrine2.fbx b/assets/Models/shrine2.fbx deleted file mode 100644 index 0577aa3e..00000000 Binary files a/assets/Models/shrine2.fbx and /dev/null differ diff --git a/assets/Models/skyscraper1.fbx b/assets/Models/skyscraper1.fbx deleted file mode 100644 index a104da15..00000000 Binary files a/assets/Models/skyscraper1.fbx and /dev/null differ diff --git a/assets/Models/startingarea1.fbx b/assets/Models/startingarea1.fbx deleted file mode 100644 index 15e9c7ae..00000000 Binary files a/assets/Models/startingarea1.fbx and /dev/null differ diff --git a/assets/Models/tank1.fbx b/assets/Models/tank1.fbx deleted file mode 100644 index 07fc5159..00000000 Binary files a/assets/Models/tank1.fbx and /dev/null differ diff --git a/assets/Models/testvalley.fbx b/assets/Models/testvalley.fbx deleted file mode 100644 index a843d202..00000000 Binary files a/assets/Models/testvalley.fbx and /dev/null differ diff --git a/assets/Models/wheat2.fbx b/assets/Models/wheat2.fbx deleted file mode 100644 index 60263545..00000000 Binary files a/assets/Models/wheat2.fbx and /dev/null differ diff --git a/assets/Textures/default_texture_map.json b/assets/Textures/default_texture_map.json index 50dc6720..bc7dbdef 100644 --- a/assets/Textures/default_texture_map.json +++ b/assets/Textures/default_texture_map.json @@ -30,7 +30,7 @@ "/Textures/transparent_blue.png" ] }, - "Models/unitsphere_1.fbx": { + "Models/basic/geometry/unitsphere_1.fbx": { "Sphere": [ "/Textures/transparent_red.png", "/Textures/transparent_red.png" @@ -324,19 +324,19 @@ "/Textures/arrow1.png" ] }, - "Models/lockoncrosshair1.fbx" : { + "Models/engine/lockoncrosshair1.fbx" : { "Cube" : [ "/Textures/w1.png", "/Textures/w1.png" ] }, - "Models/shorts1.fbx" : { + "Models/creatures/person2/clothing/shorts1.fbx" : { "ClothingItem" : [ "/Textures/shorts1.png", "/Textures/shorts1.png" ] }, - "Models/hairshort1meshed.fbx" : { + "Models/creatures/person2/hair/hairshort1meshed.fbx" : { "Hair" : [ "/Textures/b1.png", "/Textures/b1.png" @@ -358,13 +358,13 @@ "/Textures/shirt1.png" ] }, - "Models/cloudRing.fbx" : { + "Models/environment/cloudRing.fbx" : { "Sphere" : [ "/Textures/cloudRing.png", "/Textures/cloudRing.png" ] }, - "Models/skyboxSphere.fbx" : { + "Models/environment/skyboxSphere.fbx" : { "Sphere" : [ "/Textures/starrySky.png", "/Textures/starrySky.png" diff --git a/assets/Textures/f15.png b/assets/Textures/f15.png deleted file mode 100644 index ca9844cb..00000000 Binary files a/assets/Textures/f15.png and /dev/null differ diff --git a/assets/Textures/shrine2Feet.png b/assets/Textures/shrine2Feet.png deleted file mode 100644 index e33c07d5..00000000 Binary files a/assets/Textures/shrine2Feet.png and /dev/null differ diff --git a/assets/Textures/shrine2MainWalls.png b/assets/Textures/shrine2MainWalls.png deleted file mode 100644 index cbf3cffd..00000000 Binary files a/assets/Textures/shrine2MainWalls.png and /dev/null differ diff --git a/assets/Textures/shrine2Platform.png b/assets/Textures/shrine2Platform.png deleted file mode 100644 index 2c39e296..00000000 Binary files a/assets/Textures/shrine2Platform.png and /dev/null differ diff --git a/assets/Textures/shrine2Roof.png b/assets/Textures/shrine2Roof.png deleted file mode 100644 index 93481bdd..00000000 Binary files a/assets/Textures/shrine2Roof.png and /dev/null differ diff --git a/assets/Textures/shrine2Stairs.png b/assets/Textures/shrine2Stairs.png deleted file mode 100644 index 26c79ecc..00000000 Binary files a/assets/Textures/shrine2Stairs.png and /dev/null differ diff --git a/assets/Textures/shrine2SupportBeams.png b/assets/Textures/shrine2SupportBeams.png deleted file mode 100644 index 78ea71f9..00000000 Binary files a/assets/Textures/shrine2SupportBeams.png and /dev/null differ diff --git a/assets/Textures/skyscraper1.png b/assets/Textures/skyscraper1.png deleted file mode 100644 index ad0c3e65..00000000 Binary files a/assets/Textures/skyscraper1.png and /dev/null differ diff --git a/assets/Textures/trunk.png b/assets/Textures/trunk.png deleted file mode 100644 index 5f7f66a8..00000000 Binary files a/assets/Textures/trunk.png and /dev/null differ diff --git a/assets/Textures/wheat1.png b/assets/Textures/wheat1.png deleted file mode 100644 index 95da0bf9..00000000 Binary files a/assets/Textures/wheat1.png and /dev/null differ diff --git a/assets/Textures/wheat2.png b/assets/Textures/wheat2.png deleted file mode 100644 index 8c5adec0..00000000 Binary files a/assets/Textures/wheat2.png and /dev/null differ diff --git a/docs/src/highlevel-design/equipstate/equipstate.md b/docs/src/highlevel-design/equipstate/equipstate.md new file mode 100644 index 00000000..15517aae --- /dev/null +++ b/docs/src/highlevel-design/equipstate/equipstate.md @@ -0,0 +1,32 @@ +@page equipstate Equip State + + +# Relevant Classes + + + + + +# Data Explanation +## Item-side definitions + +Items must define a property `equipClass`. This determines what type of item it is. +The equip points on the creature then whitelist equipClass variants. + +IE, I would define a sword as a "weapon", then assign the item type "weapon" to a given equippoint (ie the person's hand). + +Furthermore, a creature can define a `equipWhitelist` array. This allows you to define per-item what creatures can equip it. +The goal with this is to limit item equipping when we haven't modeled out a variant for a given creature. + +IE, if you make a cool helmet for a human and don't bother to make one for dwarves, you could equipWhitelist it to just humans. + +## Creature-side definitions + +Creatures define an array `equipPoints`. This contains a list of points that the creature can equip items at. +A given equipPoint controls the bone the item is attached to, offsets/rotations from that bone, and the types of equipment that can be attached at that point. + + +## Equip Classes + +They're basically category strings. There isn't any data intrinsic to an equipClass yet. +Potentially these will eventually be broken out into a dedicated data object to support things like tooltips. diff --git a/docs/src/highlevel-design/highleveldesignindex.md b/docs/src/highlevel-design/highleveldesignindex.md index 3d4875c2..e1e14623 100644 --- a/docs/src/highlevel-design/highleveldesignindex.md +++ b/docs/src/highlevel-design/highleveldesignindex.md @@ -12,6 +12,7 @@ Discussion of, at a high game-design level, how everything should work and conne - @subpage macrosimtimeline - @subpage narrativemanager - @subpage itemsindex +- @subpage equipstate - @subpage puzzleindex - @subpage fluidindex - @subpage locomotion diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md index facd0eb1..d8ae1347 100644 --- a/docs/src/progress/renderertodo.md +++ b/docs/src/progress/renderertodo.md @@ -220,8 +220,18 @@ UI Work - Level editor ability to destroy an entity on server, have it also destroy on client, AND not persist on save - Environment controls (not persisting in save yet) +Fix Movement Bug where player keeps running after releasing control + # TODO +UI Fixes + - Refactor ui toolkit elements to separate absolute and relative position + - Fix inventory menus + +Touch Up working with items + - Make sure the models are appropriately scaled + - Remove all logic from before client-server separation + More Debug menus - Screen that shows the overall status of client scene - Number of entities diff --git a/src/main/java/electrosphere/client/targeting/crosshair/Crosshair.java b/src/main/java/electrosphere/client/targeting/crosshair/Crosshair.java index 999a76d5..32bdf48d 100644 --- a/src/main/java/electrosphere/client/targeting/crosshair/Crosshair.java +++ b/src/main/java/electrosphere/client/targeting/crosshair/Crosshair.java @@ -25,7 +25,7 @@ public class Crosshair { public static void initCrossHairEntity(){ crossHairEntity = EntityCreationUtils.createClientSpatialEntity(); - EntityCreationUtils.makeEntityDrawable(crossHairEntity, "/Models/lockoncrosshair1.fbx"); + EntityCreationUtils.makeEntityDrawable(crossHairEntity, "/Models/engine/lockoncrosshair1.fbx"); EntityUtils.setVisible(crossHairEntity, false); } diff --git a/src/main/java/electrosphere/controls/ControlHandler.java b/src/main/java/electrosphere/controls/ControlHandler.java index ce23a8b9..7d91d92b 100644 --- a/src/main/java/electrosphere/controls/ControlHandler.java +++ b/src/main/java/electrosphere/controls/ControlHandler.java @@ -81,7 +81,7 @@ import electrosphere.entity.Entity; import electrosphere.entity.btree.BehaviorTree; import electrosphere.entity.state.attack.AttackTree; import electrosphere.entity.state.attack.ShooterTree; -import electrosphere.entity.state.equip.EquipState; +import electrosphere.entity.state.equip.ClientEquipState; import electrosphere.entity.state.inventory.InventoryUtils; import electrosphere.entity.state.inventory.UnrelationalInventoryState; import electrosphere.entity.state.ironsight.IronSightTree; @@ -821,9 +821,9 @@ public class ControlHandler { mainGameControlList.add(controls.get(INPUT_CODE_INTERACT)); controls.get(INPUT_CODE_INTERACT).setOnPress(new ControlMethod(){public void execute(){ if(Globals.playerEntity != null){ - if(EquipState.hasEquipState(Globals.playerEntity) && Crosshair.hasTarget()){ + if(ClientEquipState.hasEquipState(Globals.playerEntity) && Crosshair.hasTarget()){ if(InventoryUtils.hasNaturalInventory(Globals.playerEntity)){ - InventoryUtils.attemptStoreItem(Globals.playerEntity, Crosshair.getTarget()); + InventoryUtils.clientAttemptStoreItem(Globals.playerEntity, Crosshair.getTarget()); } } } @@ -835,11 +835,11 @@ public class ControlHandler { mainGameControlList.add(controls.get(INPUT_CODE_DROP)); controls.get(INPUT_CODE_DROP).setOnPress(new ControlMethod(){public void execute(){ if(Globals.playerEntity != null){ - if(EquipState.hasEquipState(Globals.playerEntity)){ + if(ClientEquipState.hasEquipState(Globals.playerEntity)){ UnrelationalInventoryState inventory = InventoryUtils.getNaturalInventory(Globals.playerEntity); if(inventory.getItems().size() > 0){ Entity itemToDrop = inventory.getItems().get(0); - InventoryUtils.attemptEjectItem(Globals.playerEntity,itemToDrop); + InventoryUtils.clientAttemptEjectItem(Globals.playerEntity,itemToDrop); } } } @@ -1081,15 +1081,15 @@ public class ControlHandler { controls.get(DATA_STRING_INPUT_CODE_MENU_INCREMENT).setOnPress(new ControlMethod(){public void execute(){ Globals.elementManager.fireEvent( new MenuEvent(MenuEventType.INCREMENT), - Globals.elementManager.getFocusedElement().getPositionX(), - Globals.elementManager.getFocusedElement().getPositionY() + Globals.elementManager.getFocusedElement().getAbsoluteX(), + Globals.elementManager.getFocusedElement().getAbsoluteY() ); }}); controls.get(DATA_STRING_INPUT_CODE_MENU_INCREMENT).setOnRepeat(new ControlMethod(){public void execute(){ Globals.elementManager.fireEvent( new MenuEvent(MenuEventType.INCREMENT), - Globals.elementManager.getFocusedElement().getPositionX(), - Globals.elementManager.getFocusedElement().getPositionY() + Globals.elementManager.getFocusedElement().getAbsoluteX(), + Globals.elementManager.getFocusedElement().getAbsoluteY() ); }}); controls.get(DATA_STRING_INPUT_CODE_MENU_INCREMENT).setRepeatTimeout(0.5f * Main.targetFrameRate); @@ -1141,15 +1141,15 @@ public class ControlHandler { controls.get(DATA_STRING_INPUT_CODE_MENU_DECREMENT).setOnPress(new ControlMethod(){public void execute(){ Globals.elementManager.fireEvent( new MenuEvent(MenuEventType.DECREMENT), - Globals.elementManager.getFocusedElement().getPositionX(), - Globals.elementManager.getFocusedElement().getPositionY() + Globals.elementManager.getFocusedElement().getAbsoluteX(), + Globals.elementManager.getFocusedElement().getAbsoluteY() ); }}); controls.get(DATA_STRING_INPUT_CODE_MENU_DECREMENT).setOnRepeat(new ControlMethod(){public void execute(){ Globals.elementManager.fireEvent( new MenuEvent(MenuEventType.DECREMENT), - Globals.elementManager.getFocusedElement().getPositionX(), - Globals.elementManager.getFocusedElement().getPositionY() + Globals.elementManager.getFocusedElement().getAbsoluteX(), + Globals.elementManager.getFocusedElement().getAbsoluteY() ); }}); controls.get(DATA_STRING_INPUT_CODE_MENU_DECREMENT).setRepeatTimeout(0.5f * Main.targetFrameRate); diff --git a/src/main/java/electrosphere/engine/Globals.java b/src/main/java/electrosphere/engine/Globals.java index b78c6357..4fbcef1d 100644 --- a/src/main/java/electrosphere/engine/Globals.java +++ b/src/main/java/electrosphere/engine/Globals.java @@ -513,13 +513,13 @@ public class Globals { //init fluid shader program FluidChunkModelGeneration.fluidChunkShaderProgram = ShaderProgram.loadSpecificShader("/Shaders/fluid2/fluid2.vs", "/Shaders/fluid2/fluid2.fs"); //init models - assetManager.addModelPathToQueue("Models/unitsphere.fbx"); - assetManager.addModelPathToQueue("Models/unitsphere_1.fbx"); - assetManager.addModelPathToQueue("Models/unitsphere_grey.fbx"); - assetManager.addModelPathToQueue("Models/SmallCube.fbx"); - assetManager.addModelPathToQueue("Models/unitcylinder.fbx"); - assetManager.addModelPathToQueue("Models/unitplane.fbx"); - assetManager.addModelPathToQueue("Models/unitcube.fbx"); + assetManager.addModelPathToQueue("Models/basic/geometry/unitsphere.fbx"); + assetManager.addModelPathToQueue("Models/basic/geometry/unitsphere_1.fbx"); + assetManager.addModelPathToQueue("Models/basic/geometry/unitsphere_grey.fbx"); + assetManager.addModelPathToQueue("Models/basic/geometry/SmallCube.fbx"); + assetManager.addModelPathToQueue("Models/basic/geometry/unitcylinder.fbx"); + assetManager.addModelPathToQueue("Models/basic/geometry/unitplane.fbx"); + assetManager.addModelPathToQueue("Models/basic/geometry/unitcube.fbx"); imagePlaneModelID = assetManager.registerModel(RenderUtils.createPlaneModel("Shaders/plane/plane.vs", "Shaders/plane/plane.fs")); assetManager.addShaderToQueue("Shaders/plane/plane.vs", null, "Shaders/plane/plane.fs"); solidPlaneModelID = assetManager.registerModel(RenderUtils.createInWindowPanel("Shaders/ui/plainBox/plainBox.vs", "Shaders/ui/plainBox/plainBox.fs")); diff --git a/src/main/java/electrosphere/engine/loadingthreads/ClientLoading.java b/src/main/java/electrosphere/engine/loadingthreads/ClientLoading.java index 82a90957..a430b032 100644 --- a/src/main/java/electrosphere/engine/loadingthreads/ClientLoading.java +++ b/src/main/java/electrosphere/engine/loadingthreads/ClientLoading.java @@ -209,23 +209,23 @@ public class ClientLoading { //starry sky true skybox Entity skybox = EntityCreationUtils.createClientSpatialEntity(); - EntityCreationUtils.makeEntityDrawable(skybox, "Models/skyboxSphere.fbx"); + EntityCreationUtils.makeEntityDrawable(skybox, "Models/environment/skyboxSphere.fbx"); DrawableUtils.disableCulling(skybox); EntityUtils.getRotation(skybox).rotateX((float)(-Math.PI/2.0f)); EntityUtils.getScale(skybox).mul(200000.0f); - Globals.assetManager.queueOverrideMeshShader("Models/skyboxSphere.fbx", "Sphere", "Shaders/skysphere/skysphere.vs", "Shaders/skysphere/skysphere.fs"); + Globals.assetManager.queueOverrideMeshShader("Models/environment/skyboxSphere.fbx", "Sphere", "Shaders/skysphere/skysphere.vs", "Shaders/skysphere/skysphere.fs"); //cloud ring pseudo skybox Entity cloudRing = EntityCreationUtils.createClientSpatialEntity(); - EntityCreationUtils.makeEntityDrawable(cloudRing, "Models/cloudRing.fbx"); + EntityCreationUtils.makeEntityDrawable(cloudRing, "Models/environment/cloudRing.fbx"); DrawableUtils.disableCulling(cloudRing); EntityUtils.getRotation(cloudRing).rotateX((float)(-Math.PI/2.0f)); EntityUtils.getScale(cloudRing).mul(100000.0f); Globals.clientScene.registerBehaviorTree(new ApplyRotationTree(cloudRing,new Quaterniond().rotationZ(0.0001))); - Globals.assetManager.queueOverrideMeshShader("Models/cloudRing.fbx", "Sphere", "Shaders/skysphere/skysphere.vs", "Shaders/skysphere/skysphere.fs"); + Globals.assetManager.queueOverrideMeshShader("Models/environment/cloudRing.fbx", "Sphere", "Shaders/skysphere/skysphere.vs", "Shaders/skysphere/skysphere.fs"); Entity cursorTracker = EntityCreationUtils.createClientSpatialEntity(); - EntityCreationUtils.makeEntityDrawable(cursorTracker, "Models/unitsphere_1.fbx"); + EntityCreationUtils.makeEntityDrawable(cursorTracker, "Models/basic/geometry/unitsphere_1.fbx"); EntityUtils.getScale(cursorTracker).set(30f); Globals.clientSceneWrapper.getScene().registerBehaviorTree(new BehaviorTree() { @Override diff --git a/src/main/java/electrosphere/entity/Scene.java b/src/main/java/electrosphere/entity/Scene.java index 11b55083..2ae5839e 100644 --- a/src/main/java/electrosphere/entity/Scene.java +++ b/src/main/java/electrosphere/entity/Scene.java @@ -54,8 +54,10 @@ public class Scene { * @param e The entity to register */ public void registerEntity(Entity e){ + if(!entityIdMap.containsKey(e.getId())){ + entityList.add(e); + } entityIdMap.put(e.getId(), e); - entityList.add(e); } /** diff --git a/src/main/java/electrosphere/entity/state/attack/AttackTree.java b/src/main/java/electrosphere/entity/state/attack/AttackTree.java index 12b11bc0..22d4f24e 100644 --- a/src/main/java/electrosphere/entity/state/attack/AttackTree.java +++ b/src/main/java/electrosphere/entity/state/attack/AttackTree.java @@ -9,7 +9,7 @@ import electrosphere.entity.EntityUtils; import electrosphere.entity.ServerEntityUtils; import electrosphere.entity.btree.BehaviorTree; import electrosphere.entity.state.collidable.Impulse; -import electrosphere.entity.state.equip.EquipState; +import electrosphere.entity.state.equip.ClientEquipState; import electrosphere.entity.state.movement.groundmove.GroundMovementTree; import electrosphere.entity.state.rotator.RotatorTree; import electrosphere.entity.types.attach.AttachUtils; @@ -299,7 +299,7 @@ public class AttackTree implements BehaviorTree { Vector3d spawnPosition = new Vector3d(0,0,0); Quaterniond arrowRotation = new Quaterniond(); String targetBone = null; - EquipState equipState = EquipState.getEquipState(parent); + ClientEquipState equipState = ClientEquipState.getEquipState(parent); EquipPoint weaponPoint = null; if((weaponPoint = equipState.getEquipPoint(attackingPoint)) != null){ targetBone = weaponPoint.getBone(); @@ -395,8 +395,8 @@ public class AttackTree implements BehaviorTree { String getAttackType(){ String rVal = null; - if(EquipState.hasEquipState(parent)){ - EquipState equipState = EquipState.getEquipState(parent); + if(ClientEquipState.hasEquipState(parent)){ + ClientEquipState equipState = ClientEquipState.getEquipState(parent); for(String point : equipState.equippedPoints()){ Entity item = equipState.getEquippedItemAtPoint(point); if(ItemUtils.isWeapon(item)){ @@ -430,8 +430,8 @@ public class AttackTree implements BehaviorTree { rVal = true; } } else { - if(EquipState.hasEquipState(parent)){ - EquipState equipState = EquipState.getEquipState(parent); + if(ClientEquipState.hasEquipState(parent)){ + ClientEquipState equipState = ClientEquipState.getEquipState(parent); // if(equipState.hasEquipPrimary()){ // switch(attackType){ // case EntityDataStrings.ATTACK_MOVE_TYPE_MELEE_SWING_ONE_HAND: diff --git a/src/main/java/electrosphere/entity/state/attack/ServerAttackTree.java b/src/main/java/electrosphere/entity/state/attack/ServerAttackTree.java index a135b8e0..c02966c0 100644 --- a/src/main/java/electrosphere/entity/state/attack/ServerAttackTree.java +++ b/src/main/java/electrosphere/entity/state/attack/ServerAttackTree.java @@ -9,7 +9,7 @@ import electrosphere.entity.EntityUtils; import electrosphere.entity.ServerEntityUtils; import electrosphere.entity.btree.BehaviorTree; import electrosphere.entity.state.collidable.Impulse; -import electrosphere.entity.state.equip.EquipState; +import electrosphere.entity.state.equip.ServerEquipState; import electrosphere.entity.state.movement.groundmove.GroundMovementTree; import electrosphere.entity.state.movement.groundmove.ServerGroundMovementTree; import electrosphere.entity.state.rotator.RotatorTree; @@ -300,7 +300,7 @@ public class ServerAttackTree implements BehaviorTree { Vector3d spawnPosition = new Vector3d(0,0,0); Quaterniond arrowRotation = new Quaterniond(); String targetBone = null; - EquipState equipState = EquipState.getEquipState(parent); + ServerEquipState equipState = ServerEquipState.getEquipState(parent); EquipPoint weaponPoint = null; if((weaponPoint = equipState.getEquipPoint(attackingPoint)) != null){ targetBone = weaponPoint.getBone(); @@ -393,8 +393,8 @@ public class ServerAttackTree implements BehaviorTree { String getAttackType(){ String rVal = null; - if(EquipState.hasEquipState(parent)){ - EquipState equipState = EquipState.getEquipState(parent); + if(ServerEquipState.hasEquipState(parent)){ + ServerEquipState equipState = ServerEquipState.getEquipState(parent); for(String point : equipState.equippedPoints()){ Entity item = equipState.getEquippedItemAtPoint(point); if(ItemUtils.isWeapon(item)){ @@ -428,8 +428,8 @@ public class ServerAttackTree implements BehaviorTree { rVal = true; } } else { - if(EquipState.hasEquipState(parent)){ - EquipState equipState = EquipState.getEquipState(parent); + if(ServerEquipState.hasEquipState(parent)){ + ServerEquipState equipState = ServerEquipState.getEquipState(parent); // if(equipState.hasEquipPrimary()){ // switch(attackType){ // case EntityDataStrings.ATTACK_MOVE_TYPE_MELEE_SWING_ONE_HAND: diff --git a/src/main/java/electrosphere/entity/state/equip/ClientEquipState.java b/src/main/java/electrosphere/entity/state/equip/ClientEquipState.java new file mode 100644 index 00000000..55d3f855 --- /dev/null +++ b/src/main/java/electrosphere/entity/state/equip/ClientEquipState.java @@ -0,0 +1,262 @@ +package electrosphere.entity.state.equip; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.ode4j.ode.DBody; + +import electrosphere.engine.Globals; +import electrosphere.entity.Entity; +import electrosphere.entity.EntityDataStrings; +import electrosphere.entity.EntityTags; +import electrosphere.entity.EntityUtils; +import electrosphere.entity.state.gravity.GravityUtils; +import electrosphere.entity.types.attach.AttachUtils; +import electrosphere.entity.types.creature.CreatureUtils; +import electrosphere.entity.types.item.ItemUtils; +import electrosphere.game.data.creature.type.equip.EquipPoint; +import electrosphere.game.data.item.type.EquipWhitelist; +import electrosphere.net.parser.net.message.InventoryMessage; +import electrosphere.net.parser.net.message.NetworkMessage; +import electrosphere.net.synchronization.annotation.SynchronizedBehaviorTree; +import electrosphere.renderer.actor.Actor; +import electrosphere.renderer.actor.ActorMeshMask; + +@SynchronizedBehaviorTree(name = "clientEquipState", isServer = false, correspondingTree="serverEquipState") +/** + * Client view of items equipped to a given entity + */ +public class ClientEquipState { + + Entity parent; + + List equipPoints = new LinkedList(); + Map equipMap = new HashMap(); + + public ClientEquipState(Entity parent, List equipPoints){ + this.parent = parent; + for(EquipPoint point : equipPoints){ + this.equipPoints.add(point); + } + } + + public List equippedPoints(){ + return new LinkedList(equipMap.keySet()); + } + + public void commandAttemptEquip(Entity toEquip, EquipPoint point){ + boolean hasEquipped = hasEquippedAtPoint(point.getEquipPointId()); + boolean targetIsItem = ItemUtils.isItem(toEquip); + boolean targetIsAttached = AttachUtils.isAttached(toEquip); + boolean targetHasWhitelist = ItemUtils.hasEquipList(toEquip); + String equipItemClass = ItemUtils.getEquipClass(toEquip); + List pointEquipClassList = point.getEquipClassWhitelist(); + boolean itemIsInPointWhitelist = pointEquipClassList.contains(equipItemClass); + if(!hasEquipped && targetIsItem && !targetIsAttached && itemIsInPointWhitelist){ + //send packet to server requesting to equip + String pointName = point.getEquipPointId(); + int serverSideID = Globals.clientSceneWrapper.mapClientToServerId(toEquip.getId()); + NetworkMessage requestPickupMessage = InventoryMessage.constructclientRequestEquipItemMessage(pointName, serverSideID); + Globals.clientConnection.queueOutgoingMessage(requestPickupMessage); + } + } + + public void clientAttemptEquip(Entity toEquip, EquipPoint point){ + boolean hasEquipped = hasEquippedAtPoint(point.getEquipPointId()); + boolean targetIsItem = ItemUtils.isItem(toEquip); + boolean targetIsAttached = AttachUtils.isAttached(toEquip); + boolean targetHasWhitelist = ItemUtils.hasEquipList(toEquip); + String equipItemClass = ItemUtils.getEquipClass(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)){ + //put in map + equipMap.put(point.getEquipPointId(),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.clientAttachEntityToEntityAtBone(parent, toEquip, point.getBone(), AttachUtils.getEquipPointRotationOffset(point.getOffsetRotation())); + //make uncollidable + if(toEquip.containsKey(EntityDataStrings.PHYSICS_COLLISION_BODY) && toEquip.containsKey(EntityDataStrings.PHYSICS_COLLIDABLE)){ + DBody rigidBody = (DBody)toEquip.getData(EntityDataStrings.PHYSICS_COLLISION_BODY); + Globals.clientSceneWrapper.getCollisionEngine().deregisterPhysicsObject(rigidBody); + } + //hide toEquip actor + EntityUtils.setDraw(toEquip, false); + //make untargetable + Globals.clientSceneWrapper.getScene().removeEntityFromTag(toEquip, EntityTags.TARGETABLE); + break; + } + } + } else { + //since we're not replacing meshes we must be attaching to a bone + equipMap.put(point.getEquipPointId(),toEquip); + AttachUtils.clientAttachEntityToEntityAtBone(parent, toEquip, point.getBone(), AttachUtils.getEquipPointRotationOffset(point.getOffsetRotation())); + if(toEquip.containsKey(EntityDataStrings.PHYSICS_COLLISION_BODY) && toEquip.containsKey(EntityDataStrings.PHYSICS_COLLIDABLE)){ + DBody rigidBody = (DBody)toEquip.getData(EntityDataStrings.PHYSICS_COLLISION_BODY); + Globals.clientSceneWrapper.getCollisionEngine().deregisterPhysicsObject(rigidBody); + } + Globals.clientSceneWrapper.getScene().removeEntityFromTag(toEquip, EntityTags.TARGETABLE); + GravityUtils.clientAttemptDeactivateGravity(toEquip); + } + } + + // 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 EquipPoint getEquipPoint(String name){ + for(EquipPoint point : equipPoints){ + if(point.getEquipPointId().equals(name)){ + return point; + } + } + return null; + } + + public Entity getEquippedItemAtPoint(String point){ + return equipMap.get(point); + } + + /** + * Returns whether the entity has an equip state + * @param entity The entity to check + * @return True if the entity contains an equip state, false otherwise + */ + public static boolean hasEquipState(Entity entity){ + return entity.containsKey(EntityDataStrings.EQUIP_STATE); + } + + /** + * Gets the equip state on the entity + * @param entity The entity to retrieve equip state from + * @return The equip state on the entity + */ + public static ClientEquipState getEquipState(Entity entity){ + return (ClientEquipState)entity.getData(EntityDataStrings.EQUIP_STATE); + } + + /** + * Sets the equip state on the entity + * @param entity The entity to attach the equip state to + * @param equipState The equip state to attach + */ + public static void setEquipState(Entity entity, ClientEquipState equipState){ + entity.putData(EntityDataStrings.EQUIP_STATE, equipState); + } + + // 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 commandAttemptUnequip(String pointId){ + boolean hasEquipped = hasEquippedAtPoint(pointId); + if(hasEquipped){ + //send packet to server requesting to equip + NetworkMessage requestUnequipMessage = InventoryMessage.constructclientRequestUnequipItemMessage(pointId); + Globals.clientConnection.queueOutgoingMessage(requestUnequipMessage); + } + } + + public void clientTransformUnequipPoint(String pointId){ + Entity equipped = equipMap.remove(pointId); + if(equipped != null){ + boolean targetHasWhitelist = ItemUtils.hasEquipList(equipped); + if(targetHasWhitelist){ + //by attaching are we going to be replacing meshes? + String parentCreatureId = CreatureUtils.getType(parent); + List whitelist = ItemUtils.getEquipWhitelist(equipped); + for(EquipWhitelist whitelistItem : whitelist){ + if(whitelistItem.getCreatureId().equals(parentCreatureId)){ + //put in map + String modelName = whitelistItem.getModel(); + Actor parentActor = EntityUtils.getActor(parent); + //queue meshes from display model to parent actor + ActorMeshMask meshMask = parentActor.getMeshMask(); + for(String toUnblock : whitelistItem.getMeshMaskList()){ + meshMask.unblockMesh(toUnblock); + } + for(String toDraw : whitelistItem.getMeshList()){ + meshMask.removeAdditionalMesh(toDraw); + } + break; + } + } + } else { + AttachUtils.clientDetatchEntityFromEntityAtBone(parent, equipped); + EntityUtils.cleanUpEntity(equipped); + } + } + } + + public boolean hasEquippedAtPoint(String point){ + return equipMap.containsKey(point); + } + + +} diff --git a/src/main/java/electrosphere/entity/state/equip/EquipState.java b/src/main/java/electrosphere/entity/state/equip/ServerEquipState.java similarity index 63% rename from src/main/java/electrosphere/entity/state/equip/EquipState.java rename to src/main/java/electrosphere/entity/state/equip/ServerEquipState.java index b443e1af..b9adeb85 100644 --- a/src/main/java/electrosphere/entity/state/equip/EquipState.java +++ b/src/main/java/electrosphere/entity/state/equip/ServerEquipState.java @@ -8,8 +8,6 @@ import java.util.Map; import org.joml.Vector3d; import org.ode4j.ode.DBody; -import electrosphere.client.targeting.crosshair.Crosshair; -import electrosphere.collision.collidable.Collidable; import electrosphere.engine.Globals; import electrosphere.entity.Entity; import electrosphere.entity.EntityDataStrings; @@ -28,25 +26,24 @@ import electrosphere.net.parser.net.message.InventoryMessage; import electrosphere.net.parser.net.message.NetworkMessage; import electrosphere.net.server.player.Player; import electrosphere.net.server.protocol.InventoryProtocol; -import electrosphere.renderer.actor.Actor; -import electrosphere.renderer.actor.ActorMeshMask; +import electrosphere.net.synchronization.annotation.SynchronizedBehaviorTree; import electrosphere.server.datacell.Realm; import electrosphere.server.datacell.ServerDataCell; import electrosphere.server.datacell.utils.DataCellSearchUtils; import electrosphere.server.datacell.utils.ServerEntityTagUtils; +@SynchronizedBehaviorTree(name = "serverEquipState", isServer = true, correspondingTree="clientEquipState") /** - * - * @author amaterasu + * Server view of items equipped onto an entity */ -public class EquipState { +public class ServerEquipState { Entity parent; List equipPoints = new LinkedList(); Map equipMap = new HashMap(); - public EquipState(Entity parent, List equipPoints){ + public ServerEquipState(Entity parent, List equipPoints){ this.parent = parent; for(EquipPoint point : equipPoints){ this.equipPoints.add(point); @@ -67,14 +64,7 @@ public class EquipState { boolean itemIsInPointWhitelist = pointEquipClassList.contains(equipItemClass); if(!hasEquipped && targetIsItem && !targetIsAttached && itemIsInPointWhitelist){ //if we're the server, perform the attempt, otherwise send packet to server requesting to equip - if(Globals.RUN_SERVER){ - serverAttemptEquip(toEquip, point); - } else { - String pointName = point.getEquipPointId(); - int serverSideID = Globals.clientSceneWrapper.mapClientToServerId(toEquip.getId()); - NetworkMessage requestPickupMessage = InventoryMessage.constructclientRequestEquipItemMessage(pointName, serverSideID); - Globals.clientConnection.queueOutgoingMessage(requestPickupMessage); - } + serverAttemptEquip(toEquip, point); } } @@ -103,15 +93,6 @@ public class EquipState { equipMap.put(point.getEquipPointId(),inWorldItem); 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.serverAttachEntityToEntityAtBone(parent, inWorldItem, point.getBone(), AttachUtils.getEquipPointRotationOffset(point.getOffsetRotation())); //make uncollidable @@ -142,7 +123,7 @@ public class EquipState { //we need to send two packets //1) Remove item from original inventory //2) Add item with ID to "equipped" inventory - //let clients know of the updates if we're the server + //let clients know of the updates //get the parent (typically creature) that contains the in-inventory item Entity containingEntity = ItemUtils.getContainingParent(inInventoryEntity); //actually switch containers @@ -182,105 +163,6 @@ public class EquipState { } } - public void clientAttemptEquip(Entity toEquip, EquipPoint point){ - boolean hasEquipped = hasEquippedAtPoint(point.getEquipPointId()); - boolean targetIsItem = ItemUtils.isItem(toEquip); - boolean targetIsAttached = AttachUtils.isAttached(toEquip); - boolean targetHasWhitelist = ItemUtils.hasEquipList(toEquip); - String equipItemClass = ItemUtils.getEquipClass(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)){ - //put in map - equipMap.put(point.getEquipPointId(),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.clientAttachEntityToEntityAtBone(parent, toEquip, point.getBone(), AttachUtils.getEquipPointRotationOffset(point.getOffsetRotation())); - //make uncollidable - if(toEquip.containsKey(EntityDataStrings.PHYSICS_COLLISION_BODY) && toEquip.containsKey(EntityDataStrings.PHYSICS_COLLIDABLE)){ - DBody rigidBody = (DBody)toEquip.getData(EntityDataStrings.PHYSICS_COLLISION_BODY); - Globals.clientSceneWrapper.getCollisionEngine().deregisterPhysicsObject(rigidBody); - } - //hide toEquip actor - EntityUtils.setDraw(toEquip, false); - //make untargetable - Globals.clientSceneWrapper.getScene().removeEntityFromTag(toEquip, EntityTags.TARGETABLE); - break; - } - } - } else { - //since we're not replacing meshes we must be attaching to a bone - equipMap.put(point.getEquipPointId(),toEquip); - AttachUtils.clientAttachEntityToEntityAtBone(parent, toEquip, point.getBone(), AttachUtils.getEquipPointRotationOffset(point.getOffsetRotation())); - if(toEquip.containsKey(EntityDataStrings.PHYSICS_COLLISION_BODY) && toEquip.containsKey(EntityDataStrings.PHYSICS_COLLIDABLE)){ - DBody rigidBody = (DBody)toEquip.getData(EntityDataStrings.PHYSICS_COLLISION_BODY); - Globals.clientSceneWrapper.getCollisionEngine().deregisterPhysicsObject(rigidBody); - } - Globals.clientSceneWrapper.getScene().removeEntityFromTag(toEquip, EntityTags.TARGETABLE); - GravityUtils.clientAttemptDeactivateGravity(toEquip); - } - } - - // 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 EquipPoint getEquipPoint(String name){ for(EquipPoint point : equipPoints){ if(point.getEquipPointId().equals(name)){ @@ -308,8 +190,8 @@ public class EquipState { * @param entity The entity to retrieve equip state from * @return The equip state on the entity */ - public static EquipState getEquipState(Entity entity){ - return (EquipState)entity.getData(EntityDataStrings.EQUIP_STATE); + public static ServerEquipState getEquipState(Entity entity){ + return (ServerEquipState)entity.getData(EntityDataStrings.EQUIP_STATE); } /** @@ -317,7 +199,7 @@ public class EquipState { * @param entity The entity to attach the equip state to * @param equipState The equip state to attach */ - public static void setEquipState(Entity entity, EquipState equipState){ + public static void setEquipState(Entity entity, ServerEquipState equipState){ entity.putData(EntityDataStrings.EQUIP_STATE, equipState); } @@ -336,13 +218,8 @@ public class EquipState { public void commandAttemptUnequip(String pointId){ boolean hasEquipped = hasEquippedAtPoint(pointId); if(hasEquipped){ - //if we're the server, perform the attempt, otherwise send packet to server requesting to equip - if(Globals.RUN_SERVER){ - serverAttemptUnequip(pointId); - } else { - NetworkMessage requestUnequipMessage = InventoryMessage.constructclientRequestUnequipItemMessage(pointId); - Globals.clientConnection.queueOutgoingMessage(requestUnequipMessage); - } + //perform the attempt + serverAttemptUnequip(pointId); } } @@ -393,18 +270,6 @@ public class EquipState { // inventory.addItem(item); } - public void clientTransformUnequipPoint(String pointId){ - Entity equipped = equipMap.remove(pointId); - if(equipped != null){ - boolean targetHasWhitelist = ItemUtils.hasEquipList(equipped); - if(targetHasWhitelist){ - } else { - AttachUtils.clientDetatchEntityFromEntityAtBone(parent, equipped); - EntityUtils.cleanUpEntity(equipped); - } - } - } - public void serverTransformUnequipPoint(String pointId){ Entity equipped = equipMap.remove(pointId); if(equipped != null){ @@ -452,6 +317,4 @@ public class EquipState { public boolean hasEquippedAtPoint(String point){ return equipMap.containsKey(point); } - - } diff --git a/src/main/java/electrosphere/entity/state/inventory/InventoryState.java b/src/main/java/electrosphere/entity/state/inventory/InventoryState.java index 67be7703..a9940767 100644 --- a/src/main/java/electrosphere/entity/state/inventory/InventoryState.java +++ b/src/main/java/electrosphere/entity/state/inventory/InventoryState.java @@ -6,7 +6,7 @@ import electrosphere.engine.Globals; import electrosphere.entity.Entity; import electrosphere.entity.EntityUtils; import electrosphere.entity.btree.BehaviorTree; -import electrosphere.entity.state.equip.EquipState; +import electrosphere.entity.state.equip.ClientEquipState; import electrosphere.entity.types.item.ItemUtils; import electrosphere.game.data.creature.type.equip.EquipPoint; import electrosphere.menu.WindowStrings; @@ -95,9 +95,9 @@ public class InventoryState implements BehaviorTree { } break; case SERVERCOMMANDUNEQUIPITEM: { - if(Globals.playerEntity != null && EquipState.hasEquipState(Globals.playerEntity)){ + if(Globals.playerEntity != null && ClientEquipState.hasEquipState(Globals.playerEntity)){ //unequip the item - EquipState equipState = EquipState.getEquipState(Globals.playerEntity); + ClientEquipState equipState = ClientEquipState.getEquipState(Globals.playerEntity); Entity entityInSlot = equipState.getEquippedItemAtPoint(message.getequipPointId()); equipState.clientTransformUnequipPoint(message.getequipPointId()); //destroy the in-world manifestation of said item diff --git a/src/main/java/electrosphere/entity/state/inventory/InventoryUtils.java b/src/main/java/electrosphere/entity/state/inventory/InventoryUtils.java index b55090f2..626562f7 100644 --- a/src/main/java/electrosphere/entity/state/inventory/InventoryUtils.java +++ b/src/main/java/electrosphere/entity/state/inventory/InventoryUtils.java @@ -7,7 +7,8 @@ import electrosphere.engine.Globals; import electrosphere.entity.Entity; import electrosphere.entity.EntityDataStrings; import electrosphere.entity.EntityUtils; -import electrosphere.entity.state.equip.EquipState; +import electrosphere.entity.state.equip.ClientEquipState; +import electrosphere.entity.state.equip.ServerEquipState; import electrosphere.entity.state.gravity.GravityUtils; import electrosphere.entity.types.creature.CreatureUtils; import electrosphere.entity.types.item.ItemUtils; @@ -96,28 +97,26 @@ public class InventoryUtils { //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.serverRecreateContainerItem(item, creature); - //destroy the item that was left over - ItemUtils.serverDestroyInWorldItem(item); //store item in inventory inventory.addItem(inventoryItem); //set item containing parent ItemUtils.setContainingParent(inventoryItem, creature); //if we are the server, immediately send required packets - if(Globals.RUN_SERVER){ - ServerDataCell dataCell = Globals.realmManager.getEntityRealm(item).getEntityDataCellMapper().getEntityDataCell(item); - // ServerDataCell dataCell = Globals.dataCellLocationResolver.getDataCellAtPoint(EntityUtils.getPosition(item),item); - dataCell.getScene().deregisterEntity(item); - //broadcast destroy entity - dataCell.broadcastNetworkMessage(EntityMessage.constructDestroyMessage(item.getId())); - //tell controlling player that they have an item in their inventory - if(CreatureUtils.hasControllerPlayerId(creature)){ - //get the player - int controllerPlayerID = CreatureUtils.getControllerPlayerId(creature); - Player controllerPlayer = Globals.playerManager.getPlayerFromId(controllerPlayerID); - //send message - controllerPlayer.addMessage(InventoryMessage.constructaddItemToInventoryMessage(inventoryItem.getId(), ItemUtils.getType(inventoryItem))); - } + ServerDataCell dataCell = DataCellSearchUtils.getEntityDataCell(item); + // ServerDataCell dataCell = Globals.dataCellLocationResolver.getDataCellAtPoint(EntityUtils.getPosition(item),item); + dataCell.getScene().deregisterEntity(item); + //broadcast destroy entity + dataCell.broadcastNetworkMessage(EntityMessage.constructDestroyMessage(item.getId())); + //tell controlling player that they have an item in their inventory + if(CreatureUtils.hasControllerPlayerId(creature)){ + //get the player + int controllerPlayerID = CreatureUtils.getControllerPlayerId(creature); + Player controllerPlayer = Globals.playerManager.getPlayerFromId(controllerPlayerID); + //send message + controllerPlayer.addMessage(InventoryMessage.constructaddItemToInventoryMessage(inventoryItem.getId(), ItemUtils.getType(inventoryItem))); } + //destroy the item that was left over + ItemUtils.serverDestroyInWorldItem(item); } } @@ -126,18 +125,23 @@ public class InventoryUtils { * @param creature the creature which has a natural inventory * @param item the in-world item entity to store */ - public static void attemptStoreItem(Entity creature, Entity item){ - if(Globals.RUN_SERVER){ - //if we're the server, immediately attempt the transform - serverAttemptStoreItemTransform(creature,item); - } else { - //if we're the client, tell the server we want to try the transform - NetworkMessage requestPickupMessage = InventoryMessage.constructaddItemToInventoryMessage( - Globals.clientSceneWrapper.mapClientToServerId(item.getId()), - ItemUtils.getType(item) - ); - Globals.clientConnection.queueOutgoingMessage(requestPickupMessage); - } + public static void clientAttemptStoreItem(Entity creature, Entity item){ + //tell the server we want to try the transform + NetworkMessage requestPickupMessage = InventoryMessage.constructaddItemToInventoryMessage( + Globals.clientSceneWrapper.mapClientToServerId(item.getId()), + ItemUtils.getType(item) + ); + Globals.clientConnection.queueOutgoingMessage(requestPickupMessage); + } + + /** + * Attempts to store the in-world item entity in a creature inventory container + * @param creature the creature which has a natural inventory + * @param item the in-world item entity to store + */ + public static void serverAttemptStoreItem(Entity creature, Entity item){ + //immediately attempt the transform + serverAttemptStoreItemTransform(creature,item); } /** @@ -206,7 +210,7 @@ public class InventoryUtils { Entity realWorldItem = ItemUtils.getRealWorldEntity(item); if(realWorldItem != null){ //drop item - EquipState equipState = EquipState.getEquipState(creature); + ServerEquipState equipState = ServerEquipState.getEquipState(creature); equipState.serverTransformUnequipPoint(inventorySlot); // equipState.serverAttemptUnequip(inventory.getItemSlot(item)); // @@ -245,15 +249,16 @@ public class InventoryUtils { } //need creature so we can figure out where to drop the item - public static void attemptEjectItem(Entity creature, Entity item){ - if(Globals.RUN_SERVER){ - //if we're the server, immediately attempt the transform - serverAttemptEjectItemTransform(creature,item); - } else { - //if we're the client, tell the server we want to try the transform - NetworkMessage requestPickupMessage = InventoryMessage.constructremoveItemFromInventoryMessage(Globals.clientSceneWrapper.mapClientToServerId(item.getId())); - Globals.clientConnection.queueOutgoingMessage(requestPickupMessage); - } + public static void serverAttemptEjectItem(Entity creature, Entity item){ + //if we're the server, immediately attempt the transform + serverAttemptEjectItemTransform(creature,item); + } + + //need creature so we can figure out where to drop the item + public static void clientAttemptEjectItem(Entity creature, Entity item){ + //if we're the client, tell the server we want to try the transform + NetworkMessage requestPickupMessage = InventoryMessage.constructremoveItemFromInventoryMessage(Globals.clientSceneWrapper.mapClientToServerId(item.getId())); + Globals.clientConnection.queueOutgoingMessage(requestPickupMessage); } /** @@ -284,7 +289,7 @@ public class InventoryUtils { Entity realWorldItem = ItemUtils.getRealWorldEntity(item); if(realWorldItem != null){ //drop item - EquipState equipState = EquipState.getEquipState(creature); + ClientEquipState equipState = ClientEquipState.getEquipState(creature); equipState.clientTransformUnequipPoint(inventory.getItemSlot(item)); } //remove item from inventory diff --git a/src/main/java/electrosphere/entity/state/inventory/ServerInventoryState.java b/src/main/java/electrosphere/entity/state/inventory/ServerInventoryState.java index e858532e..ad4ff1d7 100644 --- a/src/main/java/electrosphere/entity/state/inventory/ServerInventoryState.java +++ b/src/main/java/electrosphere/entity/state/inventory/ServerInventoryState.java @@ -6,7 +6,7 @@ import electrosphere.engine.Globals; import electrosphere.entity.Entity; import electrosphere.entity.EntityUtils; import electrosphere.entity.btree.BehaviorTree; -import electrosphere.entity.state.equip.EquipState; +import electrosphere.entity.state.equip.ServerEquipState; import electrosphere.entity.types.item.ItemUtils; import electrosphere.game.data.creature.type.equip.EquipPoint; import electrosphere.menu.WindowStrings; @@ -42,17 +42,17 @@ public class ServerInventoryState implements BehaviorTree { networkMessageQueue.remove(message); switch(message.getMessageSubtype()){ case ADDITEMTOINVENTORY: - InventoryUtils.attemptStoreItem(parent, EntityLookupUtils.getEntityById(message.getentityId())); + InventoryUtils.serverAttemptStoreItem(parent, EntityLookupUtils.getEntityById(message.getentityId())); break; case REMOVEITEMFROMINVENTORY: - InventoryUtils.attemptEjectItem(parent, EntityLookupUtils.getEntityById(message.getentityId())); + InventoryUtils.serverAttemptEjectItem(parent, EntityLookupUtils.getEntityById(message.getentityId())); break; case CLIENTREQUESTEQUIPITEM:{ //item to equip Entity target = EntityLookupUtils.getEntityById(message.getentityId()); //perform transform if it makes sense - if(InventoryUtils.hasEquipInventory(parent) && InventoryUtils.hasNaturalInventory(parent) && EquipState.hasEquipState(parent)){ - EquipState equipState = EquipState.getEquipState(parent); + if(InventoryUtils.hasEquipInventory(parent) && InventoryUtils.hasNaturalInventory(parent) && ServerEquipState.hasEquipState(parent)){ + ServerEquipState equipState = ServerEquipState.getEquipState(parent); EquipPoint point = equipState.getEquipPoint(message.getequipPointId()); equipState.commandAttemptEquip(target, point); } @@ -60,8 +60,8 @@ public class ServerInventoryState implements BehaviorTree { break; case CLIENTREQUESTUNEQUIPITEM:{ //make sure can unequip - if(InventoryUtils.hasEquipInventory(parent) && InventoryUtils.hasNaturalInventory(parent) && EquipState.hasEquipState(parent)){ - EquipState equipState = EquipState.getEquipState(parent); + if(InventoryUtils.hasEquipInventory(parent) && InventoryUtils.hasNaturalInventory(parent) && ServerEquipState.hasEquipState(parent)){ + ServerEquipState equipState = ServerEquipState.getEquipState(parent); EquipPoint point = equipState.getEquipPoint(message.getequipPointId()); if(equipState.hasEquippedAtPoint(message.getequipPointId())){ equipState.commandAttemptUnequip(message.getequipPointId()); diff --git a/src/main/java/electrosphere/entity/types/attach/AttachUtils.java b/src/main/java/electrosphere/entity/types/attach/AttachUtils.java index 1d0495b6..e35ff6d0 100644 --- a/src/main/java/electrosphere/entity/types/attach/AttachUtils.java +++ b/src/main/java/electrosphere/entity/types/attach/AttachUtils.java @@ -10,6 +10,7 @@ import electrosphere.renderer.actor.Actor; import electrosphere.renderer.model.Model; import electrosphere.server.datacell.ServerDataCell; import electrosphere.server.datacell.utils.ServerEntityTagUtils; +import electrosphere.server.poseactor.PoseActor; import java.util.LinkedList; import java.util.List; @@ -45,7 +46,7 @@ public class AttachUtils { if((parent = (Entity)currentEntity.getData(EntityDataStrings.ATTACH_PARENT))!=null){ String targetBone; if((targetBone = (String)currentEntity.getData(EntityDataStrings.ATTACH_TARGET_BONE))!=null){ - Actor parentActor = EntityUtils.getActor(parent); + PoseActor parentActor = EntityUtils.getPoseActor(parent); //get offset rotation Quaterniond offsetRotation = getRotationOffset(currentEntity); //transform bone space @@ -420,7 +421,11 @@ public class AttachUtils { } public static Quaterniond getEquipPointRotationOffset(List values){ - return new Quaterniond(values.get(0),values.get(1),values.get(2),values.get(3)); + if(values.size() > 0){ + return new Quaterniond(values.get(0),values.get(1),values.get(2),values.get(3)); + } else { + return new Quaterniond(); + } } } diff --git a/src/main/java/electrosphere/entity/types/creature/CreatureUtils.java b/src/main/java/electrosphere/entity/types/creature/CreatureUtils.java index a38d5257..b1ec00b0 100644 --- a/src/main/java/electrosphere/entity/types/creature/CreatureUtils.java +++ b/src/main/java/electrosphere/entity/types/creature/CreatureUtils.java @@ -25,7 +25,8 @@ import electrosphere.entity.state.attack.ServerAttackTree; import electrosphere.entity.state.attack.ShooterTree; import electrosphere.entity.state.collidable.ClientCollidableTree; import electrosphere.entity.state.collidable.ServerCollidableTree; -import electrosphere.entity.state.equip.EquipState; +import electrosphere.entity.state.equip.ClientEquipState; +import electrosphere.entity.state.equip.ServerEquipState; import electrosphere.entity.state.gravity.ClientGravityTree; import electrosphere.entity.state.gravity.ServerGravityTree; import electrosphere.entity.state.idle.IdleTree; @@ -227,7 +228,7 @@ public class CreatureUtils { } } if(rawType.getEquipPoints() != null && rawType.getEquipPoints().size() > 0){ - EquipState.setEquipState(rVal, new EquipState(rVal,rawType.getEquipPoints())); + ClientEquipState.setEquipState(rVal, new ClientEquipState(rVal,rawType.getEquipPoints())); rVal.putData(EntityDataStrings.EQUIP_INVENTORY, RelationalInventoryState.buildRelationalInventoryStateFromEquipList(rawType.getEquipPoints())); } for(String token : rawType.getTokens()){ @@ -523,7 +524,7 @@ public class CreatureUtils { } } if(rawType.getEquipPoints() != null && rawType.getEquipPoints().size() > 0){ - EquipState.setEquipState(rVal, new EquipState(rVal,rawType.getEquipPoints())); + ServerEquipState.setEquipState(rVal, new ServerEquipState(rVal,rawType.getEquipPoints())); rVal.putData(EntityDataStrings.EQUIP_INVENTORY, RelationalInventoryState.buildRelationalInventoryStateFromEquipList(rawType.getEquipPoints())); } for(String token : rawType.getTokens()){ diff --git a/src/main/java/electrosphere/entity/types/item/ItemUtils.java b/src/main/java/electrosphere/entity/types/item/ItemUtils.java index 7cf736a9..3bf99483 100644 --- a/src/main/java/electrosphere/entity/types/item/ItemUtils.java +++ b/src/main/java/electrosphere/entity/types/item/ItemUtils.java @@ -389,13 +389,15 @@ public class ItemUtils { Realm itemRealm = Globals.realmManager.getEntityRealm(item); //destroy physics //this deregisters from all four & unhooks rigid bodies from the physics runtime - itemRealm.getCollisionEngine().destroyEntityThatHasPhysics(item); - //destroy hitboxes - List hitboxes = HitboxUtils.getHitboxAssociatedList(item); - if(hitboxes != null){ - for(Entity hitbox : hitboxes){ - itemRealm.getHitboxManager().deregisterHitbox(hitbox); - HitboxUtils.getHitboxData(hitbox).setActive(false); + if(itemRealm != null){ + itemRealm.getCollisionEngine().destroyEntityThatHasPhysics(item); + //destroy hitboxes + List hitboxes = HitboxUtils.getHitboxAssociatedList(item); + if(hitboxes != null){ + for(Entity hitbox : hitboxes){ + itemRealm.getHitboxManager().deregisterHitbox(hitbox); + HitboxUtils.getHitboxData(hitbox).setActive(false); + } } } //destroy graphics 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 431c0670..eb95a696 100644 --- a/src/main/java/electrosphere/game/data/item/type/Item.java +++ b/src/main/java/electrosphere/game/data/item/type/Item.java @@ -1,6 +1,5 @@ package electrosphere.game.data.item.type; -import electrosphere.entity.types.hitbox.HitboxData; import electrosphere.game.data.collidable.CollidableTemplate; import java.util.List; diff --git a/src/main/java/electrosphere/menu/WindowUtils.java b/src/main/java/electrosphere/menu/WindowUtils.java index 31b2ca41..9fd84bbb 100644 --- a/src/main/java/electrosphere/menu/WindowUtils.java +++ b/src/main/java/electrosphere/menu/WindowUtils.java @@ -21,7 +21,7 @@ public class WindowUtils { //todo: destroy elements as well mainMenu.clear(); mainMenu.addChild(newMenu); - mainMenu.applyYoga(); + mainMenu.applyYoga(0,0); Globals.elementManager.focusFirstElement(); } } @@ -35,6 +35,9 @@ public class WindowUtils { recursiveSetVisible(child, visible); } } + if(visible){ + topLevelMenu.applyYoga(0, 0); + } } public static String getInventoryWindowID(int id){ @@ -122,7 +125,7 @@ public class WindowUtils { Label loadingLabel = new Label(1.0f); loadingLabel.setText("LOADING"); loadingWindow.addChild(loadingLabel); - loadingWindow.applyYoga(); + loadingWindow.applyYoga(0,0); Globals.elementManager.registerWindow(WindowStrings.WINDOW_LOADING, loadingWindow); WindowUtils.recursiveSetVisible(loadingWindow, true); } @@ -138,7 +141,7 @@ public class WindowUtils { } static void initItemDragContainerWindow(){ - Window itemDragContainerWindow = new Window(0,0,Globals.WINDOW_WIDTH,Globals.WINDOW_HEIGHT,true); + Window itemDragContainerWindow = new Window(0,0,Globals.WINDOW_WIDTH,Globals.WINDOW_HEIGHT,false); Globals.elementManager.registerWindow(WindowStrings.WINDOW_ITEM_DRAG_CONTAINER, itemDragContainerWindow); } diff --git a/src/main/java/electrosphere/menu/debug/ImGuiEntityMacros.java b/src/main/java/electrosphere/menu/debug/ImGuiEntityMacros.java new file mode 100644 index 00000000..c5fa1763 --- /dev/null +++ b/src/main/java/electrosphere/menu/debug/ImGuiEntityMacros.java @@ -0,0 +1,118 @@ +package electrosphere.menu.debug; + +import electrosphere.engine.Globals; +import electrosphere.entity.Entity; +import electrosphere.entity.EntityUtils; +import electrosphere.entity.types.creature.CreatureUtils; +import electrosphere.entity.types.foliage.FoliageUtils; +import electrosphere.entity.types.item.ItemUtils; +import electrosphere.renderer.RenderingEngine; +import electrosphere.renderer.actor.Actor; +import electrosphere.renderer.actor.ActorMeshMask; +import electrosphere.renderer.model.Mesh; +import electrosphere.renderer.ui.imgui.ImGuiWindow; +import electrosphere.renderer.ui.imgui.ImGuiWindow.ImGuiWindowCallback; +import imgui.ImGui; + +/** + * Macros for creating imgui windows relating to entity debugging + */ +public class ImGuiEntityMacros { + + protected static ImGuiWindow clientEntityWindow; + private static boolean filterToCreatures = false; + + protected static ImGuiWindow actorView; + static Entity actorViewEntity; + + /** + * Creates the windows in this file + */ + protected static void createClientEntityWindows(){ + createClientEntityDebugWindow(); + createActorViewDebugWindow(); + } + + /** + * Client scene entity view + */ + protected static void createClientEntityDebugWindow(){ + clientEntityWindow = new ImGuiWindow("Client Entities"); + clientEntityWindow.setCallback(new ImGuiWindowCallback() { + @Override + public void exec() { + //audio engine details + ImGui.text("Client Entities"); + if(ImGui.checkbox("Filter to Creatures", filterToCreatures)){ + filterToCreatures = !filterToCreatures; + } + for(Entity entity : Globals.clientSceneWrapper.getScene().getEntityList()){ + //filters + if(filterToCreatures && !CreatureUtils.isCreature(entity)){ + continue; + } + ImGui.beginGroup(); + ImGui.text("Id: " + entity.getId() + " (" + getEntityName(entity) + ")"); + if(CreatureUtils.isCreature(entity)){ + if(ImGui.button("Actor View")){ + actorViewEntity = entity; + actorView.setOpen(true); + } + } + ImGui.endGroup(); + } + } + }); + clientEntityWindow.setOpen(false); + RenderingEngine.addImGuiWindow(clientEntityWindow); + } + + /** + * Client scene entity view + */ + protected static void createActorViewDebugWindow(){ + actorView = new ImGuiWindow("Actor View"); + actorView.setCallback(new ImGuiWindowCallback() { + @Override + public void exec() { + if(actorViewEntity != null && EntityUtils.getActor(actorViewEntity) != null){ + Actor actor = EntityUtils.getActor(actorViewEntity); + + //mesh mask + if(ImGui.collapsingHeader("Mesh Mask")){ + ActorMeshMask meshMask = actor.getMeshMask(); + ImGui.text("To Draw Meshes:"); + for(Mesh mesh : meshMask.getToDrawMeshes()){ + ImGui.text(mesh.getMeshName()); + } + ImGui.text("Blocked Meshes:"); + for(String blocked : meshMask.getBlockedMeshes()){ + ImGui.text(blocked); + } + } + } + } + }); + actorView.setOpen(false); + RenderingEngine.addImGuiWindow(actorView); + } + + /** + * Gets the displayed name of an entity (ie creature type, foliage type, terrain, etc) + * @param entity + * @return + */ + private static String getEntityName(Entity entity){ + if(CreatureUtils.isCreature(entity)){ + return CreatureUtils.getType(entity); + } + if(ItemUtils.isItem(entity)){ + return ItemUtils.getType(entity); + } + if(FoliageUtils.isFoliage(entity)){ + return FoliageUtils.getFoliageType(entity).getName(); + } + return "Entity"; + } + +} diff --git a/src/main/java/electrosphere/menu/debug/ImGuiWindowMacros.java b/src/main/java/electrosphere/menu/debug/ImGuiWindowMacros.java index f4428e39..bb60ae24 100644 --- a/src/main/java/electrosphere/menu/debug/ImGuiWindowMacros.java +++ b/src/main/java/electrosphere/menu/debug/ImGuiWindowMacros.java @@ -7,13 +7,10 @@ import org.ode4j.ode.DBody; import electrosphere.audio.VirtualAudioSource; import electrosphere.collision.PhysicsEntityUtils; -import electrosphere.collision.PhysicsUtils; -import electrosphere.controls.ControlHandler.ControlsState; import electrosphere.engine.Globals; import electrosphere.entity.EntityUtils; import electrosphere.renderer.RenderingEngine; import electrosphere.renderer.ui.imgui.ImGuiLinePlot; -import electrosphere.renderer.ui.imgui.ImGuiBarPlot; import electrosphere.renderer.ui.imgui.ImGuiWindow; import electrosphere.renderer.ui.imgui.ImGuiLinePlot.ImGuiLinePlotDataset; import electrosphere.renderer.ui.imgui.ImGuiWindow.ImGuiWindowCallback; @@ -54,6 +51,7 @@ public class ImGuiWindowMacros { createAudioDebugMenu(); createPlayerEntityDebugWindow(); createFluidDebugWindow(); + ImGuiEntityMacros.createClientEntityWindows(); } /** @@ -232,6 +230,10 @@ public class ImGuiWindowMacros { if(ImGui.button("Show Fluids Debug Menu")){ fluidWindow.setOpen(true); } + //client entity debug + if(ImGui.button("Client Entity Debug")){ + ImGuiEntityMacros.clientEntityWindow.setOpen(true); + } //close button if(ImGui.button("Close")){ mainDebugWindow.setOpen(false); diff --git a/src/main/java/electrosphere/menu/ingame/MenuGeneratorsInGame.java b/src/main/java/electrosphere/menu/ingame/MenuGeneratorsInGame.java index f70bf686..94b2a236 100644 --- a/src/main/java/electrosphere/menu/ingame/MenuGeneratorsInGame.java +++ b/src/main/java/electrosphere/menu/ingame/MenuGeneratorsInGame.java @@ -1,7 +1,6 @@ package electrosphere.menu.ingame; import org.joml.Vector3f; -import org.lwjgl.util.yoga.Yoga; import electrosphere.controls.ControlHandler.ControlsState; import electrosphere.engine.Globals; @@ -129,7 +128,7 @@ public class MenuGeneratorsInGame { return false; }})); - rVal.applyYoga(); + rVal.applyYoga(0,0); return rVal; } @@ -322,7 +321,7 @@ public class MenuGeneratorsInGame { return false; }}); - rVal.applyYoga(); + rVal.applyYoga(0,0); return rVal; } @@ -374,10 +373,10 @@ public class MenuGeneratorsInGame { if(attribute.getType().equals("bone")){ Slider attributeSlider = new Slider(50,posY,400,100,new Vector3f(0.1f,0.1f,0.1f),new Vector3f(1.0f,0,0)); attributeSlider.setOnValueChangeCallback(new ValueChangeEventCallback() {public void execute(ValueChangeEvent event) { - float value = event.getAsFloat(); - float minVal = attribute.getMinValue(); - float range = attribute.getMaxValue() - minVal; - float actualValue = minVal + range * value; + // float value = event.getAsFloat(); + // float minVal = attribute.getMinValue(); + // float range = attribute.getMaxValue() - minVal; + // float actualValue = minVal + range * value; staticMorph.updateValue(attribute.getSubtype(), attribute.getPrimaryBone(), event.getAsFloat()); if(attribute.getMirrorBone() != null){ staticMorph.updateValue(attribute.getSubtype(), attribute.getMirrorBone(), event.getAsFloat()); @@ -387,7 +386,7 @@ public class MenuGeneratorsInGame { } } - rVal.applyYoga(); + rVal.applyYoga(0,0); return rVal; } diff --git a/src/main/java/electrosphere/menu/ingame/MenuGeneratorsInventory.java b/src/main/java/electrosphere/menu/ingame/MenuGeneratorsInventory.java index 0db73e4b..74e84e96 100644 --- a/src/main/java/electrosphere/menu/ingame/MenuGeneratorsInventory.java +++ b/src/main/java/electrosphere/menu/ingame/MenuGeneratorsInventory.java @@ -2,14 +2,13 @@ package electrosphere.menu.ingame; import java.util.List; -import electrosphere.audio.AudioUtils; +import org.lwjgl.util.yoga.Yoga; + import electrosphere.audio.VirtualAudioSourceManager.VirtualAudioSourceType; import electrosphere.controls.ControlHandler.ControlsState; import electrosphere.engine.Globals; import electrosphere.entity.Entity; -import electrosphere.entity.EntityDataStrings; -import electrosphere.entity.state.equip.EquipState; -import electrosphere.entity.state.gravity.GravityUtils; +import electrosphere.entity.state.equip.ClientEquipState; import electrosphere.entity.state.inventory.InventoryUtils; import electrosphere.entity.state.inventory.RelationalInventoryState; import electrosphere.entity.state.inventory.UnrelationalInventoryState; @@ -22,10 +21,9 @@ import electrosphere.renderer.ui.elements.Label; import electrosphere.renderer.ui.elements.Window; import electrosphere.renderer.ui.elementtypes.Element; import electrosphere.renderer.ui.elementtypes.ClickableElement.ClickEventCallback; +import electrosphere.renderer.ui.elementtypes.ContainerElement; import electrosphere.renderer.ui.elementtypes.DraggableElement.DragEventCallback; -import electrosphere.renderer.ui.elementtypes.FocusableElement.FocusEventCallback; import electrosphere.renderer.ui.elementtypes.NavigableElement.NavigationEventCallback; -import electrosphere.renderer.ui.elementtypes.ValueElement.ValueChangeEventCallback; import electrosphere.renderer.ui.events.ClickEvent; import electrosphere.renderer.ui.events.DragEvent; import electrosphere.renderer.ui.events.NavigationEvent; @@ -36,7 +34,12 @@ public class MenuGeneratorsInventory { int width = 500; int height = 500; - Window rVal = new Window(0,0,Globals.WINDOW_WIDTH,Globals.WINDOW_HEIGHT,true); + Window rVal = new Window(0,0,width,height,true); + rVal.setParentAlignItem(Yoga.YGAlignCenter); + rVal.setParentJustifyContent(Yoga.YGJustifyCenter); + + //apply yoga so that the screenspace position of the window can be calculated, that allows proper placement of the absolute elements + rVal.applyYoga(0, 0); Div div = new Div(); rVal.addChild(div); @@ -67,9 +70,9 @@ public class MenuGeneratorsInventory { // Globals.dragSourceInventory = null; // Globals.draggedItem = null; Entity item = Globals.draggedItem; - if(EquipState.hasEquipState(Globals.playerEntity) && InventoryUtils.hasEquipInventory(Globals.playerEntity)){ + if(ClientEquipState.hasEquipState(Globals.playerEntity) && InventoryUtils.hasEquipInventory(Globals.playerEntity)){ RelationalInventoryState equipInventory = InventoryUtils.getEquipInventory(Globals.playerEntity); - EquipState equipState = EquipState.getEquipState(Globals.playerEntity); + ClientEquipState equipState = ClientEquipState.getEquipState(Globals.playerEntity); equipState.commandAttemptUnequip(equipInventory.getItemSlot(item)); } //clear item container ui @@ -96,17 +99,9 @@ public class MenuGeneratorsInventory { return false; }}); - //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)); - div.addChild(imagePanel); //label 1 (inventory) - Label inventoryLabel = new Label(10,10,1.0f); - inventoryLabel.setText("INVENTORY"); - div.addChild(inventoryLabel); + div.addChild(Label.createLabel("INVENTORY")); int columns = 8; int columnWidth = 60; @@ -126,16 +121,20 @@ public class MenuGeneratorsInventory { } int posX = (10 + i % columns * columnWidth); int posY = 60 + (i / columns * rowHeight); + int itemPosX = posX; + int itemPosY = posY; int panelWidth = 50; int panelHeight = 50; ImagePanel panel = new ImagePanel(posX,posY,panelWidth,panelHeight,texturePath); + panel.setAbsolutePosition(true); if(hasItem == true){ int itemId = i; panel.setOnDragStart(new DragEventCallback() {public boolean execute(DragEvent event){ // System.out.println("Drag start"); Globals.dragSourceInventory = inventory; Globals.draggedItem = inventory.getItems().get(itemId); - div.removeChild(panel); + ContainerElement container = (ContainerElement)panel.getParent(); + container.removeChild(panel); WindowUtils.pushItemIconToItemWindow(panel); //play sound effect Globals.virtualAudioSourceManager.createVirtualAudioSource("/Audio/inventoryGrabItem.ogg", VirtualAudioSourceType.UI, false); @@ -147,14 +146,27 @@ public class MenuGeneratorsInventory { panel.setPositionY(event.getCurrentY() - panelHeight / 2); return false; }}); + panel.setOnDragRelease(new DragEventCallback(){public boolean execute(DragEvent event){ + if(panel.getParent() != div){ + if(panel.getParent() != null){ + ContainerElement container = (ContainerElement)panel.getParent(); + container.removeChild(panel); + } + div.addChild(panel); + Globals.elementManager.fireEvent(event, panel.getAbsoluteX(), panel.getAbsoluteY()); + } + panel.setPositionX(div.getAbsoluteX() + itemPosX); + panel.setPositionY(div.getAbsoluteY() + itemPosY); + return false; + }}); } else { panel.setOnDragRelease(new DragEventCallback(){public boolean execute(DragEvent event){ if(Globals.dragSourceInventory instanceof RelationalInventoryState){ RelationalInventoryState sourceInventory = (RelationalInventoryState) Globals.dragSourceInventory; Entity item = Globals.draggedItem; - if(EquipState.hasEquipState(Globals.playerEntity) && InventoryUtils.hasEquipInventory(Globals.playerEntity)){ + if(ClientEquipState.hasEquipState(Globals.playerEntity) && InventoryUtils.hasEquipInventory(Globals.playerEntity)){ RelationalInventoryState equipInventory = InventoryUtils.getEquipInventory(Globals.playerEntity); - EquipState equipState = EquipState.getEquipState(Globals.playerEntity); + ClientEquipState equipState = ClientEquipState.getEquipState(Globals.playerEntity); equipState.commandAttemptUnequip(equipInventory.getItemSlot(item)); } //update ui @@ -200,10 +212,9 @@ public class MenuGeneratorsInventory { int width = 500; int height = 500; // int screenLeft = (Globals.WINDOW_WIDTH - width)/2; - Window rVal = new Window(0,0,Globals.WINDOW_WIDTH,Globals.WINDOW_HEIGHT,true); + Window rVal = new Window(0,0,width,height,true); Div div = new Div(); - div.setPositionX(1000); rVal.addChild(div); rVal.setOnNavigationCallback(new NavigationEventCallback() {public boolean execute(NavigationEvent event){ @@ -245,15 +256,9 @@ public class MenuGeneratorsInventory { return false; }}); - //black texture background - ImagePanel imagePanel = new ImagePanel(1000,0,width,height,Globals.blackTexture); - // imagePanel.setWidth(width); - // imagePanel.setHeight(height); - // imagePanel.setTexture(Globals.assetManager.fetchTexture(Globals.blackTexture)); - div.addChild(imagePanel); //label 1 (inventory) - Label inventoryLabel = new Label(1010,10,1.0f); + Label inventoryLabel = new Label(1.0f); inventoryLabel.setText("CHARACTER"); div.addChild(inventoryLabel); @@ -282,19 +287,23 @@ public class MenuGeneratorsInventory { } int panelWidth = 50; int panelHeight = 50; - int posX = 1000 + 20; + int posX = 20; if((incrementer % 2) == 1){ posX = posX + 400; } int posY = 60 + (i / 2 * (panelHeight + slotSpacing)); + int itemPosX = posX; + int itemPosY = posY; ImagePanel panel = new ImagePanel(posX,posY,panelWidth,panelHeight,texturePath); + panel.setAbsolutePosition(true); if(hasItem == true){ int itemId = i; panel.setOnDragStart(new DragEventCallback() {public boolean execute(DragEvent event){ // System.out.println("Drag start"); Globals.dragSourceInventory = inventory; Globals.draggedItem = inventory.getItemSlot(slots.get(itemId)); - div.removeChild(panel); + ContainerElement container = (ContainerElement)panel.getParent(); + container.removeChild(panel); WindowUtils.pushItemIconToItemWindow(panel); //play sound effect Globals.virtualAudioSourceManager.createVirtualAudioSource("/Audio/inventoryGrabItem.ogg", VirtualAudioSourceType.UI, false); @@ -306,6 +315,20 @@ public class MenuGeneratorsInventory { panel.setPositionY(event.getCurrentY() - panelHeight / 2); return false; }}); + panel.setOnDragRelease(new DragEventCallback(){public boolean execute(DragEvent event){ + if(panel.getParent() != div){ + if(panel.getParent() != null){ + ContainerElement container = (ContainerElement)panel.getParent(); + container.removeChild(panel); + } + div.addChild(panel); + Globals.elementManager.fireEvent(event, panel.getAbsoluteX(), panel.getAbsoluteY()); + } + panel.setPositionX(div.getAbsoluteX() + itemPosX); + panel.setPositionY(div.getAbsoluteY() + itemPosY); + return false; + }}); + } else { int itemId = i; panel.setOnDragRelease(new DragEventCallback(){public boolean execute(DragEvent event){ @@ -316,7 +339,7 @@ public class MenuGeneratorsInventory { Entity item = Globals.draggedItem; if(inventory.canEquipItemToSlot(item, slots.get(itemId))){ //fire equip event to equip state - EquipState equipState = EquipState.getEquipState(Globals.playerEntity); + ClientEquipState equipState = ClientEquipState.getEquipState(Globals.playerEntity); equipState.commandAttemptEquip(item,inventory.getEquipPointFromSlot(slots.get(itemId))); //play sound effect Globals.virtualAudioSourceManager.createVirtualAudioSource("/Audio/inventorySlotItem.ogg", VirtualAudioSourceType.UI, false); @@ -351,13 +374,16 @@ public class MenuGeneratorsInventory { div.addChild(panel); //create the slot text - posX = 1000 + 80; + posX = 80; if((incrementer % 2) == 1){ posX = posX + 190; } posY = posY + 15; - Label slotText = new Label(posX, posY, 0.4f); + Label slotText = new Label(0.7f); slotText.setText(slots.get(i)); + slotText.setPositionX(posX); + slotText.setPositionY(posY); + slotText.setAbsolutePosition(true); div.addChild(slotText); incrementer++; @@ -374,7 +400,7 @@ public class MenuGeneratorsInventory { if(Globals.dragSourceInventory instanceof UnrelationalInventoryState){ UnrelationalInventoryState inventory = (UnrelationalInventoryState) Globals.dragSourceInventory; //drop item - InventoryUtils.attemptEjectItem(Globals.playerEntity,Globals.draggedItem); + InventoryUtils.clientAttemptEjectItem(Globals.playerEntity,Globals.draggedItem); //clear ui WindowUtils.cleanItemDraggingWindow(); String sourceWindowId = WindowUtils.getInventoryWindowID(inventory.getId()); @@ -386,7 +412,7 @@ public class MenuGeneratorsInventory { } else if(Globals.dragSourceInventory instanceof RelationalInventoryState){ RelationalInventoryState inventory = (RelationalInventoryState) Globals.dragSourceInventory; //drop item - InventoryUtils.attemptEjectItem(Globals.playerEntity,Globals.draggedItem); + InventoryUtils.clientAttemptEjectItem(Globals.playerEntity,Globals.draggedItem); //clear ui WindowUtils.cleanItemDraggingWindow(); String sourceWindowId = WindowStrings.WINDOW_CHARACTER; diff --git a/src/main/java/electrosphere/menu/ingame/MenuGeneratorsLevelEditor.java b/src/main/java/electrosphere/menu/ingame/MenuGeneratorsLevelEditor.java index 5ced7ec3..f7d2f283 100644 --- a/src/main/java/electrosphere/menu/ingame/MenuGeneratorsLevelEditor.java +++ b/src/main/java/electrosphere/menu/ingame/MenuGeneratorsLevelEditor.java @@ -16,6 +16,7 @@ import electrosphere.entity.types.item.ItemUtils; import electrosphere.entity.types.object.ObjectUtils; import electrosphere.game.data.creature.type.CreatureType; import electrosphere.game.data.foliage.type.FoliageType; +import electrosphere.game.data.item.type.Item; import electrosphere.logger.LoggerInterface; import electrosphere.menu.WindowStrings; import electrosphere.menu.WindowUtils; @@ -76,7 +77,7 @@ public class MenuGeneratorsLevelEditor { fillInDefaultContent(scrollable); - mainSidePanel.applyYoga(); + mainSidePanel.applyYoga(0,0); return mainSidePanel; } @@ -107,6 +108,12 @@ public class MenuGeneratorsLevelEditor { return false; }})); + //spawn foliage button + scrollable.addChild(Button.createButton("Spawn Item", new ClickEventCallback() {public boolean execute(ClickEvent event){ + fillInSpawnItemContent(scrollable); + return false; + }})); + //select voxel button scrollable.addChild(Button.createButton("Select Voxel Type", new ClickEventCallback() {public boolean execute(ClickEvent event){ if(voxelWindowOpen){ @@ -132,7 +139,7 @@ public class MenuGeneratorsLevelEditor { return false; }})); - mainSidePanel.applyYoga(); + mainSidePanel.applyYoga(0,0); } @@ -164,9 +171,13 @@ public class MenuGeneratorsLevelEditor { }})); } - mainSidePanel.applyYoga(); + mainSidePanel.applyYoga(0,0); } + /** + * Level editor content for spawning foliage + * @param scrollable + */ private static void fillInSpawnFoliageContent(VirtualScrollable scrollable){ scrollable.clearChildren(); @@ -190,7 +201,37 @@ public class MenuGeneratorsLevelEditor { }})); } - mainSidePanel.applyYoga(); + mainSidePanel.applyYoga(0,0); + } + + /** + * Level editor menu content for spawning items + * @param scrollable + */ + private static void fillInSpawnItemContent(VirtualScrollable scrollable){ + scrollable.clearChildren(); + + //back button + scrollable.addChild(Button.createButton("Back", new ClickEventCallback() {public boolean execute(ClickEvent event){ + fillInDefaultContent(scrollable); + return false; + }})); + + //button for spawning all foliage types + for(Item item : Globals.gameConfigCurrent.getItemMap().getItems()){ + //spawn foliage button + scrollable.addChild(Button.createButton("Spawn " + item.getItemId(), new ClickEventCallback() {public boolean execute(ClickEvent event){ + LoggerInterface.loggerEngine.INFO("spawn " + item.getItemId() + "!"); + Vector3d eyePos = new Vector3d(CameraEntityUtils.getCameraEye(Globals.playerCamera)); + Vector3d centerPos = new Vector3d(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); + Realm realm = Globals.realmManager.getRealms().iterator().next(); + Vector3d cursorPos = realm.getCollisionEngine().rayCastPosition(new Vector3d(centerPos), new Vector3d(eyePos).mul(-1.0), 5.0); + ItemUtils.serverSpawnBasicItem(realm, cursorPos, item.getItemId()); + return false; + }})); + } + + mainSidePanel.applyYoga(0,0); } @@ -243,7 +284,7 @@ public class MenuGeneratorsLevelEditor { } } - mainSidePanel.applyYoga(); + mainSidePanel.applyYoga(0,0); } /** @@ -321,7 +362,7 @@ public class MenuGeneratorsLevelEditor { scrollable.addChild(zDiv); - mainSidePanel.applyYoga(); + mainSidePanel.applyYoga(0,0); } diff --git a/src/main/java/electrosphere/menu/ingame/MenuGeneratorsTerrainEditing.java b/src/main/java/electrosphere/menu/ingame/MenuGeneratorsTerrainEditing.java index ea94d9fc..474511b6 100644 --- a/src/main/java/electrosphere/menu/ingame/MenuGeneratorsTerrainEditing.java +++ b/src/main/java/electrosphere/menu/ingame/MenuGeneratorsTerrainEditing.java @@ -92,7 +92,7 @@ public class MenuGeneratorsTerrainEditing { fillInVoxelSelectors(scrollable, searchInput.getText()); - rVal.applyYoga(); + rVal.applyYoga(0,0); return rVal; } @@ -138,7 +138,7 @@ public class MenuGeneratorsTerrainEditing { scrollable.addChild(newButton); } - rVal.applyYoga(); + rVal.applyYoga(0,0); } } diff --git a/src/main/java/electrosphere/net/client/protocol/EntityProtocol.java b/src/main/java/electrosphere/net/client/protocol/EntityProtocol.java index 910ba179..68f1eedc 100644 --- a/src/main/java/electrosphere/net/client/protocol/EntityProtocol.java +++ b/src/main/java/electrosphere/net/client/protocol/EntityProtocol.java @@ -65,15 +65,13 @@ public class EntityProtocol { Globals.clientSceneWrapper.mapIdToId(newlySpawnedEntity.getId(), message.getentityID()); } break; case SPAWNITEM: { - if(!Globals.RUN_SERVER){ - LoggerInterface.loggerNetworking.DEBUG("Spawn Item " + message.getentityID() + " at " + message.getpositionX() + " " + message.getpositionY() + " " + message.getpositionZ()); - //spawn item - String itemType = message.getcreatureTemplate(); - newlySpawnedEntity = ItemUtils.clientSpawnBasicItem(itemType); - //position - ClientEntityUtils.initiallyPositionEntity(newlySpawnedEntity, new Vector3d(message.getpositionX(),message.getpositionY(),message.getpositionZ())); - Globals.clientSceneWrapper.mapIdToId(newlySpawnedEntity.getId(), message.getentityID()); - } + LoggerInterface.loggerNetworking.DEBUG("Spawn Item " + message.getentityID() + " at " + message.getpositionX() + " " + message.getpositionY() + " " + message.getpositionZ()); + //spawn item + String itemType = message.getcreatureTemplate(); + newlySpawnedEntity = ItemUtils.clientSpawnBasicItem(itemType); + //position + ClientEntityUtils.initiallyPositionEntity(newlySpawnedEntity, new Vector3d(message.getpositionX(),message.getpositionY(),message.getpositionZ())); + Globals.clientSceneWrapper.mapIdToId(newlySpawnedEntity.getId(), message.getentityID()); } break; case SPAWNFOLIAGESEED: { LoggerInterface.loggerNetworking.DEBUG("Spawn foliage " + message.getentityID() + " at " + message.getpositionX() + " " + message.getpositionY() + " " + message.getpositionZ()); diff --git a/src/main/java/electrosphere/net/client/protocol/InventoryProtocol.java b/src/main/java/electrosphere/net/client/protocol/InventoryProtocol.java index 14ad3745..5c528ded 100644 --- a/src/main/java/electrosphere/net/client/protocol/InventoryProtocol.java +++ b/src/main/java/electrosphere/net/client/protocol/InventoryProtocol.java @@ -2,7 +2,7 @@ package electrosphere.net.client.protocol; import electrosphere.engine.Globals; import electrosphere.entity.Entity; -import electrosphere.entity.state.equip.EquipState; +import electrosphere.entity.state.equip.ClientEquipState; import electrosphere.entity.state.inventory.InventoryState; import electrosphere.entity.state.inventory.InventoryUtils; import electrosphere.entity.types.item.ItemUtils; @@ -32,7 +32,7 @@ public class InventoryProtocol { //translate id Globals.clientSceneWrapper.mapIdToId(inWorldEntity.getId(), message.getentityId()); //grab equip state - EquipState equipState = EquipState.getEquipState(equipper); + ClientEquipState equipState = ClientEquipState.getEquipState(equipper); //create entity from template in message //get equippoint String equipPointName = message.getequipPointId(); diff --git a/src/main/java/electrosphere/net/server/protocol/InventoryProtocol.java b/src/main/java/electrosphere/net/server/protocol/InventoryProtocol.java index d7a9591f..4e8b9142 100644 --- a/src/main/java/electrosphere/net/server/protocol/InventoryProtocol.java +++ b/src/main/java/electrosphere/net/server/protocol/InventoryProtocol.java @@ -2,7 +2,7 @@ package electrosphere.net.server.protocol; import electrosphere.engine.Globals; import electrosphere.entity.Entity; -import electrosphere.entity.state.equip.EquipState; +import electrosphere.entity.state.equip.ClientEquipState; import electrosphere.entity.state.inventory.InventoryUtils; import electrosphere.entity.state.inventory.UnrelationalInventoryState; import electrosphere.entity.types.creature.CreatureUtils; diff --git a/src/main/java/electrosphere/renderer/actor/ActorMeshMask.java b/src/main/java/electrosphere/renderer/actor/ActorMeshMask.java index 4c506155..381fe0c1 100644 --- a/src/main/java/electrosphere/renderer/actor/ActorMeshMask.java +++ b/src/main/java/electrosphere/renderer/actor/ActorMeshMask.java @@ -11,14 +11,22 @@ import electrosphere.engine.Globals; import electrosphere.renderer.model.Mesh; import electrosphere.renderer.model.Model; +/** + * A per-actor object that contains blockers for individual parts of the base meshes of the actor. + * IE, it will contain the information that says "don't draw the base model's feet, instead draw a pair of boots" + */ public class ActorMeshMask { - // List meshMask = new LinkedList(); + //The map of base mesh name -> blocked status + //Ie "feet" -> true would mean that the base model feet should not be drawn Map meshBlockerList = new HashMap(); + //the list of meshes to draw that are stored in this object + //ie this would contain a mesh for boots Map toDrawMesh = new HashMap(); + //lock for queueing blockers Semaphore queueLock = new Semaphore(1); List queuedMeshes = new LinkedList(); List queuedBlockers = new LinkedList(); @@ -83,6 +91,14 @@ public class ActorMeshMask { return toDrawMesh.size() > 0; } + /** + * Removes a mesh from the list of extra (non-base model) meshes to draw + * @param additionalMeshName the name of the mesh to remove + */ + public void removeAdditionalMesh(String additionalMeshName){ + toDrawMesh.remove(additionalMeshName); + } + // //blocking interactions @@ -105,8 +121,17 @@ public class ActorMeshMask { meshBlockerList.remove(name); } + public List getBlockedMeshes(){ + return meshBlockerList.keySet().stream().collect(Collectors.toList()); + } + + /** + * A queued mesh blocker. + * When a creature equips an item that would block a mesh, the mesh may not have already been loaded into memory. + * This represents an item in a queue that contains a mesh that should be eventually used to block a mesh on the parent actor. + */ class MeshDrawQueueItem { String modelName; diff --git a/src/main/java/electrosphere/renderer/debug/DebugRendering.java b/src/main/java/electrosphere/renderer/debug/DebugRendering.java index 71cd0303..cd61e5af 100644 --- a/src/main/java/electrosphere/renderer/debug/DebugRendering.java +++ b/src/main/java/electrosphere/renderer/debug/DebugRendering.java @@ -139,7 +139,7 @@ public class DebugRendering { for(int i = 0; i < increment; i++){ System.out.print(" "); } - System.out.println(currentElement.getClass() + " pos:(" + currentElement.getPositionX() + "," + currentElement.getPositionY() + ") dims:(" + currentElement.getWidth() + "," + currentElement.getHeight() + ")"); + System.out.println(currentElement.getClass() + " pos:(" + currentElement.getAbsoluteX() + "," + currentElement.getAbsoluteY() + ") dims:(" + currentElement.getWidth() + "," + currentElement.getHeight() + ")"); if(currentElement instanceof ContainerElement){ ContainerElement container = (ContainerElement)currentElement; for(Element child : container.getChildren()){ diff --git a/src/main/java/electrosphere/renderer/pipelines/DebugContentPipeline.java b/src/main/java/electrosphere/renderer/pipelines/DebugContentPipeline.java index 5a127c38..0441435c 100644 --- a/src/main/java/electrosphere/renderer/pipelines/DebugContentPipeline.java +++ b/src/main/java/electrosphere/renderer/pipelines/DebugContentPipeline.java @@ -63,7 +63,7 @@ public class DebugContentPipeline implements RenderPipeline { HitboxData data = HitboxUtils.getHitboxData(currentHitbox); if(data.isActive()){ if(data.getType().equals(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HURT)){ - if((hitboxModel = Globals.assetManager.fetchModel("Models/unitsphere.fbx")) != null){ + if((hitboxModel = Globals.assetManager.fetchModel("Models/basic/geometry/unitsphere.fbx")) != null){ Vector3d position = EntityUtils.getPosition(currentHitbox); //calculate camera-modified vector3f Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); @@ -75,7 +75,7 @@ public class DebugContentPipeline implements RenderPipeline { hitboxModel.draw(renderPipelineState,openGLState); } } else if(data.getType().equals(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HIT)){ - if((hitboxModel = Globals.assetManager.fetchModel("Models/unitsphere_1.fbx")) != null){ + if((hitboxModel = Globals.assetManager.fetchModel("Models/basic/geometry/unitsphere_1.fbx")) != null){ Vector3d position = EntityUtils.getPosition(currentHitbox); //calculate camera-modified vector3f Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); @@ -88,7 +88,7 @@ public class DebugContentPipeline implements RenderPipeline { } } } else { - if((hitboxModel = Globals.assetManager.fetchModel("Models/unitsphere_grey.fbx")) != null){ + if((hitboxModel = Globals.assetManager.fetchModel("Models/basic/geometry/unitsphere_grey.fbx")) != null){ Vector3d position = EntityUtils.getPosition(currentHitbox); modelTransformMatrix.identity(); modelTransformMatrix.translate(new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera))); diff --git a/src/main/java/electrosphere/renderer/ui/ElementManager.java b/src/main/java/electrosphere/renderer/ui/ElementManager.java index e336a54b..7040755f 100644 --- a/src/main/java/electrosphere/renderer/ui/ElementManager.java +++ b/src/main/java/electrosphere/renderer/ui/ElementManager.java @@ -188,7 +188,7 @@ public class ElementManager { propagate = currentElement.handleEvent(event); } if(!propagate){ - currentWindow.applyYoga(); + currentWindow.applyYoga(0,0); break; } } @@ -426,7 +426,7 @@ public class ElementManager { */ public void navigateBackwards(){ NavigationEvent event = new NavigationEvent(NavigationEventType.BACKWARD); - fireEvent(event,currentFocusedElement.getPositionX(),currentFocusedElement.getPositionY()); + fireEvent(event,currentFocusedElement.getAbsoluteX(),currentFocusedElement.getAbsoluteY()); } /** diff --git a/src/main/java/electrosphere/renderer/ui/elements/ActorPanel.java b/src/main/java/electrosphere/renderer/ui/elements/ActorPanel.java index e4a92857..9e192945 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/ActorPanel.java +++ b/src/main/java/electrosphere/renderer/ui/elements/ActorPanel.java @@ -60,8 +60,8 @@ public class ActorPanel extends StandardElement implements DrawableElement, Drag elementBuffer = FramebufferUtils.generateTextureFramebuffer(width, height); customMat.setTexturePointer(elementBuffer.getTexturePointer()); this.actor = actor; - this.positionX = x; - this.positionY = y; + this.internalPositionX = x; + this.internalPositionY = y; this.width = width; this.height = height; this.aspectRatio = (float)width / (float)height; @@ -139,8 +139,8 @@ public class ActorPanel extends StandardElement implements DrawableElement, Drag //set viewport openGLState.glViewport(parentWidth, parentHeight); - float ndcX = (float)positionX/parentWidth; - float ndcY = (float)positionY/parentHeight; + float ndcX = (float)internalPositionX/parentWidth; + float ndcY = (float)internalPositionY/parentHeight; float ndcWidth = (float)width/parentWidth; float ndcHeight = (float)height/parentHeight; diff --git a/src/main/java/electrosphere/renderer/ui/elements/BitmapCharacter.java b/src/main/java/electrosphere/renderer/ui/elements/BitmapCharacter.java index b40ff860..969e3ec3 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/BitmapCharacter.java +++ b/src/main/java/electrosphere/renderer/ui/elements/BitmapCharacter.java @@ -9,7 +9,6 @@ import electrosphere.renderer.model.Model; import electrosphere.renderer.ui.elementtypes.DrawableElement; import electrosphere.renderer.ui.events.Event; import electrosphere.renderer.ui.font.Font; -// import electrosphere.renderer.ui.font.FontUtils; import org.joml.Vector3f; import org.lwjgl.util.yoga.Yoga; @@ -113,13 +112,18 @@ public class BitmapCharacter extends StandardElement implements DrawableElement } @Override - public void applyYoga() { + public void applyYoga(int parentX, int parentY) { //get the values from yoga float leftRaw = Yoga.YGNodeLayoutGetLeft(yogaNode); float topRaw = Yoga.YGNodeLayoutGetTop(yogaNode); //apply the values to this component this.internalPositionX = (int)leftRaw; this.internalPositionY = (int)topRaw; + //calculate absolute values + if(!useAbsolutePosition){ + this.absoluteX = parentX + internalPositionX; + this.absoluteY = parentY + internalPositionY; + } } } diff --git a/src/main/java/electrosphere/renderer/ui/elements/Button.java b/src/main/java/electrosphere/renderer/ui/elements/Button.java index bf64f209..863389fd 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/Button.java +++ b/src/main/java/electrosphere/renderer/ui/elements/Button.java @@ -171,12 +171,9 @@ public class Button extends StandardContainerElement implements DrawableElement, // //Draw children elements - for(Element child : childList){ if(child instanceof DrawableElement){ DrawableElement drawableChild = (DrawableElement) child; - child.setPositionX(this.internalPositionX); - child.setPositionY(this.internalPositionY); drawableChild.draw( renderPipelineState, openGLState, diff --git a/src/main/java/electrosphere/renderer/ui/elements/Div.java b/src/main/java/electrosphere/renderer/ui/elements/Div.java index c159c440..ad9a7c1b 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/Div.java +++ b/src/main/java/electrosphere/renderer/ui/elements/Div.java @@ -130,8 +130,8 @@ public class Div extends StandardContainerElement implements ClickableElement,Dr } if(Globals.RENDER_FLAG_RENDER_UI_BOUNDS && DebugRendering.RENDER_DEBUG_OUTLINE_DIV){ - float ndcX = (float)positionX/parentWidth; - float ndcY = (float)positionY/parentHeight; + float ndcX = (float)internalPositionX/parentWidth; + float ndcY = (float)internalPositionY/parentHeight; float ndcWidth = (float)getWidth()/parentWidth; float ndcHeight = (float)getHeight()/parentHeight; Vector3f boxPosition = new Vector3f(ndcX,ndcY,0); diff --git a/src/main/java/electrosphere/renderer/ui/elements/ImagePanel.java b/src/main/java/electrosphere/renderer/ui/elements/ImagePanel.java index 38b7ad34..925a1fbe 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/ImagePanel.java +++ b/src/main/java/electrosphere/renderer/ui/elements/ImagePanel.java @@ -81,10 +81,14 @@ public class ImagePanel extends StandardElement implements DrawableElement, Drag } else { customMat.setTexturePointer(Globals.assetManager.fetchTexture(Globals.blackTexture).getTexturePointer()); } - this.positionX = x; - this.positionY = y; + this.internalPositionX = x; + this.absoluteX = x; + this.internalPositionY = y; + this.absoluteY = y; this.width = width; this.height = height; + this.internalWidth = width; + this.internalHeight = height; } public void setTexture(Texture texture){ @@ -110,8 +114,8 @@ public class ImagePanel extends StandardElement implements DrawableElement, Drag float ndcWidth = (float)getInternalWidth()/parentWidth; float ndcHeight = (float)getInternalHeight()/parentHeight; - float ndcX = (float)(getInternalX() + parentPosX)/parentWidth; - float ndcY = (float)(getInternalY() + parentPosY)/parentHeight; + float ndcX = (float)(getAbsoluteX())/parentWidth; + float ndcY = (float)(getAbsoluteY())/parentHeight; boxPosition = new Vector3f(ndcX,ndcY,0); boxDimensions = new Vector3f(ndcWidth,ndcHeight,0); diff --git a/src/main/java/electrosphere/renderer/ui/elements/Label.java b/src/main/java/electrosphere/renderer/ui/elements/Label.java index 8435b3a6..5af3b911 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/Label.java +++ b/src/main/java/electrosphere/renderer/ui/elements/Label.java @@ -130,8 +130,8 @@ public class Label extends StandardContainerElement implements DrawableElement { } if(Globals.RENDER_FLAG_RENDER_UI_BOUNDS && DebugRendering.RENDER_DEBUG_OUTLINE_LABEL){ - float ndcX = (float)(positionX)/parentWidth; - float ndcY = (float)(positionY)/parentHeight; + float ndcX = (float)(internalPositionX)/parentWidth; + float ndcY = (float)(internalPositionY)/parentHeight; float ndcWidth = (float)internalWidth/parentWidth; float ndcHeight = (float)internalHeight/parentHeight; Vector3f boxPosition = new Vector3f(ndcX,ndcY,0); diff --git a/src/main/java/electrosphere/renderer/ui/elements/ScrollableContainer.java b/src/main/java/electrosphere/renderer/ui/elements/ScrollableContainer.java index b17befb8..173a0a15 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/ScrollableContainer.java +++ b/src/main/java/electrosphere/renderer/ui/elements/ScrollableContainer.java @@ -97,39 +97,39 @@ public class ScrollableContainer extends StandardContainerElement implements Dra //if it is, if it is offscreen, calculate offset to put it onscreen Element focused = Globals.elementManager.getFocusedElement(); if( - focused.getPositionX() + focused.getWidth() > this.width || - focused.getPositionY() + focused.getHeight() > this.height || - focused.getPositionX() < 0 || - focused.getPositionY() < 0 + focused.getRelativeX() + focused.getWidth() > this.width || + focused.getRelativeY() + focused.getHeight() > this.height || + focused.getRelativeX() < 0 || + focused.getRelativeY() < 0 ){ int neededOffsetX = 0; int neededOffsetY = 0; //basically if we're offscreen negative, pull to positive //if we're offscreen positive and we're not as large as the screen, pull from the positive into focus //if we are larger than the screen, set position to 0 - if(focused.getPositionX() < 0){ - neededOffsetX = -focused.getPositionX(); - } else if(focused.getPositionX() + focused.getWidth() > this.width){ + if(focused.getRelativeX() < 0){ + neededOffsetX = -focused.getRelativeX(); + } else if(focused.getRelativeX() + focused.getWidth() > this.width){ if(focused.getWidth() > this.width){ - neededOffsetX = -focused.getPositionX(); + neededOffsetX = -focused.getRelativeX(); } else { - neededOffsetX = -((focused.getPositionX() - this.width) + focused.getWidth()); + neededOffsetX = -((focused.getRelativeX() - this.width) + focused.getWidth()); } } - if(focused.getPositionY() < 0){ - neededOffsetY = -focused.getPositionY(); - } else if(focused.getPositionY() + focused.getHeight() > this.height){ + if(focused.getRelativeY() < 0){ + neededOffsetY = -focused.getRelativeY(); + } else if(focused.getRelativeY() + focused.getHeight() > this.height){ if(focused.getHeight() > this.height){ - neededOffsetY = -focused.getPositionY(); + neededOffsetY = -focused.getRelativeY(); } else { - neededOffsetY = -((focused.getPositionY() - this.height) + focused.getHeight()); + neededOffsetY = -((focused.getRelativeY() - this.height) + focused.getHeight()); // System.out.println(focused.getPositionY() + " " + this.height + " " + focused.getHeight()); } } //apply offset to all children for(Element child : childList){ - int newX = child.getPositionX() + neededOffsetX; - int newY = child.getPositionY() + neededOffsetY; + int newX = child.getRelativeX() + neededOffsetX; + int newY = child.getRelativeY() + neededOffsetY; child.setPositionX(newX); child.setPositionY(newY); // System.out.println(currentX + " " + currentY); diff --git a/src/main/java/electrosphere/renderer/ui/elements/Slider.java b/src/main/java/electrosphere/renderer/ui/elements/Slider.java index 79417bb9..a60b4f57 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/Slider.java +++ b/src/main/java/electrosphere/renderer/ui/elements/Slider.java @@ -79,8 +79,8 @@ public class Slider extends StandardElement implements ClickableElement, Draggab public Slider(int positionX, int positionY, int width, int height, Vector3f colorBackground, Vector3f colorForeground){ super(); - this.positionX = positionX; - this.positionY = positionY; + this.internalPositionX = positionX; + this.internalPositionY = positionY; this.width = width; this.height = height; this.colorBackground.set(colorBackground); diff --git a/src/main/java/electrosphere/renderer/ui/elements/StandardContainerElement.java b/src/main/java/electrosphere/renderer/ui/elements/StandardContainerElement.java index 14cbcd7d..3c76cc1b 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/StandardContainerElement.java +++ b/src/main/java/electrosphere/renderer/ui/elements/StandardContainerElement.java @@ -17,6 +17,10 @@ public class StandardContainerElement extends StandardElement implements Contain List childList = new LinkedList(); + public StandardContainerElement(){ + super(); + } + @Override public int getWidth() { if(width == -1){ @@ -25,14 +29,14 @@ public class StandardContainerElement extends StandardElement implements Contain int maxX = -1; for(Element child : childList){ if(minX == -1){ - minX = child.getPositionX(); - } else if(child.getPositionX() < minX){ - minX = child.getPositionX(); + minX = child.getRelativeX(); + } else if(child.getRelativeX() < minX){ + minX = child.getRelativeX(); } if(maxX == -1){ - maxX = child.getPositionX() + child.getWidth(); - } else if(child.getPositionX() + child.getWidth() > maxX){ - maxX = child.getPositionX() + child.getWidth(); + maxX = child.getRelativeX() + child.getWidth(); + } else if(child.getRelativeX() + child.getWidth() > maxX){ + maxX = child.getRelativeX() + child.getWidth(); } } if(minX == -1){ @@ -58,14 +62,14 @@ public class StandardContainerElement extends StandardElement implements Contain int maxY = -1; for(Element child : childList){ if(minY == -1){ - minY = child.getPositionY(); - } else if(child.getPositionY() < minY){ - minY = child.getPositionY(); + minY = child.getRelativeY(); + } else if(child.getRelativeY() < minY){ + minY = child.getRelativeY(); } if(maxY == -1){ - maxY = child.getPositionY() + child.getHeight(); - } else if(child.getPositionY() + child.getHeight() > maxY){ - maxY = child.getPositionY() + child.getHeight(); + maxY = child.getRelativeY() + child.getHeight(); + } else if(child.getRelativeY() + child.getHeight() > maxY){ + maxY = child.getRelativeY() + child.getHeight(); } } if(minY == -1){ @@ -84,15 +88,15 @@ public class StandardContainerElement extends StandardElement implements Contain } @Override - public int getPositionX() { - if(positionX == -1){ + public int getRelativeX() { + if(internalPositionX == -1){ if(childList.size() > 0){ int minX = -1; for(Element child : childList){ if(minX == -1){ - minX = child.getPositionX(); - } else if(child.getPositionX() < minX){ - minX = child.getPositionX(); + minX = child.getRelativeX(); + } else if(child.getRelativeX() < minX){ + minX = child.getRelativeX(); } } if(minX == -1){ @@ -108,15 +112,15 @@ public class StandardContainerElement extends StandardElement implements Contain } @Override - public int getPositionY() { - if(positionY == -1){ + public int getRelativeY() { + if(internalPositionY == -1){ if(childList.size() > 0){ int minY = -1; for(Element child : childList){ if(minY == -1){ - minY = child.getPositionY(); - } else if(child.getPositionY() < minY){ - minY = child.getPositionY(); + minY = child.getRelativeY(); + } else if(child.getRelativeY() < minY){ + minY = child.getRelativeY(); } } if(minY == -1){ @@ -143,20 +147,14 @@ public class StandardContainerElement extends StandardElement implements Contain @Override public void setPositionX(int posX) { - int deltaX = posX - getPositionX(); - this.positionX = posX; - for(Element child : childList){ - child.setPositionX(child.getPositionX() + deltaX); - } + internalPositionX = posX; + absoluteX = posX; } @Override public void setPositionY(int posY) { - int deltaY = posY - getPositionY(); - this.positionY = posY; - for(Element child : childList){ - child.setPositionY(child.getPositionY() + deltaY); - } + internalPositionY = posY; + absoluteY = posY; } @Override @@ -172,6 +170,7 @@ public class StandardContainerElement extends StandardElement implements Contain @Override public void addChild(Element child) { childList.add(child); + child.setParent(this); if(child instanceof DrawableElement){ DrawableElement drawableChild = (DrawableElement) child; drawableChild.setParentWidth(width); @@ -189,6 +188,8 @@ public class StandardContainerElement extends StandardElement implements Contain @Override public void removeChild(Element child) { childList.remove(child); + child.setParent(null); + Yoga.YGNodeRemoveChild(this.yogaNode, child.getYogaNode()); } @Override @@ -226,11 +227,7 @@ public class StandardContainerElement extends StandardElement implements Contain } @Override - public void applyYoga() { - //apply yoga values to all children - for(Element child : this.getChildren()){ - child.applyYoga(); - } + public void applyYoga(int parentX, int parentY) { //get the values from yoga float leftRaw = Yoga.YGNodeLayoutGetLeft(yogaNode); float topRaw = Yoga.YGNodeLayoutGetTop(yogaNode); @@ -239,10 +236,19 @@ public class StandardContainerElement extends StandardElement implements Contain LoggerInterface.loggerUI.INFO("" + this); LoggerInterface.loggerUI.INFO(topRaw + " " + leftRaw + " " + heightRaw + " " + widthRaw); //apply the values to this component - this.internalPositionX = (int)leftRaw; - this.internalPositionY = (int)topRaw; - this.internalWidth = (int)widthRaw; - this.internalHeight = (int)heightRaw; + if(!useAbsolutePosition){ + this.internalPositionX = (int)leftRaw; + this.internalPositionY = (int)topRaw; + this.internalWidth = (int)widthRaw; + this.internalHeight = (int)heightRaw; + //calculate absolute values + this.absoluteX = parentX + internalPositionX; + this.absoluteY = parentY + internalPositionY; + } + //apply yoga values to all children + for(Element child : this.getChildren()){ + child.applyYoga(parentX + internalPositionX,parentY + internalPositionY); + } } @Override diff --git a/src/main/java/electrosphere/renderer/ui/elements/StandardElement.java b/src/main/java/electrosphere/renderer/ui/elements/StandardElement.java index c98f736d..49bacd74 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/StandardElement.java +++ b/src/main/java/electrosphere/renderer/ui/elements/StandardElement.java @@ -13,8 +13,6 @@ public class StandardElement implements Element { //these are set by the public int width = -1; public int height = -1; - public int positionX = -1; - public int positionY = -1; public int parentWidth = 1; public int parentHeight = 1; @@ -23,6 +21,11 @@ public class StandardElement implements Element { int internalHeight; int internalPositionX; int internalPositionY; + int absoluteX; + int absoluteY; + boolean useAbsolutePosition = false; + + Element parent = null; public boolean visible = false; @@ -47,15 +50,34 @@ public class StandardElement implements Element { } @Override - public int getPositionX() { + public int getRelativeX() { return internalPositionX; } @Override - public int getPositionY() { + public int getRelativeY() { return internalPositionY; } + @Override + public int getAbsoluteX(){ + return absoluteX; + } + + @Override + public int getAbsoluteY(){ + return absoluteY; + } + + public void setAbsolutePosition(boolean useAbsolutePosition){ + if(useAbsolutePosition){ + Yoga.YGNodeStyleSetPositionType(yogaNode, Yoga.YGPositionTypeAbsolute); + } else { + Yoga.YGNodeStyleSetPositionType(yogaNode, Yoga.YGPositionTypeRelative); + } + this.useAbsolutePosition = useAbsolutePosition; + } + @Override public void setWidth(int width) { this.internalWidth = width; @@ -72,12 +94,14 @@ public class StandardElement implements Element { @Override public void setPositionX(int posX) { - this.positionX = posX; + this.internalPositionX = posX; + this.absoluteX = posX; } - @Override + @Override public void setPositionY(int posY) { - this.positionY = posY; + this.internalPositionY = posY; + this.absoluteY = posY; } @Override @@ -123,6 +147,14 @@ public class StandardElement implements Element { return internalHeight; } + public Element getParent(){ + return this.parent; + } + + public void setParent(Element parent){ + this.parent = parent; + } + @Override public void destroy(){ Yoga.YGNodeFree(this.yogaNode); @@ -134,17 +166,22 @@ public class StandardElement implements Element { } @Override - public void applyYoga() { + public void applyYoga(int parentX, int parentY) { //get the values from yoga float leftRaw = Yoga.YGNodeLayoutGetLeft(yogaNode); float topRaw = Yoga.YGNodeLayoutGetTop(yogaNode); float widthRaw = Yoga.YGNodeLayoutGetWidth(yogaNode); float heightRaw = Yoga.YGNodeLayoutGetHeight(yogaNode); - //apply the values to this component - this.internalPositionX = (int)leftRaw; - this.internalPositionY = (int)topRaw; - this.internalWidth = (int)widthRaw; - this.internalHeight = (int)heightRaw; + if(!useAbsolutePosition){ + //apply the values to this component + this.internalPositionX = (int)leftRaw; + this.internalPositionY = (int)topRaw; + this.internalWidth = (int)widthRaw; + this.internalHeight = (int)heightRaw; + //calculate absolute values + this.absoluteX = parentX + internalPositionX; + this.absoluteY = parentY + internalPositionY; + } } diff --git a/src/main/java/electrosphere/renderer/ui/elements/Window.java b/src/main/java/electrosphere/renderer/ui/elements/Window.java index 93b12717..6fb11c73 100644 --- a/src/main/java/electrosphere/renderer/ui/elements/Window.java +++ b/src/main/java/electrosphere/renderer/ui/elements/Window.java @@ -342,17 +342,12 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme } @Override - public void applyYoga() { + public void applyYoga(int parentX, int parentY) { Yoga.YGNodeStyleSetWidth(parentWindowYogaNode, Globals.WINDOW_WIDTH); Yoga.YGNodeStyleSetHeight(parentWindowYogaNode, Globals.WINDOW_HEIGHT); //calculate yoga layout Yoga.YGNodeCalculateLayout(parentWindowYogaNode, width, height, Yoga.YGFlexDirectionColumn); - //apply yoga values to all children - LoggerInterface.loggerUI.INFO("==Apply yoga to windoow=="); - for(Element child : this.getChildren()){ - child.applyYoga(); - } - // //get the values from yoga + //get the values from yoga float leftRaw = Yoga.YGNodeLayoutGetLeft(yogaNode); float topRaw = Yoga.YGNodeLayoutGetTop(yogaNode); float widthRaw = Yoga.YGNodeLayoutGetWidth(yogaNode); @@ -362,6 +357,11 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme this.positionY = (int)topRaw; this.width = (int)widthRaw; this.height = (int)heightRaw; + //apply yoga values to all children + LoggerInterface.loggerUI.INFO("==Apply yoga to windoow=="); + for(Element child : this.getChildren()){ + child.applyYoga(this.positionX,this.positionY); + } } @Override @@ -392,6 +392,7 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme @Override public void addChild(Element child) { childList.add(child); + child.setParent(this); if(child instanceof DrawableElement){ DrawableElement drawableChild = (DrawableElement) child; drawableChild.setParentWidth(width); @@ -409,6 +410,7 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme @Override public void removeChild(Element child) { childList.remove(child); + child.setParent(null); Yoga.YGNodeRemoveChild(yogaNode, child.getYogaNode()); } @@ -433,6 +435,10 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme navCallback = callback; } + public Element getParent(){ + return null; + } + @Override public int getInternalX() { return positionX; @@ -497,4 +503,36 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme Yoga.YGNodeStyleSetJustifyContent(this.parentWindowYogaNode, justification); } + @Override + public int getRelativeX() { + return this.positionX; + } + + @Override + public int getRelativeY() { + return this.positionY; + } + + @Override + public int getAbsoluteX() { + return this.positionX; + } + + @Override + public int getAbsoluteY() { + return this.positionY; + } + + @Override + public void setAbsolutePosition(boolean useAbsolutePosition) { + //not implemented + throw new UnsupportedOperationException(); + } + + @Override + public void setParent(Element parent) { + //not implemented + throw new UnsupportedOperationException(); + } + } diff --git a/src/main/java/electrosphere/renderer/ui/elementtypes/Element.java b/src/main/java/electrosphere/renderer/ui/elementtypes/Element.java index e8e38eea..54292902 100644 --- a/src/main/java/electrosphere/renderer/ui/elementtypes/Element.java +++ b/src/main/java/electrosphere/renderer/ui/elementtypes/Element.java @@ -15,14 +15,21 @@ public interface Element { public void setMinHeight(int height); //position - public int getPositionX(); - public int getPositionY(); + public int getRelativeX(); + public int getRelativeY(); + public int getAbsoluteX(); + public int getAbsoluteY(); public void setPositionX(int positionX); public void setPositionY(int positionY); + + //position-related + public void setAbsolutePosition(boolean useAbsolutePosition); //parent data public void setParentWidth(int width); public void setParentHeight(int height); + public Element getParent(); + public void setParent(Element parent); //margin public void setMarginTop(int marginTop); @@ -75,7 +82,7 @@ public interface Element { /** * Applies the yoga values to this component */ - public void applyYoga(); + public void applyYoga(int parentX, int parentY); // diff --git a/src/main/java/electrosphere/server/ai/creature/OpportunisticAttacker.java b/src/main/java/electrosphere/server/ai/creature/OpportunisticAttacker.java index 7374b5fe..7011de9c 100644 --- a/src/main/java/electrosphere/server/ai/creature/OpportunisticAttacker.java +++ b/src/main/java/electrosphere/server/ai/creature/OpportunisticAttacker.java @@ -7,7 +7,7 @@ import electrosphere.entity.EntityTags; import electrosphere.entity.EntityUtils; import electrosphere.entity.state.attack.AttackTree; import electrosphere.entity.state.attack.ServerAttackTree; -import electrosphere.entity.state.equip.EquipState; +import electrosphere.entity.state.equip.ClientEquipState; import electrosphere.entity.state.movement.groundmove.GroundMovementTree; import electrosphere.entity.state.movement.groundmove.GroundMovementTree.MovementRelativeFacing; import electrosphere.entity.types.creature.CreatureUtils; @@ -210,9 +210,9 @@ public class OpportunisticAttacker extends AI { boolean hasWeapon(){ boolean rVal = false; - if(EquipState.hasEquipState(character)){ + if(ClientEquipState.hasEquipState(character)){ //TODO:fix hasWeapon - EquipState equipState = EquipState.getEquipState(character); + ClientEquipState equipState = ClientEquipState.getEquipState(character); // if(equipState.hasEquipPrimary()){ // rVal = true; // } @@ -248,8 +248,8 @@ public class OpportunisticAttacker extends AI { } void pickupWeapon(){ - if(EquipState.hasEquipState(character)){ - EquipState equipState = EquipState.getEquipState(character); + if(ClientEquipState.hasEquipState(character)){ + ClientEquipState equipState = ClientEquipState.getEquipState(character); // if(!equipState.hasEquipPrimary()){ // equipState.attemptEquip(target); // }