Compare commits
4 Commits
29f5496e23
...
e671cda62d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e671cda62d | ||
|
|
4ae09e7afb | ||
|
|
a30ac75573 | ||
|
|
b1d79dbc16 |
@ -18,7 +18,8 @@
|
|||||||
"renderResolutionX": 1920,
|
"renderResolutionX": 1920,
|
||||||
"renderResolutionY": 1080,
|
"renderResolutionY": 1080,
|
||||||
|
|
||||||
"graphicsDebugDrawCollisionSpheres" : false,
|
"graphicsDebugDrawCollisionSpheresClient" : false,
|
||||||
|
"graphicsDebugDrawCollisionSpheresServer" : false,
|
||||||
"graphicsDebugDrawPhysicsObjects" : false,
|
"graphicsDebugDrawPhysicsObjects" : false,
|
||||||
"graphicsDebugDrawMovementVectors" : false,
|
"graphicsDebugDrawMovementVectors" : false,
|
||||||
"graphicsDebugDrawNavmesh" : false,
|
"graphicsDebugDrawNavmesh" : false,
|
||||||
|
|||||||
@ -5,32 +5,37 @@
|
|||||||
"hitboxes" : [
|
"hitboxes" : [
|
||||||
{
|
{
|
||||||
"type": "hurt",
|
"type": "hurt",
|
||||||
"bone": "Bone.031",
|
"bone": "Bicep.L",
|
||||||
"radius": 0.04
|
"radius": 0.04
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "hurt",
|
"type": "hurt",
|
||||||
"bone": "Bone.012",
|
"bone": "Bicep.R",
|
||||||
"radius": 0.04
|
"radius": 0.04
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "hurt",
|
"type": "hurt",
|
||||||
"bone": "Bone.003",
|
"bone": "Leg.L",
|
||||||
"radius": 0.04
|
"radius": 0.04
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "hurt",
|
"type": "hurt",
|
||||||
"bone": "Bone.010",
|
"bone": "Leg.R",
|
||||||
|
"radius": 0.04
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "hurt",
|
||||||
|
"bone": "Shoulder.L",
|
||||||
"radius": 0.06
|
"radius": 0.06
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "hurt",
|
"type": "hurt",
|
||||||
"bone": "Bone.001",
|
"bone": "Shoulder.R",
|
||||||
"radius": 0.06
|
"radius": 0.06
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "hurt",
|
"type": "hurt",
|
||||||
"bone": "Bone.014",
|
"bone": "Neck",
|
||||||
"radius": 0.06
|
"radius": 0.06
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -40,13 +45,8 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "hurt",
|
"type": "hurt",
|
||||||
"bone": "Bone.014",
|
"bone": "Head",
|
||||||
"radius": 0.06
|
"radius": 0.06
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "hurt",
|
|
||||||
"bone": "Bone.019",
|
|
||||||
"radius": 0.04
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"tokens" : [
|
"tokens" : [
|
||||||
@ -241,10 +241,10 @@
|
|||||||
"equipPoints" : [
|
"equipPoints" : [
|
||||||
{
|
{
|
||||||
"equipPointId" : "handLeft",
|
"equipPointId" : "handLeft",
|
||||||
"bone" : "MiddleLower.L",
|
"bone" : "Hand.L",
|
||||||
"firstPersonBone" : "hand.L",
|
"firstPersonBone" : "hand.L",
|
||||||
"offsetVector" : [],
|
"offsetVector" : [0,0,0],
|
||||||
"offsetRotation" : [],
|
"offsetRotation" : [0,0,0,1],
|
||||||
"equipClassWhitelist" : [
|
"equipClassWhitelist" : [
|
||||||
"tool",
|
"tool",
|
||||||
"shield",
|
"shield",
|
||||||
@ -253,10 +253,10 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"equipPointId" : "handRight",
|
"equipPointId" : "handRight",
|
||||||
"bone" : "MiddleLower.R",
|
"bone" : "Hand.R",
|
||||||
"firstPersonBone" : "hand.R",
|
"firstPersonBone" : "hand.R",
|
||||||
"offsetVector" : [],
|
"offsetVector" : [0,0,0],
|
||||||
"offsetRotation" : [0.3057,0.2926,0.09933,0.9006],
|
"offsetRotation" : [-0.334,0.145,-0.28,0.89],
|
||||||
"equipClassWhitelist" : [
|
"equipClassWhitelist" : [
|
||||||
"tool",
|
"tool",
|
||||||
"weapon",
|
"weapon",
|
||||||
|
|||||||
@ -11,17 +11,17 @@
|
|||||||
"damage" : 10,
|
"damage" : 10,
|
||||||
"hitboxes" : [
|
"hitboxes" : [
|
||||||
{
|
{
|
||||||
"type": "hit",
|
"type": "hit_connected",
|
||||||
"bone": "Blade1",
|
"bone": "Blade1",
|
||||||
"radius": 0.04
|
"radius": 0.04
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "hit",
|
"type": "hit_connected",
|
||||||
"bone": "Blade2",
|
"bone": "Blade2",
|
||||||
"radius": 0.04
|
"radius": 0.04
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "hit",
|
"type": "hit_connected",
|
||||||
"bone": "Blade3",
|
"bone": "Blade3",
|
||||||
"radius": 0.04
|
"radius": 0.04
|
||||||
}
|
}
|
||||||
|
|||||||
@ -26,6 +26,7 @@
|
|||||||
],
|
],
|
||||||
"files" : [
|
"files" : [
|
||||||
"Data/objects/floatingisland.json",
|
"Data/objects/floatingisland.json",
|
||||||
"Data/objects/testscene1objects.json"
|
"Data/objects/testscene1objects.json",
|
||||||
|
"Data/objects/debug_objects.json"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
18
assets/Data/objects/debug_objects.json
Normal file
18
assets/Data/objects/debug_objects.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"objects" : [
|
||||||
|
|
||||||
|
{
|
||||||
|
"objectId" : "hitboxTester",
|
||||||
|
"hitboxData" : [
|
||||||
|
{
|
||||||
|
"type": "static_capsule",
|
||||||
|
"radius": 2,
|
||||||
|
"length": 5
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tokens": []
|
||||||
|
}
|
||||||
|
|
||||||
|
],
|
||||||
|
"files" : []
|
||||||
|
}
|
||||||
10
assets/Data/tutorial/hints.json
Normal file
10
assets/Data/tutorial/hints.json
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"hints": [
|
||||||
|
{
|
||||||
|
"id": "Basic Navigation",
|
||||||
|
"titleString": "Navigation",
|
||||||
|
"descriptionString": "You can move the mouse to move the camera around. Also, you can use the W, A, S, and D keys to move your character.",
|
||||||
|
"image": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
BIN
assets/Models/basic/geometry/unitcapsule.glb
Normal file
BIN
assets/Models/basic/geometry/unitcapsule.glb
Normal file
Binary file not shown.
BIN
assets/Models/basic/geometry/unitsphere.glb
Normal file
BIN
assets/Models/basic/geometry/unitsphere.glb
Normal file
Binary file not shown.
Binary file not shown.
@ -1,3 +1,3 @@
|
|||||||
#maven.buildNumber.plugin properties file
|
#maven.buildNumber.plugin properties file
|
||||||
#Sun May 19 19:34:37 EDT 2024
|
#Fri Jun 14 13:45:11 EDT 2024
|
||||||
buildNumber=132
|
buildNumber=137
|
||||||
|
|||||||
@ -9,6 +9,7 @@
|
|||||||
- @subpage timekeeper
|
- @subpage timekeeper
|
||||||
- @subpage archimprovementtargets
|
- @subpage archimprovementtargets
|
||||||
- @subpage savesindex
|
- @subpage savesindex
|
||||||
|
- @subpage hitboxesindex
|
||||||
|
|
||||||
|
|
||||||
# What is this section
|
# What is this section
|
||||||
|
|||||||
29
docs/src/architecture/hitboxes/hitboxesindex.md
Normal file
29
docs/src/architecture/hitboxes/hitboxesindex.md
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
@page hitboxesindex Hitboxes
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Architecture Highest Level
|
||||||
|
New architecture needs to be something like
|
||||||
|
|
||||||
|
Per realm/client scene, we have a collision engine that has a whole bunch of capsules.
|
||||||
|
We update those collision engines at the top of the frame.
|
||||||
|
On collision, run collision logic
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Design Notes
|
||||||
|
We want to have one collision per "object" per frame. IE, lets say you have a sword with two hitboxes on it that both collide with an enemy.
|
||||||
|
This would technically generate two collision events per frame. Need to condense this to one collision "event".
|
||||||
|
Going to have one body per object, ie one body per sword, but then multiple shapes per body.
|
||||||
|
Then drop the collision engine down to 1 collision per body per frame.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -310,14 +310,107 @@ Attaching items to hands in first person
|
|||||||
|
|
||||||
Fix grass placement
|
Fix grass placement
|
||||||
|
|
||||||
|
(05/26/2024)
|
||||||
|
|
||||||
|
VERY rudimentary first person documentation to give basic navigation to relevant files.
|
||||||
|
|
||||||
|
Fix attacking looping and freezing the character in place
|
||||||
|
- Was using delta real time (0.02ms) instead of delta frames in server and client attack trees (1 frame/simulate() call)
|
||||||
|
|
||||||
|
Document hitboxes
|
||||||
|
- Documented how it works currently and the architecture we want to move towards
|
||||||
|
|
||||||
|
Redo hitboxes to have capsules and also chaining between frames (but not between swinging the camera around)
|
||||||
|
- Need to have an object attached to creature that stores the rigid body
|
||||||
|
- When creating the creature, for each hitbox, create shapes for the rigid body
|
||||||
|
- Attach the overall object to the creature entity
|
||||||
|
|
||||||
|
(05/27/2024)
|
||||||
|
|
||||||
|
Redo hitboxes to have capsules and also chaining between frames (but not between swinging the camera around)
|
||||||
|
- Synchronize hitbox positions each frame
|
||||||
|
|
||||||
|
(05/31/2024)
|
||||||
|
Redo hitboxes to have capsules and also chaining between frames (but not between swinging the camera around)
|
||||||
|
- Write custom callback for the collision engine for just hitboxes
|
||||||
|
|
||||||
|
(06/04/2024)
|
||||||
|
Redo hitboxes to have capsules and also chaining between frames (but not between swinging the camera around)
|
||||||
|
- Need to have an object attached to creature that stores the rigid body
|
||||||
|
- When creating the creature, for each hitbox, create shapes for the rigid body
|
||||||
|
- Attach the overall object to the creature entity
|
||||||
|
|
||||||
|
(06/07/2024)
|
||||||
|
Hitboxes work to properly use capsules (constantly destroy/recreate every frane because od4j doesn't allow rescaling :<)
|
||||||
|
|
||||||
|
(06/10/2024)
|
||||||
|
Add flow for demo menu/level loading
|
||||||
|
|
||||||
|
(06/11/2024)
|
||||||
|
Redo hitboxes to have capsules and also chaining between frames (but not between swinging the camera around)
|
||||||
|
- Properly calculate the capsule that bridges from previous frame to current frame hitbox location
|
||||||
|
- Write custom callback for the collision engine for just hitboxes
|
||||||
|
Fix player model side-jog animations
|
||||||
|
|
||||||
|
(06/13/2024)
|
||||||
|
Fix newly exported model not rendering correctly
|
||||||
|
- All bones are passed into the shader every render call, the bone values must be corrupted
|
||||||
|
- NIGHTMARE BUG
|
||||||
|
Fix equipping an item spawning two items
|
||||||
|
|
||||||
|
(06/14/2024)
|
||||||
|
Fix inventory ui not closing when you hit 'i' key (will need to update utility functions to manage input mode so you're not doing it in callback)
|
||||||
|
Develop debug ui for equip points
|
||||||
|
|
||||||
# TODO
|
# TODO
|
||||||
|
|
||||||
|
|
||||||
|
Demo requirements:
|
||||||
|
= Assets =
|
||||||
|
Block animation in first person
|
||||||
|
Block animation in third person
|
||||||
|
Fix attack animation bone rotations for hand
|
||||||
|
Clean up equip state data
|
||||||
|
Audio FX for everything
|
||||||
|
|
||||||
|
|
||||||
|
= Coding =
|
||||||
|
Fix items falling below the ground
|
||||||
|
Control rebinding menu from title screen
|
||||||
|
Redo hitboxes to have capsules and also chaining between frames (but not between swinging the camera around)
|
||||||
|
- Introduce block hitbox (blockbox) type
|
||||||
|
Enemy AI
|
||||||
|
Probably some kind of tutorial text
|
||||||
|
Network-able ui messages
|
||||||
|
Ability to display video both on title screen as well as in game windows for tutorials
|
||||||
|
better scaffolding for scripting engine with hooks for equipping items, spawning entities, pausing/resuming play, etc
|
||||||
|
Ability for private realms to have time start/stop based on the player's feedback <-- sync this up to tutorial ui via script
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
BIG BIG BIG BIG IMMEDIATE TO DO:
|
||||||
|
always enforce opengl interface across all opengl calls jesus christ the bone uniform bug was impossible
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Redo hitboxes to have capsules and also chaining between frames (but not between swinging the camera around)
|
||||||
|
- Introduce block hitbox (blockbox) type
|
||||||
|
|
||||||
|
Fix voxel type selection menu not showing textures
|
||||||
|
- The quads are off screen because the calculation for ndcX/ndcY are putting it wayyy to the right -- will need to revisit calcs for all that
|
||||||
|
|
||||||
Fix being able to walk off far side of the world (ie in level editor)
|
Fix being able to walk off far side of the world (ie in level editor)
|
||||||
|
|
||||||
Grass System properly LOD
|
Grass System properly LOD
|
||||||
- Have foliage dynamically time out cells to be reconsidered based on distance from player (if close, short cooldown, if far long cooldown)
|
- Have foliage dynamically time out cells to be reconsidered based on distance from player (if close, short cooldown, if far long cooldown)
|
||||||
|
|
||||||
|
Would be nice to be able to cut clients that stream their logs to my server
|
||||||
|
|
||||||
Data Cleanup
|
Data Cleanup
|
||||||
- Clean up creatures
|
- Clean up creatures
|
||||||
- Remove unused ones
|
- Remove unused ones
|
||||||
@ -343,6 +436,8 @@ More Debug menus
|
|||||||
- Screen that shows the overall status of fluid cell manager
|
- Screen that shows the overall status of fluid cell manager
|
||||||
- Screen that shows the overall status of realm 0
|
- Screen that shows the overall status of realm 0
|
||||||
- Screen that shows the overall status of realm manager
|
- Screen that shows the overall status of realm manager
|
||||||
|
- Particularly, want a view of all entities in the scene, and the ability to click on a single entity to get an overview of everything on the entity
|
||||||
|
- For each behavior tree, ability to click into the tree and view fine details about its state (both pure state variable as well as other relevant variables)
|
||||||
|
|
||||||
Revisit first attempt at instancing (its really laggy lol)
|
Revisit first attempt at instancing (its really laggy lol)
|
||||||
- Maybe have draw call happen on top level entity and immediately queue all children recursively
|
- Maybe have draw call happen on top level entity and immediately queue all children recursively
|
||||||
|
|||||||
@ -6,4 +6,5 @@
|
|||||||
- @subpage staticmorph
|
- @subpage staticmorph
|
||||||
- @subpage shadermask
|
- @subpage shadermask
|
||||||
- @subpage animationmask
|
- @subpage animationmask
|
||||||
- @subpage meshmask
|
- @subpage meshmask
|
||||||
|
- @subpage firstpersonviewmodel
|
||||||
10
docs/src/rendering/actors/firstpersonviewmodel.md
Normal file
10
docs/src/rendering/actors/firstpersonviewmodel.md
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
@page firstpersonviewmodel First Person Viewmodel
|
||||||
|
|
||||||
|
# The pipeline
|
||||||
|
|
||||||
|
There is a separate render pipeline for first person elements. It is composited ontop the main render in the composite pipeline.
|
||||||
|
|
||||||
|
# The actor
|
||||||
|
|
||||||
|
There is a global entity, firstPersonEntity, that is rendered in the first person pipeline. This is the source of the visuals in that render.
|
||||||
|
The animations for this actor are controlled via the `FirstPersonTree`. It provides a convenient function where you give it the entity and the name of an animation and it will play it.
|
||||||
@ -13,34 +13,41 @@
|
|||||||
"messageTypes" : [
|
"messageTypes" : [
|
||||||
{
|
{
|
||||||
"messageName" : "RequestCharacterList",
|
"messageName" : "RequestCharacterList",
|
||||||
|
"description" : "Requests the list of characters from the server for the logged in user account",
|
||||||
"data" : []
|
"data" : []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"messageName" : "ResponseCharacterList",
|
"messageName" : "ResponseCharacterList",
|
||||||
|
"description" : "Gives the client the list of characters available to it",
|
||||||
"data" : [
|
"data" : [
|
||||||
"data"
|
"data"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"messageName" : "RequestCreateCharacter",
|
"messageName" : "RequestCreateCharacter",
|
||||||
|
"description" : "Requests that the server create a new character with the data provided",
|
||||||
"data" : [
|
"data" : [
|
||||||
"data"
|
"data"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"messageName" : "ResponseCreateCharacterSuccess",
|
"messageName" : "ResponseCreateCharacterSuccess",
|
||||||
|
"description" : "Tells the client that it successfully created a character",
|
||||||
"data" : []
|
"data" : []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"messageName" : "ResponseCreateCharacterFailure",
|
"messageName" : "ResponseCreateCharacterFailure",
|
||||||
|
"description" : "Tells the client that it failed to create a character",
|
||||||
"data" : []
|
"data" : []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"messageName" : "RequestSpawnCharacter",
|
"messageName" : "RequestSpawnCharacter",
|
||||||
|
"description" : "Requests that the server spawn the client in as a given character",
|
||||||
"data" : []
|
"data" : []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"messageName" : "ResponseSpawnCharacter",
|
"messageName" : "ResponseSpawnCharacter",
|
||||||
|
"description" : "Deprecated - Unused",
|
||||||
"data" : [
|
"data" : [
|
||||||
"data"
|
"data"
|
||||||
]
|
]
|
||||||
|
|||||||
112
net/entity.json
112
net/entity.json
@ -117,6 +117,7 @@
|
|||||||
"messageTypes" : [
|
"messageTypes" : [
|
||||||
{
|
{
|
||||||
"messageName" : "Create",
|
"messageName" : "Create",
|
||||||
|
"description" : "Spawns an empty entity on the client",
|
||||||
"data" : [
|
"data" : [
|
||||||
"entityID",
|
"entityID",
|
||||||
"entityCategory",
|
"entityCategory",
|
||||||
@ -128,6 +129,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"messageName" : "SpawnCreature",
|
"messageName" : "SpawnCreature",
|
||||||
|
"description" : "Spawns a creature on the client",
|
||||||
"data" : [
|
"data" : [
|
||||||
"entityID",
|
"entityID",
|
||||||
"creatureTemplate",
|
"creatureTemplate",
|
||||||
@ -138,6 +140,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"messageName" : "SpawnItem",
|
"messageName" : "SpawnItem",
|
||||||
|
"description" : "Spawns an item on the client",
|
||||||
"data" : [
|
"data" : [
|
||||||
"entityID",
|
"entityID",
|
||||||
"creatureTemplate",
|
"creatureTemplate",
|
||||||
@ -146,28 +149,9 @@
|
|||||||
"positionZ"
|
"positionZ"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"messageName" : "SetPosition",
|
|
||||||
"data" : [
|
|
||||||
"entityID",
|
|
||||||
"time",
|
|
||||||
"positionX",
|
|
||||||
"positionY",
|
|
||||||
"positionZ"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"messageName" : "setFacing",
|
|
||||||
"data" : [
|
|
||||||
"entityID",
|
|
||||||
"time",
|
|
||||||
"rotationX",
|
|
||||||
"rotationY",
|
|
||||||
"rotationZ"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"messageName" : "moveUpdate",
|
"messageName" : "moveUpdate",
|
||||||
|
"description" : "Updates a client on the move state of an entity",
|
||||||
"data" : [
|
"data" : [
|
||||||
"entityID",
|
"entityID",
|
||||||
"time",
|
"time",
|
||||||
@ -179,11 +163,13 @@
|
|||||||
"rotationZ",
|
"rotationZ",
|
||||||
"rotationW",
|
"rotationW",
|
||||||
"velocity",
|
"velocity",
|
||||||
|
"propertyValueInt",
|
||||||
"treeState"
|
"treeState"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"messageName" : "attackUpdate",
|
"messageName" : "attackUpdate",
|
||||||
|
"description" : "Updates the client on the status of a given attack",
|
||||||
"data" : [
|
"data" : [
|
||||||
"entityID",
|
"entityID",
|
||||||
"time",
|
"time",
|
||||||
@ -199,20 +185,12 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"messageName" : "startAttack",
|
"messageName" : "startAttack",
|
||||||
|
"description" : "Alerts the server that the client wants to start attacking",
|
||||||
"data" : []
|
"data" : []
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"messageName" : "Move",
|
|
||||||
"data" : [
|
|
||||||
"entityID",
|
|
||||||
"time",
|
|
||||||
"positionX",
|
|
||||||
"positionY",
|
|
||||||
"positionZ"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"messageName" : "Kill",
|
"messageName" : "Kill",
|
||||||
|
"description" : "Kills an entity (ie plays death animation, creates effects, etc -- does not actually delete the entity from data/scene)",
|
||||||
"data" : [
|
"data" : [
|
||||||
"time",
|
"time",
|
||||||
"entityID"
|
"entityID"
|
||||||
@ -220,21 +198,14 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"messageName" : "Destroy",
|
"messageName" : "Destroy",
|
||||||
|
"description" : "Destroys an entity, clearing it from the client scene",
|
||||||
"data" : [
|
"data" : [
|
||||||
"entityID"
|
"entityID"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"messageName" : "SetBehaviorTree",
|
|
||||||
"data" : [
|
|
||||||
"entityID",
|
|
||||||
"time",
|
|
||||||
"treeType",
|
|
||||||
"treeStatus"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"messageName" : "setProperty",
|
"messageName" : "setProperty",
|
||||||
|
"description" : "Sets a property on an entity (old method user to set the player's entity)",
|
||||||
"data" : [
|
"data" : [
|
||||||
"entityID",
|
"entityID",
|
||||||
"time",
|
"time",
|
||||||
@ -242,58 +213,9 @@
|
|||||||
"propertyValue"
|
"propertyValue"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"messageName": "setBTreePropertyInt",
|
|
||||||
"data" : [
|
|
||||||
"entityID",
|
|
||||||
"time",
|
|
||||||
"bTreeID",
|
|
||||||
"propertyID",
|
|
||||||
"propertyValueInt"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"messageName": "setBTreePropertyFloat",
|
|
||||||
"data" : [
|
|
||||||
"entityID",
|
|
||||||
"time",
|
|
||||||
"bTreeID",
|
|
||||||
"propertyID",
|
|
||||||
"propertyValueFloat"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"messageName": "setBTreePropertyDouble",
|
|
||||||
"data" : [
|
|
||||||
"entityID",
|
|
||||||
"time",
|
|
||||||
"bTreeID",
|
|
||||||
"propertyID",
|
|
||||||
"propertyValueDouble"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"messageName": "setBTreePropertyString",
|
|
||||||
"data" : [
|
|
||||||
"entityID",
|
|
||||||
"time",
|
|
||||||
"bTreeID",
|
|
||||||
"propertyID",
|
|
||||||
"propertyValueString"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"messageName": "setBTreePropertyEnum",
|
|
||||||
"data" : [
|
|
||||||
"entityID",
|
|
||||||
"time",
|
|
||||||
"bTreeID",
|
|
||||||
"propertyID",
|
|
||||||
"propertyValueInt"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"messageName" : "attachEntityToEntity",
|
"messageName" : "attachEntityToEntity",
|
||||||
|
"description" : "Tells the client to attach an entity to another entity",
|
||||||
"data" : [
|
"data" : [
|
||||||
"entityID",
|
"entityID",
|
||||||
"bone",
|
"bone",
|
||||||
@ -302,6 +224,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"messageName" : "SpawnFoliageSeed",
|
"messageName" : "SpawnFoliageSeed",
|
||||||
|
"description" : "Spawns a foliage object on the client with a given seed value",
|
||||||
"data" : [
|
"data" : [
|
||||||
"entityID",
|
"entityID",
|
||||||
"creatureTemplate",
|
"creatureTemplate",
|
||||||
@ -310,6 +233,17 @@
|
|||||||
"positionY",
|
"positionY",
|
||||||
"positionZ"
|
"positionZ"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"messageName" : "updateEntityViewDir",
|
||||||
|
"description" : "Updates the server's value for where the player is looking",
|
||||||
|
"data" : [
|
||||||
|
"entityID",
|
||||||
|
"time",
|
||||||
|
"positionX",
|
||||||
|
"positionY",
|
||||||
|
"positionZ"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -42,6 +42,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"messageName" : "clientRequestEquipItem",
|
"messageName" : "clientRequestEquipItem",
|
||||||
|
"description" : "Requests that the server equip an item to the player's entity",
|
||||||
"data" : [
|
"data" : [
|
||||||
"equipPointId",
|
"equipPointId",
|
||||||
"entityId"
|
"entityId"
|
||||||
@ -49,6 +50,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"messageName" : "serverCommandMoveItemContainer",
|
"messageName" : "serverCommandMoveItemContainer",
|
||||||
|
"description" : "Instructs the client to move an item to a container",
|
||||||
"data" : [
|
"data" : [
|
||||||
"entityId",
|
"entityId",
|
||||||
"containerType",
|
"containerType",
|
||||||
@ -57,6 +59,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"messageName" : "serverCommandEquipItem",
|
"messageName" : "serverCommandEquipItem",
|
||||||
|
"description" : "Instructs the client to equip an item to an entity",
|
||||||
"data" : [
|
"data" : [
|
||||||
"equipperId",
|
"equipperId",
|
||||||
"equipPointId",
|
"equipPointId",
|
||||||
@ -66,6 +69,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"messageName" : "serverCommandUnequipItem",
|
"messageName" : "serverCommandUnequipItem",
|
||||||
|
"description" : "Instructs the client to unequip an item",
|
||||||
"data" : [
|
"data" : [
|
||||||
"equipperId",
|
"equipperId",
|
||||||
"equipPointId"
|
"equipPointId"
|
||||||
@ -73,6 +77,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"messageName" : "clientRequestUnequipItem",
|
"messageName" : "clientRequestUnequipItem",
|
||||||
|
"description" : "Requests that the server unequip an item from the client's entity",
|
||||||
"data" : [
|
"data" : [
|
||||||
"equipPointId"
|
"equipPointId"
|
||||||
]
|
]
|
||||||
|
|||||||
@ -13,32 +13,12 @@
|
|||||||
"messageTypes" : [
|
"messageTypes" : [
|
||||||
{
|
{
|
||||||
"messageName" : "RequestRaces",
|
"messageName" : "RequestRaces",
|
||||||
|
"description" : "Requests the data for all races available to the character to play",
|
||||||
"data" : []
|
"data" : []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"messageName" : "ResponseRaces",
|
"messageName" : "ResponseRaces",
|
||||||
"data" : [
|
"description" : "Responds with the data on all races available for play",
|
||||||
"data"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"messageName" : "RequestRaceData",
|
|
||||||
"data" : []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"messageName" : "ResponseRaceData",
|
|
||||||
"data" : [
|
|
||||||
"data"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"messageName" : "RequestData",
|
|
||||||
"data" : [
|
|
||||||
"data"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"messageName" : "ResponseData",
|
|
||||||
"data" : [
|
"data" : [
|
||||||
"data"
|
"data"
|
||||||
]
|
]
|
||||||
|
|||||||
@ -25,12 +25,14 @@
|
|||||||
"messageTypes" : [
|
"messageTypes" : [
|
||||||
{
|
{
|
||||||
"messageName" : "Set_ID",
|
"messageName" : "Set_ID",
|
||||||
|
"description" : "Provides the server's id for the player",
|
||||||
"data" : [
|
"data" : [
|
||||||
"playerID"
|
"playerID"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"messageName" : "SetInitialDiscretePosition",
|
"messageName" : "SetInitialDiscretePosition",
|
||||||
|
"description" : "Tells the client the initial position of the player entity",
|
||||||
"data" : [
|
"data" : [
|
||||||
"initialDiscretePositionX",
|
"initialDiscretePositionX",
|
||||||
"initialDiscretePositionY",
|
"initialDiscretePositionY",
|
||||||
|
|||||||
@ -10,10 +10,12 @@
|
|||||||
"messageTypes" : [
|
"messageTypes" : [
|
||||||
{
|
{
|
||||||
"messageName" : "Ping",
|
"messageName" : "Ping",
|
||||||
|
"description" : "Pings the other side of the socket",
|
||||||
"data" : []
|
"data" : []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"messageName" : "Pong",
|
"messageName" : "Pong",
|
||||||
|
"description" : "Replies to a ping from the other side of the socket",
|
||||||
"data" : []
|
"data" : []
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -35,10 +37,12 @@
|
|||||||
"messageTypes" : [
|
"messageTypes" : [
|
||||||
{
|
{
|
||||||
"messageName" : "AuthRequest",
|
"messageName" : "AuthRequest",
|
||||||
|
"description" : "Requests authorization from the client",
|
||||||
"data" : []
|
"data" : []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"messageName" : "AuthDetails",
|
"messageName" : "AuthDetails",
|
||||||
|
"description" : "Tells the server the auth details of this client",
|
||||||
"data" : [
|
"data" : [
|
||||||
"user",
|
"user",
|
||||||
"pass"
|
"pass"
|
||||||
@ -46,10 +50,12 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"messageName" : "AuthSuccess",
|
"messageName" : "AuthSuccess",
|
||||||
|
"description" : "Tells the client it successfully logged in",
|
||||||
"data" : []
|
"data" : []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"messageName" : "AuthFailure",
|
"messageName" : "AuthFailure",
|
||||||
|
"description" : "Tells the client it failed to log in",
|
||||||
"data" : []
|
"data" : []
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@ -30,6 +30,7 @@
|
|||||||
"messageTypes" : [
|
"messageTypes" : [
|
||||||
{
|
{
|
||||||
"messageName" : "UpdateClientState",
|
"messageName" : "UpdateClientState",
|
||||||
|
"description" : "Updates an integer on the client",
|
||||||
"data" : [
|
"data" : [
|
||||||
"entityId",
|
"entityId",
|
||||||
"bTreeId",
|
"bTreeId",
|
||||||
@ -39,6 +40,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"messageName" : "UpdateClientStringState",
|
"messageName" : "UpdateClientStringState",
|
||||||
|
"description" : "Updates a string on the client",
|
||||||
"data" : [
|
"data" : [
|
||||||
"entityId",
|
"entityId",
|
||||||
"bTreeId",
|
"bTreeId",
|
||||||
@ -48,6 +50,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"messageName" : "AttachTree",
|
"messageName" : "AttachTree",
|
||||||
|
"description" : "Attaches a btree to an entity on the client",
|
||||||
"data" : [
|
"data" : [
|
||||||
"entityId",
|
"entityId",
|
||||||
"bTreeId"
|
"bTreeId"
|
||||||
@ -55,6 +58,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"messageName" : "DetatchTree",
|
"messageName" : "DetatchTree",
|
||||||
|
"description" : "Detatches a btree from an entity on the client",
|
||||||
"data" : [
|
"data" : [
|
||||||
"entityId",
|
"entityId",
|
||||||
"bTreeId"
|
"bTreeId"
|
||||||
|
|||||||
@ -102,10 +102,12 @@
|
|||||||
"messageTypes" : [
|
"messageTypes" : [
|
||||||
{
|
{
|
||||||
"messageName" : "RequestMetadata",
|
"messageName" : "RequestMetadata",
|
||||||
|
"description" : "Requests terrain metadata from the server",
|
||||||
"data" : []
|
"data" : []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"messageName" : "ResponseMetadata",
|
"messageName" : "ResponseMetadata",
|
||||||
|
"description" : "Tell the client the terrain metadata",
|
||||||
"data" : [
|
"data" : [
|
||||||
"worldSizeDiscrete",
|
"worldSizeDiscrete",
|
||||||
"dynamicInterpolationRatio",
|
"dynamicInterpolationRatio",
|
||||||
@ -116,15 +118,9 @@
|
|||||||
"worldMaxY"
|
"worldMaxY"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"messageName" : "RequestChunk",
|
|
||||||
"data" : [
|
|
||||||
"worldX",
|
|
||||||
"worldY"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"messageName" : "RequestEditVoxel",
|
"messageName" : "RequestEditVoxel",
|
||||||
|
"description" : "Requests that a voxel be edited on the server",
|
||||||
"data" : [
|
"data" : [
|
||||||
"worldX",
|
"worldX",
|
||||||
"worldY",
|
"worldY",
|
||||||
@ -138,6 +134,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"messageName" : "UpdateVoxel",
|
"messageName" : "UpdateVoxel",
|
||||||
|
"description" : "Tells the client to update a voxel's value",
|
||||||
"data" : [
|
"data" : [
|
||||||
"worldX",
|
"worldX",
|
||||||
"worldY",
|
"worldY",
|
||||||
@ -151,6 +148,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"messageName" : "RequestUseTerrainPalette",
|
"messageName" : "RequestUseTerrainPalette",
|
||||||
|
"description" : "Requests that the current player entity use a given terrain palette",
|
||||||
"data" : [
|
"data" : [
|
||||||
"realLocationX",
|
"realLocationX",
|
||||||
"realLocationY",
|
"realLocationY",
|
||||||
@ -162,6 +160,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"messageName" : "SpawnPosition",
|
"messageName" : "SpawnPosition",
|
||||||
|
"description" : "Sets the spawn position of the client",
|
||||||
"data" : [
|
"data" : [
|
||||||
"realLocationX",
|
"realLocationX",
|
||||||
"realLocationY",
|
"realLocationY",
|
||||||
@ -170,6 +169,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"messageName" : "RequestChunkData",
|
"messageName" : "RequestChunkData",
|
||||||
|
"description" : "Requests chunk data from the server",
|
||||||
"data" : [
|
"data" : [
|
||||||
"worldX",
|
"worldX",
|
||||||
"worldY",
|
"worldY",
|
||||||
@ -178,6 +178,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"messageName" : "sendChunkData",
|
"messageName" : "sendChunkData",
|
||||||
|
"description" : "Sends chunk data to the client",
|
||||||
"data" : [
|
"data" : [
|
||||||
"worldX",
|
"worldX",
|
||||||
"worldY",
|
"worldY",
|
||||||
@ -187,6 +188,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"messageName" : "RequestFluidData",
|
"messageName" : "RequestFluidData",
|
||||||
|
"description" : "Requests a fluid data from the server",
|
||||||
"data" : [
|
"data" : [
|
||||||
"worldX",
|
"worldX",
|
||||||
"worldY",
|
"worldY",
|
||||||
@ -195,6 +197,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"messageName" : "sendFluidData",
|
"messageName" : "sendFluidData",
|
||||||
|
"description" : "Sends fluid data to the client",
|
||||||
"data" : [
|
"data" : [
|
||||||
"worldX",
|
"worldX",
|
||||||
"worldY",
|
"worldY",
|
||||||
@ -204,6 +207,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"messageName" : "updateFluidData",
|
"messageName" : "updateFluidData",
|
||||||
|
"description" : "Updates fluid data on the client",
|
||||||
"data" : [
|
"data" : [
|
||||||
"worldX",
|
"worldX",
|
||||||
"worldY",
|
"worldY",
|
||||||
|
|||||||
@ -2,6 +2,9 @@ package electrosphere.audio;
|
|||||||
|
|
||||||
import org.joml.Vector3d;
|
import org.joml.Vector3d;
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
|
|
||||||
|
import electrosphere.util.MathUtils;
|
||||||
|
|
||||||
import static org.lwjgl.openal.AL10.*;
|
import static org.lwjgl.openal.AL10.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -13,7 +16,7 @@ public class AudioListener {
|
|||||||
Vector3d position;
|
Vector3d position;
|
||||||
|
|
||||||
//eye vector for listener
|
//eye vector for listener
|
||||||
Vector3f eye = new Vector3f(1,0,0);
|
Vector3f eye = MathUtils.getOriginVectorf();
|
||||||
|
|
||||||
//up vector for listener
|
//up vector for listener
|
||||||
Vector3f up = new Vector3f(0,1,0);
|
Vector3f up = new Vector3f(0,1,0);
|
||||||
|
|||||||
@ -1,19 +1,20 @@
|
|||||||
package electrosphere.client.scene;
|
package electrosphere.client.scene;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
import org.joml.Vector3d;
|
import org.joml.Vector3d;
|
||||||
|
import org.ode4j.ode.DContactGeom;
|
||||||
|
|
||||||
import electrosphere.collision.CollisionEngine;
|
import electrosphere.collision.CollisionEngine;
|
||||||
|
import electrosphere.collision.CollisionEngine.CollisionResolutionCallback;
|
||||||
|
import electrosphere.collision.collidable.Collidable;
|
||||||
|
import electrosphere.collision.hitbox.HitboxManager;
|
||||||
|
import electrosphere.collision.hitbox.HitboxUtils;
|
||||||
import electrosphere.engine.Globals;
|
import electrosphere.engine.Globals;
|
||||||
import electrosphere.entity.ClientEntityUtils;
|
|
||||||
import electrosphere.entity.Entity;
|
import electrosphere.entity.Entity;
|
||||||
import electrosphere.entity.EntityUtils;
|
|
||||||
import electrosphere.entity.Scene;
|
import electrosphere.entity.Scene;
|
||||||
import electrosphere.logger.LoggerInterface;
|
import electrosphere.logger.LoggerInterface;
|
||||||
import electrosphere.server.terrain.manager.ServerTerrainChunk;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wrapper around the scene object to provide lots of much needed client-specific utility
|
* Wrapper around the scene object to provide lots of much needed client-specific utility
|
||||||
@ -31,9 +32,18 @@ public class ClientSceneWrapper {
|
|||||||
//The engine used to back physics collision checks in client
|
//The engine used to back physics collision checks in client
|
||||||
CollisionEngine collisionEngine;
|
CollisionEngine collisionEngine;
|
||||||
|
|
||||||
|
//The hitbox manager
|
||||||
|
HitboxManager hitboxManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param scene The scene
|
||||||
|
* @param collisionEngine The collision engine
|
||||||
|
*/
|
||||||
public ClientSceneWrapper(Scene scene, CollisionEngine collisionEngine){
|
public ClientSceneWrapper(Scene scene, CollisionEngine collisionEngine){
|
||||||
this.scene = scene;
|
this.scene = scene;
|
||||||
this.collisionEngine = collisionEngine;
|
this.collisionEngine = collisionEngine;
|
||||||
|
this.hitboxManager = new HitboxManager(resolutionCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -110,6 +120,14 @@ public class ClientSceneWrapper {
|
|||||||
return collisionEngine;
|
return collisionEngine;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the hitbox manager for the client
|
||||||
|
* @return The hitbox manager
|
||||||
|
*/
|
||||||
|
public HitboxManager getHitboxManager(){
|
||||||
|
return hitboxManager;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroys all entities outside simulation range
|
* Destroys all entities outside simulation range
|
||||||
*/
|
*/
|
||||||
@ -129,4 +147,15 @@ public class ClientSceneWrapper {
|
|||||||
Globals.profiler.endCpuSample();
|
Globals.profiler.endCpuSample();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The resolution callback that is invoked once a collision has occurred
|
||||||
|
*/
|
||||||
|
CollisionResolutionCallback resolutionCallback = new CollisionResolutionCallback() {
|
||||||
|
@Override
|
||||||
|
public void resolve(DContactGeom geom, Collidable impactor, Collidable receiver, Vector3d normal, Vector3d localPosition, Vector3d worldPos, float magnitude) {
|
||||||
|
HitboxUtils.clientDamageHitboxColision(geom, impactor, receiver, normal, localPosition, worldPos, magnitude);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,16 +6,12 @@ import electrosphere.client.fluid.manager.ClientFluidManager;
|
|||||||
import electrosphere.client.instancing.InstanceUpdater;
|
import electrosphere.client.instancing.InstanceUpdater;
|
||||||
import electrosphere.client.targeting.crosshair.Crosshair;
|
import electrosphere.client.targeting.crosshair.Crosshair;
|
||||||
import electrosphere.client.terrain.manager.ClientTerrainManager;
|
import electrosphere.client.terrain.manager.ClientTerrainManager;
|
||||||
import electrosphere.collision.PhysicsEntityUtils;
|
|
||||||
import electrosphere.collision.PhysicsUtils;
|
|
||||||
import electrosphere.engine.Globals;
|
import electrosphere.engine.Globals;
|
||||||
import electrosphere.engine.Main;
|
|
||||||
import electrosphere.entity.Entity;
|
import electrosphere.entity.Entity;
|
||||||
import electrosphere.entity.EntityTags;
|
import electrosphere.entity.EntityTags;
|
||||||
import electrosphere.entity.EntityUtils;
|
import electrosphere.entity.EntityUtils;
|
||||||
import electrosphere.entity.state.collidable.ClientCollidableTree;
|
import electrosphere.entity.state.collidable.ClientCollidableTree;
|
||||||
import electrosphere.entity.types.attach.AttachUtils;
|
import electrosphere.entity.types.attach.AttachUtils;
|
||||||
import electrosphere.entity.types.hitbox.HitboxUtils;
|
|
||||||
import electrosphere.entity.types.item.ItemUtils;
|
import electrosphere.entity.types.item.ItemUtils;
|
||||||
import electrosphere.entity.types.particle.ParticleUtils;
|
import electrosphere.entity.types.particle.ParticleUtils;
|
||||||
import electrosphere.renderer.actor.Actor;
|
import electrosphere.renderer.actor.Actor;
|
||||||
@ -44,6 +40,7 @@ public class ClientSimulation {
|
|||||||
public void simulate(){
|
public void simulate(){
|
||||||
Globals.profiler.beginCpuSample("simulate");
|
Globals.profiler.beginCpuSample("simulate");
|
||||||
|
|
||||||
|
//
|
||||||
//load terrain
|
//load terrain
|
||||||
if(isLoadingTerrain()){
|
if(isLoadingTerrain()){
|
||||||
loadTerrain();
|
loadTerrain();
|
||||||
@ -53,10 +50,11 @@ public class ClientSimulation {
|
|||||||
Globals.profiler.beginCpuSample("clientSynchronizationManager.processMessages");
|
Globals.profiler.beginCpuSample("clientSynchronizationManager.processMessages");
|
||||||
Globals.clientSynchronizationManager.processMessages();
|
Globals.clientSynchronizationManager.processMessages();
|
||||||
Globals.profiler.endCpuSample();
|
Globals.profiler.endCpuSample();
|
||||||
|
//
|
||||||
//simulate bullet physics engine step
|
//simulate bullet physics engine step
|
||||||
Globals.clientSceneWrapper.getCollisionEngine().simulatePhysics((float)Globals.timekeeper.getSimFrameTime());
|
Globals.clientSceneWrapper.getCollisionEngine().simulatePhysics((float)Globals.timekeeper.getSimFrameTime());
|
||||||
Globals.clientSceneWrapper.getCollisionEngine().updateDynamicObjectTransforms();
|
Globals.clientSceneWrapper.getCollisionEngine().updateDynamicObjectTransforms();
|
||||||
|
|
||||||
//update actor animations
|
//update actor animations
|
||||||
Globals.profiler.beginCpuSample("update actor animations");
|
Globals.profiler.beginCpuSample("update actor animations");
|
||||||
for(Entity currentEntity : Globals.clientSceneWrapper.getScene().getEntitiesWithTag(EntityTags.DRAWABLE)){
|
for(Entity currentEntity : Globals.clientSceneWrapper.getScene().getEntitiesWithTag(EntityTags.DRAWABLE)){
|
||||||
@ -66,12 +64,14 @@ public class ClientSimulation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Globals.profiler.endCpuSample();
|
Globals.profiler.endCpuSample();
|
||||||
|
//
|
||||||
//make items play idle animation
|
//make items play idle animation
|
||||||
Globals.profiler.beginCpuSample("item animations");
|
Globals.profiler.beginCpuSample("item animations");
|
||||||
for(Entity item : Globals.clientSceneWrapper.getScene().getEntitiesWithTag(EntityTags.ITEM)){
|
for(Entity item : Globals.clientSceneWrapper.getScene().getEntitiesWithTag(EntityTags.ITEM)){
|
||||||
ItemUtils.updateItemActorAnimation(item);
|
ItemUtils.updateItemActorAnimation(item);
|
||||||
}
|
}
|
||||||
Globals.profiler.endCpuSample();
|
Globals.profiler.endCpuSample();
|
||||||
|
//
|
||||||
//particle state updates
|
//particle state updates
|
||||||
Globals.profiler.beginCpuSample("particle state updates");
|
Globals.profiler.beginCpuSample("particle state updates");
|
||||||
for(Entity particle : Globals.clientSceneWrapper.getScene().getEntitiesWithTag(EntityTags.PARTICLE)){
|
for(Entity particle : Globals.clientSceneWrapper.getScene().getEntitiesWithTag(EntityTags.PARTICLE)){
|
||||||
@ -80,18 +80,12 @@ public class ClientSimulation {
|
|||||||
Globals.profiler.endCpuSample();
|
Globals.profiler.endCpuSample();
|
||||||
//update attached entity positions
|
//update attached entity positions
|
||||||
AttachUtils.clientUpdateAttachedEntityPositions();
|
AttachUtils.clientUpdateAttachedEntityPositions();
|
||||||
//update hitbox positions
|
//
|
||||||
Globals.profiler.beginCpuSample("Hitbox updates");
|
//Hitbox stuff
|
||||||
for(Entity currentHitbox : Globals.clientHitboxManager.getAllHitboxes()){
|
Globals.profiler.beginCpuSample("update hitboxes");
|
||||||
HitboxUtils.clientUpdatePosition(currentHitbox);
|
Globals.clientSceneWrapper.getHitboxManager().simulate();
|
||||||
}
|
|
||||||
//collide hitboxes
|
|
||||||
for(Entity currentHitbox : Globals.clientHitboxManager.getAllHitboxes()){
|
|
||||||
if(isReady){
|
|
||||||
HitboxUtils.clientCollideEntities(currentHitbox);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Globals.profiler.endCpuSample();
|
Globals.profiler.endCpuSample();
|
||||||
|
//
|
||||||
//update audio engine
|
//update audio engine
|
||||||
Globals.profiler.beginCpuSample("audio engine update");
|
Globals.profiler.beginCpuSample("audio engine update");
|
||||||
if(Globals.audioEngine!=null){
|
if(Globals.audioEngine!=null){
|
||||||
@ -99,31 +93,32 @@ public class ClientSimulation {
|
|||||||
Globals.virtualAudioSourceManager.update((float)Globals.timekeeper.getSimFrameTime());
|
Globals.virtualAudioSourceManager.update((float)Globals.timekeeper.getSimFrameTime());
|
||||||
}
|
}
|
||||||
Globals.profiler.endCpuSample();
|
Globals.profiler.endCpuSample();
|
||||||
|
//
|
||||||
//update foliage
|
//update foliage
|
||||||
if(Globals.clientFoliageManager != null){
|
if(Globals.clientFoliageManager != null){
|
||||||
Globals.clientFoliageManager.update();
|
Globals.clientFoliageManager.update();
|
||||||
}
|
}
|
||||||
//tally collidables and offset position accordingly
|
//
|
||||||
// for(Entity currentCollidable : Globals.entityManager.getEntitiesWithTag(EntityTags.COLLIDABLE)){
|
|
||||||
// CollidableTree tree = CollidableTree.getCollidableTree(currentCollidable);
|
|
||||||
// tree.simulate(Main.deltaFrames);
|
|
||||||
// }
|
|
||||||
//targeting crosshair
|
//targeting crosshair
|
||||||
Globals.profiler.beginCpuSample("crosshair update");
|
Globals.profiler.beginCpuSample("crosshair update");
|
||||||
Crosshair.checkTargetable();
|
Crosshair.checkTargetable();
|
||||||
Crosshair.updateTargetCrosshairPosition();
|
Crosshair.updateTargetCrosshairPosition();
|
||||||
Globals.profiler.endCpuSample();
|
Globals.profiler.endCpuSample();
|
||||||
|
//
|
||||||
//simulate behavior trees
|
//simulate behavior trees
|
||||||
Globals.clientSceneWrapper.getScene().simulateBehaviorTrees((float)Globals.timekeeper.getSimFrameTime());
|
Globals.clientSceneWrapper.getScene().simulateBehaviorTrees((float)Globals.timekeeper.getSimFrameTime());
|
||||||
|
//
|
||||||
//sum collidable impulses
|
//sum collidable impulses
|
||||||
Globals.profiler.beginCpuSample("collidable logic");
|
Globals.profiler.beginCpuSample("collidable logic");
|
||||||
for(Entity collidable : Globals.clientSceneWrapper.getScene().getEntitiesWithTag(EntityTags.COLLIDABLE)){
|
for(Entity collidable : Globals.clientSceneWrapper.getScene().getEntitiesWithTag(EntityTags.COLLIDABLE)){
|
||||||
ClientCollidableTree.getClientCollidableTree(collidable).simulate((float)Globals.timekeeper.getSimFrameTime());
|
ClientCollidableTree.getClientCollidableTree(collidable).simulate((float)Globals.timekeeper.getSimFrameTime());
|
||||||
}
|
}
|
||||||
|
//
|
||||||
//clear collidable impulse lists
|
//clear collidable impulse lists
|
||||||
Globals.clientSceneWrapper.getCollisionEngine().clearCollidableImpulseLists();
|
Globals.clientSceneWrapper.getCollisionEngine().clearCollidableImpulseLists();
|
||||||
Globals.profiler.endCpuSample();
|
Globals.profiler.endCpuSample();
|
||||||
|
|
||||||
|
//
|
||||||
//wrap up functions
|
//wrap up functions
|
||||||
runClientFunctions();
|
runClientFunctions();
|
||||||
|
|
||||||
|
|||||||
@ -11,10 +11,11 @@ import org.lwjgl.assimp.AIVector3D;
|
|||||||
import org.ode4j.math.DMatrix3;
|
import org.ode4j.math.DMatrix3;
|
||||||
import org.ode4j.ode.DBody;
|
import org.ode4j.ode.DBody;
|
||||||
import org.ode4j.ode.DBox;
|
import org.ode4j.ode.DBox;
|
||||||
|
import org.ode4j.ode.DCapsule;
|
||||||
import org.ode4j.ode.DCylinder;
|
import org.ode4j.ode.DCylinder;
|
||||||
|
import org.ode4j.ode.DGeom;
|
||||||
import org.ode4j.ode.DSphere;
|
import org.ode4j.ode.DSphere;
|
||||||
import org.ode4j.ode.DTriMesh;
|
import org.ode4j.ode.DTriMesh;
|
||||||
import org.ode4j.ode.OdeHelper;
|
|
||||||
|
|
||||||
import electrosphere.entity.types.terrain.TerrainChunkData;
|
import electrosphere.entity.types.terrain.TerrainChunkData;
|
||||||
|
|
||||||
@ -24,6 +25,7 @@ import electrosphere.entity.types.terrain.TerrainChunkData;
|
|||||||
public class CollisionBodyCreation {
|
public class CollisionBodyCreation {
|
||||||
|
|
||||||
//Matrix for correcting initial axis of eg cylinders or capsules
|
//Matrix for correcting initial axis of eg cylinders or capsules
|
||||||
|
//this rotates by 90 degrees along the x axis
|
||||||
public static final DMatrix3 AXIS_CORRECTION_MATRIX = new DMatrix3(
|
public static final DMatrix3 AXIS_CORRECTION_MATRIX = new DMatrix3(
|
||||||
1.0000000, 0.0000000, 0.0000000,
|
1.0000000, 0.0000000, 0.0000000,
|
||||||
0.0000000, 0.0000000, -1.0000000,
|
0.0000000, 0.0000000, -1.0000000,
|
||||||
@ -81,6 +83,39 @@ public class CollisionBodyCreation {
|
|||||||
return collisionEngine.createDBody(geom);
|
return collisionEngine.createDBody(geom);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a dbody with existing shapes that are provided
|
||||||
|
* @param collisionEngine the collision engine to create it in
|
||||||
|
* @param geoms the geometries to attach
|
||||||
|
* @return the dbody
|
||||||
|
*/
|
||||||
|
public static DBody createBodyWithShapes(CollisionEngine collisionEngine, DGeom ... geoms){
|
||||||
|
return collisionEngine.createDBody(geoms);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a sphere shape
|
||||||
|
* @param collisionEngine the collision engine
|
||||||
|
* @param radius the radius of the sphere
|
||||||
|
* @param categoryBits the category bits for the shape
|
||||||
|
* @return the sphere shape
|
||||||
|
*/
|
||||||
|
public static DSphere createShapeSphere(CollisionEngine collisionEngine, double radius, long categoryBits){
|
||||||
|
return collisionEngine.createSphereGeom(radius, categoryBits);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a capsule shape
|
||||||
|
* @param collisionEngine The collision engine
|
||||||
|
* @param radius the radius of the capsule
|
||||||
|
* @param length the length of the capsule
|
||||||
|
* @param categoryBits the category bits for the shape
|
||||||
|
* @return the capsule shape
|
||||||
|
*/
|
||||||
|
public static DCapsule createCapsuleShape(CollisionEngine collisionEngine, double radius, double length, long categoryBits){
|
||||||
|
return collisionEngine.createCapsuleGeom(radius, length, categoryBits);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the provided body to be a kinematic body (no gravity applied)
|
* Sets the provided body to be a kinematic body (no gravity applied)
|
||||||
* @param collisionEngine The collision engine
|
* @param collisionEngine The collision engine
|
||||||
@ -110,6 +145,35 @@ public class CollisionBodyCreation {
|
|||||||
collisionEngine.setOffsetPosition(body, offsetPosition);
|
collisionEngine.setOffsetPosition(body, offsetPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes a geom from a body
|
||||||
|
* @param collisionEngine the collision engine
|
||||||
|
* @param body the body
|
||||||
|
* @param geom the geometry
|
||||||
|
*/
|
||||||
|
public static void removeShapeFromBody(CollisionEngine collisionEngine, DBody body, DGeom geom){
|
||||||
|
collisionEngine.removeGeometryFromBody(body, geom);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroys a geometry
|
||||||
|
* @param collisionEngine The collision engine
|
||||||
|
* @param geom the geometry
|
||||||
|
*/
|
||||||
|
public static void destroyShape(CollisionEngine collisionEngine, DGeom geom){
|
||||||
|
collisionEngine.destroyGeom(geom);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attaches a geom to a body
|
||||||
|
* @param collisionEngine the collision engine
|
||||||
|
* @param body the body
|
||||||
|
* @param geom the geometry
|
||||||
|
*/
|
||||||
|
public static void attachGeomToBody(CollisionEngine collisionEngine, DBody body, DGeom geom){
|
||||||
|
collisionEngine.attachGeomToBody(body, geom);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an ode DBody from a terrain chunk data object
|
* Creates an ode DBody from a terrain chunk data object
|
||||||
@ -154,7 +218,7 @@ public class CollisionBodyCreation {
|
|||||||
*/
|
*/
|
||||||
public static DBody generateRigidBodyFromAIScene(CollisionEngine collisionEngine, AIScene scene, long categoryBits){
|
public static DBody generateRigidBodyFromAIScene(CollisionEngine collisionEngine, AIScene scene, long categoryBits){
|
||||||
|
|
||||||
DBody body = collisionEngine.createDBody(null);
|
DBody body = collisionEngine.createDBody((DGeom[])null);
|
||||||
|
|
||||||
PointerBuffer meshesBuffer = scene.mMeshes();
|
PointerBuffer meshesBuffer = scene.mMeshes();
|
||||||
while(meshesBuffer.hasRemaining()){
|
while(meshesBuffer.hasRemaining()){
|
||||||
|
|||||||
@ -31,6 +31,7 @@ import org.ode4j.ode.DBox;
|
|||||||
import org.ode4j.ode.DCapsule;
|
import org.ode4j.ode.DCapsule;
|
||||||
import org.ode4j.ode.DContact;
|
import org.ode4j.ode.DContact;
|
||||||
import org.ode4j.ode.DContactBuffer;
|
import org.ode4j.ode.DContactBuffer;
|
||||||
|
import org.ode4j.ode.DContactGeom;
|
||||||
import org.ode4j.ode.DContactJoint;
|
import org.ode4j.ode.DContactJoint;
|
||||||
import org.ode4j.ode.DCylinder;
|
import org.ode4j.ode.DCylinder;
|
||||||
import org.ode4j.ode.DGeom;
|
import org.ode4j.ode.DGeom;
|
||||||
@ -50,12 +51,13 @@ import org.ode4j.ode.OdeHelper;
|
|||||||
import electrosphere.collision.RayCastCallback.RayCastCallbackData;
|
import electrosphere.collision.RayCastCallback.RayCastCallbackData;
|
||||||
import electrosphere.collision.collidable.Collidable;
|
import electrosphere.collision.collidable.Collidable;
|
||||||
import electrosphere.engine.Globals;
|
import electrosphere.engine.Globals;
|
||||||
|
import electrosphere.engine.time.Timekeeper;
|
||||||
import electrosphere.entity.Entity;
|
import electrosphere.entity.Entity;
|
||||||
import electrosphere.entity.EntityDataStrings;
|
import electrosphere.entity.EntityDataStrings;
|
||||||
import electrosphere.entity.EntityUtils;
|
import electrosphere.entity.EntityUtils;
|
||||||
import electrosphere.entity.state.collidable.Impulse;
|
import electrosphere.entity.state.collidable.Impulse;
|
||||||
import electrosphere.entity.types.hitbox.HitboxData;
|
|
||||||
import electrosphere.game.data.collidable.CollidableTemplate;
|
import electrosphere.game.data.collidable.CollidableTemplate;
|
||||||
|
import electrosphere.game.data.collidable.HitboxData;
|
||||||
import electrosphere.logger.LoggerInterface;
|
import electrosphere.logger.LoggerInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -63,9 +65,6 @@ import electrosphere.logger.LoggerInterface;
|
|||||||
*/
|
*/
|
||||||
public class CollisionEngine {
|
public class CollisionEngine {
|
||||||
|
|
||||||
//step interval time size
|
|
||||||
public static final float ENGINE_STEP_SIZE = 0.01f;
|
|
||||||
|
|
||||||
//gravity constant
|
//gravity constant
|
||||||
public static final float GRAVITY_MAGNITUDE = 9.8f * 2;
|
public static final float GRAVITY_MAGNITUDE = 9.8f * 2;
|
||||||
|
|
||||||
@ -91,16 +90,44 @@ public class CollisionEngine {
|
|||||||
|
|
||||||
//callbacks for collision check
|
//callbacks for collision check
|
||||||
RayCastCallback rayCastCallback = new RayCastCallback();
|
RayCastCallback rayCastCallback = new RayCastCallback();
|
||||||
|
|
||||||
|
//the collision resolution callback
|
||||||
|
CollisionResolutionCallback collisionResolutionCallback;
|
||||||
|
|
||||||
|
//buffer for collisions
|
||||||
|
DContactBuffer contacts = null;
|
||||||
|
|
||||||
|
// Callback for any near collisions in the broadphase of the collision check
|
||||||
|
private DNearCallback nearCallback;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
public CollisionEngine(){
|
public CollisionEngine(){
|
||||||
world = OdeHelper.createWorld();
|
world = OdeHelper.createWorld();
|
||||||
space = OdeHelper.createBHVSpace(Collidable.TYPE_STATIC_BIT);
|
space = OdeHelper.createBHVSpace(Collidable.TYPE_STATIC_BIT);
|
||||||
world.setGravity(0,-GRAVITY_MAGNITUDE,0);
|
world.setGravity(0,-GRAVITY_MAGNITUDE,0);
|
||||||
contactgroup = OdeHelper.createJointGroup();
|
contactgroup = OdeHelper.createJointGroup();
|
||||||
|
this.nearCallback = new DNearCallback() {
|
||||||
|
@Override
|
||||||
|
public void call(Object data, DGeom o1, DGeom o2) {
|
||||||
|
nearCallback( data, o1, o2);
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void resolveCollision(Collidable impactor, Collidable receiver, Vector3d normal, Vector3d localPosition, Vector3d worldPos, float magnitude){
|
/**
|
||||||
|
* Resolves collisions in the engine
|
||||||
|
* @param contactGeom the ode4j contact geometry
|
||||||
|
* @param impactor the instigator of the collision
|
||||||
|
* @param receiver the receiver of the collision
|
||||||
|
* @param normal the normal to the collision surface
|
||||||
|
* @param localPosition the local position of the collision
|
||||||
|
* @param worldPos the world position of the collision
|
||||||
|
* @param magnitude the magnitude of the collision
|
||||||
|
*/
|
||||||
|
public static void resolveCollision(DContactGeom contactGeom, Collidable impactor, Collidable receiver, Vector3d normal, Vector3d localPosition, Vector3d worldPos, float magnitude){
|
||||||
switch(receiver.getType()){
|
switch(receiver.getType()){
|
||||||
case Collidable.TYPE_CREATURE:
|
case Collidable.TYPE_CREATURE:
|
||||||
switch(impactor.getType()){
|
switch(impactor.getType()){
|
||||||
@ -223,7 +250,7 @@ public class CollisionEngine {
|
|||||||
|
|
||||||
//simulate physics
|
//simulate physics
|
||||||
Globals.profiler.beginCpuSample("step physics");
|
Globals.profiler.beginCpuSample("step physics");
|
||||||
world.quickStep(ENGINE_STEP_SIZE);
|
world.quickStep(Timekeeper.ENGINE_STEP_SIZE);
|
||||||
Globals.profiler.endCpuSample();
|
Globals.profiler.endCpuSample();
|
||||||
|
|
||||||
// remove all contact joints
|
// remove all contact joints
|
||||||
@ -233,27 +260,45 @@ public class CollisionEngine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback for any near collisions in the broadphase of the collision check
|
* Runs a collision cycle on all bodies in the collision engine
|
||||||
*/
|
*/
|
||||||
private DNearCallback nearCallback = new DNearCallback() {
|
public void collide(){
|
||||||
@Override
|
Globals.profiler.beginCpuSample("physics");
|
||||||
public void call(Object data, DGeom o1, DGeom o2) {
|
spaceLock.acquireUninterruptibly();
|
||||||
nearCallback( data, o1, o2);
|
Globals.profiler.beginCpuSample("collide");
|
||||||
}
|
OdeHelper.spaceCollide(space, 0, nearCallback);
|
||||||
};
|
Globals.profiler.endCpuSample();
|
||||||
|
|
||||||
//buffer for collisions
|
// remove all contact joints
|
||||||
DContactBuffer contacts = null;
|
contactgroup.empty();
|
||||||
|
spaceLock.release();
|
||||||
|
Globals.profiler.endCpuSample();
|
||||||
|
}
|
||||||
|
|
||||||
// this is called by dSpaceCollide when two objects in space are
|
/**
|
||||||
// potentially colliding.
|
* Sets the near callback function for all collision calls.
|
||||||
|
* !!YOU LIKELY WANT TO INSTEAD OVERWRITE THE CollisionResolutionCallback!!
|
||||||
|
* @param callback the callback
|
||||||
|
*/
|
||||||
|
public void setNearCallback(DNearCallback callback){
|
||||||
|
this.nearCallback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is called by dSpaceCollide when two objects in space are potentially colliding.
|
||||||
|
* @param data The data
|
||||||
|
* @param o1 the first collision body
|
||||||
|
* @param o2 the second collision body
|
||||||
|
*/
|
||||||
private void nearCallback (Object data, DGeom o1, DGeom o2) {
|
private void nearCallback (Object data, DGeom o1, DGeom o2) {
|
||||||
// if (o1->body && o2->body) return;
|
// if (o1->body && o2->body) return;
|
||||||
|
|
||||||
// exit without doing anything if the two bodies are connected by a joint
|
// exit without doing anything if the two bodies are connected by a joint
|
||||||
DBody b1 = o1.getBody();
|
DBody b1 = o1.getBody();
|
||||||
DBody b2 = o2.getBody();
|
DBody b2 = o2.getBody();
|
||||||
if (b1!=null && b2!=null && areConnectedExcluding (b1,b2,DContactJoint.class)) return;
|
if (b1!=null && b2!=null && areConnectedExcluding (b1,b2,DContactJoint.class)){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//creates a buffer to store potential collisions
|
//creates a buffer to store potential collisions
|
||||||
DContactBuffer contacts = new DContactBuffer(MAX_CONTACTS); // up to MAX_CONTACTS contacts per box-box
|
DContactBuffer contacts = new DContactBuffer(MAX_CONTACTS); // up to MAX_CONTACTS contacts per box-box
|
||||||
@ -284,33 +329,51 @@ public class CollisionEngine {
|
|||||||
DContact contact = contacts.get(i);
|
DContact contact = contacts.get(i);
|
||||||
//special code for ray casting
|
//special code for ray casting
|
||||||
if (o1 instanceof DRay || o2 instanceof DRay){
|
if (o1 instanceof DRay || o2 instanceof DRay){
|
||||||
DMatrix3 Rotation = new DMatrix3();
|
DVector3 end = new DVector3();
|
||||||
Rotation.setIdentity();
|
end.eqSum( contact.geom.pos, contact.geom.normal, contact.geom.depth );
|
||||||
// dsDrawSphere(contact.geom.pos, Rotation, (0.01));
|
|
||||||
|
|
||||||
DVector3 End = new DVector3();
|
|
||||||
End.eqSum( contact.geom.pos, contact.geom.normal, contact.geom.depth );
|
|
||||||
|
|
||||||
// dsDrawLine(contact.geom.pos, End);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// contact.geom.pos
|
// Use the default collision resolution
|
||||||
resolveCollision(
|
if(collisionResolutionCallback == null) {
|
||||||
bodyPointerMap.get(o1.getBody()),
|
resolveCollision(
|
||||||
bodyPointerMap.get(o2.getBody()),
|
contact.geom,
|
||||||
PhysicsUtils.odeVecToJomlVec(contact.geom.normal).mul(-1.0),
|
bodyPointerMap.get(o1.getBody()),
|
||||||
PhysicsUtils.odeVecToJomlVec(contact.fdir1).mul(-1.0),
|
bodyPointerMap.get(o2.getBody()),
|
||||||
PhysicsUtils.odeVecToJomlVec(contact.geom.pos),
|
PhysicsUtils.odeVecToJomlVec(contact.geom.normal).mul(-1.0),
|
||||||
(float)contact.geom.depth
|
PhysicsUtils.odeVecToJomlVec(contact.fdir1).mul(-1.0),
|
||||||
|
PhysicsUtils.odeVecToJomlVec(contact.geom.pos),
|
||||||
|
(float)contact.geom.depth
|
||||||
|
);
|
||||||
|
resolveCollision(
|
||||||
|
contact.geom,
|
||||||
|
bodyPointerMap.get(o2.getBody()),
|
||||||
|
bodyPointerMap.get(o1.getBody()),
|
||||||
|
PhysicsUtils.odeVecToJomlVec(contact.geom.normal),
|
||||||
|
PhysicsUtils.odeVecToJomlVec(contact.fdir1),
|
||||||
|
PhysicsUtils.odeVecToJomlVec(contact.geom.pos),
|
||||||
|
(float)contact.geom.depth
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
//use custom collision resolution
|
||||||
|
collisionResolutionCallback.resolve(
|
||||||
|
contact.geom,
|
||||||
|
bodyPointerMap.get(o1.getBody()),
|
||||||
|
bodyPointerMap.get(o2.getBody()),
|
||||||
|
PhysicsUtils.odeVecToJomlVec(contact.geom.normal).mul(-1.0),
|
||||||
|
PhysicsUtils.odeVecToJomlVec(contact.fdir1).mul(-1.0),
|
||||||
|
PhysicsUtils.odeVecToJomlVec(contact.geom.pos),
|
||||||
|
(float)contact.geom.depth
|
||||||
);
|
);
|
||||||
resolveCollision(
|
collisionResolutionCallback.resolve(
|
||||||
bodyPointerMap.get(o2.getBody()),
|
contact.geom,
|
||||||
bodyPointerMap.get(o1.getBody()),
|
bodyPointerMap.get(o2.getBody()),
|
||||||
PhysicsUtils.odeVecToJomlVec(contact.geom.normal),
|
bodyPointerMap.get(o1.getBody()),
|
||||||
PhysicsUtils.odeVecToJomlVec(contact.fdir1),
|
PhysicsUtils.odeVecToJomlVec(contact.geom.normal),
|
||||||
PhysicsUtils.odeVecToJomlVec(contact.geom.pos),
|
PhysicsUtils.odeVecToJomlVec(contact.fdir1),
|
||||||
(float)contact.geom.depth
|
PhysicsUtils.odeVecToJomlVec(contact.geom.pos),
|
||||||
|
(float)contact.geom.depth
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
//add contact to contact group
|
//add contact to contact group
|
||||||
DJoint c = OdeHelper.createContactJoint (world,contactgroup,contact );
|
DJoint c = OdeHelper.createContactJoint (world,contactgroup,contact );
|
||||||
@ -325,6 +388,14 @@ public class CollisionEngine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the function that is called once a collision has happened
|
||||||
|
* @param collisionResolutionCallback the function
|
||||||
|
*/
|
||||||
|
public void setCollisionResolutionCallback(CollisionResolutionCallback collisionResolutionCallback){
|
||||||
|
this.collisionResolutionCallback = collisionResolutionCallback;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -691,6 +762,19 @@ public class CollisionEngine {
|
|||||||
spaceLock.release();
|
spaceLock.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the transform of a geometry
|
||||||
|
* @param geom The geometry
|
||||||
|
* @param position The position
|
||||||
|
* @param rotation The rotation
|
||||||
|
*/
|
||||||
|
protected void setGeomTransform(DGeom geom, Vector3d position, Quaterniond rotation){
|
||||||
|
spaceLock.acquireUninterruptibly();
|
||||||
|
geom.setOffsetWorldPosition(position.x, position.y, position.z);
|
||||||
|
geom.setOffsetQuaternion(PhysicsUtils.jomlQuatToOdeQuat(rotation));
|
||||||
|
spaceLock.release();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Corrects the initial axis of eg cylinders or capsules
|
* Corrects the initial axis of eg cylinders or capsules
|
||||||
* @param geom the geometry to correct
|
* @param geom the geometry to correct
|
||||||
@ -758,5 +842,49 @@ public class CollisionEngine {
|
|||||||
body.getGeomIterator().next().setOffsetPosition(offsetVector.x,offsetVector.y,offsetVector.z);
|
body.getGeomIterator().next().setOffsetPosition(offsetVector.x,offsetVector.y,offsetVector.z);
|
||||||
spaceLock.release();
|
spaceLock.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the geometry from the body
|
||||||
|
* @param body the body
|
||||||
|
* @param geom the geometry
|
||||||
|
*/
|
||||||
|
protected void removeGeometryFromBody(DBody body, DGeom geom){
|
||||||
|
geom.setBody(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroys a geometry
|
||||||
|
* @param geom The geometry
|
||||||
|
*/
|
||||||
|
protected void destroyGeom(DGeom geom){
|
||||||
|
geom.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attaches a geom to a body
|
||||||
|
* @param body the body
|
||||||
|
* @param geom the geom
|
||||||
|
*/
|
||||||
|
protected void attachGeomToBody(DBody body, DGeom geom){
|
||||||
|
geom.setBody(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A callback for resolving collisions between two entities
|
||||||
|
*/
|
||||||
|
public interface CollisionResolutionCallback {
|
||||||
|
/**
|
||||||
|
* Resolves a collision between two collidables in the engine
|
||||||
|
* @param contactGeom the ode4j contact geom
|
||||||
|
* @param impactor The collidable initiating the contact
|
||||||
|
* @param receiver The collidable recieving the contact
|
||||||
|
* @param normal The normal of the collision
|
||||||
|
* @param localPosition The local position of the collision
|
||||||
|
* @param worldPos The world position of the collision
|
||||||
|
* @param magnitude The magnitude of the collision
|
||||||
|
*/
|
||||||
|
public void resolve(DContactGeom contactGeom, Collidable impactor, Collidable receiver, Vector3d normal, Vector3d localPosition, Vector3d worldPos, float magnitude);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,10 +2,11 @@ package electrosphere.collision;
|
|||||||
|
|
||||||
import org.joml.Matrix4d;
|
import org.joml.Matrix4d;
|
||||||
import org.joml.Matrix4f;
|
import org.joml.Matrix4f;
|
||||||
|
import org.joml.Quaterniond;
|
||||||
import org.joml.Vector3d;
|
import org.joml.Vector3d;
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
import org.ode4j.ode.DBody;
|
import org.ode4j.ode.DBody;
|
||||||
import org.ode4j.ode.DCylinder;
|
import org.ode4j.ode.DGeom;
|
||||||
import org.ode4j.ode.DTriMesh;
|
import org.ode4j.ode.DTriMesh;
|
||||||
|
|
||||||
import electrosphere.collision.collidable.Collidable;
|
import electrosphere.collision.collidable.Collidable;
|
||||||
@ -301,5 +302,14 @@ public class PhysicsEntityUtils {
|
|||||||
public static DBody getDBody(Entity entity){
|
public static DBody getDBody(Entity entity){
|
||||||
return (DBody)entity.getData(EntityDataStrings.PHYSICS_COLLISION_BODY);
|
return (DBody)entity.getData(EntityDataStrings.PHYSICS_COLLISION_BODY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the position of a DGeom
|
||||||
|
* @param collisionEngine the collision engine
|
||||||
|
* @param geom the geometry
|
||||||
|
*/
|
||||||
|
public static void setGeometryPosition(CollisionEngine collisionEngine, DGeom geom, Vector3d position, Quaterniond rotation){
|
||||||
|
collisionEngine.setGeomTransform(geom, position, rotation);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -39,7 +39,15 @@ public class PhysicsUtils {
|
|||||||
*/
|
*/
|
||||||
public static Vector3d odeVecToJomlVec(org.ode4j.math.DVector3C vector){
|
public static Vector3d odeVecToJomlVec(org.ode4j.math.DVector3C vector){
|
||||||
return new Vector3d(vector.get0(),vector.get1(),vector.get2());
|
return new Vector3d(vector.get0(),vector.get1(),vector.get2());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a joml vector to an Ode vector
|
||||||
|
* @param vector joml vector
|
||||||
|
* @return Ode vector
|
||||||
|
*/
|
||||||
|
public static org.ode4j.math.DVector3C jomlVecToOdeVec(Vector3d vector){
|
||||||
|
return new org.ode4j.math.DVector3(vector.x,vector.y,vector.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -0,0 +1,85 @@
|
|||||||
|
package electrosphere.collision.hitbox;
|
||||||
|
|
||||||
|
import electrosphere.collision.CollisionEngine;
|
||||||
|
import electrosphere.collision.CollisionEngine.CollisionResolutionCallback;
|
||||||
|
import electrosphere.engine.Globals;
|
||||||
|
import electrosphere.entity.state.hitbox.HitboxCollectionState;
|
||||||
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manages all hitboxes on either the server or client
|
||||||
|
*/
|
||||||
|
public class HitboxManager {
|
||||||
|
|
||||||
|
//the list of all hitboxes
|
||||||
|
CopyOnWriteArrayList<HitboxCollectionState> hitboxes = new CopyOnWriteArrayList<HitboxCollectionState>();
|
||||||
|
|
||||||
|
//the collision engine for this hitbox manager
|
||||||
|
CollisionEngine collisionEngine;
|
||||||
|
|
||||||
|
//an id incrementer for hitboxes
|
||||||
|
long idIncrementer = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param resolutionCallback The callback that fires when a collision occurs
|
||||||
|
*/
|
||||||
|
public HitboxManager(CollisionResolutionCallback resolutionCallback){
|
||||||
|
collisionEngine = new CollisionEngine();
|
||||||
|
collisionEngine.setCollisionResolutionCallback(resolutionCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a hitbox to the manager
|
||||||
|
* @param hitbox the hitbox to register
|
||||||
|
*/
|
||||||
|
public void registerHitbox(HitboxCollectionState hitbox){
|
||||||
|
hitboxes.add(hitbox);
|
||||||
|
idIncrementer++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets all hitboxes in the manager
|
||||||
|
* @return all hitboxes in the manager
|
||||||
|
*/
|
||||||
|
public CopyOnWriteArrayList<HitboxCollectionState> getAllHitboxes(){
|
||||||
|
return hitboxes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deregisters a hitbox from the manager
|
||||||
|
* @param hitbox the hitbox to deregister
|
||||||
|
*/
|
||||||
|
public void deregisterHitbox(HitboxCollectionState hitbox){
|
||||||
|
hitboxes.remove(hitbox);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the collision engine associated with the hitbox manager
|
||||||
|
* @return The collision engine
|
||||||
|
*/
|
||||||
|
public CollisionEngine getCollisionEngine(){
|
||||||
|
return this.collisionEngine;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs all per frame functions of the hitbox manager
|
||||||
|
*/
|
||||||
|
public void simulate(){
|
||||||
|
//update all positions
|
||||||
|
Globals.profiler.beginCpuSample("Update hitbox positions");
|
||||||
|
for(HitboxCollectionState state : hitboxes){
|
||||||
|
state.clearCollisions();
|
||||||
|
state.updateHitboxPositions(this.collisionEngine);
|
||||||
|
}
|
||||||
|
Globals.profiler.endCpuSample();
|
||||||
|
//collide hitboxes
|
||||||
|
Globals.profiler.beginCpuSample("Collide hitboxes");
|
||||||
|
this.collisionEngine.collide();
|
||||||
|
this.collisionEngine.clearCollidableImpulseLists();
|
||||||
|
Globals.profiler.endCpuSample();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
324
src/main/java/electrosphere/collision/hitbox/HitboxUtils.java
Normal file
324
src/main/java/electrosphere/collision/hitbox/HitboxUtils.java
Normal file
@ -0,0 +1,324 @@
|
|||||||
|
package electrosphere.collision.hitbox;
|
||||||
|
|
||||||
|
import electrosphere.collision.collidable.Collidable;
|
||||||
|
import electrosphere.entity.Entity;
|
||||||
|
import electrosphere.entity.EntityDataStrings;
|
||||||
|
import electrosphere.entity.EntityUtils;
|
||||||
|
import electrosphere.entity.types.attach.AttachUtils;
|
||||||
|
import electrosphere.entity.state.hitbox.HitboxCollectionState;
|
||||||
|
import electrosphere.entity.state.hitbox.HitboxCollectionState.HitboxState;
|
||||||
|
import electrosphere.entity.state.hitbox.HitboxCollectionState.HitboxType;
|
||||||
|
import electrosphere.game.data.collidable.HitboxData;
|
||||||
|
|
||||||
|
import org.joml.Quaterniond;
|
||||||
|
import org.joml.Vector3d;
|
||||||
|
import org.joml.Vector3f;
|
||||||
|
import org.ode4j.ode.DContactGeom;
|
||||||
|
import org.ode4j.ode.DGeom;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utilities for working with hitboxes
|
||||||
|
*/
|
||||||
|
public class HitboxUtils {
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * Spawns a hitbox entity on the client
|
||||||
|
// * @param parent The parent entity to attach the hitbox to
|
||||||
|
// * @param bone The bone on the parent to attach to
|
||||||
|
// * @param size The radius of the hitsphere
|
||||||
|
// * @return The hitbox entity
|
||||||
|
// */
|
||||||
|
// public static Entity clientSpawnRegularHitbox(Entity parent, String bone, float size){
|
||||||
|
// Entity rVal = EntityCreationUtils.createClientSpatialEntity();
|
||||||
|
// HitboxData data = new HitboxData();
|
||||||
|
// data.setActive(false);
|
||||||
|
// data.setBone(bone);
|
||||||
|
// data.setRadius(size);
|
||||||
|
// data.setType(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HIT);
|
||||||
|
// rVal.putData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT, parent);
|
||||||
|
// rVal.putData(EntityDataStrings.HITBOX_DATA, data);
|
||||||
|
// rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
|
||||||
|
// rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true);
|
||||||
|
// Globals.clientHitboxManager.registerHitbox(rVal);
|
||||||
|
// return rVal;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * Spawns a hitbox entity on the server
|
||||||
|
// * @param parent The parent entity to attach the hitbox to
|
||||||
|
// * @param bone The bone to attach to the hitbox to
|
||||||
|
// * @param size The radius of the hitsphere
|
||||||
|
// * @return The hitbox entity
|
||||||
|
// */
|
||||||
|
// public static Entity serverSpawnRegularHitbox(Entity parent, String bone, float size){
|
||||||
|
// Entity rVal = EntityCreationUtils.createServerEntity(Globals.realmManager.getEntityRealm(parent), new Vector3d(0,0,0));
|
||||||
|
// HitboxData data = new HitboxData();
|
||||||
|
// data.setActive(false);
|
||||||
|
// data.setBone(bone);
|
||||||
|
// data.setRadius(size);
|
||||||
|
// data.setType(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HIT);
|
||||||
|
// rVal.putData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT, parent);
|
||||||
|
// rVal.putData(EntityDataStrings.HITBOX_DATA, data);
|
||||||
|
// rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
|
||||||
|
// rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true);
|
||||||
|
// Globals.realmManager.getEntityRealm(parent).getHitboxManager().registerHitbox(rVal);
|
||||||
|
// return rVal;
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * Spawns a hurtbox on the client
|
||||||
|
// * @param parent The parent entity of the hurtbox
|
||||||
|
// * @param bone The bone on the parent to attach the hurtbox to
|
||||||
|
// * @param size The radius of the hurtsphere
|
||||||
|
// * @return The hurtbox entity
|
||||||
|
// */
|
||||||
|
// public static Entity clientSpawnRegularHurtbox(Entity parent, String bone, float size){
|
||||||
|
// Entity rVal = EntityCreationUtils.createClientSpatialEntity();
|
||||||
|
// HitboxData data = new HitboxData();
|
||||||
|
// data.setActive(true);
|
||||||
|
// data.setBone(bone);
|
||||||
|
// data.setRadius(size);
|
||||||
|
// data.setType(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HURT);
|
||||||
|
// rVal.putData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT, parent);
|
||||||
|
// rVal.putData(EntityDataStrings.HITBOX_DATA, data);
|
||||||
|
// rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
|
||||||
|
// rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true);
|
||||||
|
// Globals.clientHitboxManager.registerHitbox(rVal);
|
||||||
|
// return rVal;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * Spawns a hurtbox on the server
|
||||||
|
// * @param parent The parent entity of the hurtbox
|
||||||
|
// * @param bone The bone on the parent to attach the hurtbox to
|
||||||
|
// * @param size The radius of the hurtsphere
|
||||||
|
// * @return The hurtbox entity
|
||||||
|
// */
|
||||||
|
// public static Entity serverSpawnRegularHurtbox(Entity parent, String bone, float size){
|
||||||
|
// Entity rVal = EntityCreationUtils.createServerEntity(Globals.realmManager.getEntityRealm(parent), new Vector3d(0,0,0));
|
||||||
|
// HitboxData data = new HitboxData();
|
||||||
|
// data.setActive(true);
|
||||||
|
// data.setBone(bone);
|
||||||
|
// data.setRadius(size);
|
||||||
|
// data.setType(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HURT);
|
||||||
|
// rVal.putData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT, parent);
|
||||||
|
// rVal.putData(EntityDataStrings.HITBOX_DATA, data);
|
||||||
|
// rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
|
||||||
|
// rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true);
|
||||||
|
// Globals.realmManager.getEntityRealm(parent).getHitboxManager().registerHitbox(rVal);
|
||||||
|
// return rVal;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * More sophisticated function for spawning in hitboxes. Takes a position callback so it's not tied to a bone
|
||||||
|
// * @param parent The parent entity of the hitbox
|
||||||
|
// * @param positionCallback The position callback for keeping hitbox entity position up to date
|
||||||
|
// * @param size The size of the hitbox
|
||||||
|
// * @param hurtbox If true, it will instead be a hurtbox
|
||||||
|
// * @param filter an optional list of parent entities to not colide with
|
||||||
|
// * @return The hitbox entity
|
||||||
|
// */
|
||||||
|
// public static Entity clientSpawnRegularHitbox(Entity parent, HitboxPositionCallback positionCallback, float size, boolean hurtbox, List<Entity> filter){
|
||||||
|
// Entity rVal = EntityCreationUtils.createClientSpatialEntity();
|
||||||
|
// HitboxData data = new HitboxData();
|
||||||
|
// data.setActive(true);
|
||||||
|
// data.setPositionCallback(positionCallback);
|
||||||
|
// data.setRadius(size);
|
||||||
|
// data.setEntityFilter(filter);
|
||||||
|
// if(hurtbox){
|
||||||
|
// data.setType(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HURT);
|
||||||
|
// } else {
|
||||||
|
// data.setType(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HIT);
|
||||||
|
// }
|
||||||
|
// rVal.putData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT, parent);
|
||||||
|
// rVal.putData(EntityDataStrings.HITBOX_DATA, data);
|
||||||
|
// rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
|
||||||
|
// rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true);
|
||||||
|
// Globals.clientHitboxManager.registerHitbox(rVal);
|
||||||
|
// return rVal;
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * More sophisticated function for spawning in hitboxes. Takes a position callback so it's not tied to a bone
|
||||||
|
// * @param parent The parent entity of the hitbox
|
||||||
|
// * @param positionCallback The position callback for keeping hitbox entity position up to date
|
||||||
|
// * @param size The size of the hitbox
|
||||||
|
// * @param hurtbox If true, it will instead be a hurtbox
|
||||||
|
// * @param filter an optional list of parent entities to not colide with
|
||||||
|
// * @return The hitbox entity
|
||||||
|
// */
|
||||||
|
// public static Entity serverSpawnRegularHitbox(Entity parent, HitboxPositionCallback positionCallback, float size, boolean hurtbox, List<Entity> filter){
|
||||||
|
// Entity rVal = EntityCreationUtils.createServerEntity(Globals.realmManager.getEntityRealm(parent), new Vector3d(0,0,0));
|
||||||
|
// HitboxData data = new HitboxData();
|
||||||
|
// data.setActive(true);
|
||||||
|
// data.setPositionCallback(positionCallback);
|
||||||
|
// data.setRadius(size);
|
||||||
|
// data.setEntityFilter(filter);
|
||||||
|
// if(hurtbox){
|
||||||
|
// data.setType(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HURT);
|
||||||
|
// } else {
|
||||||
|
// data.setType(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HIT);
|
||||||
|
// }
|
||||||
|
// rVal.putData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT, parent);
|
||||||
|
// rVal.putData(EntityDataStrings.HITBOX_DATA, data);
|
||||||
|
// rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
|
||||||
|
// rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true);
|
||||||
|
// Globals.realmManager.getEntityRealm(parent).getHitboxManager().registerHitbox(rVal);
|
||||||
|
// return rVal;
|
||||||
|
// }
|
||||||
|
|
||||||
|
public static void clientUpdatePosition(Entity hitbox){
|
||||||
|
Entity parent = ((Entity)hitbox.getData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT));
|
||||||
|
HitboxData hitboxData = getHitboxData(hitbox);
|
||||||
|
String boneName = hitboxData.getBone();
|
||||||
|
if(boneName != null){
|
||||||
|
Quaterniond parentRotation = EntityUtils.getRotation(parent);
|
||||||
|
Vector3f positionScale = EntityUtils.getScale(parent);
|
||||||
|
Vector3d worldPosition = new Vector3d();
|
||||||
|
Vector3f bonePosition = EntityUtils.getActor(parent).getBonePosition(boneName);
|
||||||
|
Vector3d parentPos = EntityUtils.getPosition(parent);
|
||||||
|
worldPosition.set(bonePosition.x,bonePosition.y,bonePosition.z);
|
||||||
|
Quaterniond rotation = new Quaterniond(parentRotation);
|
||||||
|
|
||||||
|
worldPosition = worldPosition.mul(positionScale);
|
||||||
|
|
||||||
|
worldPosition = worldPosition.rotate(rotation);
|
||||||
|
|
||||||
|
|
||||||
|
worldPosition.add(new Vector3f((float)parentPos.x,(float)parentPos.y,(float)parentPos.z));
|
||||||
|
|
||||||
|
EntityUtils.getPosition(hitbox).set(worldPosition);
|
||||||
|
} else {
|
||||||
|
HitboxPositionCallback positionCallback = hitboxData.getPositionCallback();
|
||||||
|
EntityUtils.getPosition(hitbox).set(positionCallback.getPosition());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the position of a hitbox
|
||||||
|
* @param hitbox the hitbox to update
|
||||||
|
*/
|
||||||
|
public static void serverUpdatePosition(Entity hitbox){
|
||||||
|
Entity parent = ((Entity)hitbox.getData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT));
|
||||||
|
HitboxData hitboxData = getHitboxData(hitbox);
|
||||||
|
String boneName = hitboxData.getBone();
|
||||||
|
if(boneName != null){
|
||||||
|
Quaterniond parentRotation = EntityUtils.getRotation(parent);
|
||||||
|
Vector3f positionScale = EntityUtils.getScale(parent);
|
||||||
|
Vector3d worldPosition = new Vector3d();
|
||||||
|
Vector3f bonePosition = EntityUtils.getPoseActor(parent).getBonePosition(boneName);
|
||||||
|
Vector3d parentPos = EntityUtils.getPosition(parent);
|
||||||
|
worldPosition.set(bonePosition.x,bonePosition.y,bonePosition.z);
|
||||||
|
Quaterniond rotation = new Quaterniond(parentRotation);
|
||||||
|
|
||||||
|
worldPosition = worldPosition.mul(positionScale);
|
||||||
|
|
||||||
|
worldPosition = worldPosition.rotate(rotation);
|
||||||
|
|
||||||
|
|
||||||
|
worldPosition.add(new Vector3d(parentPos.x,parentPos.y,parentPos.z));
|
||||||
|
|
||||||
|
EntityUtils.getPosition(hitbox).set(worldPosition);
|
||||||
|
} else {
|
||||||
|
HitboxPositionCallback positionCallback = hitboxData.getPositionCallback();
|
||||||
|
EntityUtils.getPosition(hitbox).set(positionCallback.getPosition());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles a damage collision on the client
|
||||||
|
* @param impactor the entity initiating the collision
|
||||||
|
* @param receiver the entity receiving the collision
|
||||||
|
*/
|
||||||
|
public static void clientDamageHitboxColision(DContactGeom contactGeom, Collidable impactor, Collidable receiver, Vector3d normal, Vector3d localPosition, Vector3d worldPos, float magnitude){
|
||||||
|
|
||||||
|
Entity impactorParent = impactor.getParent();
|
||||||
|
Entity receiverParent = receiver.getParent();
|
||||||
|
HitboxCollectionState impactorState = HitboxCollectionState.getHitboxState(impactorParent);
|
||||||
|
HitboxCollectionState receiverState = HitboxCollectionState.getHitboxState(receiverParent);
|
||||||
|
DGeom impactorGeom = contactGeom.g1;
|
||||||
|
DGeom receiverGeom = contactGeom.g2;
|
||||||
|
HitboxState impactorShapeStatus = impactorState.getShapeStatus(impactorGeom);
|
||||||
|
HitboxState receiverShapeStatus = receiverState.getShapeStatus(receiverGeom);
|
||||||
|
|
||||||
|
|
||||||
|
//currently, impactor needs to be an item, and the receiver must not be an item
|
||||||
|
boolean isDamageEvent =
|
||||||
|
impactorShapeStatus != null &&
|
||||||
|
receiverShapeStatus != null &&
|
||||||
|
impactorShapeStatus.getType() == HitboxType.HIT &&
|
||||||
|
receiverShapeStatus.getType() == HitboxType.HURT &&
|
||||||
|
AttachUtils.getParent(impactorParent) != receiverParent
|
||||||
|
;
|
||||||
|
|
||||||
|
if(impactorShapeStatus != null){
|
||||||
|
impactorShapeStatus.setHadCollision(true);
|
||||||
|
}
|
||||||
|
if(receiverShapeStatus != null){
|
||||||
|
receiverShapeStatus.setHadCollision(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isDamageEvent){
|
||||||
|
//TODO: client logic for audio etc
|
||||||
|
}
|
||||||
|
|
||||||
|
// Entity hitboxParent = (Entity)impactor.getData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT);
|
||||||
|
// Entity hurtboxParent = (Entity)receiver.getData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT);
|
||||||
|
|
||||||
|
//if the entity is attached to is an item, we need to compare with the parent of the item
|
||||||
|
//to make sure you don't stab yourself for instance
|
||||||
|
// boolean isItem = ItemUtils.isItem(hitboxParent);//hitboxParent.containsKey(EntityDataStrings.ITEM_IS_ITEM);
|
||||||
|
// Entity hitboxAttachParent = AttachUtils.getParent(hitboxParent);
|
||||||
|
|
||||||
|
// if(isItem){
|
||||||
|
// if(hitboxAttachParent != hurtboxParent){
|
||||||
|
// Vector3d hurtboxPos = EntityUtils.getPosition(receiver);
|
||||||
|
// ParticleEffects.spawnBloodsplats(new Vector3f((float)hurtboxPos.x,(float)hurtboxPos.y,(float)hurtboxPos.z).add(0,0.1f,0), 20, 40);
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
|
||||||
|
// //client no longer manages damage; however, keeping this code around for the moment to show how we
|
||||||
|
// //might approach adding client-side effects as soon as impact occurs (ie play a sound, shoot sparks, etc)
|
||||||
|
// //before the server responds with a valid collision event or not
|
||||||
|
|
||||||
|
// // int damage = 0;
|
||||||
|
// // //for entities using attacktree
|
||||||
|
// // if(CreatureUtils.clientGetAttackTree(hitboxParent) != null){
|
||||||
|
// // damage = ItemUtils.getWeaponDataRaw(hitboxParent).getDamage();
|
||||||
|
// // } else {
|
||||||
|
// // //for entities using shooter tree
|
||||||
|
// // if(ProjectileTree.getProjectileTree(hitboxParent) != null){
|
||||||
|
// // damage = (int)ProjectileTree.getProjectileTree(hitboxParent).getDamage();
|
||||||
|
// // }
|
||||||
|
// // }
|
||||||
|
// // LifeUtils.getLifeState(hurtboxParent).damage(damage);
|
||||||
|
// // if(!LifeUtils.getLifeState(hurtboxParent).isIsAlive()){
|
||||||
|
// // EntityUtils.getPosition(hurtboxParent).set(Globals.spawnPoint);
|
||||||
|
// // LifeUtils.getLifeState(hurtboxParent).revive();
|
||||||
|
// // }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the data for a hitbox
|
||||||
|
* @param e the entity encapsulating the hitbox
|
||||||
|
* @return the hitbox data
|
||||||
|
*/
|
||||||
|
public static HitboxData getHitboxData(Entity e){
|
||||||
|
return (HitboxData)e.getData(EntityDataStrings.HITBOX_DATA);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Intended to be implemented as an anonoymous class when needed
|
||||||
|
*/
|
||||||
|
public interface HitboxPositionCallback {
|
||||||
|
/**
|
||||||
|
* Gets the current position this hitbox should be at
|
||||||
|
* @return The position this hitbox should be at
|
||||||
|
*/
|
||||||
|
public Vector3d getPosition();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -10,19 +10,36 @@ import electrosphere.engine.Globals;
|
|||||||
import electrosphere.entity.Entity;
|
import electrosphere.entity.Entity;
|
||||||
import electrosphere.entity.EntityUtils;
|
import electrosphere.entity.EntityUtils;
|
||||||
import electrosphere.entity.types.camera.CameraEntityUtils;
|
import electrosphere.entity.types.camera.CameraEntityUtils;
|
||||||
|
import electrosphere.net.parser.net.message.EntityMessage;
|
||||||
import electrosphere.renderer.ui.events.MouseEvent;
|
import electrosphere.renderer.ui.events.MouseEvent;
|
||||||
|
import electrosphere.util.MathUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler for camera-related events and controls
|
||||||
|
*/
|
||||||
public class CameraHandler {
|
public class CameraHandler {
|
||||||
|
|
||||||
|
//the horizontal mouse sensitivity
|
||||||
float mouseSensitivityHorizontal = .1f;
|
float mouseSensitivityHorizontal = .1f;
|
||||||
|
//the vertical mouse sensitivity
|
||||||
float mouseSensitivityVertical = .08f;
|
float mouseSensitivityVertical = .08f;
|
||||||
|
//the speed of the freecam
|
||||||
float cameraSpeed;
|
float cameraSpeed;
|
||||||
|
//the current yaw
|
||||||
float yaw = 150;
|
float yaw = 150;
|
||||||
|
//the current pitch
|
||||||
float pitch = 50;
|
float pitch = 50;
|
||||||
|
//the camera's rotation vector
|
||||||
Vector3f cameraRotationVector = new Vector3f();
|
Vector3f cameraRotationVector = new Vector3f();
|
||||||
|
//the radial offset of the camera
|
||||||
Vector3f radialOffset = new Vector3f(0,1,0);
|
Vector3f radialOffset = new Vector3f(0,1,0);
|
||||||
|
//if set to true, the camera will track the player's entity
|
||||||
boolean trackPlayerEntity = true;
|
boolean trackPlayerEntity = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles a mouse event
|
||||||
|
* @param event The mouse event
|
||||||
|
*/
|
||||||
public void handleMouseEvent(MouseEvent event){
|
public void handleMouseEvent(MouseEvent event){
|
||||||
|
|
||||||
if(Globals.controlHandler != null && !Globals.controlHandler.isMouseVisible()){
|
if(Globals.controlHandler != null && !Globals.controlHandler.isMouseVisible()){
|
||||||
@ -40,10 +57,17 @@ public class CameraHandler {
|
|||||||
updateGlobalCamera();
|
updateGlobalCamera();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the radial offset
|
||||||
|
* @param offset the radial offset
|
||||||
|
*/
|
||||||
public void updateRadialOffset(Vector3f offset){
|
public void updateRadialOffset(Vector3f offset){
|
||||||
radialOffset = offset;
|
radialOffset = offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the global camera
|
||||||
|
*/
|
||||||
public void updateGlobalCamera(){
|
public void updateGlobalCamera(){
|
||||||
Globals.profiler.beginCpuSample("updateGlobalCamera");
|
Globals.profiler.beginCpuSample("updateGlobalCamera");
|
||||||
if(Globals.playerCamera != null){
|
if(Globals.playerCamera != null){
|
||||||
@ -82,7 +106,7 @@ public class CameraHandler {
|
|||||||
// float pitchRad = pitch / 180.0f * (float)Math.PI;
|
// float pitchRad = pitch / 180.0f * (float)Math.PI;
|
||||||
// float rollRad = 0.0f;
|
// float rollRad = 0.0f;
|
||||||
// pitchQuat.mul(yawQuat);
|
// pitchQuat.mul(yawQuat);
|
||||||
cameraRotationVector = pitchQuat.transform(new Vector3f(0,0,1));
|
cameraRotationVector = pitchQuat.transform(MathUtils.getOriginVectorf());
|
||||||
cameraRotationVector = yawQuat.transform(cameraRotationVector);
|
cameraRotationVector = yawQuat.transform(cameraRotationVector);
|
||||||
cameraRotationVector.normalize();
|
cameraRotationVector.normalize();
|
||||||
|
|
||||||
@ -107,8 +131,21 @@ public class CameraHandler {
|
|||||||
cameraRotationVector.mul(CameraEntityUtils.getOrbitalCameraDistance(Globals.playerCamera));
|
cameraRotationVector.mul(CameraEntityUtils.getOrbitalCameraDistance(Globals.playerCamera));
|
||||||
CameraEntityUtils.setCameraEye(Globals.playerCamera, cameraRotationVector);
|
CameraEntityUtils.setCameraEye(Globals.playerCamera, cameraRotationVector);
|
||||||
|
|
||||||
|
//tell the server that we changed where we're looking
|
||||||
|
Globals.clientConnection.queueOutgoingMessage(
|
||||||
|
EntityMessage.constructupdateEntityViewDirMessage(
|
||||||
|
Globals.clientSceneWrapper.mapClientToServerId(Globals.playerEntity.getId()),
|
||||||
|
Globals.timekeeper.getNumberOfSimFramesElapsed(),
|
||||||
|
cameraRotationVector.x,
|
||||||
|
cameraRotationVector.y,
|
||||||
|
cameraRotationVector.z
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
//the view matrix
|
||||||
Globals.viewMatrix = CameraEntityUtils.getCameraViewMatrix(Globals.playerCamera);
|
Globals.viewMatrix = CameraEntityUtils.getCameraViewMatrix(Globals.playerCamera);
|
||||||
|
|
||||||
|
//update the cursor on client side
|
||||||
updatePlayerCursor();
|
updatePlayerCursor();
|
||||||
}
|
}
|
||||||
Globals.profiler.endCpuSample();
|
Globals.profiler.endCpuSample();
|
||||||
@ -136,10 +173,18 @@ public class CameraHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the yaw of the camera handler
|
||||||
|
* @return the yaw
|
||||||
|
*/
|
||||||
public float getYaw(){
|
public float getYaw(){
|
||||||
return yaw;
|
return yaw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the pitch of the camera handler
|
||||||
|
* @return the pitch
|
||||||
|
*/
|
||||||
public float getPitch(){
|
public float getPitch(){
|
||||||
return pitch;
|
return pitch;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -61,6 +61,7 @@ import static org.lwjgl.glfw.GLFW.GLFW_MOUSE_BUTTON_RIGHT;
|
|||||||
import static org.lwjgl.glfw.GLFW.glfwGetCursorPos;
|
import static org.lwjgl.glfw.GLFW.glfwGetCursorPos;
|
||||||
import static org.lwjgl.glfw.GLFW.glfwSetInputMode;
|
import static org.lwjgl.glfw.GLFW.glfwSetInputMode;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -107,8 +108,7 @@ import electrosphere.renderer.ui.events.MouseEvent;
|
|||||||
import electrosphere.renderer.ui.events.ScrollEvent;
|
import electrosphere.renderer.ui.events.ScrollEvent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Main handler for controls
|
||||||
* @author amaterasu
|
|
||||||
*/
|
*/
|
||||||
public class ControlHandler {
|
public class ControlHandler {
|
||||||
|
|
||||||
@ -204,7 +204,9 @@ public class ControlHandler {
|
|||||||
public static final String FREECAM_RIGHT = "freecamRight";
|
public static final String FREECAM_RIGHT = "freecamRight";
|
||||||
public static final String FREECAM_MOUSE = "freecamMouse";
|
public static final String FREECAM_MOUSE = "freecamMouse";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The different buckets of inputs that the control handler be configured to scan for each frame
|
||||||
|
*/
|
||||||
public static enum ControlsState {
|
public static enum ControlsState {
|
||||||
TITLE_PAGE,
|
TITLE_PAGE,
|
||||||
TITLE_MENU,
|
TITLE_MENU,
|
||||||
@ -215,14 +217,39 @@ public class ControlHandler {
|
|||||||
NO_INPUT,
|
NO_INPUT,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//The bucket of inputs that the control handler is currently scanning for
|
||||||
ControlsState state = ControlsState.TITLE_MENU;
|
ControlsState state = ControlsState.TITLE_MENU;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The list of control states that have the mouse visible and enabled
|
||||||
|
*/
|
||||||
|
static ControlsState[] mouseEnabledStates = new ControlsState[]{
|
||||||
|
ControlsState.TITLE_PAGE,
|
||||||
|
ControlsState.TITLE_MENU,
|
||||||
|
ControlsState.IN_GAME_MAIN_MENU,
|
||||||
|
ControlsState.INVENTORY,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//controls whether the mouse is visible or not
|
||||||
boolean mouseIsVisible = true;
|
boolean mouseIsVisible = true;
|
||||||
|
|
||||||
|
//if set to true, opengl will try to capture the screen next frame
|
||||||
boolean shouldRecaptureScreen = false;
|
boolean shouldRecaptureScreen = false;
|
||||||
|
|
||||||
//controls whether the camera is first or third person
|
//controls whether the camera is first or third person
|
||||||
boolean cameraIsThirdPerson = false;
|
boolean cameraIsThirdPerson = true;
|
||||||
|
|
||||||
|
//The list of window strings that would block main game controls
|
||||||
|
static String[] controlBlockingWindows = new String[]{
|
||||||
|
WindowStrings.LEVEL_EDTIOR_SIDE_PANEL,
|
||||||
|
WindowStrings.VOXEL_TYPE_SELECTION,
|
||||||
|
WindowStrings.WINDOW_CHARACTER,
|
||||||
|
WindowStrings.WINDOW_DEBUG,
|
||||||
|
WindowStrings.WINDOW_MENU_INGAME_MAIN,
|
||||||
|
WindowStrings.WINDOW_MENU_INVENTORY,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -234,10 +261,10 @@ public class ControlHandler {
|
|||||||
double ypos = 300;
|
double ypos = 300;
|
||||||
double mouse_X_Buffer[] = new double[1];
|
double mouse_X_Buffer[] = new double[1];
|
||||||
double mouse_Y_Buffer[] = new double[1];
|
double mouse_Y_Buffer[] = new double[1];
|
||||||
boolean dragging = false;
|
boolean dragging = false; //tracks whether the mouse is doing a drag input or not
|
||||||
|
|
||||||
|
|
||||||
|
//The map of data string -> control object
|
||||||
HashMap<String, Control> controls;
|
HashMap<String, Control> controls;
|
||||||
|
|
||||||
List<Control> mainGameControlList = new LinkedList<Control>();
|
List<Control> mainGameControlList = new LinkedList<Control>();
|
||||||
@ -248,10 +275,17 @@ public class ControlHandler {
|
|||||||
List<Control> alwaysOnDebugControlList = new LinkedList<Control>();
|
List<Control> alwaysOnDebugControlList = new LinkedList<Control>();
|
||||||
List<Control> freeCameraControlList = new LinkedList<Control>();
|
List<Control> freeCameraControlList = new LinkedList<Control>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
ControlHandler(){
|
ControlHandler(){
|
||||||
controls = new HashMap<String, Control>();
|
controls = new HashMap<String, Control>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates an example controls map
|
||||||
|
* @return the example controls map object
|
||||||
|
*/
|
||||||
public static ControlHandler generateExampleControlsMap(){
|
public static ControlHandler generateExampleControlsMap(){
|
||||||
ControlHandler handler = new ControlHandler();
|
ControlHandler handler = new ControlHandler();
|
||||||
/*
|
/*
|
||||||
@ -355,11 +389,6 @@ public class ControlHandler {
|
|||||||
framestep controls
|
framestep controls
|
||||||
*/
|
*/
|
||||||
handler.addControl(DEBUG_FRAMESTEP, new Control(ControlType.KEY, GLFW_KEY_P));
|
handler.addControl(DEBUG_FRAMESTEP, new Control(ControlType.KEY, GLFW_KEY_P));
|
||||||
|
|
||||||
/*
|
|
||||||
set state
|
|
||||||
*/
|
|
||||||
handler.setHandlerState(ControlsState.TITLE_MENU);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Free camera
|
* Free camera
|
||||||
@ -393,7 +422,9 @@ public class ControlHandler {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Polls the currently set bucket of controls
|
||||||
|
*/
|
||||||
public void pollControls(){
|
public void pollControls(){
|
||||||
switch(state){
|
switch(state){
|
||||||
|
|
||||||
@ -446,7 +477,9 @@ public class ControlHandler {
|
|||||||
Globals.scrollCallback.clear();
|
Globals.scrollCallback.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attaches callbacks to each of the control objects
|
||||||
|
*/
|
||||||
public void setCallbacks(){
|
public void setCallbacks(){
|
||||||
setMainGameControls();
|
setMainGameControls();
|
||||||
setInGameDebugControls();
|
setInGameDebugControls();
|
||||||
@ -457,6 +490,10 @@ public class ControlHandler {
|
|||||||
setFreecamControls();
|
setFreecamControls();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets callbacks for the main game controls
|
||||||
|
*/
|
||||||
void setMainGameControls(){
|
void setMainGameControls(){
|
||||||
/*
|
/*
|
||||||
Camera rotation
|
Camera rotation
|
||||||
@ -909,7 +946,7 @@ public class ControlHandler {
|
|||||||
mainGameControlList.add(controls.get(DATA_STRING_INPUT_CODE_IN_GAME_MAIN_MENU));
|
mainGameControlList.add(controls.get(DATA_STRING_INPUT_CODE_IN_GAME_MAIN_MENU));
|
||||||
controls.get(DATA_STRING_INPUT_CODE_IN_GAME_MAIN_MENU).setOnClick(new ControlMethod(){public void execute(){
|
controls.get(DATA_STRING_INPUT_CODE_IN_GAME_MAIN_MENU).setOnClick(new ControlMethod(){public void execute(){
|
||||||
// Globals.elementManager.registerWindow(WindowStrings.WINDOW_MENU_INGAME_MAIN, MenuGenerators.createInGameMainMenu());
|
// Globals.elementManager.registerWindow(WindowStrings.WINDOW_MENU_INGAME_MAIN, MenuGenerators.createInGameMainMenu());
|
||||||
// Globals.controlHandler.setHandlerState(ControlsState.IN_GAME_MAIN_MENU);
|
// Globals.controlHandler.hintUpdateControlState(ControlsState.IN_GAME_MAIN_MENU);
|
||||||
|
|
||||||
// Window mainMenuWindow = new Window(0, 0, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT);
|
// Window mainMenuWindow = new Window(0, 0, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT);
|
||||||
Window mainMenuInGame = MenuGeneratorsInGame.createInGameMainMenu();
|
Window mainMenuInGame = MenuGeneratorsInGame.createInGameMainMenu();
|
||||||
@ -917,8 +954,7 @@ public class ControlHandler {
|
|||||||
Globals.elementManager.registerWindow(WindowStrings.WINDOW_MENU_INGAME_MAIN, mainMenuInGame);
|
Globals.elementManager.registerWindow(WindowStrings.WINDOW_MENU_INGAME_MAIN, mainMenuInGame);
|
||||||
WindowUtils.recursiveSetVisible(Globals.elementManager.getWindow(WindowStrings.WINDOW_MENU_INGAME_MAIN), true);
|
WindowUtils.recursiveSetVisible(Globals.elementManager.getWindow(WindowStrings.WINDOW_MENU_INGAME_MAIN), true);
|
||||||
Globals.elementManager.focusFirstElement();
|
Globals.elementManager.focusFirstElement();
|
||||||
Globals.controlHandler.setHandlerState(ControlsState.IN_GAME_MAIN_MENU);
|
Globals.controlHandler.hintUpdateControlState(ControlsState.IN_GAME_MAIN_MENU);
|
||||||
Globals.controlHandler.showMouse();
|
|
||||||
//play sound effect
|
//play sound effect
|
||||||
Globals.virtualAudioSourceManager.createVirtualAudioSource("/Audio/openMenu.ogg", VirtualAudioSourceType.UI, false);
|
Globals.virtualAudioSourceManager.createVirtualAudioSource("/Audio/openMenu.ogg", VirtualAudioSourceType.UI, false);
|
||||||
}});
|
}});
|
||||||
@ -939,12 +975,13 @@ public class ControlHandler {
|
|||||||
//make visible
|
//make visible
|
||||||
WindowUtils.recursiveSetVisible(Globals.elementManager.getWindow(WindowUtils.getInventoryWindowID(inventory.getId())), true);
|
WindowUtils.recursiveSetVisible(Globals.elementManager.getWindow(WindowUtils.getInventoryWindowID(inventory.getId())), true);
|
||||||
//controls
|
//controls
|
||||||
Globals.controlHandler.setHandlerState(ControlsState.INVENTORY);
|
Globals.controlHandler.hintUpdateControlState(ControlsState.INVENTORY);
|
||||||
Globals.controlHandler.showMouse();
|
|
||||||
//play sound effect
|
//play sound effect
|
||||||
Globals.virtualAudioSourceManager.createVirtualAudioSource("/Audio/openMenu.ogg", VirtualAudioSourceType.UI, false);
|
Globals.virtualAudioSourceManager.createVirtualAudioSource("/Audio/openMenu.ogg", VirtualAudioSourceType.UI, false);
|
||||||
//
|
//
|
||||||
Globals.openInventoriesCount++;
|
Globals.openInventoriesCount++;
|
||||||
|
} else if(InventoryUtils.hasNaturalInventory(Globals.playerEntity) && Globals.elementManager.getWindow(WindowUtils.getInventoryWindowID(InventoryUtils.getNaturalInventory(Globals.playerEntity).getId())) != null){
|
||||||
|
Globals.elementManager.closeWindow(WindowUtils.getInventoryWindowID(InventoryUtils.getNaturalInventory(Globals.playerEntity).getId()));
|
||||||
}
|
}
|
||||||
}});
|
}});
|
||||||
controls.get(INPUT_CODE_INVENTORY_OPEN).setRepeatTimeout(0.5f * Main.targetFrameRate);
|
controls.get(INPUT_CODE_INVENTORY_OPEN).setRepeatTimeout(0.5f * Main.targetFrameRate);
|
||||||
@ -957,18 +994,19 @@ public class ControlHandler {
|
|||||||
controls.get(INPUT_CODE_CHARACTER_OPEN).setOnClick(new ControlMethod(){public void execute(){
|
controls.get(INPUT_CODE_CHARACTER_OPEN).setOnClick(new ControlMethod(){public void execute(){
|
||||||
if(InventoryUtils.hasEquipInventory(Globals.playerEntity) && Globals.elementManager.getWindow(WindowStrings.WINDOW_CHARACTER) == null){
|
if(InventoryUtils.hasEquipInventory(Globals.playerEntity) && Globals.elementManager.getWindow(WindowStrings.WINDOW_CHARACTER) == null){
|
||||||
//create window
|
//create window
|
||||||
Window mainMenuWindow = MenuGeneratorsInventory.createCharacterInventoryMenu(InventoryUtils.getEquipInventory(Globals.playerEntity));
|
Window characterInventoryMenu = MenuGeneratorsInventory.createCharacterInventoryMenu(InventoryUtils.getEquipInventory(Globals.playerEntity));
|
||||||
//register
|
//register
|
||||||
Globals.elementManager.registerWindow(WindowStrings.WINDOW_CHARACTER, mainMenuWindow);
|
Globals.elementManager.registerWindow(WindowStrings.WINDOW_CHARACTER, characterInventoryMenu);
|
||||||
//make visible
|
//make visible
|
||||||
WindowUtils.recursiveSetVisible(Globals.elementManager.getWindow(WindowStrings.WINDOW_CHARACTER), true);
|
WindowUtils.recursiveSetVisible(Globals.elementManager.getWindow(WindowStrings.WINDOW_CHARACTER), true);
|
||||||
//controls
|
//controls
|
||||||
Globals.controlHandler.setHandlerState(ControlsState.INVENTORY);
|
Globals.controlHandler.hintUpdateControlState(ControlsState.INVENTORY);
|
||||||
Globals.controlHandler.showMouse();
|
|
||||||
//play sound effect
|
//play sound effect
|
||||||
Globals.virtualAudioSourceManager.createVirtualAudioSource("/Audio/openMenu.ogg", VirtualAudioSourceType.UI, false);
|
Globals.virtualAudioSourceManager.createVirtualAudioSource("/Audio/openMenu.ogg", VirtualAudioSourceType.UI, false);
|
||||||
//
|
//
|
||||||
Globals.openInventoriesCount++;
|
Globals.openInventoriesCount++;
|
||||||
|
} else if(InventoryUtils.hasEquipInventory(Globals.playerEntity) && Globals.elementManager.getWindow(WindowStrings.WINDOW_CHARACTER) != null){
|
||||||
|
Globals.elementManager.closeWindow(WindowStrings.WINDOW_CHARACTER);
|
||||||
}
|
}
|
||||||
}});
|
}});
|
||||||
controls.get(INPUT_CODE_CHARACTER_OPEN).setRepeatTimeout(0.5f * Main.targetFrameRate);
|
controls.get(INPUT_CODE_CHARACTER_OPEN).setRepeatTimeout(0.5f * Main.targetFrameRate);
|
||||||
@ -1037,6 +1075,10 @@ public class ControlHandler {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the in game debug control callbacks
|
||||||
|
*/
|
||||||
void setInGameDebugControls(){
|
void setInGameDebugControls(){
|
||||||
mainGameDebugControlList.add(controls.get(DATA_STRING_INPUT_CODE_DEBUG_SPAWN_ITEM));
|
mainGameDebugControlList.add(controls.get(DATA_STRING_INPUT_CODE_DEBUG_SPAWN_ITEM));
|
||||||
controls.get(DATA_STRING_INPUT_CODE_DEBUG_SPAWN_ITEM).setOnPress(new ControlMethod(){public void execute(){
|
controls.get(DATA_STRING_INPUT_CODE_DEBUG_SPAWN_ITEM).setOnPress(new ControlMethod(){public void execute(){
|
||||||
@ -1050,6 +1092,10 @@ public class ControlHandler {
|
|||||||
controls.get(DEBUG_FRAMESTEP).setOnRelease(new ControlMethod(){public void execute(){
|
controls.get(DEBUG_FRAMESTEP).setOnRelease(new ControlMethod(){public void execute(){
|
||||||
Main.setFramestep(1);
|
Main.setFramestep(1);
|
||||||
}});
|
}});
|
||||||
|
controls.get(DEBUG_FRAMESTEP).setOnRepeat(new ControlMethod(){public void execute(){
|
||||||
|
Main.setFramestep(1);
|
||||||
|
}});
|
||||||
|
controls.get(DEBUG_FRAMESTEP).setRepeatTimeout(0.5f * Main.targetFrameRate);
|
||||||
// RenderingEngine.incrementOutputFramebuffer();
|
// RenderingEngine.incrementOutputFramebuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1197,6 +1243,9 @@ public class ControlHandler {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the freecam control callbacks
|
||||||
|
*/
|
||||||
void setFreecamControls(){
|
void setFreecamControls(){
|
||||||
freeCameraControlList.add(controls.get(FREECAM_UP));
|
freeCameraControlList.add(controls.get(FREECAM_UP));
|
||||||
controls.get(FREECAM_UP).setOnRepeat(new ControlMethod(){public void execute(){
|
controls.get(FREECAM_UP).setOnRepeat(new ControlMethod(){public void execute(){
|
||||||
@ -1269,6 +1318,9 @@ public class ControlHandler {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the typing control callbacks
|
||||||
|
*/
|
||||||
void setTypingControls(){
|
void setTypingControls(){
|
||||||
|
|
||||||
String[] typeKeybinds = {
|
String[] typeKeybinds = {
|
||||||
@ -1332,6 +1384,9 @@ public class ControlHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the inventory control callbacks
|
||||||
|
*/
|
||||||
void setInventoryControls(){
|
void setInventoryControls(){
|
||||||
/*
|
/*
|
||||||
Close inventory
|
Close inventory
|
||||||
@ -1380,6 +1435,10 @@ public class ControlHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks a list of controls to see if the corresponding key/mouse event is firing this frame
|
||||||
|
* @param controls The list of controls to check
|
||||||
|
*/
|
||||||
public void runHandlers(List<Control> controls){
|
public void runHandlers(List<Control> controls){
|
||||||
|
|
||||||
//construct mouse event
|
//construct mouse event
|
||||||
@ -1461,6 +1520,55 @@ public class ControlHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if any menus are open that would intercept player input (main menu, inventory, debug, etc)
|
||||||
|
* @return true if such a menu is open, false otherwise
|
||||||
|
*/
|
||||||
|
private boolean hasControlBlockingMenuOpen(){
|
||||||
|
boolean rVal = false;
|
||||||
|
//check main ui framework windows
|
||||||
|
for(String windowString : controlBlockingWindows){
|
||||||
|
rVal = rVal || WindowUtils.windowIsOpen(windowString);
|
||||||
|
}
|
||||||
|
//check imgui windows
|
||||||
|
rVal = rVal || Globals.renderingEngine.getImGuiPipeline().shouldCaptureControls();
|
||||||
|
return rVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hints to the engine that it should update the control state
|
||||||
|
* The provided control state will be overwritten if, for instance,
|
||||||
|
* there is a menu open that demands mouse input and you are trying
|
||||||
|
* to tell the engine to convert to immediate player control
|
||||||
|
* @param desiredState The desired control state
|
||||||
|
*/
|
||||||
|
public void hintUpdateControlState(ControlsState desiredState){
|
||||||
|
ControlsState properState = desiredState;
|
||||||
|
//correct for freecam or actual ingame control based on value of getTrackPlayerEntity
|
||||||
|
if(desiredState == ControlsState.IN_GAME_FREE_CAMERA && Globals.cameraHandler.getTrackPlayerEntity()){
|
||||||
|
properState = ControlsState.MAIN_GAME;
|
||||||
|
}
|
||||||
|
if(desiredState == ControlsState.MAIN_GAME && !Globals.cameraHandler.getTrackPlayerEntity()){
|
||||||
|
properState = ControlsState.IN_GAME_FREE_CAMERA;
|
||||||
|
}
|
||||||
|
|
||||||
|
//set to menu state if a menu is open, otherwise use the hinted control scheme
|
||||||
|
if(hasControlBlockingMenuOpen()){
|
||||||
|
setHandlerState(ControlsState.IN_GAME_MAIN_MENU);
|
||||||
|
} else {
|
||||||
|
setHandlerState(properState);
|
||||||
|
}
|
||||||
|
//checks if the current handler state should have mouse enabled or not
|
||||||
|
if(Arrays.binarySearch(mouseEnabledStates,getHandlerState()) >= 0){
|
||||||
|
showMouse();
|
||||||
|
} else {
|
||||||
|
hideMouse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transfers the mouse position from the glfw buffer to variables stored inside the control handler
|
||||||
|
*/
|
||||||
void getMousePositionInBuffer(){
|
void getMousePositionInBuffer(){
|
||||||
//only if not headless, gather position
|
//only if not headless, gather position
|
||||||
if(!Globals.HEADLESS){
|
if(!Globals.HEADLESS){
|
||||||
@ -1470,6 +1578,10 @@ public class ControlHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the mouse button 1 is currently pressed
|
||||||
|
* @return true if pressed, false otherwise
|
||||||
|
*/
|
||||||
boolean getButton1Raw(){
|
boolean getButton1Raw(){
|
||||||
if(Globals.HEADLESS){
|
if(Globals.HEADLESS){
|
||||||
return false;
|
return false;
|
||||||
@ -1478,6 +1590,10 @@ public class ControlHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the mouse button 2 is currently pressed
|
||||||
|
* @return true if pressed, false otherwise
|
||||||
|
*/
|
||||||
boolean getButton2Raw(){
|
boolean getButton2Raw(){
|
||||||
if(Globals.HEADLESS){
|
if(Globals.HEADLESS){
|
||||||
return false;
|
return false;
|
||||||
@ -1502,33 +1618,51 @@ public class ControlHandler {
|
|||||||
controls.put(controlName, c);
|
controls.put(controlName, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setHandlerState(ControlsState state){
|
/**
|
||||||
|
* Sets the state of the controls handler
|
||||||
|
* @param state the state
|
||||||
|
*/
|
||||||
|
private void setHandlerState(ControlsState state){
|
||||||
this.state = state;
|
this.state = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the current state of the controls handler
|
||||||
|
* @return the state
|
||||||
|
*/
|
||||||
public ControlsState getHandlerState(){
|
public ControlsState getHandlerState(){
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ControlsState getState(){
|
/**
|
||||||
return state;
|
* Hides the mouse
|
||||||
}
|
*/
|
||||||
|
|
||||||
public void hideMouse(){
|
public void hideMouse(){
|
||||||
glfwSetInputMode(Globals.window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
|
glfwSetInputMode(Globals.window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
|
||||||
glfwSetInputMode(Globals.window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
glfwSetInputMode(Globals.window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
||||||
mouseIsVisible = false;
|
mouseIsVisible = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows the mouse
|
||||||
|
*/
|
||||||
public void showMouse(){
|
public void showMouse(){
|
||||||
glfwSetInputMode(Globals.window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
|
glfwSetInputMode(Globals.window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
|
||||||
mouseIsVisible = true;
|
mouseIsVisible = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets whether the mouse is visible or not
|
||||||
|
* @return true if visible, false otherwise
|
||||||
|
*/
|
||||||
public boolean isMouseVisible(){
|
public boolean isMouseVisible(){
|
||||||
return mouseIsVisible;
|
return mouseIsVisible;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the mouse position as a vector2f
|
||||||
|
* @return The vector containing the mouse position
|
||||||
|
*/
|
||||||
public Vector2f getMousePosition(){
|
public Vector2f getMousePosition(){
|
||||||
double posX[] = new double[1];
|
double posX[] = new double[1];
|
||||||
double posY[] = new double[1];
|
double posY[] = new double[1];
|
||||||
@ -1537,6 +1671,11 @@ public class ControlHandler {
|
|||||||
return rVal;
|
return rVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a keycode to a string containing a code related to the keycode (ie "A" for 65, "Escape" for 256, etc)
|
||||||
|
* @param code The keycode
|
||||||
|
* @return The corresponding string code
|
||||||
|
*/
|
||||||
public static String convertKeycodeToName(int code){
|
public static String convertKeycodeToName(int code){
|
||||||
String rVal = "";
|
String rVal = "";
|
||||||
switch(code){
|
switch(code){
|
||||||
@ -1667,10 +1806,18 @@ public class ControlHandler {
|
|||||||
return rVal;
|
return rVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether the engine should try to recapture window focus next frame or not
|
||||||
|
* @param shouldRecapture true if should try to recapture next frame, false otherwise
|
||||||
|
*/
|
||||||
public void setRecapture(boolean shouldRecapture){
|
public void setRecapture(boolean shouldRecapture){
|
||||||
this.shouldRecaptureScreen = shouldRecapture;
|
this.shouldRecaptureScreen = shouldRecapture;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the engine should try to recapture window focus next frame or not
|
||||||
|
* @return true if it should try to recapture, false otherwise
|
||||||
|
*/
|
||||||
public boolean shouldRecapture(){
|
public boolean shouldRecapture(){
|
||||||
return this.shouldRecaptureScreen;
|
return this.shouldRecaptureScreen;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,6 +24,7 @@ import electrosphere.client.terrain.cells.VoxelTextureAtlas;
|
|||||||
import electrosphere.client.terrain.manager.ClientTerrainManager;
|
import electrosphere.client.terrain.manager.ClientTerrainManager;
|
||||||
import electrosphere.collision.CollisionEngine;
|
import electrosphere.collision.CollisionEngine;
|
||||||
import electrosphere.collision.CollisionWorldData;
|
import electrosphere.collision.CollisionWorldData;
|
||||||
|
import electrosphere.collision.hitbox.HitboxManager;
|
||||||
import electrosphere.controls.CameraHandler;
|
import electrosphere.controls.CameraHandler;
|
||||||
import electrosphere.controls.ControlCallback;
|
import electrosphere.controls.ControlCallback;
|
||||||
import electrosphere.controls.ControlHandler;
|
import electrosphere.controls.ControlHandler;
|
||||||
@ -37,7 +38,6 @@ import electrosphere.engine.profiler.Profiler;
|
|||||||
import electrosphere.engine.time.Timekeeper;
|
import electrosphere.engine.time.Timekeeper;
|
||||||
import electrosphere.entity.Entity;
|
import electrosphere.entity.Entity;
|
||||||
import electrosphere.entity.Scene;
|
import electrosphere.entity.Scene;
|
||||||
import electrosphere.entity.types.hitbox.HitboxManager;
|
|
||||||
import electrosphere.game.config.UserSettings;
|
import electrosphere.game.config.UserSettings;
|
||||||
import electrosphere.game.data.voxel.VoxelType;
|
import electrosphere.game.data.voxel.VoxelType;
|
||||||
import electrosphere.game.server.structure.virtual.StructureManager;
|
import electrosphere.game.server.structure.virtual.StructureManager;
|
||||||
@ -84,6 +84,11 @@ import electrosphere.util.FileUtils;
|
|||||||
* @author amaterasu
|
* @author amaterasu
|
||||||
*/
|
*/
|
||||||
public class Globals {
|
public class Globals {
|
||||||
|
|
||||||
|
//
|
||||||
|
//Process data
|
||||||
|
//
|
||||||
|
public static String javaPID;
|
||||||
|
|
||||||
//
|
//
|
||||||
//Top level user settings object
|
//Top level user settings object
|
||||||
@ -133,6 +138,7 @@ public class Globals {
|
|||||||
//Client connection to server
|
//Client connection to server
|
||||||
//
|
//
|
||||||
public static ClientNetworking clientConnection;
|
public static ClientNetworking clientConnection;
|
||||||
|
public static boolean RUN_DEMO = false;
|
||||||
public static boolean RUN_CLIENT = true;
|
public static boolean RUN_CLIENT = true;
|
||||||
public static int clientCharacterID;
|
public static int clientCharacterID;
|
||||||
|
|
||||||
@ -302,9 +308,6 @@ public class Globals {
|
|||||||
//script engine
|
//script engine
|
||||||
public static ScriptEngine scriptEngine;
|
public static ScriptEngine scriptEngine;
|
||||||
|
|
||||||
//manages hitboxes
|
|
||||||
public static HitboxManager clientHitboxManager;
|
|
||||||
|
|
||||||
//client scene management
|
//client scene management
|
||||||
public static Scene clientScene;
|
public static Scene clientScene;
|
||||||
public static ClientSceneWrapper clientSceneWrapper;
|
public static ClientSceneWrapper clientSceneWrapper;
|
||||||
@ -442,8 +445,6 @@ public class Globals {
|
|||||||
//script engine
|
//script engine
|
||||||
scriptEngine = new ScriptEngine();
|
scriptEngine = new ScriptEngine();
|
||||||
scriptEngine.init();
|
scriptEngine.init();
|
||||||
//hitbox manager
|
|
||||||
clientHitboxManager = new HitboxManager();
|
|
||||||
//ai manager
|
//ai manager
|
||||||
aiManager = new AIManager();
|
aiManager = new AIManager();
|
||||||
//realm & data cell manager
|
//realm & data cell manager
|
||||||
@ -520,11 +521,13 @@ public class Globals {
|
|||||||
//init fluid shader program
|
//init fluid shader program
|
||||||
FluidChunkModelGeneration.fluidChunkShaderProgram = ShaderProgram.loadSpecificShader("/Shaders/fluid2/fluid2.vs", "/Shaders/fluid2/fluid2.fs");
|
FluidChunkModelGeneration.fluidChunkShaderProgram = ShaderProgram.loadSpecificShader("/Shaders/fluid2/fluid2.vs", "/Shaders/fluid2/fluid2.fs");
|
||||||
//init models
|
//init models
|
||||||
|
assetManager.addModelPathToQueue("Models/basic/geometry/unitsphere.glb");
|
||||||
assetManager.addModelPathToQueue("Models/basic/geometry/unitsphere.fbx");
|
assetManager.addModelPathToQueue("Models/basic/geometry/unitsphere.fbx");
|
||||||
assetManager.addModelPathToQueue("Models/basic/geometry/unitsphere_1.fbx");
|
assetManager.addModelPathToQueue("Models/basic/geometry/unitsphere_1.fbx");
|
||||||
assetManager.addModelPathToQueue("Models/basic/geometry/unitsphere_grey.fbx");
|
assetManager.addModelPathToQueue("Models/basic/geometry/unitsphere_grey.fbx");
|
||||||
assetManager.addModelPathToQueue("Models/basic/geometry/SmallCube.fbx");
|
assetManager.addModelPathToQueue("Models/basic/geometry/SmallCube.fbx");
|
||||||
assetManager.addModelPathToQueue("Models/basic/geometry/unitcylinder.fbx");
|
assetManager.addModelPathToQueue("Models/basic/geometry/unitcylinder.fbx");
|
||||||
|
assetManager.addModelPathToQueue("Models/basic/geometry/unitcapsule.glb");
|
||||||
assetManager.addModelPathToQueue("Models/basic/geometry/unitplane.fbx");
|
assetManager.addModelPathToQueue("Models/basic/geometry/unitplane.fbx");
|
||||||
assetManager.addModelPathToQueue("Models/basic/geometry/unitcube.fbx");
|
assetManager.addModelPathToQueue("Models/basic/geometry/unitcube.fbx");
|
||||||
imagePlaneModelID = assetManager.registerModel(RenderUtils.createPlaneModel("Shaders/plane/plane.vs", "Shaders/plane/plane.fs"));
|
imagePlaneModelID = assetManager.registerModel(RenderUtils.createPlaneModel("Shaders/plane/plane.vs", "Shaders/plane/plane.fs"));
|
||||||
|
|||||||
@ -11,6 +11,7 @@ import org.ode4j.ode.OdeHelper;
|
|||||||
import electrosphere.audio.AudioEngine;
|
import electrosphere.audio.AudioEngine;
|
||||||
import electrosphere.audio.VirtualAudioSourceManager;
|
import electrosphere.audio.VirtualAudioSourceManager;
|
||||||
import electrosphere.controls.ControlHandler;
|
import electrosphere.controls.ControlHandler;
|
||||||
|
import electrosphere.controls.ControlHandler.ControlsState;
|
||||||
import electrosphere.engine.cli.CLIParser;
|
import electrosphere.engine.cli.CLIParser;
|
||||||
import electrosphere.engine.loadingthreads.LoadingThread;
|
import electrosphere.engine.loadingthreads.LoadingThread;
|
||||||
import electrosphere.engine.time.Timekeeper;
|
import electrosphere.engine.time.Timekeeper;
|
||||||
@ -22,7 +23,9 @@ import electrosphere.renderer.RenderingEngine;
|
|||||||
import electrosphere.server.simulation.MacroSimulation;
|
import electrosphere.server.simulation.MacroSimulation;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The main class
|
||||||
|
*/
|
||||||
public class Main {
|
public class Main {
|
||||||
|
|
||||||
|
|
||||||
@ -63,8 +66,8 @@ public class Main {
|
|||||||
//initialize logging interfaces
|
//initialize logging interfaces
|
||||||
LoggerInterface.initLoggers();
|
LoggerInterface.initLoggers();
|
||||||
|
|
||||||
//gets pid of engine
|
//gets java pid of engine
|
||||||
System.out.println(ManagementFactory.getRuntimeMXBean().getName());
|
Globals.javaPID = ManagementFactory.getRuntimeMXBean().getName();
|
||||||
|
|
||||||
//load user settings
|
//load user settings
|
||||||
UserSettings.loadUserSettings();
|
UserSettings.loadUserSettings();
|
||||||
@ -140,6 +143,9 @@ public class Main {
|
|||||||
Globals.initDefaultGraphicalResources();
|
Globals.initDefaultGraphicalResources();
|
||||||
ImGuiWindowMacros.initImGuiWindows();
|
ImGuiWindowMacros.initImGuiWindows();
|
||||||
|
|
||||||
|
//inits the controls state of the control handler
|
||||||
|
Globals.controlHandler.hintUpdateControlState(ControlsState.TITLE_MENU);
|
||||||
|
|
||||||
//start initial asset loading
|
//start initial asset loading
|
||||||
new Thread(Globals.initialAssetLoadingThread).start();
|
new Thread(Globals.initialAssetLoadingThread).start();
|
||||||
}
|
}
|
||||||
@ -186,7 +192,11 @@ public class Main {
|
|||||||
|
|
||||||
//fire off a loading thread for the title menus/screen
|
//fire off a loading thread for the title menus/screen
|
||||||
LoggerInterface.loggerStartup.INFO("Fire off loading thread");
|
LoggerInterface.loggerStartup.INFO("Fire off loading thread");
|
||||||
if(Globals.RUN_CLIENT){
|
if(Globals.RUN_DEMO){
|
||||||
|
LoadingThread serverThread = new LoadingThread(LoadingThread.LOAD_DEMO_MENU);
|
||||||
|
Globals.loadingThreadsList.add(serverThread);
|
||||||
|
serverThread.start();
|
||||||
|
} else if(Globals.RUN_CLIENT){
|
||||||
LoadingThread serverThread = new LoadingThread(LoadingThread.LOAD_TITLE_MENU);
|
LoadingThread serverThread = new LoadingThread(LoadingThread.LOAD_TITLE_MENU);
|
||||||
Globals.loadingThreadsList.add(serverThread);
|
Globals.loadingThreadsList.add(serverThread);
|
||||||
serverThread.start();
|
serverThread.start();
|
||||||
@ -217,10 +227,11 @@ public class Main {
|
|||||||
*/
|
*/
|
||||||
public static void mainLoop(long maxFrames){
|
public static void mainLoop(long maxFrames){
|
||||||
|
|
||||||
double functionTrackTimeStart = 0;
|
|
||||||
//main loop
|
//main loop
|
||||||
while (running) {
|
while (running) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
Globals.profiler.beginRootCpuSample("frame");
|
Globals.profiler.beginRootCpuSample("frame");
|
||||||
LoggerInterface.loggerEngine.DEBUG("Begin Main Loop Frame");
|
LoggerInterface.loggerEngine.DEBUG("Begin Main Loop Frame");
|
||||||
|
|
||||||
@ -396,6 +407,15 @@ public class Main {
|
|||||||
LoggerInterface.loggerEngine.DEBUG("End Main Loop Frame");
|
LoggerInterface.loggerEngine.DEBUG("End Main Loop Frame");
|
||||||
Globals.profiler.endCpuSample();
|
Globals.profiler.endCpuSample();
|
||||||
|
|
||||||
|
} catch (NullPointerException ex){
|
||||||
|
LoggerInterface.loggerEngine.ERROR("Main frame uncaught NPE", ex);
|
||||||
|
//after a while, jvm will stop reporting stack traces with errors
|
||||||
|
//need to explicitly kill the vm if you want to see the stack trace
|
||||||
|
if(Globals.ENGINE_DEBUG){
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LoggerInterface.loggerEngine.WARNING("ENGINE SHUTDOWN");
|
LoggerInterface.loggerEngine.WARNING("ENGINE SHUTDOWN");
|
||||||
|
|||||||
@ -239,13 +239,21 @@ public class AssetManager {
|
|||||||
//
|
//
|
||||||
//Pose Models
|
//Pose Models
|
||||||
//
|
//
|
||||||
|
/**
|
||||||
|
* Adds a pose model to the list of pose models to load
|
||||||
|
* @param path The path to load
|
||||||
|
*/
|
||||||
public void addPoseModelPathToQueue(String path){
|
public void addPoseModelPathToQueue(String path){
|
||||||
if(!poseModelsInQueue.contains(path) && !poseModelsLoadedIntoMemory.containsKey(path)){
|
if(!poseModelsInQueue.contains(path) && !poseModelsLoadedIntoMemory.containsKey(path)){
|
||||||
poseModelsInQueue.add(path);
|
poseModelsInQueue.add(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches a pose model
|
||||||
|
* @param path The path to fetch
|
||||||
|
* @return The pose model if it exists, null otherwise
|
||||||
|
*/
|
||||||
public PoseModel fetchPoseModel(String path){
|
public PoseModel fetchPoseModel(String path){
|
||||||
PoseModel rVal = null;
|
PoseModel rVal = null;
|
||||||
if(poseModelsLoadedIntoMemory.containsKey(path)){
|
if(poseModelsLoadedIntoMemory.containsKey(path)){
|
||||||
|
|||||||
@ -209,7 +209,7 @@ public class ArenaLoading {
|
|||||||
// public void simulate(){
|
// public void simulate(){
|
||||||
// if(i < 100){
|
// if(i < 100){
|
||||||
// i++;
|
// i++;
|
||||||
// CollisionObjUtils.getCollidable(sword).addImpulse(new Impulse(new Vector3d(0,0,1), new Vector3d(-1,0,0), 0.001, Collidable.TYPE_CREATURE));
|
// CollisionObjUtils.getCollidable(sword).addImpulse(new Impulse(MathUtils.ORIGIN_VECTOR, new Vector3d(-1,0,0), 0.001, Collidable.TYPE_CREATURE));
|
||||||
// EntityUtils.getPosition(sword).set(1,0.2f,2);
|
// EntityUtils.getPosition(sword).set(1,0.2f,2);
|
||||||
// }
|
// }
|
||||||
// }});
|
// }});
|
||||||
|
|||||||
@ -38,6 +38,7 @@ import electrosphere.net.NetUtils;
|
|||||||
import electrosphere.net.client.ClientNetworking;
|
import electrosphere.net.client.ClientNetworking;
|
||||||
import electrosphere.renderer.ui.elements.Window;
|
import electrosphere.renderer.ui.elements.Window;
|
||||||
import electrosphere.server.datacell.EntityDataCellMapper;
|
import electrosphere.server.datacell.EntityDataCellMapper;
|
||||||
|
import electrosphere.util.MathUtils;
|
||||||
|
|
||||||
public class ClientLoading {
|
public class ClientLoading {
|
||||||
|
|
||||||
@ -55,7 +56,7 @@ public class ClientLoading {
|
|||||||
WindowUtils.replaceMainMenuContents(MenuGenerators.createEmptyMainMenu());
|
WindowUtils.replaceMainMenuContents(MenuGenerators.createEmptyMainMenu());
|
||||||
loadingWindow.setVisible(true);
|
loadingWindow.setVisible(true);
|
||||||
//disable menu input
|
//disable menu input
|
||||||
Globals.controlHandler.setHandlerState(ControlHandler.ControlsState.NO_INPUT);
|
Globals.controlHandler.hintUpdateControlState(ControlHandler.ControlsState.NO_INPUT);
|
||||||
//initialize the client thread (client)
|
//initialize the client thread (client)
|
||||||
initClientThread();
|
initClientThread();
|
||||||
//while we don't know what races are playable, wait
|
//while we don't know what races are playable, wait
|
||||||
@ -77,7 +78,7 @@ public class ClientLoading {
|
|||||||
//log
|
//log
|
||||||
LoggerInterface.loggerEngine.INFO("[Client]Finished loading character creation menu");
|
LoggerInterface.loggerEngine.INFO("[Client]Finished loading character creation menu");
|
||||||
//set menu controls again
|
//set menu controls again
|
||||||
Globals.controlHandler.setHandlerState(ControlHandler.ControlsState.TITLE_MENU);
|
Globals.controlHandler.hintUpdateControlState(ControlHandler.ControlsState.TITLE_MENU);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -87,7 +88,7 @@ public class ClientLoading {
|
|||||||
WindowUtils.replaceMainMenuContents(MenuGenerators.createEmptyMainMenu());
|
WindowUtils.replaceMainMenuContents(MenuGenerators.createEmptyMainMenu());
|
||||||
loadingWindow.setVisible(true);
|
loadingWindow.setVisible(true);
|
||||||
//disable menu input
|
//disable menu input
|
||||||
Globals.controlHandler.setHandlerState(ControlHandler.ControlsState.NO_INPUT);
|
Globals.controlHandler.hintUpdateControlState(ControlHandler.ControlsState.NO_INPUT);
|
||||||
//initialize the "real" objects simulation
|
//initialize the "real" objects simulation
|
||||||
initClientSimulation();
|
initClientSimulation();
|
||||||
//init foliage manager
|
//init foliage manager
|
||||||
@ -104,8 +105,6 @@ public class ClientLoading {
|
|||||||
setSimulationsToReady();
|
setSimulationsToReady();
|
||||||
//init culling manager and other graphics-focused non-simulation items
|
//init culling manager and other graphics-focused non-simulation items
|
||||||
initEntityCullingManager();
|
initEntityCullingManager();
|
||||||
//hide cursor
|
|
||||||
Globals.controlHandler.hideMouse();
|
|
||||||
//make loading window disappear
|
//make loading window disappear
|
||||||
loadingWindow.setVisible(false);
|
loadingWindow.setVisible(false);
|
||||||
//recapture screen
|
//recapture screen
|
||||||
@ -119,7 +118,7 @@ public class ClientLoading {
|
|||||||
Globals.RENDER_FLAG_RENDER_WHITE_BACKGROUND = false;
|
Globals.RENDER_FLAG_RENDER_WHITE_BACKGROUND = false;
|
||||||
LoggerInterface.loggerEngine.INFO("[Client]Finished loading main game");
|
LoggerInterface.loggerEngine.INFO("[Client]Finished loading main game");
|
||||||
//set controls state
|
//set controls state
|
||||||
Globals.controlHandler.setHandlerState(ControlHandler.ControlsState.MAIN_GAME);
|
Globals.controlHandler.hintUpdateControlState(ControlHandler.ControlsState.MAIN_GAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -177,9 +176,9 @@ public class ClientLoading {
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
if(Globals.controlHandler.cameraIsThirdPerson()){
|
if(Globals.controlHandler.cameraIsThirdPerson()){
|
||||||
Globals.playerCamera = CameraEntityUtils.spawnPlayerEntityTrackingCameraEntity(new Vector3f(1,0,1), new Vector3f(0,0,1));
|
Globals.playerCamera = CameraEntityUtils.spawnPlayerEntityTrackingCameraEntity(new Vector3f(1,0,1), MathUtils.getOriginVectorf());
|
||||||
} else {
|
} else {
|
||||||
Globals.playerCamera = CameraEntityUtils.spawnPlayerEntityTrackingCameraFirstPersonEntity(new Vector3f(1,0,1), new Vector3f(0,0,1));
|
Globals.playerCamera = CameraEntityUtils.spawnPlayerEntityTrackingCameraFirstPersonEntity(new Vector3f(1,0,1), MathUtils.getOriginVectorf());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,31 @@
|
|||||||
|
package electrosphere.engine.loadingthreads;
|
||||||
|
|
||||||
|
import electrosphere.engine.Globals;
|
||||||
|
import electrosphere.menu.WindowStrings;
|
||||||
|
import electrosphere.menu.WindowUtils;
|
||||||
|
import electrosphere.menu.mainmenu.MenuGeneratorsDemo;
|
||||||
|
import electrosphere.renderer.ui.elements.Window;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loading routines for the demo version of the game
|
||||||
|
*/
|
||||||
|
public class DemoLoading {
|
||||||
|
|
||||||
|
//the name of the save for the demo version of the game
|
||||||
|
public static final String DEMO_LEVEL_PATH = "demo";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the title menu elements for the demo version of the engine
|
||||||
|
*/
|
||||||
|
public static void loadDemoMenu(){
|
||||||
|
Globals.currentSaveName = DEMO_LEVEL_PATH;
|
||||||
|
|
||||||
|
WindowUtils.replaceMainMenuContents(MenuGeneratorsDemo.createTitleMenu());
|
||||||
|
|
||||||
|
Window loadingWindow = (Window)Globals.elementManager.getWindow(WindowStrings.WINDOW_LOADING);
|
||||||
|
WindowUtils.recursiveSetVisible(loadingWindow,false);
|
||||||
|
WindowUtils.focusWindow(WindowStrings.WINDOW_MENU_MAIN);
|
||||||
|
WindowUtils.recursiveSetVisible(Globals.elementManager.getWindow(WindowStrings.WINDOW_MENU_MAIN), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -3,24 +3,30 @@ package electrosphere.engine.loadingthreads;
|
|||||||
import java.util.concurrent.Semaphore;
|
import java.util.concurrent.Semaphore;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Threads for loading engine state
|
||||||
* @author amaterasu
|
|
||||||
*/
|
*/
|
||||||
public class LoadingThread extends Thread {
|
public class LoadingThread extends Thread {
|
||||||
|
|
||||||
public static final int LOAD_TITLE_MENU = 0;
|
public static final int LOAD_TITLE_MENU = 0; //loads the main game title menu
|
||||||
public static final int LOAD_MAIN_GAME = 1;
|
public static final int LOAD_MAIN_GAME = 1; //loads the main game
|
||||||
public static final int LOAD_ARENA = 2;
|
public static final int LOAD_ARENA = 2; //loads the arena
|
||||||
public static final int LOAD_CHARACTER_SERVER = 3;
|
public static final int LOAD_CHARACTER_SERVER = 3; //loads the character creation menus on the client
|
||||||
public static final int LOAD_CLIENT_WORLD = 4;
|
public static final int LOAD_CLIENT_WORLD = 4; //loads the client world
|
||||||
public static final int LOAD_DEBUG_RANDOM_SP_WORLD = 5;
|
public static final int LOAD_DEBUG_RANDOM_SP_WORLD = 5; //loads a random singleplayer debug world
|
||||||
public static final int LOAD_LEVEL_EDITOR = 6;
|
public static final int LOAD_LEVEL_EDITOR = 6; //loads the level editor
|
||||||
public static final int LOAD_LEVEL = 7;
|
public static final int LOAD_LEVEL = 7; //loads a level
|
||||||
|
public static final int LOAD_DEMO_MENU = 8; //loads the main menu ui for the demo version of the client
|
||||||
|
|
||||||
|
//the type of loading to do
|
||||||
int threadType;
|
int threadType;
|
||||||
|
|
||||||
|
//a lock to track when the loading had completed and block until then
|
||||||
Semaphore lock;
|
Semaphore lock;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the work for a loading thread
|
||||||
|
* @param type The type of thread
|
||||||
|
*/
|
||||||
public LoadingThread(int type){
|
public LoadingThread(int type){
|
||||||
threadType = type;
|
threadType = type;
|
||||||
lock = new Semaphore(1);
|
lock = new Semaphore(1);
|
||||||
@ -52,7 +58,7 @@ public class LoadingThread extends Thread {
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
|
||||||
//intended to act like you went through the steps of setting up a vanilla settings SP world
|
//intended to act like you went through the steps of setting up a vanilla settings SP world
|
||||||
case LOAD_DEBUG_RANDOM_SP_WORLD: {
|
case LOAD_DEBUG_RANDOM_SP_WORLD: {
|
||||||
DebugSPWorldLoading.loadDebugSPWorld();
|
DebugSPWorldLoading.loadDebugSPWorld();
|
||||||
} break;
|
} break;
|
||||||
@ -66,12 +72,20 @@ public class LoadingThread extends Thread {
|
|||||||
case LOAD_LEVEL: {
|
case LOAD_LEVEL: {
|
||||||
LevelLoading.loadLevel();
|
LevelLoading.loadLevel();
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
//the demo menu ui
|
||||||
|
case LOAD_DEMO_MENU: {
|
||||||
|
DemoLoading.loadDemoMenu();
|
||||||
|
} break;
|
||||||
|
|
||||||
}
|
}
|
||||||
lock.release();
|
lock.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the thread has finished loading
|
||||||
|
* @return true if it has finished, false otherwise
|
||||||
|
*/
|
||||||
public boolean isDone(){
|
public boolean isDone(){
|
||||||
boolean rVal = lock.tryAcquire();
|
boolean rVal = lock.tryAcquire();
|
||||||
if(rVal == true){
|
if(rVal == true){
|
||||||
|
|||||||
@ -198,8 +198,15 @@ public class LoadingUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads graphics assets necessary for the client of the game engine. This should be stuff that is used essentially universally (ie textures for debugging).
|
||||||
|
*/
|
||||||
static void initGameGraphicalEntities(){
|
static void initGameGraphicalEntities(){
|
||||||
|
|
||||||
|
Globals.assetManager.addTexturePathtoQueue("Textures/transparent_red.png");
|
||||||
|
Globals.assetManager.addTexturePathtoQueue("Textures/transparent_blue.png");
|
||||||
|
Globals.assetManager.addTexturePathtoQueue("Textures/transparent_grey.png");
|
||||||
|
|
||||||
|
|
||||||
float skyR = 100;
|
float skyR = 100;
|
||||||
float skyG = 150;
|
float skyG = 150;
|
||||||
|
|||||||
@ -36,6 +36,9 @@ public class Timekeeper {
|
|||||||
//the maximum number of simulation frames that can happen in a row before the main loop immediately skips more
|
//the maximum number of simulation frames that can happen in a row before the main loop immediately skips more
|
||||||
public static final int SIM_FRAME_HARDCAP = 3;
|
public static final int SIM_FRAME_HARDCAP = 3;
|
||||||
|
|
||||||
|
//step interval time size (for physics)
|
||||||
|
public static final float ENGINE_STEP_SIZE = 0.01f;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -135,4 +138,13 @@ public class Timekeeper {
|
|||||||
return currentTime;
|
return currentTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The number of frames we're simulating this cycle
|
||||||
|
* @return The number of frames we're simulating this cycle
|
||||||
|
*/
|
||||||
|
public long getDeltaFrames(){
|
||||||
|
//this should always return 1. We're always simulating 1 frame per run of the loop in main
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,18 +1,17 @@
|
|||||||
package electrosphere.entity;
|
package electrosphere.entity;
|
||||||
|
|
||||||
import org.joml.Quaterniond;
|
import org.joml.Quaterniond;
|
||||||
import org.joml.Quaternionf;
|
|
||||||
import org.joml.Vector3d;
|
import org.joml.Vector3d;
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
|
|
||||||
import electrosphere.engine.Globals;
|
import electrosphere.engine.Globals;
|
||||||
import electrosphere.renderer.actor.ActorUtils;
|
import electrosphere.renderer.actor.ActorUtils;
|
||||||
import electrosphere.renderer.actor.instance.InstancedActor;
|
|
||||||
import electrosphere.server.datacell.Realm;
|
import electrosphere.server.datacell.Realm;
|
||||||
import electrosphere.server.datacell.ServerDataCell;
|
import electrosphere.server.datacell.ServerDataCell;
|
||||||
import electrosphere.server.datacell.utils.EntityLookupUtils;
|
import electrosphere.server.datacell.utils.EntityLookupUtils;
|
||||||
import electrosphere.server.datacell.utils.ServerBehaviorTreeUtils;
|
import electrosphere.server.datacell.utils.ServerBehaviorTreeUtils;
|
||||||
import electrosphere.server.poseactor.PoseActor;
|
import electrosphere.server.datacell.utils.ServerEntityTagUtils;
|
||||||
|
import electrosphere.server.poseactor.PoseActorUtils;
|
||||||
|
|
||||||
public class EntityCreationUtils {
|
public class EntityCreationUtils {
|
||||||
|
|
||||||
@ -82,12 +81,13 @@ public class EntityCreationUtils {
|
|||||||
* @param modelPath The model path for the model to back the pose actor
|
* @param modelPath The model path for the model to back the pose actor
|
||||||
*/
|
*/
|
||||||
public static void makeEntityPoseable(Entity entity, String modelPath){
|
public static void makeEntityPoseable(Entity entity, String modelPath){
|
||||||
entity.putData(EntityDataStrings.POSE_ACTOR, new PoseActor(modelPath));
|
entity.putData(EntityDataStrings.POSE_ACTOR, PoseActorUtils.createPoseActorFromModelPath(modelPath));
|
||||||
entity.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
|
entity.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
|
||||||
entity.putData(EntityDataStrings.DATA_STRING_ROTATION, new Quaterniond().identity());
|
entity.putData(EntityDataStrings.DATA_STRING_ROTATION, new Quaterniond().identity());
|
||||||
entity.putData(EntityDataStrings.DATA_STRING_SCALE, new Vector3f(1,1,1));
|
entity.putData(EntityDataStrings.DATA_STRING_SCALE, new Vector3f(1,1,1));
|
||||||
entity.putData(EntityDataStrings.DATA_STRING_DRAW, true);
|
entity.putData(EntityDataStrings.DATA_STRING_DRAW, true);
|
||||||
entity.putData(EntityDataStrings.DRAW_SOLID_PASS, true);
|
entity.putData(EntityDataStrings.DRAW_SOLID_PASS, true);
|
||||||
|
ServerEntityTagUtils.attachTagToEntity(entity, EntityTags.POSEABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -103,7 +103,6 @@ public class EntityCreationUtils {
|
|||||||
entity.putData(EntityDataStrings.DATA_STRING_SCALE, new Vector3f(1,1,1));
|
entity.putData(EntityDataStrings.DATA_STRING_SCALE, new Vector3f(1,1,1));
|
||||||
entity.putData(EntityDataStrings.DATA_STRING_DRAW, true);
|
entity.putData(EntityDataStrings.DATA_STRING_DRAW, true);
|
||||||
entity.putData(EntityDataStrings.DRAW_SOLID_PASS, true);
|
entity.putData(EntityDataStrings.DRAW_SOLID_PASS, true);
|
||||||
Globals.clientScene.registerEntity(entity);
|
|
||||||
Globals.clientScene.registerEntityToTag(entity, EntityTags.DRAWABLE);
|
Globals.clientScene.registerEntityToTag(entity, EntityTags.DRAWABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,7 +118,6 @@ public class EntityCreationUtils {
|
|||||||
entity.putData(EntityDataStrings.DATA_STRING_SCALE, new Vector3f(1,1,1));
|
entity.putData(EntityDataStrings.DATA_STRING_SCALE, new Vector3f(1,1,1));
|
||||||
entity.putData(EntityDataStrings.DATA_STRING_DRAW, true);
|
entity.putData(EntityDataStrings.DATA_STRING_DRAW, true);
|
||||||
entity.putData(EntityDataStrings.DRAW_SOLID_PASS, true);
|
entity.putData(EntityDataStrings.DRAW_SOLID_PASS, true);
|
||||||
Globals.clientScene.registerEntity(entity);
|
|
||||||
Globals.clientScene.registerEntityToTag(entity, EntityTags.DRAWABLE);
|
Globals.clientScene.registerEntityToTag(entity, EntityTags.DRAWABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -256,7 +256,6 @@ public class EntityDataStrings {
|
|||||||
/*
|
/*
|
||||||
Equip state
|
Equip state
|
||||||
*/
|
*/
|
||||||
public static final String EQUIP_STATE = "equipState";
|
|
||||||
public static final String TREE_CLIENTEQUIPSTATE = "treeClientEquipState";
|
public static final String TREE_CLIENTEQUIPSTATE = "treeClientEquipState";
|
||||||
public static final String EQUIP_INVENTORY = "equipInventory";
|
public static final String EQUIP_INVENTORY = "equipInventory";
|
||||||
public static final String TREE_SERVEREQUIPSTATE = "treeServerEquipState";
|
public static final String TREE_SERVEREQUIPSTATE = "treeServerEquipState";
|
||||||
@ -282,6 +281,11 @@ public class EntityDataStrings {
|
|||||||
* Pose actor
|
* Pose actor
|
||||||
*/
|
*/
|
||||||
public static final String POSE_ACTOR = "poseActor";
|
public static final String POSE_ACTOR = "poseActor";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Server-specific btrees
|
||||||
|
*/
|
||||||
|
public static final String TREE_SERVERPLAYERVIEWDIR = "treeServerPlayerViewDir";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Entity categories
|
Entity categories
|
||||||
|
|||||||
@ -19,6 +19,7 @@ public class EntityTags {
|
|||||||
public static final String DRAWABLE = "drawable"; //is it drawable
|
public static final String DRAWABLE = "drawable"; //is it drawable
|
||||||
public static final String DRAW_INSTANCED = "drawInstanced"; //if it's instanced, but not necessarily managed by a service (ie a tree branch)
|
public static final String DRAW_INSTANCED = "drawInstanced"; //if it's instanced, but not necessarily managed by a service (ie a tree branch)
|
||||||
public static final String DRAW_INSTANCED_MANAGED = "drawInstancedManaged"; //if it's managed by a service (ie foliage manager)
|
public static final String DRAW_INSTANCED_MANAGED = "drawInstancedManaged"; //if it's managed by a service (ie foliage manager)
|
||||||
|
public static final String POSEABLE = "poseable"; //is it poseable on server
|
||||||
public static final String LIGHT = "light";
|
public static final String LIGHT = "light";
|
||||||
public static final String ITEM = "item";
|
public static final String ITEM = "item";
|
||||||
public static final String GRAVITY = "gravity";
|
public static final String GRAVITY = "gravity";
|
||||||
|
|||||||
@ -1,32 +1,21 @@
|
|||||||
/*
|
|
||||||
* To change this license header, choose License Headers in Project Properties.
|
|
||||||
* To change this template file, choose Tools | Templates
|
|
||||||
* and open the template in the editor.
|
|
||||||
*/
|
|
||||||
package electrosphere.entity;
|
package electrosphere.entity;
|
||||||
|
|
||||||
import electrosphere.engine.Globals;
|
import electrosphere.engine.Globals;
|
||||||
import electrosphere.entity.state.movement.groundmove.ClientGroundMovementTree;
|
|
||||||
import electrosphere.entity.types.collision.CollisionObjUtils;
|
|
||||||
import electrosphere.entity.types.creature.CreatureUtils;
|
|
||||||
import electrosphere.entity.types.item.ItemUtils;
|
|
||||||
import electrosphere.renderer.actor.Actor;
|
import electrosphere.renderer.actor.Actor;
|
||||||
import electrosphere.renderer.actor.ActorUtils;
|
import electrosphere.renderer.actor.ActorUtils;
|
||||||
import electrosphere.renderer.model.Model;
|
|
||||||
import electrosphere.server.datacell.Realm;
|
import electrosphere.server.datacell.Realm;
|
||||||
import electrosphere.server.datacell.ServerDataCell;
|
import electrosphere.server.datacell.ServerDataCell;
|
||||||
import electrosphere.server.datacell.utils.DataCellSearchUtils;
|
|
||||||
import electrosphere.server.datacell.utils.EntityLookupUtils;
|
import electrosphere.server.datacell.utils.EntityLookupUtils;
|
||||||
import electrosphere.server.poseactor.PoseActor;
|
import electrosphere.server.poseactor.PoseActor;
|
||||||
|
import electrosphere.server.poseactor.PoseActorUtils;
|
||||||
|
import electrosphere.util.MathUtils;
|
||||||
|
|
||||||
import org.joml.Quaterniond;
|
import org.joml.Quaterniond;
|
||||||
import org.joml.Quaternionf;
|
|
||||||
import org.joml.Vector3d;
|
import org.joml.Vector3d;
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Utilties for dealing with entities
|
||||||
* @author amaterasu
|
|
||||||
*/
|
*/
|
||||||
public class EntityUtils {
|
public class EntityUtils {
|
||||||
|
|
||||||
@ -74,7 +63,7 @@ public class EntityUtils {
|
|||||||
Entity rVal = new Entity();
|
Entity rVal = new Entity();
|
||||||
rVal.putData(EntityDataStrings.DATA_STRING_ACTOR, ActorUtils.createActorOfLoadingModel(modelPath));
|
rVal.putData(EntityDataStrings.DATA_STRING_ACTOR, ActorUtils.createActorOfLoadingModel(modelPath));
|
||||||
rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
|
rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
|
||||||
rVal.putData(EntityDataStrings.DATA_STRING_ROTATION, new Quaterniond().rotateAxis(0, new Vector3d(1,0,0)));
|
rVal.putData(EntityDataStrings.DATA_STRING_ROTATION, new Quaterniond().rotateAxis(0, MathUtils.getOriginVector()));
|
||||||
rVal.putData(EntityDataStrings.DATA_STRING_SCALE, new Vector3f(1,1,1));
|
rVal.putData(EntityDataStrings.DATA_STRING_SCALE, new Vector3f(1,1,1));
|
||||||
rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true);
|
rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true);
|
||||||
rVal.putData(EntityDataStrings.DRAW_SOLID_PASS, true);
|
rVal.putData(EntityDataStrings.DRAW_SOLID_PASS, true);
|
||||||
@ -90,7 +79,7 @@ public class EntityUtils {
|
|||||||
*/
|
*/
|
||||||
protected static Entity spawnPoseableEntity(String modelPath){
|
protected static Entity spawnPoseableEntity(String modelPath){
|
||||||
Entity rVal = new Entity();
|
Entity rVal = new Entity();
|
||||||
rVal.putData(EntityDataStrings.POSE_ACTOR, new PoseActor(modelPath));
|
rVal.putData(EntityDataStrings.POSE_ACTOR, PoseActorUtils.createPoseActorFromModelPath(modelPath));
|
||||||
// rVal.putData(EntityDataStrings.DATA_STRING_MODEL_PATH, modelPath);
|
// rVal.putData(EntityDataStrings.DATA_STRING_MODEL_PATH, modelPath);
|
||||||
rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
|
rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
|
||||||
rVal.putData(EntityDataStrings.DATA_STRING_ROTATION, new Quaterniond().identity());
|
rVal.putData(EntityDataStrings.DATA_STRING_ROTATION, new Quaterniond().identity());
|
||||||
@ -104,7 +93,7 @@ public class EntityUtils {
|
|||||||
Entity rVal = new Entity();
|
Entity rVal = new Entity();
|
||||||
rVal.putData(EntityDataStrings.DATA_STRING_ACTOR, ActorUtils.createActorFromModelPath(modelPath));
|
rVal.putData(EntityDataStrings.DATA_STRING_ACTOR, ActorUtils.createActorFromModelPath(modelPath));
|
||||||
rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
|
rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
|
||||||
rVal.putData(EntityDataStrings.DATA_STRING_ROTATION, new Quaterniond().rotateAxis(0, new Vector3d(1,0,0)));
|
rVal.putData(EntityDataStrings.DATA_STRING_ROTATION, new Quaterniond().rotateAxis(0, MathUtils.getOriginVector()));
|
||||||
rVal.putData(EntityDataStrings.DATA_STRING_SCALE, new Vector3f(1,1,1));
|
rVal.putData(EntityDataStrings.DATA_STRING_SCALE, new Vector3f(1,1,1));
|
||||||
rVal.putData(EntityDataStrings.DATA_STRING_UI_ELEMENT, true);
|
rVal.putData(EntityDataStrings.DATA_STRING_UI_ELEMENT, true);
|
||||||
Globals.clientScene.registerEntity(rVal);
|
Globals.clientScene.registerEntity(rVal);
|
||||||
|
|||||||
@ -3,44 +3,31 @@ package electrosphere.entity.state.attack;
|
|||||||
|
|
||||||
import electrosphere.net.synchronization.BehaviorTreeIdEnums;
|
import electrosphere.net.synchronization.BehaviorTreeIdEnums;
|
||||||
|
|
||||||
import electrosphere.collision.collidable.Collidable;
|
|
||||||
import electrosphere.engine.Globals;
|
import electrosphere.engine.Globals;
|
||||||
import electrosphere.engine.Main;
|
|
||||||
import electrosphere.entity.Entity;
|
import electrosphere.entity.Entity;
|
||||||
import electrosphere.entity.EntityDataStrings;
|
import electrosphere.entity.EntityDataStrings;
|
||||||
import electrosphere.entity.EntityUtils;
|
import electrosphere.entity.EntityUtils;
|
||||||
import electrosphere.entity.ServerEntityUtils;
|
|
||||||
import electrosphere.entity.btree.BehaviorTree;
|
import electrosphere.entity.btree.BehaviorTree;
|
||||||
import electrosphere.entity.state.client.firstPerson.FirstPersonTree;
|
import electrosphere.entity.state.client.firstPerson.FirstPersonTree;
|
||||||
import electrosphere.entity.state.collidable.Impulse;
|
import electrosphere.entity.state.collidable.Impulse;
|
||||||
import electrosphere.entity.state.equip.ClientEquipState;
|
import electrosphere.entity.state.equip.ClientEquipState;
|
||||||
import electrosphere.entity.state.movement.groundmove.ClientGroundMovementTree;
|
import electrosphere.entity.state.hitbox.HitboxCollectionState;
|
||||||
import electrosphere.entity.state.rotator.RotatorTree;
|
import electrosphere.entity.state.rotator.RotatorTree;
|
||||||
import electrosphere.entity.types.attach.AttachUtils;
|
import electrosphere.entity.types.attach.AttachUtils;
|
||||||
import electrosphere.entity.types.collision.CollisionObjUtils;
|
import electrosphere.entity.types.collision.CollisionObjUtils;
|
||||||
import electrosphere.entity.types.creature.CreatureUtils;
|
import electrosphere.entity.types.creature.CreatureUtils;
|
||||||
import electrosphere.entity.types.hitbox.HitboxUtils;
|
|
||||||
import electrosphere.entity.types.item.ItemUtils;
|
import electrosphere.entity.types.item.ItemUtils;
|
||||||
import electrosphere.entity.types.projectile.ProjectileUtils;
|
|
||||||
import electrosphere.game.data.creature.type.attack.AttackMove;
|
import electrosphere.game.data.creature.type.attack.AttackMove;
|
||||||
import electrosphere.game.data.creature.type.equip.EquipPoint;
|
|
||||||
import electrosphere.net.parser.net.message.EntityMessage;
|
import electrosphere.net.parser.net.message.EntityMessage;
|
||||||
import electrosphere.net.synchronization.annotation.SyncedField;
|
import electrosphere.net.synchronization.annotation.SyncedField;
|
||||||
import electrosphere.net.synchronization.annotation.SynchronizableEnum;
|
import electrosphere.net.synchronization.annotation.SynchronizableEnum;
|
||||||
import electrosphere.net.synchronization.annotation.SynchronizedBehaviorTree;
|
import electrosphere.net.synchronization.annotation.SynchronizedBehaviorTree;
|
||||||
import electrosphere.renderer.actor.Actor;
|
import electrosphere.renderer.actor.Actor;
|
||||||
import electrosphere.renderer.anim.Animation;
|
|
||||||
import electrosphere.server.datacell.Realm;
|
|
||||||
import electrosphere.server.datacell.utils.EntityLookupUtils;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
import org.joml.Quaterniond;
|
|
||||||
import org.joml.Quaternionf;
|
|
||||||
import org.joml.Quaternionfc;
|
|
||||||
import org.joml.Vector3d;
|
import org.joml.Vector3d;
|
||||||
import org.joml.Vector3f;
|
|
||||||
|
|
||||||
@SynchronizedBehaviorTree(name = "clientAttackTree", isServer = false, correspondingTree="serverAttackTree")
|
@SynchronizedBehaviorTree(name = "clientAttackTree", isServer = false, correspondingTree="serverAttackTree")
|
||||||
/**
|
/**
|
||||||
@ -108,8 +95,8 @@ public class ClientAttackTree implements BehaviorTree {
|
|||||||
String attackingPoint = null;
|
String attackingPoint = null;
|
||||||
|
|
||||||
public ClientAttackTree(Entity e){
|
public ClientAttackTree(Entity e){
|
||||||
state = AttackTreeState.IDLE;
|
setState(AttackTreeState.IDLE);
|
||||||
driftState = AttackTreeDriftState.NO_DRIFT;
|
setDriftState(AttackTreeDriftState.NO_DRIFT);
|
||||||
parent = e;
|
parent = e;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,6 +110,9 @@ public class ClientAttackTree implements BehaviorTree {
|
|||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts an attack
|
||||||
|
*/
|
||||||
public void start(){
|
public void start(){
|
||||||
currentMoveCanHold = false;
|
currentMoveCanHold = false;
|
||||||
currentMoveHasWindup = false;
|
currentMoveHasWindup = false;
|
||||||
@ -135,8 +125,8 @@ public class ClientAttackTree implements BehaviorTree {
|
|||||||
String attackType = getAttackType();
|
String attackType = getAttackType();
|
||||||
//if we can attack, setup doing so
|
//if we can attack, setup doing so
|
||||||
if(canAttack(attackType)){
|
if(canAttack(attackType)){
|
||||||
parent.putData(EntityDataStrings.ATTACK_MOVE_TYPE_ACTIVE, attackType);
|
setAttackMoveTypeActive(attackType);
|
||||||
currentMoveset = (List<AttackMove>)parent.getData(attackType);
|
currentMoveset = getMoveset(attackType);
|
||||||
if(currentMoveset != null){
|
if(currentMoveset != null){
|
||||||
Globals.clientConnection.queueOutgoingMessage(EntityMessage.constructstartAttackMessage());
|
Globals.clientConnection.queueOutgoingMessage(EntityMessage.constructstartAttackMessage());
|
||||||
}
|
}
|
||||||
@ -148,23 +138,30 @@ public class ClientAttackTree implements BehaviorTree {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void interrupt(){
|
public void interrupt(){
|
||||||
state = AttackTreeState.IDLE;
|
setState(AttackTreeState.IDLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void slowdown(){
|
public void slowdown(){
|
||||||
state = AttackTreeState.COOLDOWN;
|
setState(AttackTreeState.COOLDOWN);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void simulate(float deltaTime){
|
public void simulate(float deltaTime){
|
||||||
frameCurrent = frameCurrent + (float)Globals.timekeeper.getSimFrameTime();
|
frameCurrent = frameCurrent + (float)Globals.timekeeper.getDeltaFrames();
|
||||||
float velocity = CreatureUtils.getVelocity(parent);
|
|
||||||
Actor entityActor = EntityUtils.getActor(parent);
|
Actor entityActor = EntityUtils.getActor(parent);
|
||||||
Vector3d position = EntityUtils.getPosition(parent);
|
|
||||||
Vector3d movementVector = CreatureUtils.getFacingVector(parent);
|
Vector3d movementVector = CreatureUtils.getFacingVector(parent);
|
||||||
|
|
||||||
|
//
|
||||||
//synchronize move from server
|
//synchronize move from server
|
||||||
if(this.currentMove == null && this.currentMoveId != null){
|
if(this.currentMoveset == null){
|
||||||
|
this.currentMoveset = getMoveset(getAttackType());
|
||||||
|
}
|
||||||
|
if(
|
||||||
|
this.currentMoveset != null &&
|
||||||
|
(this.currentMove == null && this.currentMoveId != null)
|
||||||
|
||
|
||||||
|
(this.currentMove != null && this.currentMove.getAttackMoveId() != this.currentMoveId)
|
||||||
|
){
|
||||||
for(AttackMove move : currentMoveset){
|
for(AttackMove move : currentMoveset){
|
||||||
if(move.getAttackMoveId().equals(currentMoveId)){
|
if(move.getAttackMoveId().equals(currentMoveId)){
|
||||||
currentMove = move;
|
currentMove = move;
|
||||||
@ -172,6 +169,7 @@ public class ClientAttackTree implements BehaviorTree {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
//parse attached network messages
|
//parse attached network messages
|
||||||
for(EntityMessage message : networkMessageQueue){
|
for(EntityMessage message : networkMessageQueue){
|
||||||
networkMessageQueue.remove(message);
|
networkMessageQueue.remove(message);
|
||||||
@ -183,23 +181,23 @@ public class ClientAttackTree implements BehaviorTree {
|
|||||||
lastUpdateTime = updateTime;
|
lastUpdateTime = updateTime;
|
||||||
switch(message.gettreeState()){
|
switch(message.gettreeState()){
|
||||||
case 0:
|
case 0:
|
||||||
state = AttackTreeState.WINDUP;
|
setState(AttackTreeState.WINDUP);
|
||||||
frameCurrent = 0;
|
frameCurrent = 0;
|
||||||
// System.out.println("Set state STARTUP");
|
// System.out.println("Set state STARTUP");
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
frameCurrent = currentMove.getWindupFrames()+1;
|
frameCurrent = currentMove.getWindupFrames()+1;
|
||||||
state = AttackTreeState.ATTACK;
|
setState(AttackTreeState.ATTACK);
|
||||||
// System.out.println("Set state MOVE");
|
// System.out.println("Set state MOVE");
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
frameCurrent = currentMove.getWindupFrames()+currentMove.getAttackFrames()+1;
|
frameCurrent = currentMove.getWindupFrames()+currentMove.getAttackFrames()+1;
|
||||||
state = AttackTreeState.COOLDOWN;
|
setState(AttackTreeState.COOLDOWN);
|
||||||
// System.out.println("Set state SLOWDOWN");
|
// System.out.println("Set state SLOWDOWN");
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
frameCurrent = 60;
|
frameCurrent = 60;
|
||||||
state = AttackTreeState.IDLE;
|
setState(AttackTreeState.IDLE);
|
||||||
// System.out.println("Set state IDLE");
|
// System.out.println("Set state IDLE");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -207,17 +205,7 @@ public class ClientAttackTree implements BehaviorTree {
|
|||||||
EntityUtils.getPosition(parent).set(message.getpositionX(),message.getpositionY(),message.getpositionZ());
|
EntityUtils.getPosition(parent).set(message.getpositionX(),message.getpositionY(),message.getpositionZ());
|
||||||
CreatureUtils.setFacingVector(parent, new Vector3d(message.getrotationX(),message.getrotationY(),message.getrotationZ()));
|
CreatureUtils.setFacingVector(parent, new Vector3d(message.getrotationX(),message.getrotationY(),message.getrotationZ()));
|
||||||
break;
|
break;
|
||||||
case ATTACHENTITYTOENTITY:
|
default:
|
||||||
case CREATE:
|
|
||||||
case DESTROY:
|
|
||||||
case MOVE:
|
|
||||||
case MOVEUPDATE:
|
|
||||||
case SETBEHAVIORTREE:
|
|
||||||
case SETFACING:
|
|
||||||
case SETPOSITION:
|
|
||||||
case SETPROPERTY:
|
|
||||||
case KILL:
|
|
||||||
case SPAWNCREATURE:
|
|
||||||
//silently ignore
|
//silently ignore
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -230,30 +218,26 @@ public class ClientAttackTree implements BehaviorTree {
|
|||||||
//calculate the vector of movement
|
//calculate the vector of movement
|
||||||
CollisionObjUtils.getCollidable(parent).addImpulse(new Impulse(new Vector3d(movementVector), new Vector3d(0,0,0), new Vector3d(0,0,0), currentMove.getDriftGoal() * Globals.timekeeper.getSimFrameTime(), "movement"));
|
CollisionObjUtils.getCollidable(parent).addImpulse(new Impulse(new Vector3d(movementVector), new Vector3d(0,0,0), new Vector3d(0,0,0), currentMove.getDriftGoal() * Globals.timekeeper.getSimFrameTime(), "movement"));
|
||||||
if(frameCurrent > currentMove.getDriftFrameEnd()){
|
if(frameCurrent > currentMove.getDriftFrameEnd()){
|
||||||
driftState = AttackTreeDriftState.NO_DRIFT;
|
setDriftState(AttackTreeDriftState.NO_DRIFT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NO_DRIFT:
|
case NO_DRIFT:
|
||||||
if(currentMove != null){
|
if(currentMove != null){
|
||||||
if(frameCurrent > currentMove.getDriftFrameStart() && frameCurrent < currentMove.getDriftFrameEnd()){
|
if(frameCurrent > currentMove.getDriftFrameStart() && frameCurrent < currentMove.getDriftFrameEnd()){
|
||||||
driftState = AttackTreeDriftState.DRIFT;
|
setDriftState(AttackTreeDriftState.DRIFT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if(state != AttackTreeState.IDLE){
|
|
||||||
// System.out.println(frameCurrent);
|
|
||||||
// }
|
|
||||||
|
|
||||||
//state machine
|
//state machine
|
||||||
switch(state){
|
switch(state){
|
||||||
case WINDUP:
|
case WINDUP: {
|
||||||
if(parent.containsKey(EntityDataStrings.CLIENT_ROTATOR_TREE)){
|
if(parent.containsKey(EntityDataStrings.CLIENT_ROTATOR_TREE)){
|
||||||
RotatorTree.getClientRotatorTree(parent).setActive(true);
|
RotatorTree.getClientRotatorTree(parent).setActive(true);
|
||||||
}
|
}
|
||||||
if(currentMove != null && frameCurrent > currentMove.getWindupFrames()){
|
if(currentMove != null){
|
||||||
if(entityActor != null){
|
if(entityActor != null){
|
||||||
if(!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(currentMove.getWindupAnimationName())){
|
if(!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(currentMove.getWindupAnimationName())){
|
||||||
entityActor.playAnimation(currentMove.getWindupAnimationName(),1);
|
entityActor.playAnimation(currentMove.getWindupAnimationName(),1);
|
||||||
@ -261,98 +245,54 @@ public class ClientAttackTree implements BehaviorTree {
|
|||||||
}
|
}
|
||||||
FirstPersonTree.conditionallyPlayAnimation(Globals.firstPersonEntity, currentMove.getAnimationFirstPersonWindup().getName());
|
FirstPersonTree.conditionallyPlayAnimation(Globals.firstPersonEntity, currentMove.getAnimationFirstPersonWindup().getName());
|
||||||
}
|
}
|
||||||
if(currentMoveCanHold && stillHold){
|
}
|
||||||
state = AttackTreeState.HOLD;
|
} break;
|
||||||
} else {
|
case HOLD: {
|
||||||
state = AttackTreeState.ATTACK;
|
if(entityActor != null){
|
||||||
|
if(!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(currentMove.getHoldAnimationName())){
|
||||||
|
entityActor.playAnimation(currentMove.getHoldAnimationName(),1);
|
||||||
|
entityActor.incrementAnimationTime(0.0001);
|
||||||
|
}
|
||||||
|
FirstPersonTree.conditionallyPlayAnimation(Globals.firstPersonEntity, currentMove.getAnimationFirstPersonHold().getName());
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
case ATTACK: {
|
||||||
|
if(entityActor != null && currentMove != null){
|
||||||
|
if(!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(currentMove.getAttackAnimationName())){
|
||||||
|
entityActor.playAnimation(currentMove.getAttackAnimationName(),1);
|
||||||
|
entityActor.incrementAnimationTime(0.0001);
|
||||||
|
}
|
||||||
|
FirstPersonTree.conditionallyPlayAnimation(Globals.firstPersonEntity, currentMove.getAnimationFirstPersonAttack().getName());
|
||||||
|
}
|
||||||
|
//activate hitboxes
|
||||||
|
List<Entity> attachedEntities = AttachUtils.getChildrenList(parent);
|
||||||
|
for(Entity currentAttached : attachedEntities){
|
||||||
|
if(HitboxCollectionState.hasHitboxState(currentAttached)){
|
||||||
|
HitboxCollectionState currentState = HitboxCollectionState.getHitboxState(currentAttached);
|
||||||
|
currentState.setActive(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
} break;
|
||||||
case HOLD:
|
case COOLDOWN: {
|
||||||
if(entityActor != null){
|
//deactive hitboxes
|
||||||
if(!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(animationName)){
|
List<Entity> attachedEntities = AttachUtils.getChildrenList(parent);
|
||||||
entityActor.playAnimation(animationName,1);
|
for(Entity currentAttached : attachedEntities){
|
||||||
entityActor.incrementAnimationTime(0.0001);
|
if(HitboxCollectionState.hasHitboxState(currentAttached)){
|
||||||
}
|
HitboxCollectionState currentState = HitboxCollectionState.getHitboxState(currentAttached);
|
||||||
FirstPersonTree.conditionallyPlayAnimation(Globals.firstPersonEntity, currentMove.getAnimationFirstPersonHold().getName());
|
currentState.setActive(false);
|
||||||
}
|
|
||||||
if(!stillHold){
|
|
||||||
state = AttackTreeState.ATTACK;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ATTACK:
|
|
||||||
if(parent.containsKey(EntityDataStrings.ATTACH_CHILDREN_LIST)){
|
|
||||||
List<Entity> attachedEntities = AttachUtils.getChildrenList(parent);
|
|
||||||
for(Entity currentAttached : attachedEntities){
|
|
||||||
if(currentAttached.containsKey(EntityDataStrings.HITBOX_ASSOCIATED_LIST)){
|
|
||||||
List<Entity> hitboxes = HitboxUtils.getHitboxAssociatedList(currentAttached);
|
|
||||||
for(Entity hitbox : hitboxes){
|
|
||||||
HitboxUtils.getHitboxData(hitbox).setActive(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(firesProjectile && projectileToFire != null){
|
|
||||||
//spawn projectile
|
|
||||||
//TODO: solve spawnPosition, initialVector
|
|
||||||
Vector3d spawnPosition = new Vector3d(0,0,0);
|
|
||||||
Quaterniond arrowRotation = new Quaterniond();
|
|
||||||
String targetBone = null;
|
|
||||||
ClientEquipState equipState = ClientEquipState.getEquipState(parent);
|
|
||||||
EquipPoint weaponPoint = null;
|
|
||||||
if((weaponPoint = equipState.getEquipPoint(attackingPoint)) != null){
|
|
||||||
targetBone = weaponPoint.getBone();
|
|
||||||
}
|
|
||||||
if(targetBone != null){
|
|
||||||
Actor parentActor = EntityUtils.getActor(parent);
|
|
||||||
//transform bone space
|
|
||||||
spawnPosition = new Vector3d(parentActor.getBonePosition(targetBone));
|
|
||||||
spawnPosition = spawnPosition.mul(((Vector3f)EntityUtils.getScale(parent)));
|
|
||||||
Quaterniond rotation = EntityUtils.getRotation(parent);
|
|
||||||
spawnPosition = spawnPosition.rotate(new Quaterniond(rotation.x,rotation.y,rotation.z,rotation.w));
|
|
||||||
//transform worldspace
|
|
||||||
spawnPosition.add(new Vector3d(EntityUtils.getPosition(parent)));
|
|
||||||
//set
|
|
||||||
// EntityUtils.getPosition(currentEntity).set(position);
|
|
||||||
//set rotation
|
|
||||||
// Quaternionf rotation = parentActor.getBoneRotation(targetBone);
|
|
||||||
// EntityUtils.getRotation(currentEntity).set(rotation).normalize();
|
|
||||||
// Vector3d facingAngle = CreatureUtils.getFacingVector(parent);
|
|
||||||
arrowRotation = parentActor.getBoneRotation(targetBone);
|
|
||||||
// EntityUtils.getRotation(currentEntity).rotationTo(new Vector3f(0,0,1), new Vector3f((float)facingAngle.x,(float)facingAngle.y,(float)facingAngle.z)).mul(parentActor.getBoneRotation(targetBone)).normalize();
|
|
||||||
}
|
|
||||||
Vector3f initialVector = new Vector3f((float)movementVector.x,(float)movementVector.y,(float)movementVector.z).normalize();
|
|
||||||
ProjectileUtils.clientSpawnBasicProjectile(projectileToFire, spawnPosition, arrowRotation, 750, initialVector, 0.03f);
|
|
||||||
projectileToFire = null;
|
|
||||||
}
|
|
||||||
if(currentMove != null && frameCurrent > currentMove.getWindupFrames() + currentMove.getAttackFrames()){
|
|
||||||
state = AttackTreeState.COOLDOWN;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case COOLDOWN:
|
|
||||||
if(parent.containsKey(EntityDataStrings.ATTACH_CHILDREN_LIST)){
|
|
||||||
List<Entity> attachedEntities = AttachUtils.getChildrenList(parent);
|
|
||||||
for(Entity currentAttached : attachedEntities){
|
|
||||||
if(currentAttached.containsKey(EntityDataStrings.HITBOX_ASSOCIATED_LIST)){
|
|
||||||
List<Entity> hitboxes = HitboxUtils.getHitboxAssociatedList(currentAttached);
|
|
||||||
for(Entity hitbox : hitboxes){
|
|
||||||
HitboxUtils.getHitboxData(hitbox).setActive(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(currentMove != null && frameCurrent > currentMove.getWindupFrames() + currentMove.getAttackFrames() + currentMove.getCooldownFrames()){
|
if(currentMove != null && frameCurrent > currentMove.getWindupFrames() + currentMove.getAttackFrames() + currentMove.getCooldownFrames()){
|
||||||
state = AttackTreeState.IDLE;
|
|
||||||
frameCurrent = 0;
|
frameCurrent = 0;
|
||||||
if(parent.containsKey(EntityDataStrings.CLIENT_ROTATOR_TREE)){
|
if(parent.containsKey(EntityDataStrings.CLIENT_ROTATOR_TREE)){
|
||||||
RotatorTree.getClientRotatorTree(parent).setActive(false);
|
RotatorTree.getClientRotatorTree(parent).setActive(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
} break;
|
||||||
case IDLE:
|
case IDLE: {
|
||||||
currentMove = null;
|
currentMove = null;
|
||||||
currentMoveset = null;
|
currentMoveset = null;
|
||||||
break;
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -360,11 +300,15 @@ public class ClientAttackTree implements BehaviorTree {
|
|||||||
networkMessageQueue.add(networkMessage);
|
networkMessageQueue.add(networkMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the current attack type
|
||||||
|
* @return The current attack type
|
||||||
|
*/
|
||||||
String getAttackType(){
|
String getAttackType(){
|
||||||
String rVal = null;
|
String rVal = null;
|
||||||
if(ClientEquipState.hasEquipState(parent)){
|
if(ClientEquipState.hasEquipState(parent)){
|
||||||
ClientEquipState equipState = ClientEquipState.getEquipState(parent);
|
ClientEquipState equipState = ClientEquipState.getEquipState(parent);
|
||||||
for(String point : equipState.equippedPoints()){
|
for(String point : equipState.getEquippedPoints()){
|
||||||
Entity item = equipState.getEquippedItemAtPoint(point);
|
Entity item = equipState.getEquippedItemAtPoint(point);
|
||||||
if(ItemUtils.isWeapon(item)){
|
if(ItemUtils.isWeapon(item)){
|
||||||
attackingPoint = point;
|
attackingPoint = point;
|
||||||
@ -399,7 +343,7 @@ public class ClientAttackTree implements BehaviorTree {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(ClientEquipState.hasEquipState(parent)){
|
if(ClientEquipState.hasEquipState(parent)){
|
||||||
ClientEquipState equipState = ClientEquipState.getEquipState(parent);
|
// ClientEquipState equipState = ClientEquipState.getEquipState(parent);
|
||||||
// if(equipState.hasEquipPrimary()){
|
// if(equipState.hasEquipPrimary()){
|
||||||
// switch(attackType){
|
// switch(attackType){
|
||||||
// case EntityDataStrings.ATTACK_MOVE_TYPE_MELEE_SWING_ONE_HAND:
|
// case EntityDataStrings.ATTACK_MOVE_TYPE_MELEE_SWING_ONE_HAND:
|
||||||
@ -423,6 +367,12 @@ public class ClientAttackTree implements BehaviorTree {
|
|||||||
return rVal;
|
return rVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the object for next move in the current attack chain
|
||||||
|
* @param moveset The moveset to search
|
||||||
|
* @param nextMoveId The id of the next move
|
||||||
|
* @return The object that corresponds to the id if it exists, otherwise false
|
||||||
|
*/
|
||||||
AttackMove getNextMove(List<AttackMove> moveset, String nextMoveId){
|
AttackMove getNextMove(List<AttackMove> moveset, String nextMoveId){
|
||||||
AttackMove rVal = null;
|
AttackMove rVal = null;
|
||||||
for(AttackMove move : moveset){
|
for(AttackMove move : moveset){
|
||||||
@ -433,6 +383,23 @@ public class ClientAttackTree implements BehaviorTree {
|
|||||||
}
|
}
|
||||||
return rVal;
|
return rVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the current attack type of the entity
|
||||||
|
* @param attackType the current attack type
|
||||||
|
*/
|
||||||
|
public void setAttackMoveTypeActive(String attackType){
|
||||||
|
parent.putData(EntityDataStrings.ATTACK_MOVE_TYPE_ACTIVE, attackType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the current moveset
|
||||||
|
* @param attackType the attack type
|
||||||
|
* @return The moveset if it exists
|
||||||
|
*/
|
||||||
|
public List<AttackMove> getMoveset(String attackType){
|
||||||
|
return (List<AttackMove>)parent.getData(attackType);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p> Automatically generated </p>
|
* <p> Automatically generated </p>
|
||||||
|
|||||||
@ -9,26 +9,22 @@ import electrosphere.net.parser.net.message.SynchronizationMessage;
|
|||||||
|
|
||||||
import electrosphere.server.datacell.utils.DataCellSearchUtils;
|
import electrosphere.server.datacell.utils.DataCellSearchUtils;
|
||||||
|
|
||||||
import electrosphere.collision.collidable.Collidable;
|
|
||||||
import electrosphere.engine.Globals;
|
import electrosphere.engine.Globals;
|
||||||
import electrosphere.engine.Main;
|
|
||||||
import electrosphere.entity.Entity;
|
import electrosphere.entity.Entity;
|
||||||
import electrosphere.entity.EntityDataStrings;
|
import electrosphere.entity.EntityDataStrings;
|
||||||
import electrosphere.entity.EntityUtils;
|
import electrosphere.entity.EntityUtils;
|
||||||
import electrosphere.entity.ServerEntityUtils;
|
|
||||||
import electrosphere.entity.btree.BehaviorTree;
|
import electrosphere.entity.btree.BehaviorTree;
|
||||||
import electrosphere.entity.state.attack.ClientAttackTree.AttackTreeDriftState;
|
import electrosphere.entity.state.attack.ClientAttackTree.AttackTreeDriftState;
|
||||||
import electrosphere.entity.state.attack.ClientAttackTree.AttackTreeState;
|
import electrosphere.entity.state.attack.ClientAttackTree.AttackTreeState;
|
||||||
|
import electrosphere.entity.state.client.firstPerson.FirstPersonTree;
|
||||||
import electrosphere.entity.state.collidable.Impulse;
|
import electrosphere.entity.state.collidable.Impulse;
|
||||||
import electrosphere.entity.state.equip.ServerEquipState;
|
import electrosphere.entity.state.equip.ServerEquipState;
|
||||||
import electrosphere.entity.state.movement.groundmove.ClientGroundMovementTree;
|
import electrosphere.entity.state.hitbox.HitboxCollectionState;
|
||||||
import electrosphere.entity.state.movement.groundmove.ServerGroundMovementTree;
|
import electrosphere.entity.state.movement.groundmove.ServerGroundMovementTree;
|
||||||
import electrosphere.entity.state.rotator.RotatorTree;
|
|
||||||
import electrosphere.entity.state.rotator.ServerRotatorTree;
|
import electrosphere.entity.state.rotator.ServerRotatorTree;
|
||||||
import electrosphere.entity.types.attach.AttachUtils;
|
import electrosphere.entity.types.attach.AttachUtils;
|
||||||
import electrosphere.entity.types.collision.CollisionObjUtils;
|
import electrosphere.entity.types.collision.CollisionObjUtils;
|
||||||
import electrosphere.entity.types.creature.CreatureUtils;
|
import electrosphere.entity.types.creature.CreatureUtils;
|
||||||
import electrosphere.entity.types.hitbox.HitboxUtils;
|
|
||||||
import electrosphere.entity.types.item.ItemUtils;
|
import electrosphere.entity.types.item.ItemUtils;
|
||||||
import electrosphere.entity.types.projectile.ProjectileUtils;
|
import electrosphere.entity.types.projectile.ProjectileUtils;
|
||||||
import electrosphere.game.data.creature.type.attack.AttackMove;
|
import electrosphere.game.data.creature.type.attack.AttackMove;
|
||||||
@ -37,17 +33,14 @@ import electrosphere.net.parser.net.message.EntityMessage;
|
|||||||
import electrosphere.net.synchronization.annotation.SyncedField;
|
import electrosphere.net.synchronization.annotation.SyncedField;
|
||||||
import electrosphere.net.synchronization.annotation.SynchronizedBehaviorTree;
|
import electrosphere.net.synchronization.annotation.SynchronizedBehaviorTree;
|
||||||
import electrosphere.renderer.actor.Actor;
|
import electrosphere.renderer.actor.Actor;
|
||||||
import electrosphere.renderer.anim.Animation;
|
|
||||||
import electrosphere.server.datacell.Realm;
|
import electrosphere.server.datacell.Realm;
|
||||||
import electrosphere.server.datacell.utils.EntityLookupUtils;
|
|
||||||
import electrosphere.server.poseactor.PoseActor;
|
import electrosphere.server.poseactor.PoseActor;
|
||||||
|
import electrosphere.util.MathUtils;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
import org.joml.Quaterniond;
|
import org.joml.Quaterniond;
|
||||||
import org.joml.Quaternionf;
|
|
||||||
import org.joml.Quaternionfc;
|
|
||||||
import org.joml.Vector3d;
|
import org.joml.Vector3d;
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
|
|
||||||
@ -58,9 +51,11 @@ import org.joml.Vector3f;
|
|||||||
public class ServerAttackTree implements BehaviorTree {
|
public class ServerAttackTree implements BehaviorTree {
|
||||||
|
|
||||||
@SyncedField
|
@SyncedField
|
||||||
|
//the state of the attack tree
|
||||||
AttackTreeState state;
|
AttackTreeState state;
|
||||||
|
|
||||||
@SyncedField
|
@SyncedField
|
||||||
|
//the state of drifting caused by the attack animation
|
||||||
AttackTreeDriftState driftState;
|
AttackTreeDriftState driftState;
|
||||||
|
|
||||||
Entity parent;
|
Entity parent;
|
||||||
@ -77,8 +72,8 @@ public class ServerAttackTree implements BehaviorTree {
|
|||||||
|
|
||||||
List<AttackMove> currentMoveset = null;
|
List<AttackMove> currentMoveset = null;
|
||||||
@SyncedField
|
@SyncedField
|
||||||
String currentMoveId = null;
|
String currentMoveId = null; //the id of the current move -- used to synchronize the move to client
|
||||||
AttackMove currentMove = null;
|
AttackMove currentMove = null; //the actual current move object
|
||||||
Entity currentWeapon = null;
|
Entity currentWeapon = null;
|
||||||
boolean currentMoveHasWindup;
|
boolean currentMoveHasWindup;
|
||||||
boolean currentMoveCanHold;
|
boolean currentMoveCanHold;
|
||||||
@ -115,8 +110,8 @@ public class ServerAttackTree implements BehaviorTree {
|
|||||||
String attackType = getAttackType();
|
String attackType = getAttackType();
|
||||||
//if we can attack, setup doing so
|
//if we can attack, setup doing so
|
||||||
if(canAttack(attackType)){
|
if(canAttack(attackType)){
|
||||||
parent.putData(EntityDataStrings.ATTACK_MOVE_TYPE_ACTIVE, attackType);
|
setAttackMoveTypeActive(attackType);
|
||||||
currentMoveset = (List<AttackMove>)parent.getData(attackType);
|
currentMoveset = getMoveset(attackType);
|
||||||
if(currentMoveset != null){
|
if(currentMoveset != null){
|
||||||
if(currentMove == null){
|
if(currentMove == null){
|
||||||
currentMove = currentMoveset.get(0);
|
currentMove = currentMoveset.get(0);
|
||||||
@ -145,8 +140,8 @@ public class ServerAttackTree implements BehaviorTree {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Vector3d movementVector = CreatureUtils.getFacingVector(parent);
|
Vector3d movementVector = CreatureUtils.getFacingVector(parent);
|
||||||
EntityUtils.getRotation(parent).rotationTo(new Vector3d(0,0,1), new Vector3d(movementVector.x,movementVector.y,movementVector.z));
|
EntityUtils.getRotation(parent).rotationTo(MathUtils.getOriginVector(), new Vector3d(movementVector.x,movementVector.y,movementVector.z));
|
||||||
//set initial stuff
|
//set initial stuff (this alerts the client as well)
|
||||||
setCurrentMoveId(currentMove.getAttackMoveId());
|
setCurrentMoveId(currentMove.getAttackMoveId());
|
||||||
setState(AttackTreeState.WINDUP);
|
setState(AttackTreeState.WINDUP);
|
||||||
frameCurrent = 0;
|
frameCurrent = 0;
|
||||||
@ -171,7 +166,7 @@ public class ServerAttackTree implements BehaviorTree {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void simulate(float deltaTime){
|
public void simulate(float deltaTime){
|
||||||
frameCurrent = frameCurrent + (float)Globals.timekeeper.getSimFrameTime();
|
frameCurrent = frameCurrent + (float)Globals.timekeeper.getDeltaFrames();
|
||||||
float velocity = CreatureUtils.getVelocity(parent);
|
float velocity = CreatureUtils.getVelocity(parent);
|
||||||
PoseActor entityPoseActor = EntityUtils.getPoseActor(parent);
|
PoseActor entityPoseActor = EntityUtils.getPoseActor(parent);
|
||||||
Vector3d position = EntityUtils.getPosition(parent);
|
Vector3d position = EntityUtils.getPosition(parent);
|
||||||
@ -180,37 +175,9 @@ public class ServerAttackTree implements BehaviorTree {
|
|||||||
//parse attached network messages
|
//parse attached network messages
|
||||||
for(EntityMessage message : networkMessageQueue){
|
for(EntityMessage message : networkMessageQueue){
|
||||||
networkMessageQueue.remove(message);
|
networkMessageQueue.remove(message);
|
||||||
// System.out.println("MOVE to " + message.getX() + " " + message.getY() + " " + message.getZ());
|
|
||||||
long updateTime = message.gettime();
|
|
||||||
switch(message.getMessageSubtype()){
|
switch(message.getMessageSubtype()){
|
||||||
case ATTACKUPDATE:
|
case ATTACKUPDATE:
|
||||||
if(updateTime > lastUpdateTime){
|
|
||||||
lastUpdateTime = updateTime;
|
|
||||||
switch(message.gettreeState()){
|
|
||||||
case 0:
|
|
||||||
setState(AttackTreeState.WINDUP);
|
|
||||||
frameCurrent = 0;
|
|
||||||
// System.out.println("Set state STARTUP");
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
frameCurrent = currentMove.getWindupFrames()+1;
|
|
||||||
setState(AttackTreeState.ATTACK);
|
|
||||||
// System.out.println("Set state MOVE");
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
frameCurrent = currentMove.getWindupFrames()+currentMove.getAttackFrames()+1;
|
|
||||||
setState(AttackTreeState.COOLDOWN);
|
|
||||||
// System.out.println("Set state SLOWDOWN");
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
frameCurrent = 60;
|
|
||||||
setState(AttackTreeState.IDLE);
|
|
||||||
// System.out.println("Set state IDLE");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EntityUtils.getPosition(parent).set(message.getpositionX(),message.getpositionY(),message.getpositionZ());
|
EntityUtils.getPosition(parent).set(message.getpositionX(),message.getpositionY(),message.getpositionZ());
|
||||||
CreatureUtils.setFacingVector(parent, new Vector3d(message.getrotationX(),message.getrotationY(),message.getrotationZ()));
|
|
||||||
break;
|
break;
|
||||||
case STARTATTACK: {
|
case STARTATTACK: {
|
||||||
start();
|
start();
|
||||||
@ -247,7 +214,7 @@ public class ServerAttackTree implements BehaviorTree {
|
|||||||
|
|
||||||
//state machine
|
//state machine
|
||||||
switch(state){
|
switch(state){
|
||||||
case WINDUP:
|
case WINDUP: {
|
||||||
if(parent.containsKey(EntityDataStrings.SERVER_ROTATOR_TREE)){
|
if(parent.containsKey(EntityDataStrings.SERVER_ROTATOR_TREE)){
|
||||||
ServerRotatorTree.getServerRotatorTree(parent).setActive(true);
|
ServerRotatorTree.getServerRotatorTree(parent).setActive(true);
|
||||||
}
|
}
|
||||||
@ -278,28 +245,32 @@ public class ServerAttackTree implements BehaviorTree {
|
|||||||
0
|
0
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
break;
|
} break;
|
||||||
case HOLD:
|
case HOLD: {
|
||||||
if(entityPoseActor != null){
|
if(entityPoseActor != null){
|
||||||
if(!entityPoseActor.isPlayingAnimation() || !entityPoseActor.isPlayingAnimation(animationName)){
|
if(!entityPoseActor.isPlayingAnimation() || !entityPoseActor.isPlayingAnimation(animationName)){
|
||||||
entityPoseActor.playAnimation(animationName,1);
|
entityPoseActor.playAnimation(animationName,1);
|
||||||
entityPoseActor.incrementAnimationTime(0.0001);
|
entityPoseActor.incrementAnimationTime(0.0001);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
if(!stillHold){
|
||||||
if(!stillHold){
|
setState(AttackTreeState.ATTACK);
|
||||||
setState(AttackTreeState.ATTACK);
|
}
|
||||||
}
|
} break;
|
||||||
break;
|
case ATTACK: {
|
||||||
case ATTACK:
|
if(entityPoseActor != null && currentMove != null){
|
||||||
if(parent.containsKey(EntityDataStrings.ATTACH_CHILDREN_LIST)){
|
if(!entityPoseActor.isPlayingAnimation() || !entityPoseActor.isPlayingAnimation(currentMove.getAttackAnimationName())){
|
||||||
List<Entity> attachedEntities = AttachUtils.getChildrenList(parent);
|
entityPoseActor.playAnimation(currentMove.getAttackAnimationName(),1);
|
||||||
for(Entity currentAttached : attachedEntities){
|
entityPoseActor.incrementAnimationTime(0.0001);
|
||||||
if(currentAttached.containsKey(EntityDataStrings.HITBOX_ASSOCIATED_LIST)){
|
}
|
||||||
List<Entity> hitboxes = HitboxUtils.getHitboxAssociatedList(currentAttached);
|
FirstPersonTree.conditionallyPlayAnimation(Globals.firstPersonEntity, currentMove.getAnimationFirstPersonAttack().getName());
|
||||||
for(Entity hitbox : hitboxes){
|
}
|
||||||
HitboxUtils.getHitboxData(hitbox).setActive(true);
|
//activate hitboxes
|
||||||
}
|
List<Entity> attachedEntities = AttachUtils.getChildrenList(parent);
|
||||||
}
|
for(Entity currentAttached : attachedEntities){
|
||||||
|
if(HitboxCollectionState.hasHitboxState(currentAttached)){
|
||||||
|
HitboxCollectionState currentState = HitboxCollectionState.getHitboxState(currentAttached);
|
||||||
|
currentState.setActive(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(firesProjectile && projectileToFire != null){
|
if(firesProjectile && projectileToFire != null){
|
||||||
@ -329,7 +300,7 @@ public class ServerAttackTree implements BehaviorTree {
|
|||||||
// EntityUtils.getRotation(currentEntity).set(rotation).normalize();
|
// EntityUtils.getRotation(currentEntity).set(rotation).normalize();
|
||||||
// Vector3d facingAngle = CreatureUtils.getFacingVector(parent);
|
// Vector3d facingAngle = CreatureUtils.getFacingVector(parent);
|
||||||
arrowRotation = parentActor.getBoneRotation(targetBone);
|
arrowRotation = parentActor.getBoneRotation(targetBone);
|
||||||
// EntityUtils.getRotation(currentEntity).rotationTo(new Vector3f(0,0,1), new Vector3f((float)facingAngle.x,(float)facingAngle.y,(float)facingAngle.z)).mul(parentActor.getBoneRotation(targetBone)).normalize();
|
// EntityUtils.getRotation(currentEntity).rotationTo(MathUtils.ORIGIN_VECTORF, new Vector3f((float)facingAngle.x,(float)facingAngle.y,(float)facingAngle.z)).mul(parentActor.getBoneRotation(targetBone)).normalize();
|
||||||
}
|
}
|
||||||
Vector3f initialVector = new Vector3f((float)movementVector.x,(float)movementVector.y,(float)movementVector.z).normalize();
|
Vector3f initialVector = new Vector3f((float)movementVector.x,(float)movementVector.y,(float)movementVector.z).normalize();
|
||||||
Realm parentRealm = Globals.realmManager.getEntityRealm(parent);
|
Realm parentRealm = Globals.realmManager.getEntityRealm(parent);
|
||||||
@ -353,17 +324,14 @@ public class ServerAttackTree implements BehaviorTree {
|
|||||||
1
|
1
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
break;
|
} break;
|
||||||
case COOLDOWN:
|
case COOLDOWN: {
|
||||||
if(parent.containsKey(EntityDataStrings.ATTACH_CHILDREN_LIST)){
|
//deactive hitboxes
|
||||||
List<Entity> attachedEntities = AttachUtils.getChildrenList(parent);
|
List<Entity> attachedEntities = AttachUtils.getChildrenList(parent);
|
||||||
for(Entity currentAttached : attachedEntities){
|
for(Entity currentAttached : attachedEntities){
|
||||||
if(currentAttached.containsKey(EntityDataStrings.HITBOX_ASSOCIATED_LIST)){
|
if(HitboxCollectionState.hasHitboxState(currentAttached)){
|
||||||
List<Entity> hitboxes = HitboxUtils.getHitboxAssociatedList(currentAttached);
|
HitboxCollectionState currentState = HitboxCollectionState.getHitboxState(currentAttached);
|
||||||
for(Entity hitbox : hitboxes){
|
currentState.setActive(false);
|
||||||
HitboxUtils.getHitboxData(hitbox).setActive(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(frameCurrent > currentMove.getWindupFrames() + currentMove.getAttackFrames() + currentMove.getCooldownFrames()){
|
if(frameCurrent > currentMove.getWindupFrames() + currentMove.getAttackFrames() + currentMove.getCooldownFrames()){
|
||||||
@ -387,11 +355,11 @@ public class ServerAttackTree implements BehaviorTree {
|
|||||||
2
|
2
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
break;
|
} break;
|
||||||
case IDLE:
|
case IDLE: {
|
||||||
currentMove = null;
|
currentMove = null;
|
||||||
currentMoveset = null;
|
currentMoveset = null;
|
||||||
break;
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -422,6 +390,11 @@ public class ServerAttackTree implements BehaviorTree {
|
|||||||
return rVal;
|
return rVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the entity can attack or not
|
||||||
|
* @param attackType The type of attack to perform
|
||||||
|
* @return true if it can attack, false otherwise
|
||||||
|
*/
|
||||||
boolean canAttack(String attackType){
|
boolean canAttack(String attackType){
|
||||||
boolean rVal = true;
|
boolean rVal = true;
|
||||||
if(attackType == null){
|
if(attackType == null){
|
||||||
@ -437,7 +410,7 @@ public class ServerAttackTree implements BehaviorTree {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(ServerEquipState.hasEquipState(parent)){
|
if(ServerEquipState.hasEquipState(parent)){
|
||||||
ServerEquipState equipState = ServerEquipState.getEquipState(parent);
|
// ServerEquipState equipState = ServerEquipState.getEquipState(parent);
|
||||||
// if(equipState.hasEquipPrimary()){
|
// if(equipState.hasEquipPrimary()){
|
||||||
// switch(attackType){
|
// switch(attackType){
|
||||||
// case EntityDataStrings.ATTACK_MOVE_TYPE_MELEE_SWING_ONE_HAND:
|
// case EntityDataStrings.ATTACK_MOVE_TYPE_MELEE_SWING_ONE_HAND:
|
||||||
@ -471,6 +444,23 @@ public class ServerAttackTree implements BehaviorTree {
|
|||||||
}
|
}
|
||||||
return rVal;
|
return rVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the current attack type of the entity
|
||||||
|
* @param attackType the current attack type
|
||||||
|
*/
|
||||||
|
public void setAttackMoveTypeActive(String attackType){
|
||||||
|
parent.putData(EntityDataStrings.ATTACK_MOVE_TYPE_ACTIVE, attackType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the current moveset
|
||||||
|
* @param attackType the attack type
|
||||||
|
* @return The moveset if it exists
|
||||||
|
*/
|
||||||
|
public List<AttackMove> getMoveset(String attackType){
|
||||||
|
return (List<AttackMove>)parent.getData(attackType);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p> Automatically generated </p>
|
* <p> Automatically generated </p>
|
||||||
|
|||||||
@ -0,0 +1,27 @@
|
|||||||
|
package electrosphere.entity.state.block;
|
||||||
|
|
||||||
|
import electrosphere.net.synchronization.annotation.SyncedField;
|
||||||
|
import electrosphere.net.synchronization.annotation.SynchronizableEnum;
|
||||||
|
import electrosphere.net.synchronization.annotation.SynchronizedBehaviorTree;
|
||||||
|
|
||||||
|
@SynchronizedBehaviorTree(name = "clientBlockTree", isServer = false, correspondingTree="serverBlockTree")
|
||||||
|
/**
|
||||||
|
* Client block tree
|
||||||
|
*/
|
||||||
|
public class ClientBlockTree {
|
||||||
|
|
||||||
|
@SynchronizableEnum
|
||||||
|
/**
|
||||||
|
* The state of the block tree
|
||||||
|
*/
|
||||||
|
public enum BlockState {
|
||||||
|
BLOCKING,
|
||||||
|
NOT_BLOCKING,
|
||||||
|
}
|
||||||
|
|
||||||
|
@SyncedField
|
||||||
|
BlockState state;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,16 @@
|
|||||||
|
package electrosphere.entity.state.block;
|
||||||
|
|
||||||
|
import electrosphere.entity.state.block.ClientBlockTree.BlockState;
|
||||||
|
import electrosphere.net.synchronization.annotation.SyncedField;
|
||||||
|
import electrosphere.net.synchronization.annotation.SynchronizedBehaviorTree;
|
||||||
|
|
||||||
|
@SynchronizedBehaviorTree(name = "serverBlockTree", isServer = true, correspondingTree="clientBlockTree")
|
||||||
|
/**
|
||||||
|
* Server block tree
|
||||||
|
*/
|
||||||
|
public class ServerBlockTree {
|
||||||
|
|
||||||
|
@SyncedField
|
||||||
|
BlockState state;
|
||||||
|
|
||||||
|
}
|
||||||
@ -115,7 +115,7 @@ public class FirstPersonTree implements BehaviorTree {
|
|||||||
* @param animationName the name of the animation
|
* @param animationName the name of the animation
|
||||||
*/
|
*/
|
||||||
public static void conditionallyPlayAnimation(Entity entity, String animationName){
|
public static void conditionallyPlayAnimation(Entity entity, String animationName){
|
||||||
if(hasTree(entity)){
|
if(entity != null && hasTree(entity)){
|
||||||
getTree(entity).playAnimation(animationName);
|
getTree(entity).playAnimation(animationName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -48,7 +48,7 @@ public class ClientEquipState implements BehaviorTree {
|
|||||||
* @param parent the entity this is attached to
|
* @param parent the entity this is attached to
|
||||||
* @param equipPoints the list of available points
|
* @param equipPoints the list of available points
|
||||||
*/
|
*/
|
||||||
public ClientEquipState(Entity parent, List<EquipPoint> equipPoints){
|
private ClientEquipState(Entity parent, List<EquipPoint> equipPoints){
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
for(EquipPoint point : equipPoints){
|
for(EquipPoint point : equipPoints){
|
||||||
this.equipPoints.add(point);
|
this.equipPoints.add(point);
|
||||||
@ -59,10 +59,19 @@ public class ClientEquipState implements BehaviorTree {
|
|||||||
* Gets the list of equipped points
|
* Gets the list of equipped points
|
||||||
* @return the list
|
* @return the list
|
||||||
*/
|
*/
|
||||||
public List<String> equippedPoints(){
|
public List<String> getEquippedPoints(){
|
||||||
return new LinkedList<String>(equipMap.keySet());
|
return new LinkedList<String>(equipMap.keySet());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the list of all equip points
|
||||||
|
* @return The list of all equip points
|
||||||
|
*/
|
||||||
|
public List<EquipPoint> getAllEquipPoints(){
|
||||||
|
return equipPoints;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attempts to equip the item
|
* Attempts to equip the item
|
||||||
* @param toEquip the item to equip
|
* @param toEquip the item to equip
|
||||||
@ -72,7 +81,6 @@ public class ClientEquipState implements BehaviorTree {
|
|||||||
boolean hasEquipped = hasEquippedAtPoint(point.getEquipPointId());
|
boolean hasEquipped = hasEquippedAtPoint(point.getEquipPointId());
|
||||||
boolean targetIsItem = ItemUtils.isItem(toEquip);
|
boolean targetIsItem = ItemUtils.isItem(toEquip);
|
||||||
boolean targetIsAttached = AttachUtils.isAttached(toEquip);
|
boolean targetIsAttached = AttachUtils.isAttached(toEquip);
|
||||||
boolean targetHasWhitelist = ItemUtils.hasEquipList(toEquip);
|
|
||||||
String equipItemClass = ItemUtils.getEquipClass(toEquip);
|
String equipItemClass = ItemUtils.getEquipClass(toEquip);
|
||||||
List<String> pointEquipClassList = point.getEquipClassWhitelist();
|
List<String> pointEquipClassList = point.getEquipClassWhitelist();
|
||||||
boolean itemIsInPointWhitelist = pointEquipClassList.contains(equipItemClass);
|
boolean itemIsInPointWhitelist = pointEquipClassList.contains(equipItemClass);
|
||||||
@ -90,7 +98,7 @@ public class ClientEquipState implements BehaviorTree {
|
|||||||
* @param toEquip The entity to equip
|
* @param toEquip The entity to equip
|
||||||
* @param point The equipment point to equip to
|
* @param point The equipment point to equip to
|
||||||
*/
|
*/
|
||||||
public void clientAttemptEquip(Entity toEquip, EquipPoint point){
|
public void attemptEquip(Entity toEquip, EquipPoint point){
|
||||||
boolean hasEquipped = hasEquippedAtPoint(point.getEquipPointId());
|
boolean hasEquipped = hasEquippedAtPoint(point.getEquipPointId());
|
||||||
boolean targetIsItem = ItemUtils.isItem(toEquip);
|
boolean targetIsItem = ItemUtils.isItem(toEquip);
|
||||||
boolean targetIsAttached = AttachUtils.isAttached(toEquip);
|
boolean targetIsAttached = AttachUtils.isAttached(toEquip);
|
||||||
@ -222,7 +230,7 @@ public class ClientEquipState implements BehaviorTree {
|
|||||||
* @return True if the entity contains an equip state, false otherwise
|
* @return True if the entity contains an equip state, false otherwise
|
||||||
*/
|
*/
|
||||||
public static boolean hasEquipState(Entity entity){
|
public static boolean hasEquipState(Entity entity){
|
||||||
return entity.containsKey(EntityDataStrings.EQUIP_STATE);
|
return entity.containsKey(EntityDataStrings.TREE_CLIENTEQUIPSTATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -231,7 +239,7 @@ public class ClientEquipState implements BehaviorTree {
|
|||||||
* @return The equip state on the entity
|
* @return The equip state on the entity
|
||||||
*/
|
*/
|
||||||
public static ClientEquipState getEquipState(Entity entity){
|
public static ClientEquipState getEquipState(Entity entity){
|
||||||
return (ClientEquipState)entity.getData(EntityDataStrings.EQUIP_STATE);
|
return (ClientEquipState)entity.getData(EntityDataStrings.TREE_CLIENTEQUIPSTATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -240,7 +248,7 @@ public class ClientEquipState implements BehaviorTree {
|
|||||||
* @param equipState The equip state to attach
|
* @param equipState The equip state to attach
|
||||||
*/
|
*/
|
||||||
public static void setEquipState(Entity entity, ClientEquipState equipState){
|
public static void setEquipState(Entity entity, ClientEquipState equipState){
|
||||||
entity.putData(EntityDataStrings.EQUIP_STATE, equipState);
|
entity.putData(EntityDataStrings.TREE_CLIENTEQUIPSTATE, equipState);
|
||||||
}
|
}
|
||||||
|
|
||||||
// public void drop(Entity entity){
|
// public void drop(Entity entity){
|
||||||
|
|||||||
@ -190,7 +190,7 @@ public class ServerEquipState implements BehaviorTree {
|
|||||||
* @return True if the entity contains an equip state, false otherwise
|
* @return True if the entity contains an equip state, false otherwise
|
||||||
*/
|
*/
|
||||||
public static boolean hasEquipState(Entity entity){
|
public static boolean hasEquipState(Entity entity){
|
||||||
return entity.containsKey(EntityDataStrings.EQUIP_STATE);
|
return entity.containsKey(EntityDataStrings.TREE_SERVEREQUIPSTATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -199,7 +199,7 @@ public class ServerEquipState implements BehaviorTree {
|
|||||||
* @return The equip state on the entity
|
* @return The equip state on the entity
|
||||||
*/
|
*/
|
||||||
public static ServerEquipState getEquipState(Entity entity){
|
public static ServerEquipState getEquipState(Entity entity){
|
||||||
return (ServerEquipState)entity.getData(EntityDataStrings.EQUIP_STATE);
|
return (ServerEquipState)entity.getData(EntityDataStrings.TREE_SERVEREQUIPSTATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -208,7 +208,7 @@ public class ServerEquipState implements BehaviorTree {
|
|||||||
* @param equipState The equip state to attach
|
* @param equipState The equip state to attach
|
||||||
*/
|
*/
|
||||||
public static void setEquipState(Entity entity, ServerEquipState equipState){
|
public static void setEquipState(Entity entity, ServerEquipState equipState){
|
||||||
entity.putData(EntityDataStrings.EQUIP_STATE, equipState);
|
entity.putData(EntityDataStrings.TREE_SERVEREQUIPSTATE, equipState);
|
||||||
}
|
}
|
||||||
|
|
||||||
// public void drop(Entity entity){
|
// public void drop(Entity entity){
|
||||||
|
|||||||
@ -52,7 +52,7 @@ public class AmbientFoliage implements BehaviorTree {
|
|||||||
|
|
||||||
//rotate to face cameras
|
//rotate to face cameras
|
||||||
// Vector3f cameraEyeVector = CameraEntityUtils.getCameraEye(Globals.playerCamera);
|
// Vector3f cameraEyeVector = CameraEntityUtils.getCameraEye(Globals.playerCamera);
|
||||||
// EntityUtils.getRotation(parent).rotateTo(new Vector3d(1,0,0), new Vector3d(cameraEyeVector));
|
// EntityUtils.getRotation(parent).rotateTo(MathUtils.ORIGIN_VECTOR, new Vector3d(cameraEyeVector));
|
||||||
|
|
||||||
|
|
||||||
//TODO: simulate wind offset
|
//TODO: simulate wind offset
|
||||||
|
|||||||
@ -0,0 +1,594 @@
|
|||||||
|
package electrosphere.entity.state.hitbox;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.joml.Quaterniond;
|
||||||
|
import org.joml.Vector3d;
|
||||||
|
import org.joml.Vector3f;
|
||||||
|
import org.ode4j.ode.DBody;
|
||||||
|
import org.ode4j.ode.DGeom;
|
||||||
|
|
||||||
|
import electrosphere.collision.CollisionBodyCreation;
|
||||||
|
import electrosphere.collision.CollisionEngine;
|
||||||
|
import electrosphere.collision.PhysicsEntityUtils;
|
||||||
|
import electrosphere.collision.PhysicsUtils;
|
||||||
|
import electrosphere.collision.collidable.Collidable;
|
||||||
|
import electrosphere.collision.hitbox.HitboxManager;
|
||||||
|
import electrosphere.collision.hitbox.HitboxUtils.HitboxPositionCallback;
|
||||||
|
import electrosphere.entity.Entity;
|
||||||
|
import electrosphere.entity.EntityDataStrings;
|
||||||
|
import electrosphere.entity.EntityUtils;
|
||||||
|
import electrosphere.entity.state.hitbox.HitboxCollectionState.HitboxState.HitboxShapeType;
|
||||||
|
import electrosphere.game.data.collidable.HitboxData;
|
||||||
|
import electrosphere.util.MathUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The state of the collection of all hitboxes on this entity
|
||||||
|
* Ie, it stores the state of each hitbox that is attached to this entity
|
||||||
|
*/
|
||||||
|
public class HitboxCollectionState {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Types of hitboxes
|
||||||
|
*/
|
||||||
|
public enum HitboxType {
|
||||||
|
HIT, // damages another entity
|
||||||
|
HURT, // receives damage from another entity
|
||||||
|
BLOCK, // blocks a hit from another entity
|
||||||
|
}
|
||||||
|
|
||||||
|
//the parent entity of the hitbox state
|
||||||
|
Entity parent;
|
||||||
|
|
||||||
|
//the body that contains all the hitbox shapes
|
||||||
|
DBody body;
|
||||||
|
|
||||||
|
//The collidable associated with the body
|
||||||
|
Collidable collidable;
|
||||||
|
|
||||||
|
//the list of all geoms in the collection state
|
||||||
|
List<DGeom> geoms = new LinkedList<DGeom>();
|
||||||
|
//the map of bone -> hitbox shape in ode4j
|
||||||
|
Map<String,DGeom> hitboxGeomMap = new HashMap<String,DGeom>();
|
||||||
|
//the map of geometry -> hitbox shape status, useful for finding data about a given hitbox during collision
|
||||||
|
Map<DGeom,HitboxState> geomStateMap = new HashMap<DGeom,HitboxState>();
|
||||||
|
|
||||||
|
//callback to provide a position for the hitbox each frame
|
||||||
|
HitboxPositionCallback positionCallback;
|
||||||
|
|
||||||
|
//controls whether the hitbox state is active or not
|
||||||
|
boolean active = true;
|
||||||
|
|
||||||
|
//the associated manager
|
||||||
|
HitboxManager manager;
|
||||||
|
|
||||||
|
//controls whether this hitbox collection thinks its on the server or client
|
||||||
|
boolean isServer = true;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create hitbox state for an entity
|
||||||
|
* @param collisionEngine the collision engine
|
||||||
|
* @param entity The entity to attach the state to
|
||||||
|
* @param hitboxListRaw The list of hitbox data to apply
|
||||||
|
* @return The hitbox state that has been attached to the entity
|
||||||
|
*/
|
||||||
|
public static HitboxCollectionState attachHitboxState(HitboxManager manager, boolean isServer, Entity entity, List<HitboxData> hitboxListRaw){
|
||||||
|
HitboxCollectionState rVal = new HitboxCollectionState();
|
||||||
|
|
||||||
|
rVal.isServer = isServer;
|
||||||
|
//create the shapes
|
||||||
|
for(HitboxData hitboxDataRaw : hitboxListRaw){
|
||||||
|
DGeom geom = null;
|
||||||
|
HitboxType type = HitboxType.HIT;
|
||||||
|
HitboxShapeType shapeType = HitboxShapeType.SPHERE;
|
||||||
|
switch(hitboxDataRaw.getType()){
|
||||||
|
case HitboxData.HITBOX_TYPE_HIT: {
|
||||||
|
type = HitboxType.HIT;
|
||||||
|
shapeType = HitboxShapeType.SPHERE;
|
||||||
|
geom = CollisionBodyCreation.createShapeSphere(manager.getCollisionEngine(), hitboxDataRaw.getRadius(), Collidable.TYPE_OBJECT_BIT);
|
||||||
|
} break;
|
||||||
|
case HitboxData.HITBOX_TYPE_HURT: {
|
||||||
|
type = HitboxType.HURT;
|
||||||
|
shapeType = HitboxShapeType.SPHERE;
|
||||||
|
geom = CollisionBodyCreation.createShapeSphere(manager.getCollisionEngine(), hitboxDataRaw.getRadius(), Collidable.TYPE_OBJECT_BIT);
|
||||||
|
} break;
|
||||||
|
case HitboxData.HITBOX_TYPE_HIT_CONNECTED: {
|
||||||
|
type = HitboxType.HIT;
|
||||||
|
shapeType = HitboxShapeType.CAPSULE;
|
||||||
|
geom = CollisionBodyCreation.createShapeSphere(manager.getCollisionEngine(), hitboxDataRaw.getRadius(), Collidable.TYPE_OBJECT_BIT);
|
||||||
|
} break;
|
||||||
|
case HitboxData.HITBOX_TYPE_HURT_CONNECTED: {
|
||||||
|
type = HitboxType.HURT;
|
||||||
|
shapeType = HitboxShapeType.CAPSULE;
|
||||||
|
geom = CollisionBodyCreation.createShapeSphere(manager.getCollisionEngine(), hitboxDataRaw.getRadius(), Collidable.TYPE_OBJECT_BIT);
|
||||||
|
} break;
|
||||||
|
case HitboxData.HITBOX_TYPE_STATIC_CAPSULE: {
|
||||||
|
type = HitboxType.HURT;
|
||||||
|
shapeType = HitboxShapeType.STATIC_CAPSULE;
|
||||||
|
geom = CollisionBodyCreation.createCapsuleShape(manager.getCollisionEngine(), hitboxDataRaw.getRadius(), hitboxDataRaw.getLength(), Collidable.TYPE_OBJECT_BIT);
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
if(hitboxDataRaw.getBone() != null){
|
||||||
|
rVal.hitboxGeomMap.put(hitboxDataRaw.getBone(),geom);
|
||||||
|
}
|
||||||
|
rVal.geoms.add(geom);
|
||||||
|
rVal.geomStateMap.put(geom,new HitboxState(hitboxDataRaw.getBone(), hitboxDataRaw, type, shapeType, true));
|
||||||
|
}
|
||||||
|
|
||||||
|
//create body with all the shapes
|
||||||
|
DGeom[] geomArray = rVal.geoms.toArray(new DGeom[rVal.geoms.size()]);
|
||||||
|
rVal.body = CollisionBodyCreation.createBodyWithShapes(manager.getCollisionEngine(), geomArray);
|
||||||
|
|
||||||
|
//register collidable with collision engine
|
||||||
|
Collidable collidable = new Collidable(entity, Collidable.TYPE_OBJECT);
|
||||||
|
manager.getCollisionEngine().registerCollisionObject(rVal.body, collidable);
|
||||||
|
|
||||||
|
//attach
|
||||||
|
entity.putData(EntityDataStrings.HITBOX_DATA, rVal);
|
||||||
|
rVal.parent = entity;
|
||||||
|
|
||||||
|
//register
|
||||||
|
manager.registerHitbox(rVal);
|
||||||
|
rVal.manager = manager;
|
||||||
|
|
||||||
|
return rVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create hitbox state for an entity
|
||||||
|
* @param collisionEngine the collision engine
|
||||||
|
* @param entity The entity to attach the state to
|
||||||
|
* @param data The hitbox data to apply
|
||||||
|
* @param callback The callback that provides a position for the hitbox each frame
|
||||||
|
* @return The hitbox state that has been attached to the entity
|
||||||
|
*/
|
||||||
|
public static HitboxCollectionState attachHitboxStateWithCallback(HitboxManager manager, CollisionEngine collisionEngine, Entity entity, HitboxData data, HitboxPositionCallback callback){
|
||||||
|
HitboxCollectionState rVal = new HitboxCollectionState();
|
||||||
|
|
||||||
|
//create the shapes
|
||||||
|
rVal.hitboxGeomMap.put(data.getBone(),CollisionBodyCreation.createShapeSphere(collisionEngine, data.getRadius(), Collidable.TYPE_OBJECT_BIT));
|
||||||
|
|
||||||
|
//create body with all the shapes
|
||||||
|
DGeom[] geomArray = rVal.hitboxGeomMap.values().toArray(new DGeom[rVal.hitboxGeomMap.values().size()]);
|
||||||
|
rVal.body = CollisionBodyCreation.createBodyWithShapes(collisionEngine, geomArray);
|
||||||
|
|
||||||
|
//register collidable with collision engine
|
||||||
|
Collidable collidable = new Collidable(entity, Collidable.TYPE_OBJECT);
|
||||||
|
collisionEngine.registerCollisionObject(rVal.body, collidable);
|
||||||
|
|
||||||
|
//attach
|
||||||
|
entity.putData(EntityDataStrings.HITBOX_DATA, rVal);
|
||||||
|
rVal.parent = entity;
|
||||||
|
|
||||||
|
//register
|
||||||
|
manager.registerHitbox(rVal);
|
||||||
|
rVal.manager = manager;
|
||||||
|
|
||||||
|
return rVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears the collision status of all shapes
|
||||||
|
*/
|
||||||
|
public void clearCollisions(){
|
||||||
|
for(DGeom geom : this.geoms){
|
||||||
|
HitboxState shapeStatus = this.geomStateMap.get(geom);
|
||||||
|
shapeStatus.setHadCollision(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the positions of all hitboxes
|
||||||
|
*/
|
||||||
|
public void updateHitboxPositions(CollisionEngine collisionEngine){
|
||||||
|
if(parent != null && !isServer && EntityUtils.getActor(parent) != null){
|
||||||
|
if(!this.hitboxGeomMap.isEmpty()){
|
||||||
|
Vector3d entityPosition = EntityUtils.getPosition(parent);
|
||||||
|
this.body.setPosition(PhysicsUtils.jomlVecToOdeVec(entityPosition));
|
||||||
|
for(String boneName : this.hitboxGeomMap.keySet()){
|
||||||
|
Vector3f bonePosition = EntityUtils.getActor(parent).getBonePosition(boneName);
|
||||||
|
DGeom geom = this.hitboxGeomMap.get(boneName);
|
||||||
|
HitboxState shapeStatus = this.geomStateMap.get(geom);
|
||||||
|
switch(shapeStatus.shapeType){
|
||||||
|
case SPHERE: {
|
||||||
|
this.updateSphereShapePosition(collisionEngine,boneName,bonePosition);
|
||||||
|
} break;
|
||||||
|
case CAPSULE: {
|
||||||
|
this.updateCapsuleShapePosition(collisionEngine,boneName,bonePosition);
|
||||||
|
} break;
|
||||||
|
case STATIC_CAPSULE: {
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if(positionCallback != null){
|
||||||
|
DGeom geom = body.getGeomIterator().next();
|
||||||
|
Vector3d worldPosition = this.positionCallback.getPosition();
|
||||||
|
Quaterniond rotation = new Quaterniond().identity();
|
||||||
|
|
||||||
|
PhysicsEntityUtils.setGeometryPosition(collisionEngine, geom, worldPosition, rotation);
|
||||||
|
}
|
||||||
|
} else if(parent != null && isServer && EntityUtils.getPoseActor(parent) != null){
|
||||||
|
if(!this.hitboxGeomMap.isEmpty()){
|
||||||
|
Vector3d entityPosition = EntityUtils.getPosition(parent);
|
||||||
|
this.body.setPosition(PhysicsUtils.jomlVecToOdeVec(entityPosition));
|
||||||
|
for(String boneName : this.hitboxGeomMap.keySet()){
|
||||||
|
Vector3f bonePosition = EntityUtils.getPoseActor(parent).getBonePosition(boneName);
|
||||||
|
DGeom geom = this.hitboxGeomMap.get(boneName);
|
||||||
|
HitboxState shapeStatus = this.geomStateMap.get(geom);
|
||||||
|
switch(shapeStatus.shapeType){
|
||||||
|
case SPHERE: {
|
||||||
|
this.updateSphereShapePosition(collisionEngine,boneName,bonePosition);
|
||||||
|
} break;
|
||||||
|
case CAPSULE: {
|
||||||
|
this.updateCapsuleShapePosition(collisionEngine,boneName,bonePosition);
|
||||||
|
} break;
|
||||||
|
case STATIC_CAPSULE: {
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if(positionCallback != null){
|
||||||
|
DGeom geom = body.getGeomIterator().next();
|
||||||
|
Vector3d worldPosition = this.positionCallback.getPosition();
|
||||||
|
Quaterniond rotation = new Quaterniond().identity();
|
||||||
|
|
||||||
|
PhysicsEntityUtils.setGeometryPosition(collisionEngine, geom, worldPosition, rotation);
|
||||||
|
}
|
||||||
|
} else if(parent != null && isServer){
|
||||||
|
for(DGeom geom : this.geoms){
|
||||||
|
HitboxState shapeStatus = this.geomStateMap.get(geom);
|
||||||
|
switch(shapeStatus.shapeType){
|
||||||
|
case SPHERE: {
|
||||||
|
} break;
|
||||||
|
case CAPSULE: {
|
||||||
|
} break;
|
||||||
|
case STATIC_CAPSULE: {
|
||||||
|
this.updateStaticCapsulePosition(collisionEngine, geom, shapeStatus);
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the position of the geom for a static capsule
|
||||||
|
* @param collisionEngine The collision engine
|
||||||
|
* @param boneName The name of the bone the static capsule is attached to
|
||||||
|
* @param bonePosition The position of the bone
|
||||||
|
*/
|
||||||
|
private void updateStaticCapsulePosition(CollisionEngine collisionEngine, DGeom geom, HitboxState shapeStatus){
|
||||||
|
Vector3d parentPos = EntityUtils.getPosition(parent);
|
||||||
|
PhysicsEntityUtils.setGeometryPosition(collisionEngine, geom, parentPos, new Quaterniond(0.707,0,0,0.707));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the position of a sphere-shape-type hitbox
|
||||||
|
* @param collisionEngine The collision engine
|
||||||
|
* @param boneName The name of the bone
|
||||||
|
* @param bonePosition the position of the bone
|
||||||
|
*/
|
||||||
|
private void updateSphereShapePosition(CollisionEngine collisionEngine, String boneName, Vector3f bonePosition){
|
||||||
|
DGeom geom = this.hitboxGeomMap.get(boneName);
|
||||||
|
Quaterniond parentRotation = EntityUtils.getRotation(parent);
|
||||||
|
Vector3f positionScale = EntityUtils.getScale(parent);
|
||||||
|
Vector3d worldPosition = new Vector3d();
|
||||||
|
Vector3d parentPos = EntityUtils.getPosition(parent);
|
||||||
|
Quaterniond rotation = new Quaterniond(parentRotation);
|
||||||
|
|
||||||
|
//calculate new world pos
|
||||||
|
worldPosition.set(bonePosition.x,bonePosition.y,bonePosition.z);
|
||||||
|
worldPosition = worldPosition.mul(positionScale);
|
||||||
|
worldPosition = worldPosition.rotate(rotation);
|
||||||
|
worldPosition.add(new Vector3f((float)parentPos.x,(float)parentPos.y,(float)parentPos.z));
|
||||||
|
|
||||||
|
PhysicsEntityUtils.setGeometryPosition(collisionEngine, geom, worldPosition, rotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the position of a capsule-shape hitbox
|
||||||
|
* @param collisionEngine
|
||||||
|
* @param boneName
|
||||||
|
* @param bonePosition
|
||||||
|
*/
|
||||||
|
private void updateCapsuleShapePosition(CollisionEngine collisionEngine, String boneName, Vector3f bonePosition){
|
||||||
|
DGeom geom = this.hitboxGeomMap.get(boneName);
|
||||||
|
HitboxState shapeStatus = this.geomStateMap.get(geom);
|
||||||
|
Quaterniond parentRotation = EntityUtils.getRotation(parent);
|
||||||
|
Vector3f positionScale = EntityUtils.getScale(parent);
|
||||||
|
Vector3d worldPosition = new Vector3d();
|
||||||
|
Vector3d parentPos = EntityUtils.getPosition(parent);
|
||||||
|
Quaterniond rotation = new Quaterniond(parentRotation);
|
||||||
|
Vector3d previousWorldPos = shapeStatus.getPreviousWorldPos();
|
||||||
|
|
||||||
|
//calculate new world pos
|
||||||
|
worldPosition.set(bonePosition.x,bonePosition.y,bonePosition.z);
|
||||||
|
worldPosition = worldPosition.mul(positionScale);
|
||||||
|
worldPosition = worldPosition.rotate(rotation);
|
||||||
|
worldPosition.add(new Vector3f((float)parentPos.x,(float)parentPos.y,(float)parentPos.z));
|
||||||
|
double length = shapeStatus.getHitboxData().getRadius();
|
||||||
|
double radius = shapeStatus.getHitboxData().getRadius();
|
||||||
|
|
||||||
|
if(previousWorldPos != null){
|
||||||
|
//called all subsequent updates to hitbox position
|
||||||
|
|
||||||
|
//destroy old capsule
|
||||||
|
this.geomStateMap.remove(geom);
|
||||||
|
this.geoms.remove(geom);
|
||||||
|
CollisionBodyCreation.destroyShape(collisionEngine, geom);
|
||||||
|
|
||||||
|
//calculate position between new world point and old world point
|
||||||
|
Vector3d bodyPosition = new Vector3d(worldPosition).lerp(previousWorldPos, 0.5);
|
||||||
|
|
||||||
|
//calculate rotation from old position to new position
|
||||||
|
//the second quaternion is a rotation along the x axis. This is used to put the hitbox rotation into ode's space
|
||||||
|
//ode is Z-axis-up
|
||||||
|
rotation = MathUtils.calculateRotationFromPointToPoint(previousWorldPos,worldPosition).mul(new Quaterniond(0,0,0.707,0.707));
|
||||||
|
|
||||||
|
//create new capsule
|
||||||
|
length = previousWorldPos.distance(worldPosition) / 2.0;
|
||||||
|
if(length > 5000 || Double.isNaN(length) || Double.isInfinite(length) || length <= 0){
|
||||||
|
length = 0.1;
|
||||||
|
System.out.println("HitboxState --- THIS IS NAN WHEN YOU SPAWN A KATANA BECAUSE THE BONE POSITION IS NAN???");
|
||||||
|
}
|
||||||
|
geom = CollisionBodyCreation.createCapsuleShape(manager.getCollisionEngine(), shapeStatus.getHitboxData().getRadius(), length, Collidable.TYPE_OBJECT_BIT);
|
||||||
|
CollisionBodyCreation.attachGeomToBody(collisionEngine,body,geom);
|
||||||
|
PhysicsEntityUtils.setGeometryPosition(collisionEngine, geom, bodyPosition, rotation);
|
||||||
|
} else {
|
||||||
|
//called first time the hitbox updates position
|
||||||
|
this.geomStateMap.remove(geom);
|
||||||
|
this.geoms.remove(geom);
|
||||||
|
CollisionBodyCreation.destroyShape(collisionEngine, geom);
|
||||||
|
|
||||||
|
//create new capsule
|
||||||
|
geom = CollisionBodyCreation.createCapsuleShape(manager.getCollisionEngine(), shapeStatus.getHitboxData().getRadius(), length, Collidable.TYPE_OBJECT_BIT);
|
||||||
|
CollisionBodyCreation.attachGeomToBody(collisionEngine,body,geom);
|
||||||
|
}
|
||||||
|
//update maps and other variables for next frame
|
||||||
|
this.hitboxGeomMap.put(boneName,geom);
|
||||||
|
this.geomStateMap.put(geom,shapeStatus);
|
||||||
|
this.geoms.add(geom);
|
||||||
|
shapeStatus.setPreviousWorldPos(worldPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the status of a shape in the hitbox object
|
||||||
|
* @param geom The geometry that is the shape within the hitbox data
|
||||||
|
* @return The status of the shape
|
||||||
|
*/
|
||||||
|
public HitboxState getShapeStatus(DGeom geom){
|
||||||
|
return this.geomStateMap.get(geom);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the hitbox state of the entity
|
||||||
|
* @param entity the entity
|
||||||
|
* @return the hitbox state if it exists
|
||||||
|
*/
|
||||||
|
public static HitboxCollectionState getHitboxState(Entity entity){
|
||||||
|
return (HitboxCollectionState)entity.getData(EntityDataStrings.HITBOX_DATA);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the entity has hitbox state or not
|
||||||
|
* @param entity the entity to check
|
||||||
|
* @return true if there is hitbox state, false otherwise
|
||||||
|
*/
|
||||||
|
public static boolean hasHitboxState(Entity entity){
|
||||||
|
return entity.containsKey(EntityDataStrings.HITBOX_DATA);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroys the hitbox state and removes it from the entity
|
||||||
|
* @param entity the entity
|
||||||
|
* @return The hitbox state if it exists, null otherwise
|
||||||
|
*/
|
||||||
|
public static HitboxCollectionState destroyHitboxState(Entity entity){
|
||||||
|
HitboxCollectionState state = null;
|
||||||
|
if(hasHitboxState(entity)){
|
||||||
|
state = getHitboxState(entity);
|
||||||
|
state.manager.deregisterHitbox(state);
|
||||||
|
}
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets whether the hitbox state is active or not
|
||||||
|
* @return true if active, false otherwise
|
||||||
|
*/
|
||||||
|
public boolean isActive(){
|
||||||
|
return active;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the active state of the hitbox
|
||||||
|
* @param state true to make it active, false otherwise
|
||||||
|
*/
|
||||||
|
public void setActive(boolean state){
|
||||||
|
this.active = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the list of all DGeoms in the data
|
||||||
|
* @return the list of all DGeoms
|
||||||
|
*/
|
||||||
|
public List<DGeom> getGeometries(){
|
||||||
|
return this.geoms;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the set of bone names in the state data
|
||||||
|
* @return The set of bone names in the state data
|
||||||
|
*/
|
||||||
|
public Set<String> getBones(){
|
||||||
|
return this.hitboxGeomMap.keySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets geometry on a single hitbox based on its bone name
|
||||||
|
* @param boneName the bone name
|
||||||
|
* @return the hitbox geometry
|
||||||
|
*/
|
||||||
|
public DGeom getGeometry(String boneName){
|
||||||
|
return this.hitboxGeomMap.get(boneName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The status of a single shape inside the overall hitbox data
|
||||||
|
* IE a single sphere on the overall body
|
||||||
|
*/
|
||||||
|
public static class HitboxState {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Types of geometry that can be used as individual shapes within a hitbox
|
||||||
|
*/
|
||||||
|
public enum HitboxShapeType {
|
||||||
|
//this is a true sphere. It will teleport every frame to its new position
|
||||||
|
SPHERE,
|
||||||
|
//for this one, the shape is a capsule in the collision engine, however
|
||||||
|
//the capsule is used to have continuity between the last position the hitbox occupied and the current one
|
||||||
|
CAPSULE,
|
||||||
|
//this is a true static capsule, it doesn't act as two connected spheres but is instead a capsule that teleports between frames
|
||||||
|
STATIC_CAPSULE,
|
||||||
|
}
|
||||||
|
|
||||||
|
//the name of the bone the hitbox is attached to
|
||||||
|
String boneName;
|
||||||
|
|
||||||
|
//the type of hitbox
|
||||||
|
HitboxType type;
|
||||||
|
|
||||||
|
//the type of geometry
|
||||||
|
HitboxShapeType shapeType;
|
||||||
|
|
||||||
|
//controls whether the hitbox is active
|
||||||
|
boolean isActive;
|
||||||
|
|
||||||
|
//the previous position of this hitbox shape
|
||||||
|
Vector3d previousWorldPos = null;
|
||||||
|
|
||||||
|
//if true, just had a collision
|
||||||
|
boolean hadCollision = false;
|
||||||
|
|
||||||
|
//the data of the hitbox
|
||||||
|
HitboxData data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a status object for a hitbox
|
||||||
|
* @param boneName The name of the bone the hitbox is attached to, if any
|
||||||
|
* @param data the hitbox data object
|
||||||
|
* @param type The type of hitbox
|
||||||
|
* @param shapeType The type of shape the hitbox is
|
||||||
|
* @param isActive if the hitbox is active or not
|
||||||
|
*/
|
||||||
|
public HitboxState(String boneName, HitboxData data, HitboxType type, HitboxShapeType shapeType, boolean isActive){
|
||||||
|
this.boneName = boneName;
|
||||||
|
this.data = data;
|
||||||
|
this.type = type;
|
||||||
|
this.shapeType = shapeType;
|
||||||
|
this.isActive = isActive;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the name of the bone the hitbox is attached to
|
||||||
|
* @return The name of the bone
|
||||||
|
*/
|
||||||
|
public String getBoneName(){
|
||||||
|
return boneName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the name of the bone the hitbox is attached to
|
||||||
|
* @param boneName The bone name
|
||||||
|
*/
|
||||||
|
public void setBoneName(String boneName){
|
||||||
|
this.boneName = boneName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the hitbox data for this shape
|
||||||
|
* @return The data
|
||||||
|
*/
|
||||||
|
public HitboxData getHitboxData(){
|
||||||
|
return this.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the hitbox data for this shape
|
||||||
|
* @param data The data
|
||||||
|
*/
|
||||||
|
public void setHitboxData(HitboxData data){
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the type of hitbox
|
||||||
|
* @return The type
|
||||||
|
*/
|
||||||
|
public HitboxType getType(){
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the type of hitbox
|
||||||
|
* @param type The type
|
||||||
|
*/
|
||||||
|
public void setType(HitboxType type){
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets whether the hitbox is active or not
|
||||||
|
* @return true if active, false otherwise
|
||||||
|
*/
|
||||||
|
public boolean isActive(){
|
||||||
|
return isActive;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether the hitbox is active or not
|
||||||
|
* @param active true for active, false otherwise
|
||||||
|
*/
|
||||||
|
public void setActive(boolean active){
|
||||||
|
this.isActive = active;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the previous world position of this hitbox
|
||||||
|
* @return The previous world position
|
||||||
|
*/
|
||||||
|
public Vector3d getPreviousWorldPos(){
|
||||||
|
return this.previousWorldPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sets the previous world position of this hitbox shape
|
||||||
|
* @param previousWorldPos The previous world position
|
||||||
|
*/
|
||||||
|
public void setPreviousWorldPos(Vector3d previousWorldPos){
|
||||||
|
this.previousWorldPos = previousWorldPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the status of whether this hitbox just had a collision or not
|
||||||
|
* @param hadCollision true if had a collision, false otherwise
|
||||||
|
*/
|
||||||
|
public void setHadCollision(boolean hadCollision){
|
||||||
|
this.hadCollision = hadCollision;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the collision status of the hitbox
|
||||||
|
* @return true if had a collision, false otherwise
|
||||||
|
*/
|
||||||
|
public boolean getHadCollision(){
|
||||||
|
return this.hadCollision;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -28,7 +28,7 @@ import electrosphere.renderer.anim.Animation;
|
|||||||
/**
|
/**
|
||||||
* Tree for playing an idle animation when an entity isn't doing anything
|
* Tree for playing an idle animation when an entity isn't doing anything
|
||||||
*/
|
*/
|
||||||
public class IdleTree implements BehaviorTree {
|
public class ClientIdleTree implements BehaviorTree {
|
||||||
|
|
||||||
@SynchronizableEnum
|
@SynchronizableEnum
|
||||||
public static enum IdleTreeState {
|
public static enum IdleTreeState {
|
||||||
@ -42,11 +42,19 @@ public class IdleTree implements BehaviorTree {
|
|||||||
Entity parent;
|
Entity parent;
|
||||||
IdleData idleData;
|
IdleData idleData;
|
||||||
|
|
||||||
public IdleTree(Entity e){
|
/**
|
||||||
|
* Creates an idle tree
|
||||||
|
* @param e the entity to attach the tree to
|
||||||
|
*/
|
||||||
|
public ClientIdleTree(Entity e){
|
||||||
state = IdleTreeState.IDLE;
|
state = IdleTreeState.IDLE;
|
||||||
parent = e;
|
parent = e;
|
||||||
|
//check if this is a creature, if so add its idle data
|
||||||
CreatureType creatureType = Globals.gameConfigCurrent.getCreatureTypeLoader().getCreature(CreatureUtils.getType(parent));
|
CreatureType creatureType = Globals.gameConfigCurrent.getCreatureTypeLoader().getCreature(CreatureUtils.getType(parent));
|
||||||
idleData = creatureType.getIdleData();
|
if(creatureType != null){
|
||||||
|
idleData = creatureType.getIdleData();
|
||||||
|
}
|
||||||
|
//TODO: if object, check if object has idle data and add accordingly
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -139,8 +147,8 @@ public class IdleTree implements BehaviorTree {
|
|||||||
* @param entity The entity to attach to
|
* @param entity The entity to attach to
|
||||||
* @param tree The behavior tree to attach
|
* @param tree The behavior tree to attach
|
||||||
*/
|
*/
|
||||||
public static IdleTree attachTree(Entity parent){
|
public static ClientIdleTree attachTree(Entity parent){
|
||||||
IdleTree rVal = new IdleTree(parent);
|
ClientIdleTree rVal = new ClientIdleTree(parent);
|
||||||
//put manual code here (setting params, etc)
|
//put manual code here (setting params, etc)
|
||||||
|
|
||||||
|
|
||||||
@ -194,8 +202,8 @@ public class IdleTree implements BehaviorTree {
|
|||||||
* @param entity the entity
|
* @param entity the entity
|
||||||
* @return The IdleTree
|
* @return The IdleTree
|
||||||
*/
|
*/
|
||||||
public static IdleTree getIdleTree(Entity entity){
|
public static ClientIdleTree getIdleTree(Entity entity){
|
||||||
return (IdleTree)entity.getData(EntityDataStrings.TREE_IDLE);
|
return (ClientIdleTree)entity.getData(EntityDataStrings.TREE_IDLE);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* <p> Automatically generated </p>
|
* <p> Automatically generated </p>
|
||||||
@ -2,7 +2,7 @@ package electrosphere.entity.state.idle;
|
|||||||
|
|
||||||
import electrosphere.entity.state.attack.ClientAttackTree.AttackTreeState;
|
import electrosphere.entity.state.attack.ClientAttackTree.AttackTreeState;
|
||||||
import electrosphere.entity.state.attack.ServerAttackTree;
|
import electrosphere.entity.state.attack.ServerAttackTree;
|
||||||
import electrosphere.entity.state.idle.IdleTree.IdleTreeState;
|
import electrosphere.entity.state.idle.ClientIdleTree.IdleTreeState;
|
||||||
import electrosphere.entity.state.movement.AirplaneMovementTree;
|
import electrosphere.entity.state.movement.AirplaneMovementTree;
|
||||||
import electrosphere.entity.state.movement.groundmove.ClientGroundMovementTree.MovementTreeState;
|
import electrosphere.entity.state.movement.groundmove.ClientGroundMovementTree.MovementTreeState;
|
||||||
import electrosphere.entity.state.movement.groundmove.ServerGroundMovementTree;
|
import electrosphere.entity.state.movement.groundmove.ServerGroundMovementTree;
|
||||||
@ -12,6 +12,7 @@ import electrosphere.entity.EntityDataStrings;
|
|||||||
import electrosphere.entity.EntityUtils;
|
import electrosphere.entity.EntityUtils;
|
||||||
import electrosphere.entity.btree.BehaviorTree;
|
import electrosphere.entity.btree.BehaviorTree;
|
||||||
import electrosphere.entity.types.creature.CreatureUtils;
|
import electrosphere.entity.types.creature.CreatureUtils;
|
||||||
|
import electrosphere.game.data.creature.type.CreatureType;
|
||||||
import electrosphere.net.parser.net.message.EntityMessage;
|
import electrosphere.net.parser.net.message.EntityMessage;
|
||||||
import electrosphere.net.parser.net.message.SynchronizationMessage;
|
import electrosphere.net.parser.net.message.SynchronizationMessage;
|
||||||
import electrosphere.net.synchronization.BehaviorTreeIdEnums;
|
import electrosphere.net.synchronization.BehaviorTreeIdEnums;
|
||||||
@ -39,6 +40,10 @@ public class ServerIdleTree implements BehaviorTree {
|
|||||||
|
|
||||||
CopyOnWriteArrayList<EntityMessage> networkMessageQueue = new CopyOnWriteArrayList<EntityMessage>();
|
CopyOnWriteArrayList<EntityMessage> networkMessageQueue = new CopyOnWriteArrayList<EntityMessage>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a server idle tree
|
||||||
|
* @param e The entity to attach it to
|
||||||
|
*/
|
||||||
public ServerIdleTree(Entity e){
|
public ServerIdleTree(Entity e){
|
||||||
state = IdleTreeState.IDLE;
|
state = IdleTreeState.IDLE;
|
||||||
parent = e;
|
parent = e;
|
||||||
@ -68,7 +73,7 @@ public class ServerIdleTree implements BehaviorTree {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void simulate(float deltaTime){
|
public void simulate(float deltaTime){
|
||||||
PoseActor entityActor = EntityUtils.getPoseActor(parent);
|
PoseActor poseActor = EntityUtils.getPoseActor(parent);
|
||||||
|
|
||||||
boolean movementTreeIsIdle = movementTreeIsIdle();
|
boolean movementTreeIsIdle = movementTreeIsIdle();
|
||||||
|
|
||||||
@ -83,12 +88,12 @@ public class ServerIdleTree implements BehaviorTree {
|
|||||||
//state machine
|
//state machine
|
||||||
switch(state){
|
switch(state){
|
||||||
case IDLE:
|
case IDLE:
|
||||||
if(entityActor != null){
|
if(poseActor != null){
|
||||||
if(
|
if(
|
||||||
(!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(Animation.ANIMATION_IDLE_1))
|
(!poseActor.isPlayingAnimation() || !poseActor.isPlayingAnimation(Animation.ANIMATION_IDLE_1))
|
||||||
){
|
){
|
||||||
entityActor.playAnimation(Animation.ANIMATION_IDLE_1,3);
|
poseActor.playAnimation(Animation.ANIMATION_IDLE_1,3);
|
||||||
entityActor.incrementAnimationTime(0.0001);
|
poseActor.incrementAnimationTime(0.0001);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
isIdle = true;
|
isIdle = true;
|
||||||
@ -184,7 +189,7 @@ public class ServerIdleTree implements BehaviorTree {
|
|||||||
*/
|
*/
|
||||||
public void setState(IdleTreeState state){
|
public void setState(IdleTreeState state){
|
||||||
this.state = state;
|
this.state = state;
|
||||||
int value = IdleTree.getIdleTreeStateEnumAsShort(state);
|
int value = ClientIdleTree.getIdleTreeStateEnumAsShort(state);
|
||||||
DataCellSearchUtils.getEntityDataCell(parent).broadcastNetworkMessage(SynchronizationMessage.constructUpdateClientStateMessage(parent.getId(), 7, 9, value));
|
DataCellSearchUtils.getEntityDataCell(parent).broadcastNetworkMessage(SynchronizationMessage.constructUpdateClientStateMessage(parent.getId(), 7, 9, value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -5,7 +5,6 @@ import java.util.concurrent.CopyOnWriteArrayList;
|
|||||||
import org.joml.Vector3d;
|
import org.joml.Vector3d;
|
||||||
|
|
||||||
import electrosphere.engine.Globals;
|
import electrosphere.engine.Globals;
|
||||||
import electrosphere.engine.Main;
|
|
||||||
import electrosphere.entity.Entity;
|
import electrosphere.entity.Entity;
|
||||||
import electrosphere.entity.EntityUtils;
|
import electrosphere.entity.EntityUtils;
|
||||||
import electrosphere.entity.btree.BehaviorTree;
|
import electrosphere.entity.btree.BehaviorTree;
|
||||||
@ -17,6 +16,9 @@ import electrosphere.net.parser.net.message.EntityMessage;
|
|||||||
import electrosphere.renderer.actor.Actor;
|
import electrosphere.renderer.actor.Actor;
|
||||||
import electrosphere.server.datacell.utils.DataCellSearchUtils;
|
import electrosphere.server.datacell.utils.DataCellSearchUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The status of the life value of a given entity
|
||||||
|
*/
|
||||||
public class LifeState implements BehaviorTree {
|
public class LifeState implements BehaviorTree {
|
||||||
|
|
||||||
|
|
||||||
@ -108,7 +110,6 @@ public class LifeState implements BehaviorTree {
|
|||||||
public void damage(int damage){
|
public void damage(int damage){
|
||||||
if(!isInvincible){
|
if(!isInvincible){
|
||||||
lifeCurrent = lifeCurrent - damage;
|
lifeCurrent = lifeCurrent - damage;
|
||||||
System.out.println(lifeCurrent);
|
|
||||||
isInvincible = true;
|
isInvincible = true;
|
||||||
if(lifeCurrent < 0){
|
if(lifeCurrent < 0){
|
||||||
lifeCurrent = 0;
|
lifeCurrent = 0;
|
||||||
@ -148,16 +149,7 @@ public class LifeState implements BehaviorTree {
|
|||||||
deathFrameCurrent = frameskip;
|
deathFrameCurrent = frameskip;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ATTACHENTITYTOENTITY:
|
default:
|
||||||
case ATTACKUPDATE:
|
|
||||||
case CREATE:
|
|
||||||
case DESTROY:
|
|
||||||
case SETBEHAVIORTREE:
|
|
||||||
case SETPOSITION:
|
|
||||||
case SETPROPERTY:
|
|
||||||
case MOVE:
|
|
||||||
case SETFACING:
|
|
||||||
case MOVEUPDATE:
|
|
||||||
//silently ignore
|
//silently ignore
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,7 +20,9 @@ import electrosphere.net.parser.net.message.EntityMessage;
|
|||||||
import electrosphere.renderer.actor.Actor;
|
import electrosphere.renderer.actor.Actor;
|
||||||
import electrosphere.renderer.anim.Animation;
|
import electrosphere.renderer.anim.Animation;
|
||||||
import electrosphere.server.datacell.utils.DataCellSearchUtils;
|
import electrosphere.server.datacell.utils.DataCellSearchUtils;
|
||||||
|
import electrosphere.util.MathUtils;
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public class AirplaneMovementTree implements BehaviorTree {
|
public class AirplaneMovementTree implements BehaviorTree {
|
||||||
|
|
||||||
public static enum AirplaneMovementTreeState {
|
public static enum AirplaneMovementTreeState {
|
||||||
@ -82,7 +84,7 @@ public class AirplaneMovementTree implements BehaviorTree {
|
|||||||
Actor entityActor = EntityUtils.getActor(parent);
|
Actor entityActor = EntityUtils.getActor(parent);
|
||||||
Vector3d position = EntityUtils.getPosition(parent);
|
Vector3d position = EntityUtils.getPosition(parent);
|
||||||
Vector3d facingVector = CreatureUtils.getFacingVector(parent);
|
Vector3d facingVector = CreatureUtils.getFacingVector(parent);
|
||||||
Quaterniond movementQuaternion = new Quaterniond().rotationTo(new Vector3d(0,0,1), new Vector3d(facingVector.x,0,facingVector.z)).normalize();
|
Quaterniond movementQuaternion = new Quaterniond().rotationTo(MathUtils.getOriginVector(), new Vector3d(facingVector.x,0,facingVector.z)).normalize();
|
||||||
Quaterniond rotation = EntityUtils.getRotation(parent);
|
Quaterniond rotation = EntityUtils.getRotation(parent);
|
||||||
//
|
//
|
||||||
//handle network messages
|
//handle network messages
|
||||||
@ -91,11 +93,6 @@ public class AirplaneMovementTree implements BehaviorTree {
|
|||||||
networkMessageQueue.remove(message);
|
networkMessageQueue.remove(message);
|
||||||
long updateTime = message.gettime();
|
long updateTime = message.gettime();
|
||||||
switch(message.getMessageSubtype()){
|
switch(message.getMessageSubtype()){
|
||||||
case MOVE: {
|
|
||||||
if(Globals.RUN_CLIENT){
|
|
||||||
position.set(message.getpositionX(), message.getpositionY(), message.getpositionZ());
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
//received a message to update the tree
|
//received a message to update the tree
|
||||||
case MOVEUPDATE: {
|
case MOVEUPDATE: {
|
||||||
if(updateTime > lastUpdateTime){
|
if(updateTime > lastUpdateTime){
|
||||||
@ -120,15 +117,6 @@ public class AirplaneMovementTree implements BehaviorTree {
|
|||||||
//we want to always update the server facing vector with where the client says they're facing
|
//we want to always update the server facing vector with where the client says they're facing
|
||||||
CreatureUtils.setFacingVector(parent, new Vector3d(message.getrotationX(),message.getrotationY(),message.getrotationZ()));
|
CreatureUtils.setFacingVector(parent, new Vector3d(message.getrotationX(),message.getrotationY(),message.getrotationZ()));
|
||||||
}
|
}
|
||||||
} break;
|
|
||||||
case SETBEHAVIORTREE: {
|
|
||||||
|
|
||||||
} break;
|
|
||||||
case SETFACING: {
|
|
||||||
|
|
||||||
} break;
|
|
||||||
case SETPOSITION: {
|
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
case ATTACHENTITYTOENTITY:
|
case ATTACHENTITYTOENTITY:
|
||||||
case ATTACKUPDATE:
|
case ATTACKUPDATE:
|
||||||
@ -200,15 +188,15 @@ public class AirplaneMovementTree implements BehaviorTree {
|
|||||||
|
|
||||||
|
|
||||||
Quaterniond yawQuat = new Quaterniond().fromAxisAngleRad(new Vector3d(0,1,0), yaw);
|
Quaterniond yawQuat = new Quaterniond().fromAxisAngleRad(new Vector3d(0,1,0), yaw);
|
||||||
Quaterniond pitchQuat = new Quaterniond().fromAxisAngleRad(new Vector3d(1,0,0), pitch);
|
Quaterniond pitchQuat = new Quaterniond().fromAxisAngleRad(MathUtils.getOriginVector(), pitch);
|
||||||
Quaterniond rollQuat = new Quaterniond().fromAxisAngleRad(new Vector3d(0,0,1), rollVal);
|
Quaterniond rollQuat = new Quaterniond().fromAxisAngleRad(MathUtils.getOriginVector(), rollVal);
|
||||||
|
|
||||||
rotation.slerp(yawQuat.mul(pitchQuat).mul(rollQuat),0.1);
|
rotation.slerp(yawQuat.mul(pitchQuat).mul(rollQuat),0.1);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//rotate thrust vector
|
//rotate thrust vector
|
||||||
rotationVector.set(rotation.transform(new Vector3d(0,0,1)));
|
rotationVector.set(rotation.transform(MathUtils.getOriginVector()));
|
||||||
// rotationVector.set(new Vector3f((float)rotationVector.x,(float)rotationVector.y,(float)rotationVector.z).mul(1.0f - this.maxRotationSpeed).add(new Vector3f(cameraEyeVector).mul(-this.maxRotationSpeed)));
|
// rotationVector.set(new Vector3f((float)rotationVector.x,(float)rotationVector.y,(float)rotationVector.z).mul(1.0f - this.maxRotationSpeed).add(new Vector3f(cameraEyeVector).mul(-this.maxRotationSpeed)));
|
||||||
|
|
||||||
|
|
||||||
@ -224,7 +212,7 @@ public class AirplaneMovementTree implements BehaviorTree {
|
|||||||
* @param collidable The collidable of the entity
|
* @param collidable The collidable of the entity
|
||||||
*/
|
*/
|
||||||
void addMovementForce(float velocity, Quaterniond rotation, Collidable collidable){
|
void addMovementForce(float velocity, Quaterniond rotation, Collidable collidable){
|
||||||
Vector3d impulseDir = rotation.transform(new Vector3d(0,0,1));
|
Vector3d impulseDir = rotation.transform(MathUtils.getOriginVector());
|
||||||
collidable.addImpulse(new Impulse(new Vector3d(impulseDir), new Vector3d(0,0,0), new Vector3d(0,0,0), velocity * Globals.timekeeper.getSimFrameTime(), "movement"));
|
collidable.addImpulse(new Impulse(new Vector3d(impulseDir), new Vector3d(0,0,0), new Vector3d(0,0,0), velocity * Globals.timekeeper.getSimFrameTime(), "movement"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -257,6 +245,7 @@ public class AirplaneMovementTree implements BehaviorTree {
|
|||||||
rotation.z,
|
rotation.z,
|
||||||
rotation.w,
|
rotation.w,
|
||||||
velocity,
|
velocity,
|
||||||
|
0,
|
||||||
stateNumber
|
stateNumber
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import electrosphere.entity.EntityDataStrings;
|
|||||||
import electrosphere.entity.EntityUtils;
|
import electrosphere.entity.EntityUtils;
|
||||||
import electrosphere.entity.btree.BehaviorTree;
|
import electrosphere.entity.btree.BehaviorTree;
|
||||||
import electrosphere.renderer.actor.Actor;
|
import electrosphere.renderer.actor.Actor;
|
||||||
|
import electrosphere.server.poseactor.PoseActor;
|
||||||
|
|
||||||
public class ServerFallTree implements BehaviorTree {
|
public class ServerFallTree implements BehaviorTree {
|
||||||
|
|
||||||
@ -28,17 +29,17 @@ public class ServerFallTree implements BehaviorTree {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void simulate(float deltaTime) {
|
public void simulate(float deltaTime) {
|
||||||
Actor entityActor = EntityUtils.getActor(parent);
|
PoseActor poseActor = EntityUtils.getPoseActor(parent);
|
||||||
switch(state){
|
switch(state){
|
||||||
case ACTIVE:
|
case ACTIVE:
|
||||||
if(entityActor != null){
|
if(poseActor != null){
|
||||||
String animationToPlay = determineCorrectAnimation();
|
String animationToPlay = determineCorrectAnimation();
|
||||||
if(
|
if(
|
||||||
!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(animationToPlay) &&
|
!poseActor.isPlayingAnimation() || !poseActor.isPlayingAnimation(animationToPlay) &&
|
||||||
(jumpTree == null || !jumpTree.isJumping())
|
(jumpTree == null || !jumpTree.isJumping())
|
||||||
){
|
){
|
||||||
entityActor.playAnimation(animationToPlay,1);
|
poseActor.playAnimation(animationToPlay,1);
|
||||||
entityActor.incrementAnimationTime(0.0001);
|
poseActor.incrementAnimationTime(0.0001);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -58,14 +59,14 @@ public class ServerFallTree implements BehaviorTree {
|
|||||||
public void land(){
|
public void land(){
|
||||||
if(state != FallState.INACTIVE){
|
if(state != FallState.INACTIVE){
|
||||||
state = FallState.INACTIVE;
|
state = FallState.INACTIVE;
|
||||||
Actor entityActor = EntityUtils.getActor(parent);
|
PoseActor poseActor = EntityUtils.getPoseActor(parent);
|
||||||
if(entityActor != null){
|
if(poseActor != null){
|
||||||
String animationToPlay = determineCorrectAnimation();
|
String animationToPlay = determineCorrectAnimation();
|
||||||
if(
|
if(
|
||||||
!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(animationToPlay)
|
!poseActor.isPlayingAnimation() || !poseActor.isPlayingAnimation(animationToPlay)
|
||||||
){
|
){
|
||||||
entityActor.playAnimation(animationToPlay,1);
|
poseActor.playAnimation(animationToPlay,1);
|
||||||
entityActor.incrementAnimationTime(0.0001);
|
poseActor.incrementAnimationTime(0.0001);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,6 +14,7 @@ import electrosphere.entity.state.collidable.Impulse;
|
|||||||
import electrosphere.entity.state.gravity.GravityUtils;
|
import electrosphere.entity.state.gravity.GravityUtils;
|
||||||
import electrosphere.entity.types.collision.CollisionObjUtils;
|
import electrosphere.entity.types.collision.CollisionObjUtils;
|
||||||
import electrosphere.renderer.actor.Actor;
|
import electrosphere.renderer.actor.Actor;
|
||||||
|
import electrosphere.server.poseactor.PoseActor;
|
||||||
|
|
||||||
public class ServerJumpTree implements BehaviorTree {
|
public class ServerJumpTree implements BehaviorTree {
|
||||||
|
|
||||||
@ -53,14 +54,14 @@ public class ServerJumpTree implements BehaviorTree {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void simulate(float deltaTime) {
|
public void simulate(float deltaTime) {
|
||||||
Actor entityActor = EntityUtils.getActor(parent);
|
PoseActor poseActor = EntityUtils.getPoseActor(parent);
|
||||||
switch(state){
|
switch(state){
|
||||||
case ACTIVE:
|
case ACTIVE:
|
||||||
if(entityActor != null){
|
if(poseActor != null){
|
||||||
String animationToPlay = determineCorrectAnimation();
|
String animationToPlay = determineCorrectAnimation();
|
||||||
if(!entityActor.isPlayingAnimation() || !entityActor.isPlayingAnimation(animationToPlay)){
|
if(!poseActor.isPlayingAnimation() || !poseActor.isPlayingAnimation(animationToPlay)){
|
||||||
entityActor.playAnimation(animationToPlay,1);
|
poseActor.playAnimation(animationToPlay,1);
|
||||||
entityActor.incrementAnimationTime(0.0001);
|
poseActor.incrementAnimationTime(0.0001);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
currentFrame++;
|
currentFrame++;
|
||||||
|
|||||||
@ -3,20 +3,13 @@ package electrosphere.entity.state.movement.groundmove;
|
|||||||
|
|
||||||
import electrosphere.net.synchronization.BehaviorTreeIdEnums;
|
import electrosphere.net.synchronization.BehaviorTreeIdEnums;
|
||||||
|
|
||||||
import electrosphere.entity.state.collidable.Impulse;
|
|
||||||
import electrosphere.entity.state.gravity.ClientGravityTree;
|
|
||||||
import electrosphere.entity.state.gravity.GravityUtils;
|
import electrosphere.entity.state.gravity.GravityUtils;
|
||||||
import electrosphere.collision.CollisionEngine;
|
|
||||||
import electrosphere.collision.PhysicsEntityUtils;
|
import electrosphere.collision.PhysicsEntityUtils;
|
||||||
import electrosphere.collision.PhysicsUtils;
|
|
||||||
import electrosphere.collision.collidable.Collidable;
|
import electrosphere.collision.collidable.Collidable;
|
||||||
import electrosphere.engine.Globals;
|
import electrosphere.engine.Globals;
|
||||||
import electrosphere.engine.Main;
|
|
||||||
import electrosphere.entity.types.camera.CameraEntityUtils;
|
|
||||||
import electrosphere.entity.types.collision.CollisionObjUtils;
|
import electrosphere.entity.types.collision.CollisionObjUtils;
|
||||||
import electrosphere.entity.types.creature.CreatureUtils;
|
import electrosphere.entity.types.creature.CreatureUtils;
|
||||||
import electrosphere.game.data.creature.type.movement.GroundMovementSystem;
|
import electrosphere.game.data.creature.type.movement.GroundMovementSystem;
|
||||||
import electrosphere.entity.ClientEntityUtils;
|
|
||||||
import electrosphere.entity.Entity;
|
import electrosphere.entity.Entity;
|
||||||
import electrosphere.entity.EntityDataStrings;
|
import electrosphere.entity.EntityDataStrings;
|
||||||
import electrosphere.entity.EntityUtils;
|
import electrosphere.entity.EntityUtils;
|
||||||
@ -28,24 +21,18 @@ import electrosphere.entity.state.movement.FallTree;
|
|||||||
import electrosphere.entity.state.movement.JumpTree;
|
import electrosphere.entity.state.movement.JumpTree;
|
||||||
import electrosphere.entity.state.movement.SprintTree;
|
import electrosphere.entity.state.movement.SprintTree;
|
||||||
import electrosphere.entity.state.movement.SprintTree.SprintTreeState;
|
import electrosphere.entity.state.movement.SprintTree.SprintTreeState;
|
||||||
import electrosphere.net.NetUtils;
|
|
||||||
import electrosphere.net.parser.net.message.EntityMessage;
|
import electrosphere.net.parser.net.message.EntityMessage;
|
||||||
import electrosphere.net.synchronization.annotation.SyncedField;
|
import electrosphere.net.synchronization.annotation.SyncedField;
|
||||||
|
import electrosphere.net.synchronization.annotation.SynchronizableEnum;
|
||||||
import electrosphere.net.synchronization.annotation.SynchronizedBehaviorTree;
|
import electrosphere.net.synchronization.annotation.SynchronizedBehaviorTree;
|
||||||
import electrosphere.renderer.anim.Animation;
|
import electrosphere.renderer.anim.Animation;
|
||||||
import electrosphere.renderer.model.Model;
|
import electrosphere.util.MathUtils;
|
||||||
import electrosphere.server.datacell.utils.DataCellSearchUtils;
|
|
||||||
import electrosphere.renderer.actor.Actor;
|
import electrosphere.renderer.actor.Actor;
|
||||||
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
import org.joml.Quaterniond;
|
import org.joml.Quaterniond;
|
||||||
import org.joml.Quaternionf;
|
|
||||||
import org.joml.Vector3d;
|
import org.joml.Vector3d;
|
||||||
import org.joml.Vector3f;
|
|
||||||
import org.ode4j.math.DVector3;
|
|
||||||
import org.ode4j.math.DVector3C;
|
import org.ode4j.math.DVector3C;
|
||||||
import org.ode4j.ode.DBody;
|
import org.ode4j.ode.DBody;
|
||||||
|
|
||||||
@ -69,6 +56,7 @@ public class ClientGroundMovementTree implements BehaviorTree {
|
|||||||
* The relative facing of the character to its rotation
|
* The relative facing of the character to its rotation
|
||||||
* (ie is it strafing, moveing straight forward, backpedaling, etc)
|
* (ie is it strafing, moveing straight forward, backpedaling, etc)
|
||||||
*/
|
*/
|
||||||
|
@SynchronizableEnum
|
||||||
public static enum MovementRelativeFacing {
|
public static enum MovementRelativeFacing {
|
||||||
FORWARD,
|
FORWARD,
|
||||||
LEFT,
|
LEFT,
|
||||||
@ -81,8 +69,10 @@ public class ClientGroundMovementTree implements BehaviorTree {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static final double STATE_DIFFERENCE_HARD_UPDATE_THRESHOLD = 1.0;
|
static final double STATE_DIFFERENCE_HARD_UPDATE_THRESHOLD = 1.0;
|
||||||
static final double STATE_DIFFERENCE_SOFT_UPDATE_THRESHOLD = 0.2;
|
static final double STATE_DIFFERENCE_SOFT_UPDATE_THRESHOLD = 0.1;
|
||||||
static final double SOFT_UPDATE_MULTIPLIER = 0.1;
|
static final double SOFT_UPDATE_MULTIPLIER = 0.3;
|
||||||
|
static final double STATE_DIFFERENCE_CREEP_MULTIPLIER = 0.001; //while the movement tree is idle, slowly creep the position of the entity towards the true server position by this amount
|
||||||
|
static final double STATE_DIFFERENCE_CREEP_CUTOFF = 0.01; //the cutoff for creep when we say it's "close enough"
|
||||||
|
|
||||||
String animationStartUp = Animation.ANIMATION_MOVEMENT_STARTUP;
|
String animationStartUp = Animation.ANIMATION_MOVEMENT_STARTUP;
|
||||||
String animationMain = Animation.ANIMATION_MOVEMENT_MOVE;
|
String animationMain = Animation.ANIMATION_MOVEMENT_MOVE;
|
||||||
@ -107,18 +97,32 @@ public class ClientGroundMovementTree implements BehaviorTree {
|
|||||||
|
|
||||||
CopyOnWriteArrayList<EntityMessage> networkMessageQueue = new CopyOnWriteArrayList<EntityMessage>();
|
CopyOnWriteArrayList<EntityMessage> networkMessageQueue = new CopyOnWriteArrayList<EntityMessage>();
|
||||||
|
|
||||||
|
//the last frame we got an update on true position from the server
|
||||||
long lastUpdateTime = 0;
|
long lastUpdateTime = 0;
|
||||||
|
//the last position reported by the server
|
||||||
|
Vector3d lastServerPosition = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param e The parent entity
|
||||||
|
*/
|
||||||
private ClientGroundMovementTree(Entity e){
|
private ClientGroundMovementTree(Entity e){
|
||||||
state = MovementTreeState.IDLE;
|
state = MovementTreeState.IDLE;
|
||||||
parent = e;
|
parent = e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the state of the tree
|
||||||
|
* @return The state
|
||||||
|
*/
|
||||||
public MovementTreeState getState(){
|
public MovementTreeState getState(){
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Requests to the server that the entity start moving
|
||||||
|
* @param facing The facing relative to the view direction that the entity should move in (ie strafe right vs walk straight forward)
|
||||||
|
*/
|
||||||
public void start(MovementRelativeFacing facing){
|
public void start(MovementRelativeFacing facing){
|
||||||
if(canStartMoving()){
|
if(canStartMoving()){
|
||||||
setFacing(facing);
|
setFacing(facing);
|
||||||
@ -126,7 +130,6 @@ public class ClientGroundMovementTree implements BehaviorTree {
|
|||||||
//if we aren't the server, alert the server we intend to walk forward
|
//if we aren't the server, alert the server we intend to walk forward
|
||||||
Vector3d position = EntityUtils.getPosition(parent);
|
Vector3d position = EntityUtils.getPosition(parent);
|
||||||
Quaterniond rotation = EntityUtils.getRotation(parent);
|
Quaterniond rotation = EntityUtils.getRotation(parent);
|
||||||
Vector3d facingVector = CreatureUtils.getFacingVector(parent);
|
|
||||||
float velocity = CreatureUtils.getVelocity(parent);
|
float velocity = CreatureUtils.getVelocity(parent);
|
||||||
Globals.clientConnection.queueOutgoingMessage(
|
Globals.clientConnection.queueOutgoingMessage(
|
||||||
EntityMessage.constructmoveUpdateMessage(
|
EntityMessage.constructmoveUpdateMessage(
|
||||||
@ -140,23 +143,21 @@ public class ClientGroundMovementTree implements BehaviorTree {
|
|||||||
rotation.z,
|
rotation.z,
|
||||||
rotation.w,
|
rotation.w,
|
||||||
velocity,
|
velocity,
|
||||||
|
ClientGroundMovementTree.getMovementRelativeFacingEnumAsShort(facing),
|
||||||
0 //magic number corresponding to state startup
|
0 //magic number corresponding to state startup
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void interrupt(){
|
/**
|
||||||
state = MovementTreeState.IDLE;
|
* Requests to the server that the movetree stop
|
||||||
CreatureUtils.setVelocity(parent, 0);
|
*/
|
||||||
}
|
|
||||||
|
|
||||||
public void slowdown(){
|
public void slowdown(){
|
||||||
state = MovementTreeState.SLOWDOWN;
|
state = MovementTreeState.SLOWDOWN;
|
||||||
//if we aren't the server, alert the server we intend to slow down
|
//if we aren't the server, alert the server we intend to slow down
|
||||||
Vector3d position = EntityUtils.getPosition(parent);
|
Vector3d position = EntityUtils.getPosition(parent);
|
||||||
Quaterniond rotation = EntityUtils.getRotation(parent);
|
Quaterniond rotation = EntityUtils.getRotation(parent);
|
||||||
Vector3d facingVector = CreatureUtils.getFacingVector(parent);
|
|
||||||
float velocity = CreatureUtils.getVelocity(parent);
|
float velocity = CreatureUtils.getVelocity(parent);
|
||||||
Globals.clientConnection.queueOutgoingMessage(
|
Globals.clientConnection.queueOutgoingMessage(
|
||||||
EntityMessage.constructmoveUpdateMessage(
|
EntityMessage.constructmoveUpdateMessage(
|
||||||
@ -170,11 +171,13 @@ public class ClientGroundMovementTree implements BehaviorTree {
|
|||||||
rotation.z,
|
rotation.z,
|
||||||
rotation.w,
|
rotation.w,
|
||||||
velocity,
|
velocity,
|
||||||
|
ClientGroundMovementTree.getMovementRelativeFacingEnumAsShort(facing),
|
||||||
2 //magic number corresponding to state slowdown
|
2 //magic number corresponding to state slowdown
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void simulate(float deltaTime){
|
public void simulate(float deltaTime){
|
||||||
float velocity = CreatureUtils.getVelocity(parent);
|
float velocity = CreatureUtils.getVelocity(parent);
|
||||||
float acceleration = CreatureUtils.getAcceleration(parent);
|
float acceleration = CreatureUtils.getAcceleration(parent);
|
||||||
@ -215,7 +218,7 @@ public class ClientGroundMovementTree implements BehaviorTree {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// float movementYaw = CameraEntityUtils.getCameraYaw(Globals.playerCamera);
|
// float movementYaw = CameraEntityUtils.getCameraYaw(Globals.playerCamera);
|
||||||
Quaterniond movementQuaternion = new Quaterniond().rotationTo(new Vector3d(0,0,1), new Vector3d(facingVector.x,0,facingVector.z)).normalize();
|
Quaterniond movementQuaternion = new Quaterniond().rotationTo(MathUtils.getOriginVector(), new Vector3d(facingVector.x,0,facingVector.z)).normalize();
|
||||||
Quaterniond rotation = EntityUtils.getRotation(parent);
|
Quaterniond rotation = EntityUtils.getRotation(parent);
|
||||||
//TODO: optimize away and document (I know for the moment if this exception isn't here it will bite me in the ass later)
|
//TODO: optimize away and document (I know for the moment if this exception isn't here it will bite me in the ass later)
|
||||||
if(facingVector.length() == 0){
|
if(facingVector.length() == 0){
|
||||||
@ -229,11 +232,6 @@ public class ClientGroundMovementTree implements BehaviorTree {
|
|||||||
long updateTime = message.gettime();
|
long updateTime = message.gettime();
|
||||||
// System.out.println("MOVE to " + message.getX() + " " + message.getY() + " " + message.getZ());
|
// System.out.println("MOVE to " + message.getX() + " " + message.getY() + " " + message.getZ());
|
||||||
switch(message.getMessageSubtype()){
|
switch(message.getMessageSubtype()){
|
||||||
case MOVE:
|
|
||||||
position.set(message.getpositionX(), message.getpositionY(), message.getpositionZ());
|
|
||||||
break;
|
|
||||||
case SETFACING:
|
|
||||||
break;
|
|
||||||
case MOVEUPDATE:
|
case MOVEUPDATE:
|
||||||
if(updateTime > lastUpdateTime){
|
if(updateTime > lastUpdateTime){
|
||||||
lastUpdateTime = updateTime;
|
lastUpdateTime = updateTime;
|
||||||
@ -258,14 +256,13 @@ public class ClientGroundMovementTree implements BehaviorTree {
|
|||||||
// System.out.println("Set state IDLE");
|
// System.out.println("Set state IDLE");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// System.out.println(EntityUtils.getEntityPosition(parent));
|
|
||||||
// System.out.println(message.getpositionX() + " " + message.getpositionY() + " " + message.getpositionZ());
|
|
||||||
//this should only fire on the client, we don't want the server snap updating due to client position reporting
|
//this should only fire on the client, we don't want the server snap updating due to client position reporting
|
||||||
// if(position.distance(message.getpositionX(),message.getpositionY(),message.getpositionZ()) > STATE_DIFFERENCE_HARD_UPDATE_THRESHOLD){
|
lastServerPosition = new Vector3d(message.getpositionX(),message.getpositionY(),message.getpositionZ());
|
||||||
// EntityUtils.getPosition(parent).set(message.getpositionX(),message.getpositionY(),message.getpositionZ());
|
if(position.distance(lastServerPosition) > STATE_DIFFERENCE_HARD_UPDATE_THRESHOLD){
|
||||||
// } else if(position.distance(message.getpositionX(),message.getpositionY(),message.getpositionZ()) > STATE_DIFFERENCE_SOFT_UPDATE_THRESHOLD){
|
EntityUtils.getPosition(parent).set(lastServerPosition);
|
||||||
// EntityUtils.getPosition(parent).add(new Vector3d(message.getpositionX(),message.getpositionY(),message.getpositionZ()).mul(SOFT_UPDATE_MULTIPLIER));
|
} else if(position.distance(lastServerPosition) > STATE_DIFFERENCE_SOFT_UPDATE_THRESHOLD){
|
||||||
// }
|
EntityUtils.getPosition(parent).lerp(lastServerPosition,SOFT_UPDATE_MULTIPLIER);
|
||||||
|
}
|
||||||
//we want to always update the server facing vector with where the client says they're facing
|
//we want to always update the server facing vector with where the client says they're facing
|
||||||
EntityUtils.getRotation(parent).set(message.getrotationX(),message.getrotationY(),message.getrotationZ(),message.getrotationW());
|
EntityUtils.getRotation(parent).set(message.getrotationX(),message.getrotationY(),message.getrotationZ(),message.getrotationW());
|
||||||
CollisionObjUtils.clientPositionCharacter(parent, position);
|
CollisionObjUtils.clientPositionCharacter(parent, position);
|
||||||
@ -282,7 +279,7 @@ public class ClientGroundMovementTree implements BehaviorTree {
|
|||||||
|
|
||||||
//state machine
|
//state machine
|
||||||
switch(state){
|
switch(state){
|
||||||
case STARTUP:
|
case STARTUP: {
|
||||||
if(entityActor != null){
|
if(entityActor != null){
|
||||||
String animationToPlay = determineCorrectAnimation();
|
String animationToPlay = determineCorrectAnimation();
|
||||||
if(
|
if(
|
||||||
@ -313,9 +310,8 @@ public class ClientGroundMovementTree implements BehaviorTree {
|
|||||||
rotation.set(movementQuaternion);
|
rotation.set(movementQuaternion);
|
||||||
|
|
||||||
GravityUtils.clientAttemptActivateGravity(parent);
|
GravityUtils.clientAttemptActivateGravity(parent);
|
||||||
|
} break;
|
||||||
break;
|
case MOVE: {
|
||||||
case MOVE:
|
|
||||||
//check if can restart animation
|
//check if can restart animation
|
||||||
//if yes, restart animation
|
//if yes, restart animation
|
||||||
if(entityActor != null){
|
if(entityActor != null){
|
||||||
@ -343,9 +339,8 @@ public class ClientGroundMovementTree implements BehaviorTree {
|
|||||||
rotation.set(movementQuaternion);
|
rotation.set(movementQuaternion);
|
||||||
|
|
||||||
GravityUtils.clientAttemptActivateGravity(parent);
|
GravityUtils.clientAttemptActivateGravity(parent);
|
||||||
|
} break;
|
||||||
break;
|
case SLOWDOWN: {
|
||||||
case SLOWDOWN:
|
|
||||||
//run slowdown code
|
//run slowdown code
|
||||||
if(entityActor != null){
|
if(entityActor != null){
|
||||||
String animationToPlay = determineCorrectAnimation();
|
String animationToPlay = determineCorrectAnimation();
|
||||||
@ -382,10 +377,13 @@ public class ClientGroundMovementTree implements BehaviorTree {
|
|||||||
rotation.set(movementQuaternion);
|
rotation.set(movementQuaternion);
|
||||||
|
|
||||||
GravityUtils.clientAttemptActivateGravity(parent);
|
GravityUtils.clientAttemptActivateGravity(parent);
|
||||||
|
} break;
|
||||||
break;
|
case IDLE: {
|
||||||
case IDLE:
|
Vector3d playerPos = EntityUtils.getPosition(parent);
|
||||||
break;
|
if(lastServerPosition != null && lastServerPosition.distance(playerPos) > STATE_DIFFERENCE_CREEP_CUTOFF){
|
||||||
|
playerPos.lerp(lastServerPosition,STATE_DIFFERENCE_CREEP_MULTIPLIER);
|
||||||
|
}
|
||||||
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -710,4 +708,74 @@ public class ClientGroundMovementTree implements BehaviorTree {
|
|||||||
return (ClientGroundMovementTree)entity.getData(EntityDataStrings.TREE_CLIENTGROUNDMOVEMENTTREE);
|
return (ClientGroundMovementTree)entity.getData(EntityDataStrings.TREE_CLIENTGROUNDMOVEMENTTREE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Gets the ClientGroundMovementTree of the entity
|
||||||
|
* </p>
|
||||||
|
* @param entity the entity
|
||||||
|
* @return The ClientGroundMovementTree
|
||||||
|
*/
|
||||||
|
public static ClientGroundMovementTree getClientGroundMovementTree(Entity entity){
|
||||||
|
return (ClientGroundMovementTree)entity.getData(EntityDataStrings.TREE_CLIENTGROUNDMOVEMENTTREE);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <p> Automatically generated </p>
|
||||||
|
* <p>
|
||||||
|
* Converts this enum type to an equivalent short value
|
||||||
|
* </p>
|
||||||
|
* @param enumVal The enum value
|
||||||
|
* @return The short value
|
||||||
|
*/
|
||||||
|
public static short getMovementRelativeFacingEnumAsShort(MovementRelativeFacing enumVal){
|
||||||
|
switch(enumVal){
|
||||||
|
case FORWARD:
|
||||||
|
return 0;
|
||||||
|
case LEFT:
|
||||||
|
return 1;
|
||||||
|
case RIGHT:
|
||||||
|
return 2;
|
||||||
|
case BACKWARD:
|
||||||
|
return 3;
|
||||||
|
case FORWARD_LEFT:
|
||||||
|
return 4;
|
||||||
|
case FORWARD_RIGHT:
|
||||||
|
return 5;
|
||||||
|
case BACKWARD_LEFT:
|
||||||
|
return 6;
|
||||||
|
case BACKWARD_RIGHT:
|
||||||
|
return 7;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <p> Automatically generated </p>
|
||||||
|
* <p>
|
||||||
|
* Converts a short to the equivalent enum value
|
||||||
|
* </p>
|
||||||
|
* @param shortVal The short value
|
||||||
|
* @return The enum value
|
||||||
|
*/
|
||||||
|
public static MovementRelativeFacing getMovementRelativeFacingShortAsEnum(short shortVal){
|
||||||
|
switch(shortVal){
|
||||||
|
case 0:
|
||||||
|
return MovementRelativeFacing.FORWARD;
|
||||||
|
case 1:
|
||||||
|
return MovementRelativeFacing.LEFT;
|
||||||
|
case 2:
|
||||||
|
return MovementRelativeFacing.RIGHT;
|
||||||
|
case 3:
|
||||||
|
return MovementRelativeFacing.BACKWARD;
|
||||||
|
case 4:
|
||||||
|
return MovementRelativeFacing.FORWARD_LEFT;
|
||||||
|
case 5:
|
||||||
|
return MovementRelativeFacing.FORWARD_RIGHT;
|
||||||
|
case 6:
|
||||||
|
return MovementRelativeFacing.BACKWARD_LEFT;
|
||||||
|
case 7:
|
||||||
|
return MovementRelativeFacing.BACKWARD_RIGHT;
|
||||||
|
default:
|
||||||
|
return MovementRelativeFacing.FORWARD;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,17 +1,14 @@
|
|||||||
package electrosphere.entity.state.movement.groundmove;
|
package electrosphere.entity.state.movement.groundmove;
|
||||||
|
|
||||||
|
|
||||||
|
import electrosphere.net.parser.net.message.SynchronizationMessage;
|
||||||
|
|
||||||
import electrosphere.net.synchronization.BehaviorTreeIdEnums;
|
import electrosphere.net.synchronization.BehaviorTreeIdEnums;
|
||||||
|
|
||||||
import electrosphere.entity.state.collidable.Impulse;
|
|
||||||
import electrosphere.entity.state.gravity.GravityUtils;
|
import electrosphere.entity.state.gravity.GravityUtils;
|
||||||
import electrosphere.collision.CollisionEngine;
|
|
||||||
import electrosphere.collision.PhysicsEntityUtils;
|
import electrosphere.collision.PhysicsEntityUtils;
|
||||||
import electrosphere.collision.PhysicsUtils;
|
|
||||||
import electrosphere.collision.collidable.Collidable;
|
import electrosphere.collision.collidable.Collidable;
|
||||||
import electrosphere.engine.Globals;
|
import electrosphere.engine.Globals;
|
||||||
import electrosphere.engine.Main;
|
|
||||||
import electrosphere.entity.types.camera.CameraEntityUtils;
|
|
||||||
import electrosphere.entity.types.creature.CreatureUtils;
|
import electrosphere.entity.types.creature.CreatureUtils;
|
||||||
import electrosphere.entity.Entity;
|
import electrosphere.entity.Entity;
|
||||||
import electrosphere.entity.EntityDataStrings;
|
import electrosphere.entity.EntityDataStrings;
|
||||||
@ -25,38 +22,28 @@ import electrosphere.entity.state.movement.ServerSprintTree;
|
|||||||
import electrosphere.entity.state.movement.ServerSprintTree.SprintTreeState;
|
import electrosphere.entity.state.movement.ServerSprintTree.SprintTreeState;
|
||||||
import electrosphere.entity.state.movement.groundmove.ClientGroundMovementTree.MovementRelativeFacing;
|
import electrosphere.entity.state.movement.groundmove.ClientGroundMovementTree.MovementRelativeFacing;
|
||||||
import electrosphere.entity.state.movement.groundmove.ClientGroundMovementTree.MovementTreeState;
|
import electrosphere.entity.state.movement.groundmove.ClientGroundMovementTree.MovementTreeState;
|
||||||
import electrosphere.net.NetUtils;
|
|
||||||
import electrosphere.net.parser.net.message.EntityMessage;
|
import electrosphere.net.parser.net.message.EntityMessage;
|
||||||
import electrosphere.net.synchronization.annotation.SyncedField;
|
import electrosphere.net.synchronization.annotation.SyncedField;
|
||||||
import electrosphere.net.synchronization.annotation.SynchronizedBehaviorTree;
|
import electrosphere.net.synchronization.annotation.SynchronizedBehaviorTree;
|
||||||
import electrosphere.renderer.anim.Animation;
|
import electrosphere.renderer.anim.Animation;
|
||||||
import electrosphere.renderer.model.Model;
|
|
||||||
import electrosphere.server.datacell.utils.DataCellSearchUtils;
|
import electrosphere.server.datacell.utils.DataCellSearchUtils;
|
||||||
import electrosphere.server.poseactor.PoseActor;
|
import electrosphere.server.poseactor.PoseActor;
|
||||||
import electrosphere.renderer.actor.Actor;
|
import electrosphere.util.MathUtils;
|
||||||
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
import org.joml.Quaterniond;
|
import org.joml.Quaterniond;
|
||||||
import org.joml.Quaternionf;
|
|
||||||
import org.joml.Vector3d;
|
import org.joml.Vector3d;
|
||||||
import org.joml.Vector3f;
|
|
||||||
import org.ode4j.math.DVector3C;
|
import org.ode4j.math.DVector3C;
|
||||||
import org.ode4j.ode.DBody;
|
import org.ode4j.ode.DBody;
|
||||||
|
|
||||||
@SynchronizedBehaviorTree(name = "serverGroundMovementTree", isServer = false, correspondingTree="clientGroundMovementTree")
|
@SynchronizedBehaviorTree(name = "serverGroundMovementTree", isServer = true, correspondingTree="clientGroundMovementTree")
|
||||||
/*
|
/*
|
||||||
Behavior tree for movement in an entity
|
Behavior tree for movement in an entity
|
||||||
*/
|
*/
|
||||||
public class ServerGroundMovementTree implements BehaviorTree {
|
public class ServerGroundMovementTree implements BehaviorTree {
|
||||||
|
|
||||||
|
|
||||||
static final double STATE_DIFFERENCE_HARD_UPDATE_THRESHOLD = 1.0;
|
|
||||||
static final double STATE_DIFFERENCE_SOFT_UPDATE_THRESHOLD = 0.2;
|
|
||||||
static final double SOFT_UPDATE_MULTIPLIER = 0.1;
|
|
||||||
|
|
||||||
String animationStartUp = Animation.ANIMATION_MOVEMENT_STARTUP;
|
String animationStartUp = Animation.ANIMATION_MOVEMENT_STARTUP;
|
||||||
String animationMain = Animation.ANIMATION_MOVEMENT_MOVE;
|
String animationMain = Animation.ANIMATION_MOVEMENT_MOVE;
|
||||||
String animationSlowDown = Animation.ANIMATION_MOVEMENT_MOVE;
|
String animationSlowDown = Animation.ANIMATION_MOVEMENT_MOVE;
|
||||||
@ -81,7 +68,7 @@ public class ServerGroundMovementTree implements BehaviorTree {
|
|||||||
long lastUpdateTime = 0;
|
long lastUpdateTime = 0;
|
||||||
|
|
||||||
|
|
||||||
public ServerGroundMovementTree(Entity e){
|
private ServerGroundMovementTree(Entity e){
|
||||||
state = MovementTreeState.IDLE;
|
state = MovementTreeState.IDLE;
|
||||||
facing = MovementRelativeFacing.FORWARD;
|
facing = MovementRelativeFacing.FORWARD;
|
||||||
parent = e;
|
parent = e;
|
||||||
@ -91,6 +78,10 @@ public class ServerGroundMovementTree implements BehaviorTree {
|
|||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts the server movement tree
|
||||||
|
* @param facing The facing dir to start with
|
||||||
|
*/
|
||||||
public void start(MovementRelativeFacing facing){
|
public void start(MovementRelativeFacing facing){
|
||||||
if(canStartMoving()){
|
if(canStartMoving()){
|
||||||
setFacing(facing);
|
setFacing(facing);
|
||||||
@ -98,7 +89,6 @@ public class ServerGroundMovementTree implements BehaviorTree {
|
|||||||
//if we aren't the server, alert the server we intend to walk forward
|
//if we aren't the server, alert the server we intend to walk forward
|
||||||
Vector3d position = EntityUtils.getPosition(parent);
|
Vector3d position = EntityUtils.getPosition(parent);
|
||||||
Quaterniond rotation = EntityUtils.getRotation(parent);
|
Quaterniond rotation = EntityUtils.getRotation(parent);
|
||||||
Vector3d facingVector = CreatureUtils.getFacingVector(parent);
|
|
||||||
float velocity = CreatureUtils.getVelocity(parent);
|
float velocity = CreatureUtils.getVelocity(parent);
|
||||||
DataCellSearchUtils.getEntityDataCell(parent).broadcastNetworkMessage(
|
DataCellSearchUtils.getEntityDataCell(parent).broadcastNetworkMessage(
|
||||||
EntityMessage.constructmoveUpdateMessage(
|
EntityMessage.constructmoveUpdateMessage(
|
||||||
@ -112,23 +102,29 @@ public class ServerGroundMovementTree implements BehaviorTree {
|
|||||||
rotation.z,
|
rotation.z,
|
||||||
rotation.w,
|
rotation.w,
|
||||||
velocity,
|
velocity,
|
||||||
|
ClientGroundMovementTree.getMovementRelativeFacingEnumAsShort(facing),
|
||||||
0 //magic number corresponding to state startup
|
0 //magic number corresponding to state startup
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interrupts the tree
|
||||||
|
*/
|
||||||
public void interrupt(){
|
public void interrupt(){
|
||||||
state = MovementTreeState.IDLE;
|
state = MovementTreeState.IDLE;
|
||||||
CreatureUtils.setVelocity(parent, 0);
|
CreatureUtils.setVelocity(parent, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Triggers the move tree to slow down
|
||||||
|
*/
|
||||||
public void slowdown(){
|
public void slowdown(){
|
||||||
state = MovementTreeState.SLOWDOWN;
|
state = MovementTreeState.SLOWDOWN;
|
||||||
//if we aren't the server, alert the server we intend to slow down
|
//if we aren't the server, alert the server we intend to slow down
|
||||||
Vector3d position = EntityUtils.getPosition(parent);
|
Vector3d position = EntityUtils.getPosition(parent);
|
||||||
Quaterniond rotation = EntityUtils.getRotation(parent);
|
Quaterniond rotation = EntityUtils.getRotation(parent);
|
||||||
Vector3d facingVector = CreatureUtils.getFacingVector(parent);
|
|
||||||
float velocity = CreatureUtils.getVelocity(parent);
|
float velocity = CreatureUtils.getVelocity(parent);
|
||||||
DataCellSearchUtils.getEntityDataCell(parent).broadcastNetworkMessage(
|
DataCellSearchUtils.getEntityDataCell(parent).broadcastNetworkMessage(
|
||||||
EntityMessage.constructmoveUpdateMessage(
|
EntityMessage.constructmoveUpdateMessage(
|
||||||
@ -142,11 +138,13 @@ public class ServerGroundMovementTree implements BehaviorTree {
|
|||||||
rotation.z,
|
rotation.z,
|
||||||
rotation.w,
|
rotation.w,
|
||||||
velocity,
|
velocity,
|
||||||
|
ClientGroundMovementTree.getMovementRelativeFacingEnumAsShort(facing),
|
||||||
2 //magic number corresponding to state slowdown
|
2 //magic number corresponding to state slowdown
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void simulate(float deltaTime){
|
public void simulate(float deltaTime){
|
||||||
float velocity = 0;
|
float velocity = 0;
|
||||||
float acceleration = 0;
|
float acceleration = 0;
|
||||||
@ -156,7 +154,7 @@ public class ServerGroundMovementTree implements BehaviorTree {
|
|||||||
acceleration = CreatureUtils.getAcceleration(parent);
|
acceleration = CreatureUtils.getAcceleration(parent);
|
||||||
maxNaturalVelocity = sprintTree != null && sprintTree.getState() == SprintTreeState.SPRINTING ? sprintTree.getMaxVelocity() : CreatureUtils.getMaxNaturalVelocity(parent);
|
maxNaturalVelocity = sprintTree != null && sprintTree.getState() == SprintTreeState.SPRINTING ? sprintTree.getMaxVelocity() : CreatureUtils.getMaxNaturalVelocity(parent);
|
||||||
}
|
}
|
||||||
PoseActor entityPoseActor = EntityUtils.getPoseActor(parent);
|
PoseActor poseActor = EntityUtils.getPoseActor(parent);
|
||||||
// Model entityModel = Globals.assetManager.fetchModel(EntityUtils.getEntityModelPath(parent));
|
// Model entityModel = Globals.assetManager.fetchModel(EntityUtils.getEntityModelPath(parent));
|
||||||
Vector3d position = EntityUtils.getPosition(parent);
|
Vector3d position = EntityUtils.getPosition(parent);
|
||||||
Vector3d facingVector = CreatureUtils.getFacingVector(parent);
|
Vector3d facingVector = CreatureUtils.getFacingVector(parent);
|
||||||
@ -192,7 +190,7 @@ public class ServerGroundMovementTree implements BehaviorTree {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// float movementYaw = CameraEntityUtils.getCameraYaw(Globals.playerCamera);
|
// float movementYaw = CameraEntityUtils.getCameraYaw(Globals.playerCamera);
|
||||||
Quaterniond movementQuaternion = new Quaterniond().rotationTo(new Vector3d(0,0,1), new Vector3d(facingVector.x,0,facingVector.z)).normalize();
|
Quaterniond movementQuaternion = new Quaterniond().rotationTo(MathUtils.getOriginVector(), new Vector3d(facingVector.x,0,facingVector.z)).normalize();
|
||||||
Quaterniond rotation = EntityUtils.getRotation(parent);
|
Quaterniond rotation = EntityUtils.getRotation(parent);
|
||||||
//TODO: optimize away and document (I know for the moment if this exception isn't here it will bite me in the ass later)
|
//TODO: optimize away and document (I know for the moment if this exception isn't here it will bite me in the ass later)
|
||||||
if(facingVector.length() == 0){
|
if(facingVector.length() == 0){
|
||||||
@ -206,16 +204,23 @@ public class ServerGroundMovementTree implements BehaviorTree {
|
|||||||
long updateTime = message.gettime();
|
long updateTime = message.gettime();
|
||||||
// System.out.println("MOVE to " + message.getX() + " " + message.getY() + " " + message.getZ());
|
// System.out.println("MOVE to " + message.getX() + " " + message.getY() + " " + message.getZ());
|
||||||
switch(message.getMessageSubtype()){
|
switch(message.getMessageSubtype()){
|
||||||
case MOVE: {
|
|
||||||
} break;
|
|
||||||
case SETFACING:
|
|
||||||
break;
|
|
||||||
case MOVEUPDATE: {
|
case MOVEUPDATE: {
|
||||||
if(updateTime >= lastUpdateTime){
|
if(updateTime >= lastUpdateTime){
|
||||||
lastUpdateTime = updateTime;
|
lastUpdateTime = updateTime;
|
||||||
|
switch(message.gettreeState()){
|
||||||
|
//0 is startup
|
||||||
|
case 0: {
|
||||||
|
start(ClientGroundMovementTree.getMovementRelativeFacingShortAsEnum((short)message.getpropertyValueInt()));
|
||||||
|
} break;
|
||||||
|
case 2: {
|
||||||
|
slowdown();
|
||||||
|
} break;
|
||||||
|
default: {
|
||||||
|
|
||||||
|
} break;
|
||||||
|
}
|
||||||
//we want to always update the server facing vector with where the client says they're facing
|
//we want to always update the server facing vector with where the client says they're facing
|
||||||
EntityUtils.getRotation(parent).set(message.getrotationX(),message.getrotationY(),message.getrotationZ(),message.getrotationW());
|
EntityUtils.getRotation(parent).set(message.getrotationX(),message.getrotationY(),message.getrotationZ(),message.getrotationW());
|
||||||
CreatureUtils.setFacingVector(parent, new Vector3d(0,0,1).rotate(EntityUtils.getRotation(parent)));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
@ -228,16 +233,16 @@ public class ServerGroundMovementTree implements BehaviorTree {
|
|||||||
|
|
||||||
//state machine
|
//state machine
|
||||||
switch(state){
|
switch(state){
|
||||||
case STARTUP:
|
case STARTUP: {
|
||||||
if(entityPoseActor != null){
|
if(poseActor != null){
|
||||||
String animationToPlay = determineCorrectAnimation();
|
String animationToPlay = determineCorrectAnimation();
|
||||||
if(
|
if(
|
||||||
!entityPoseActor.isPlayingAnimation() || !entityPoseActor.isPlayingAnimation(animationToPlay) &&
|
!poseActor.isPlayingAnimation() || !poseActor.isPlayingAnimation(animationToPlay) &&
|
||||||
(jumpTree == null || !jumpTree.isJumping()) &&
|
(jumpTree == null || !jumpTree.isJumping()) &&
|
||||||
(fallTree == null || !fallTree.isFalling())
|
(fallTree == null || !fallTree.isFalling())
|
||||||
){
|
){
|
||||||
entityPoseActor.playAnimation(animationToPlay,1);
|
poseActor.playAnimation(animationToPlay,1);
|
||||||
entityPoseActor.incrementAnimationTime(0.0001);
|
poseActor.incrementAnimationTime(0.0001);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//run startup code
|
//run startup code
|
||||||
@ -266,33 +271,34 @@ public class ServerGroundMovementTree implements BehaviorTree {
|
|||||||
GravityUtils.serverAttemptActivateGravity(parent);
|
GravityUtils.serverAttemptActivateGravity(parent);
|
||||||
|
|
||||||
DataCellSearchUtils.getEntityDataCell(parent).broadcastNetworkMessage(
|
DataCellSearchUtils.getEntityDataCell(parent).broadcastNetworkMessage(
|
||||||
EntityMessage.constructmoveUpdateMessage(
|
EntityMessage.constructmoveUpdateMessage(
|
||||||
parent.getId(),
|
parent.getId(),
|
||||||
Globals.timekeeper.getNumberOfSimFramesElapsed(),
|
Globals.timekeeper.getNumberOfSimFramesElapsed(),
|
||||||
position.x,
|
position.x,
|
||||||
position.y,
|
position.y,
|
||||||
position.z,
|
position.z,
|
||||||
rotation.x,
|
rotation.x,
|
||||||
rotation.y,
|
rotation.y,
|
||||||
rotation.z,
|
rotation.z,
|
||||||
rotation.w,
|
rotation.w,
|
||||||
velocity,
|
velocity,
|
||||||
0
|
ClientGroundMovementTree.getMovementRelativeFacingEnumAsShort(facing),
|
||||||
)
|
0
|
||||||
|
)
|
||||||
);
|
);
|
||||||
break;
|
} break;
|
||||||
case MOVE:
|
case MOVE: {
|
||||||
//check if can restart animation
|
//check if can restart animation
|
||||||
//if yes, restart animation
|
//if yes, restart animation
|
||||||
if(entityPoseActor != null){
|
if(poseActor != null){
|
||||||
String animationToPlay = determineCorrectAnimation();
|
String animationToPlay = determineCorrectAnimation();
|
||||||
if(
|
if(
|
||||||
!entityPoseActor.isPlayingAnimation() || !entityPoseActor.isPlayingAnimation(animationToPlay) &&
|
!poseActor.isPlayingAnimation() || !poseActor.isPlayingAnimation(animationToPlay) &&
|
||||||
(jumpTree == null || !jumpTree.isJumping()) &&
|
(jumpTree == null || !jumpTree.isJumping()) &&
|
||||||
(fallTree == null || !fallTree.isFalling())
|
(fallTree == null || !fallTree.isFalling())
|
||||||
){
|
){
|
||||||
entityPoseActor.playAnimation(animationToPlay,1);
|
poseActor.playAnimation(animationToPlay,1);
|
||||||
entityPoseActor.incrementAnimationTime(0.0001);
|
poseActor.incrementAnimationTime(0.0001);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(velocity != maxNaturalVelocity){
|
if(velocity != maxNaturalVelocity){
|
||||||
@ -316,32 +322,33 @@ public class ServerGroundMovementTree implements BehaviorTree {
|
|||||||
GravityUtils.serverAttemptActivateGravity(parent);
|
GravityUtils.serverAttemptActivateGravity(parent);
|
||||||
|
|
||||||
DataCellSearchUtils.getEntityDataCell(parent).broadcastNetworkMessage(
|
DataCellSearchUtils.getEntityDataCell(parent).broadcastNetworkMessage(
|
||||||
EntityMessage.constructmoveUpdateMessage(
|
EntityMessage.constructmoveUpdateMessage(
|
||||||
parent.getId(),
|
parent.getId(),
|
||||||
Globals.timekeeper.getNumberOfSimFramesElapsed(),
|
Globals.timekeeper.getNumberOfSimFramesElapsed(),
|
||||||
position.x,
|
position.x,
|
||||||
position.y,
|
position.y,
|
||||||
position.z,
|
position.z,
|
||||||
rotation.x,
|
rotation.x,
|
||||||
rotation.y,
|
rotation.y,
|
||||||
rotation.z,
|
rotation.z,
|
||||||
rotation.w,
|
rotation.w,
|
||||||
velocity,
|
velocity,
|
||||||
1
|
ClientGroundMovementTree.getMovementRelativeFacingEnumAsShort(facing),
|
||||||
)
|
1
|
||||||
|
)
|
||||||
);
|
);
|
||||||
break;
|
} break;
|
||||||
case SLOWDOWN:
|
case SLOWDOWN: {
|
||||||
//run slowdown code
|
//run slowdown code
|
||||||
if(entityPoseActor != null){
|
if(poseActor != null){
|
||||||
String animationToPlay = determineCorrectAnimation();
|
String animationToPlay = determineCorrectAnimation();
|
||||||
if(
|
if(
|
||||||
!entityPoseActor.isPlayingAnimation() || !entityPoseActor.isPlayingAnimation(animationToPlay) &&
|
!poseActor.isPlayingAnimation() || !poseActor.isPlayingAnimation(animationToPlay) &&
|
||||||
(jumpTree == null || !jumpTree.isJumping()) &&
|
(jumpTree == null || !jumpTree.isJumping()) &&
|
||||||
(fallTree == null || !fallTree.isFalling())
|
(fallTree == null || !fallTree.isFalling())
|
||||||
){
|
){
|
||||||
entityPoseActor.playAnimation(animationToPlay,1);
|
poseActor.playAnimation(animationToPlay,1);
|
||||||
entityPoseActor.incrementAnimationTime(0.0001);
|
poseActor.incrementAnimationTime(0.0001);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//velocity stuff
|
//velocity stuff
|
||||||
@ -350,10 +357,10 @@ public class ServerGroundMovementTree implements BehaviorTree {
|
|||||||
if(velocity <= 0){
|
if(velocity <= 0){
|
||||||
velocity = 0;
|
velocity = 0;
|
||||||
state = MovementTreeState.IDLE;
|
state = MovementTreeState.IDLE;
|
||||||
if(entityPoseActor != null){
|
if(poseActor != null){
|
||||||
String animationToPlay = determineCorrectAnimation();
|
String animationToPlay = determineCorrectAnimation();
|
||||||
if(entityPoseActor.isPlayingAnimation() && entityPoseActor.isPlayingAnimation(animationToPlay)){
|
if(poseActor.isPlayingAnimation() && poseActor.isPlayingAnimation(animationToPlay)){
|
||||||
entityPoseActor.stopAnimation(animationToPlay);
|
poseActor.stopAnimation(animationToPlay);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -375,23 +382,24 @@ public class ServerGroundMovementTree implements BehaviorTree {
|
|||||||
GravityUtils.serverAttemptActivateGravity(parent);
|
GravityUtils.serverAttemptActivateGravity(parent);
|
||||||
|
|
||||||
DataCellSearchUtils.getEntityDataCell(parent).broadcastNetworkMessage(
|
DataCellSearchUtils.getEntityDataCell(parent).broadcastNetworkMessage(
|
||||||
EntityMessage.constructmoveUpdateMessage(
|
EntityMessage.constructmoveUpdateMessage(
|
||||||
parent.getId(),
|
parent.getId(),
|
||||||
Globals.timekeeper.getNumberOfSimFramesElapsed(),
|
Globals.timekeeper.getNumberOfSimFramesElapsed(),
|
||||||
position.x,
|
position.x,
|
||||||
position.y,
|
position.y,
|
||||||
position.z,
|
position.z,
|
||||||
rotation.x,
|
rotation.x,
|
||||||
rotation.y,
|
rotation.y,
|
||||||
rotation.z,
|
rotation.z,
|
||||||
rotation.w,
|
rotation.w,
|
||||||
velocity,
|
velocity,
|
||||||
2
|
ClientGroundMovementTree.getMovementRelativeFacingEnumAsShort(facing),
|
||||||
)
|
2
|
||||||
|
)
|
||||||
);
|
);
|
||||||
break;
|
} break;
|
||||||
case IDLE:
|
case IDLE: {
|
||||||
break;
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -667,6 +675,8 @@ public class ServerGroundMovementTree implements BehaviorTree {
|
|||||||
*/
|
*/
|
||||||
public void setFacing(MovementRelativeFacing facing){
|
public void setFacing(MovementRelativeFacing facing){
|
||||||
this.facing = facing;
|
this.facing = facing;
|
||||||
|
int value = ClientGroundMovementTree.getMovementRelativeFacingEnumAsShort(facing);
|
||||||
|
DataCellSearchUtils.getEntityDataCell(parent).broadcastNetworkMessage(SynchronizationMessage.constructUpdateClientStateMessage(parent.getId(), 9, 11, value));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -0,0 +1,85 @@
|
|||||||
|
package electrosphere.entity.state.server;
|
||||||
|
|
||||||
|
import org.joml.Vector3d;
|
||||||
|
|
||||||
|
import electrosphere.entity.Entity;
|
||||||
|
import electrosphere.entity.EntityDataStrings;
|
||||||
|
import electrosphere.entity.btree.BehaviorTree;
|
||||||
|
import electrosphere.entity.types.creature.CreatureUtils;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores the direction that the server thinks the player is looking
|
||||||
|
*/
|
||||||
|
public class ServerPlayerViewDirTree implements BehaviorTree {
|
||||||
|
|
||||||
|
//the direction of the view
|
||||||
|
Vector3d playerViewDir = new Vector3d();
|
||||||
|
|
||||||
|
//the last time this value was updated
|
||||||
|
long lastUpdateTime = 0;
|
||||||
|
|
||||||
|
//the parent entity
|
||||||
|
Entity parent;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void simulate(float deltaTime) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param parent
|
||||||
|
*/
|
||||||
|
private ServerPlayerViewDirTree(Entity parent){
|
||||||
|
this.parent = parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attaches a ServerPlayerViewDirTree to a given entity
|
||||||
|
* @param entity The entity to add to
|
||||||
|
*/
|
||||||
|
public static void attachServerPlayerViewDirTree(Entity entity){
|
||||||
|
ServerPlayerViewDirTree tree = new ServerPlayerViewDirTree(entity);
|
||||||
|
entity.putData(EntityDataStrings.TREE_SERVERPLAYERVIEWDIR, tree);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the server player view dir tree if it exists
|
||||||
|
* @param entity The entity to get from
|
||||||
|
* @return The ServerPlayerViewDirTree if it exists, null otherwise
|
||||||
|
*/
|
||||||
|
public static ServerPlayerViewDirTree getTree(Entity entity){
|
||||||
|
return (ServerPlayerViewDirTree)entity.getData(EntityDataStrings.TREE_SERVERPLAYERVIEWDIR);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the entity has a copy of this btree or not
|
||||||
|
* @param entity The entity
|
||||||
|
* @return true if the entity has the btree, false otherwise
|
||||||
|
*/
|
||||||
|
public static boolean hasTree(Entity entity){
|
||||||
|
return entity.containsKey(EntityDataStrings.TREE_SERVERPLAYERVIEWDIR);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the player view dir
|
||||||
|
* @return The player view dir
|
||||||
|
*/
|
||||||
|
public Vector3d getPlayerViewDir(){
|
||||||
|
return playerViewDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the player view dir vector
|
||||||
|
* @param playerViewDir The player view dir vector
|
||||||
|
*/
|
||||||
|
public void setPlayerViewDir(Vector3d playerViewDir, long time){
|
||||||
|
if(time > lastUpdateTime){
|
||||||
|
this.playerViewDir = playerViewDir;
|
||||||
|
this.lastUpdateTime = time;
|
||||||
|
CreatureUtils.setFacingVector(parent, new Vector3d(-playerViewDir.x,0,-playerViewDir.z));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -7,10 +7,10 @@ import electrosphere.entity.EntityTags;
|
|||||||
import electrosphere.entity.EntityUtils;
|
import electrosphere.entity.EntityUtils;
|
||||||
import electrosphere.entity.types.creature.CreatureUtils;
|
import electrosphere.entity.types.creature.CreatureUtils;
|
||||||
import electrosphere.renderer.actor.Actor;
|
import electrosphere.renderer.actor.Actor;
|
||||||
import electrosphere.renderer.model.Model;
|
|
||||||
import electrosphere.server.datacell.ServerDataCell;
|
import electrosphere.server.datacell.ServerDataCell;
|
||||||
import electrosphere.server.datacell.utils.ServerEntityTagUtils;
|
import electrosphere.server.datacell.utils.ServerEntityTagUtils;
|
||||||
import electrosphere.server.poseactor.PoseActor;
|
import electrosphere.server.poseactor.PoseActor;
|
||||||
|
import electrosphere.util.MathUtils;
|
||||||
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -18,10 +18,8 @@ import java.util.List;
|
|||||||
import org.joml.Matrix4d;
|
import org.joml.Matrix4d;
|
||||||
import org.joml.Matrix4f;
|
import org.joml.Matrix4f;
|
||||||
import org.joml.Quaterniond;
|
import org.joml.Quaterniond;
|
||||||
import org.joml.Quaternionf;
|
|
||||||
import org.joml.Vector3d;
|
import org.joml.Vector3d;
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
import org.joml.Vector4d;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utilities for attaching entities to entities
|
* Utilities for attaching entities to entities
|
||||||
@ -39,7 +37,28 @@ public class AttachUtils {
|
|||||||
// FUNCTIONS TO UPDATE ATTACHMENTS FOR CURRENT FRAME
|
// FUNCTIONS TO UPDATE ATTACHMENTS FOR CURRENT FRAME
|
||||||
//
|
//
|
||||||
|
|
||||||
|
///
|
||||||
|
///
|
||||||
|
/// SERVER
|
||||||
|
///
|
||||||
|
///
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates positions of all attached entities in a data cell
|
||||||
|
* @param cell The data cell
|
||||||
|
*/
|
||||||
public static void serverUpdateAttachedEntityPositions(ServerDataCell cell){
|
public static void serverUpdateAttachedEntityPositions(ServerDataCell cell){
|
||||||
|
Globals.profiler.beginCpuSample("AttachUtils.serverUpdateAttachedEntityPositions");
|
||||||
|
serverUpdateBoneAttachedEntityPositions(cell);
|
||||||
|
serverUpdateNonBoneAttachments(cell);
|
||||||
|
Globals.profiler.endCpuSample();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates entities attached to bones of actors in a data cell
|
||||||
|
* @param cell The data cell
|
||||||
|
*/
|
||||||
|
public static void serverUpdateBoneAttachedEntityPositions(ServerDataCell cell){
|
||||||
for(Entity currentEntity : cell.getScene().getEntitiesWithTag(EntityTags.BONE_ATTACHED)){
|
for(Entity currentEntity : cell.getScene().getEntitiesWithTag(EntityTags.BONE_ATTACHED)){
|
||||||
Entity parent;
|
Entity parent;
|
||||||
if((parent = (Entity)currentEntity.getData(EntityDataStrings.ATTACH_PARENT))!=null){
|
if((parent = (Entity)currentEntity.getData(EntityDataStrings.ATTACH_PARENT))!=null){
|
||||||
@ -63,30 +82,102 @@ public class AttachUtils {
|
|||||||
Vector3d facingAngle = CreatureUtils.getFacingVector(parent);
|
Vector3d facingAngle = CreatureUtils.getFacingVector(parent);
|
||||||
//calculate rotation of model
|
//calculate rotation of model
|
||||||
EntityUtils.getRotation(currentEntity)
|
EntityUtils.getRotation(currentEntity)
|
||||||
.rotationTo(new Vector3d(0,0,1), new Vector3d(facingAngle.x,facingAngle.y,facingAngle.z))
|
.rotationTo(MathUtils.getOriginVector(), new Vector3d(facingAngle.x,facingAngle.y,facingAngle.z))
|
||||||
.mul(parentActor.getBoneRotation(targetBone))
|
.mul(parentActor.getBoneRotation(targetBone))
|
||||||
.mul(offsetRotation)
|
.mul(offsetRotation)
|
||||||
.normalize();
|
.normalize();
|
||||||
}
|
}
|
||||||
|
} else if(currentEntity.getData(EntityDataStrings.ATTACH_TARGET_BASE)!=null){
|
||||||
|
Vector3d positionOffset = getAttachPositionOffset(currentEntity);
|
||||||
|
Vector3d parentPosition = EntityUtils.getPosition(parent);
|
||||||
|
EntityUtils.getPosition(currentEntity).set(new Vector3d(parentPosition).add(positionOffset));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates entities that aren't attached to a bone directly in a data cell
|
||||||
|
* @param cell the data cell
|
||||||
|
*/
|
||||||
|
private static void serverUpdateNonBoneAttachments(ServerDataCell cell){
|
||||||
|
Globals.profiler.beginCpuSample("AttachUtils.serverUpdateNonBoneAttachments");
|
||||||
|
Matrix4d parentTransform = new Matrix4d().identity();
|
||||||
|
Vector3d position = new Vector3d();
|
||||||
|
Quaterniond rotation = new Quaterniond();
|
||||||
|
Vector3d scaleRaw = new Vector3d();
|
||||||
|
Vector3f scale = new Vector3f();
|
||||||
|
Entity parent;
|
||||||
|
Matrix4f transform;
|
||||||
|
//update entities attached to centerpoint + transform of other entities
|
||||||
|
for(Entity currentEntity : cell.getScene().getEntitiesWithTag(EntityTags.TRANSFORM_ATTACHED)){
|
||||||
|
if((parent = (Entity)currentEntity.getData(EntityDataStrings.ATTACH_PARENT))!=null){
|
||||||
|
if((transform = getTransformOffset(currentEntity))!=null){
|
||||||
|
//parent objects
|
||||||
|
Vector3d parentPosition = EntityUtils.getPosition(parent);
|
||||||
|
Quaterniond parentRotation = EntityUtils.getRotation(parent);
|
||||||
|
Vector3f parentScale = EntityUtils.getScale(parent);
|
||||||
|
// calculate new transform for current entity
|
||||||
|
parentTransform.identity()
|
||||||
|
.translate(parentPosition)
|
||||||
|
.rotate(parentRotation)
|
||||||
|
.scale(parentScale.x,parentScale.y,parentScale.z)
|
||||||
|
.mul(transform);
|
||||||
|
//transform bone space
|
||||||
|
parentTransform.getTranslation(position);
|
||||||
|
parentTransform.getUnnormalizedRotation(rotation).normalize();
|
||||||
|
parentTransform.getScale(scaleRaw);
|
||||||
|
scale.set((float)scaleRaw.x,(float)scaleRaw.y,(float)scaleRaw.z);
|
||||||
|
//transform worldspace
|
||||||
|
// position.add(new Vector3d(EntityUtils.getPosition(parent)));
|
||||||
|
//set
|
||||||
|
EntityUtils.getPosition(currentEntity).set(position);
|
||||||
|
EntityUtils.getRotation(currentEntity).set(rotation);
|
||||||
|
EntityUtils.getScale(currentEntity).set(scale);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Globals.profiler.endCpuSample();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
///
|
||||||
|
///
|
||||||
|
/// CLIENT
|
||||||
|
///
|
||||||
|
///
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Client version of attachment update functions
|
* Client version of attachment update functions
|
||||||
*/
|
*/
|
||||||
public static void clientUpdateAttachedEntityPositions(){
|
public static void clientUpdateAttachedEntityPositions(){
|
||||||
Globals.profiler.beginCpuSample("AttachUtils.clientUpdateAttachedEntityPositions");
|
Globals.profiler.beginCpuSample("AttachUtils.clientUpdateAttachedEntityPositions");
|
||||||
updateBoneAttachments();
|
clientUpdateBoneAttachments();
|
||||||
updateNonBoneAttachments();
|
clientUpdateNonBoneAttachments();
|
||||||
Globals.profiler.endCpuSample();
|
Globals.profiler.endCpuSample();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates entities attached to bones
|
* Updates entities attached to bones
|
||||||
*/
|
*/
|
||||||
private static void updateBoneAttachments(){
|
private static void clientUpdateBoneAttachments(){
|
||||||
Globals.profiler.beginCpuSample("AttachUtils.updateBoneAttachments");
|
Globals.profiler.beginCpuSample("AttachUtils.clientUpdateBoneAttachments");
|
||||||
//update entities attached to bones of other entities
|
//update entities attached to bones of other entities
|
||||||
for(Entity currentEntity : Globals.clientSceneWrapper.getScene().getEntitiesWithTag(EntityTags.BONE_ATTACHED)){
|
for(Entity currentEntity : Globals.clientSceneWrapper.getScene().getEntitiesWithTag(EntityTags.BONE_ATTACHED)){
|
||||||
Entity parent;
|
Entity parent;
|
||||||
@ -110,11 +201,11 @@ public class AttachUtils {
|
|||||||
// EntityUtils.getRotation(currentEntity).set(rotation).normalize();
|
// EntityUtils.getRotation(currentEntity).set(rotation).normalize();
|
||||||
Vector3d facingAngle = CreatureUtils.getFacingVector(parent);
|
Vector3d facingAngle = CreatureUtils.getFacingVector(parent);
|
||||||
if(facingAngle == null){
|
if(facingAngle == null){
|
||||||
facingAngle = new Vector3d(0,0,1);
|
facingAngle = MathUtils.getOriginVector();
|
||||||
}
|
}
|
||||||
//calculate rotation of model
|
//calculate rotation of model
|
||||||
EntityUtils.getRotation(currentEntity)
|
EntityUtils.getRotation(currentEntity)
|
||||||
.rotationTo(new Vector3d(0,0,1), new Vector3d(facingAngle.x,facingAngle.y,facingAngle.z))
|
.rotationTo(MathUtils.getOriginVector(), new Vector3d(facingAngle.x,facingAngle.y,facingAngle.z))
|
||||||
.mul(parentActor.getBoneRotation(targetBone))
|
.mul(parentActor.getBoneRotation(targetBone))
|
||||||
.mul(offsetRotation)
|
.mul(offsetRotation)
|
||||||
.normalize();
|
.normalize();
|
||||||
@ -128,7 +219,10 @@ public class AttachUtils {
|
|||||||
Globals.profiler.endCpuSample();
|
Globals.profiler.endCpuSample();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void updateNonBoneAttachments(){
|
/**
|
||||||
|
* Updates entities that aren't attached to a bone directly
|
||||||
|
*/
|
||||||
|
private static void clientUpdateNonBoneAttachments(){
|
||||||
Globals.profiler.beginCpuSample("AttachUtils.updateNonBoneAttachments");
|
Globals.profiler.beginCpuSample("AttachUtils.updateNonBoneAttachments");
|
||||||
Matrix4d parentTransform = new Matrix4d().identity();
|
Matrix4d parentTransform = new Matrix4d().identity();
|
||||||
Vector3d position = new Vector3d();
|
Vector3d position = new Vector3d();
|
||||||
@ -212,6 +306,13 @@ public class AttachUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attaches an entity to another entity at a given bone
|
||||||
|
* @param parent The parent entity
|
||||||
|
* @param toAttach The entity that will be attached
|
||||||
|
* @param boneName The name of the bone
|
||||||
|
* @param rotation The rotation applied
|
||||||
|
*/
|
||||||
public static void clientAttachEntityToEntityAtBone(Entity parent, Entity toAttach, String boneName, Quaterniond rotation){
|
public static void clientAttachEntityToEntityAtBone(Entity parent, Entity toAttach, String boneName, Quaterniond rotation){
|
||||||
Globals.clientSceneWrapper.getScene().registerEntityToTag(toAttach, EntityTags.BONE_ATTACHED);
|
Globals.clientSceneWrapper.getScene().registerEntityToTag(toAttach, EntityTags.BONE_ATTACHED);
|
||||||
toAttach.putData(EntityDataStrings.ATTACH_ENTITY_IS_ATTACHED, true);
|
toAttach.putData(EntityDataStrings.ATTACH_ENTITY_IS_ATTACHED, true);
|
||||||
@ -334,6 +435,11 @@ public class AttachUtils {
|
|||||||
// FUNCTIONS TO DETATCH AN ENTITY
|
// FUNCTIONS TO DETATCH AN ENTITY
|
||||||
//
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detatches an entity on the server
|
||||||
|
* @param parent The parent entity
|
||||||
|
* @param toAttach The attached entity
|
||||||
|
*/
|
||||||
public static void serverDetatchEntityFromEntityAtBone(Entity parent, Entity toAttach){
|
public static void serverDetatchEntityFromEntityAtBone(Entity parent, Entity toAttach){
|
||||||
ServerEntityTagUtils.removeTagFromEntity(toAttach, EntityTags.BONE_ATTACHED);
|
ServerEntityTagUtils.removeTagFromEntity(toAttach, EntityTags.BONE_ATTACHED);
|
||||||
toAttach.removeData(EntityDataStrings.ATTACH_ENTITY_IS_ATTACHED);
|
toAttach.removeData(EntityDataStrings.ATTACH_ENTITY_IS_ATTACHED);
|
||||||
@ -344,6 +450,11 @@ public class AttachUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detatches an entity on the client
|
||||||
|
* @param parent The parent entity
|
||||||
|
* @param toAttach The attached entity
|
||||||
|
*/
|
||||||
public static void clientDetatchEntityFromEntityAtBone(Entity parent, Entity toAttach){
|
public static void clientDetatchEntityFromEntityAtBone(Entity parent, Entity toAttach){
|
||||||
Globals.clientSceneWrapper.getScene().removeEntityFromTag(toAttach, EntityTags.BONE_ATTACHED);
|
Globals.clientSceneWrapper.getScene().removeEntityFromTag(toAttach, EntityTags.BONE_ATTACHED);
|
||||||
toAttach.removeData(EntityDataStrings.ATTACH_ENTITY_IS_ATTACHED);
|
toAttach.removeData(EntityDataStrings.ATTACH_ENTITY_IS_ATTACHED);
|
||||||
@ -385,6 +496,11 @@ public class AttachUtils {
|
|||||||
// GETTERS
|
// GETTERS
|
||||||
//
|
//
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether this entity is attached to another entity or not
|
||||||
|
* @param e The entity
|
||||||
|
* @return true if attached, false otherwise
|
||||||
|
*/
|
||||||
public static boolean isAttached(Entity e){
|
public static boolean isAttached(Entity e){
|
||||||
return e.containsKey(EntityDataStrings.ATTACH_ENTITY_IS_ATTACHED);
|
return e.containsKey(EntityDataStrings.ATTACH_ENTITY_IS_ATTACHED);
|
||||||
}
|
}
|
||||||
@ -397,10 +513,24 @@ public class AttachUtils {
|
|||||||
return (Entity)e.getData(EntityDataStrings.ATTACH_PARENT);
|
return (Entity)e.getData(EntityDataStrings.ATTACH_PARENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the rotation offset of a given entity
|
||||||
|
* @param e The entity
|
||||||
|
* @return The rotation offset
|
||||||
|
*/
|
||||||
protected static Quaterniond getRotationOffset(Entity e){
|
protected static Quaterniond getRotationOffset(Entity e){
|
||||||
return (Quaterniond)e.getData(EntityDataStrings.ATTACH_ROTATION_OFFSET);
|
return (Quaterniond)e.getData(EntityDataStrings.ATTACH_ROTATION_OFFSET);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the attached rotation offset
|
||||||
|
* @param e the attached entity
|
||||||
|
* @param rotation The rotation offset
|
||||||
|
*/
|
||||||
|
public static void setRotationOffset(Entity e, Quaterniond rotation){
|
||||||
|
e.putData(EntityDataStrings.ATTACH_ROTATION_OFFSET, rotation);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the transform for a transform attached entity
|
* Gets the transform for a transform attached entity
|
||||||
* @param e The entity
|
* @param e The entity
|
||||||
|
|||||||
@ -12,6 +12,7 @@ import electrosphere.collision.CollisionBodyCreation;
|
|||||||
import electrosphere.collision.PhysicsEntityUtils;
|
import electrosphere.collision.PhysicsEntityUtils;
|
||||||
import electrosphere.collision.PhysicsUtils;
|
import electrosphere.collision.PhysicsUtils;
|
||||||
import electrosphere.collision.collidable.Collidable;
|
import electrosphere.collision.collidable.Collidable;
|
||||||
|
import electrosphere.collision.hitbox.HitboxUtils;
|
||||||
import electrosphere.engine.Globals;
|
import electrosphere.engine.Globals;
|
||||||
import electrosphere.entity.Entity;
|
import electrosphere.entity.Entity;
|
||||||
import electrosphere.entity.EntityCreationUtils;
|
import electrosphere.entity.EntityCreationUtils;
|
||||||
@ -29,7 +30,8 @@ import electrosphere.entity.state.equip.ClientEquipState;
|
|||||||
import electrosphere.entity.state.equip.ServerEquipState;
|
import electrosphere.entity.state.equip.ServerEquipState;
|
||||||
import electrosphere.entity.state.gravity.ClientGravityTree;
|
import electrosphere.entity.state.gravity.ClientGravityTree;
|
||||||
import electrosphere.entity.state.gravity.ServerGravityTree;
|
import electrosphere.entity.state.gravity.ServerGravityTree;
|
||||||
import electrosphere.entity.state.idle.IdleTree;
|
import electrosphere.entity.state.hitbox.HitboxCollectionState;
|
||||||
|
import electrosphere.entity.state.idle.ClientIdleTree;
|
||||||
import electrosphere.entity.state.idle.ServerIdleTree;
|
import electrosphere.entity.state.idle.ServerIdleTree;
|
||||||
import electrosphere.entity.state.inventory.ClientInventoryState;
|
import electrosphere.entity.state.inventory.ClientInventoryState;
|
||||||
import electrosphere.entity.state.inventory.InventoryUtils;
|
import electrosphere.entity.state.inventory.InventoryUtils;
|
||||||
@ -50,9 +52,8 @@ import electrosphere.entity.state.rotator.RotatorHierarchyNode;
|
|||||||
import electrosphere.entity.state.rotator.RotatorTree;
|
import electrosphere.entity.state.rotator.RotatorTree;
|
||||||
import electrosphere.entity.state.rotator.ServerRotatorTree;
|
import electrosphere.entity.state.rotator.ServerRotatorTree;
|
||||||
import electrosphere.entity.types.collision.CollisionObjUtils;
|
import electrosphere.entity.types.collision.CollisionObjUtils;
|
||||||
import electrosphere.entity.types.hitbox.HitboxData;
|
|
||||||
import electrosphere.entity.types.hitbox.HitboxUtils;
|
|
||||||
import electrosphere.game.data.collidable.CollidableTemplate;
|
import electrosphere.game.data.collidable.CollidableTemplate;
|
||||||
|
import electrosphere.game.data.collidable.HitboxData;
|
||||||
import electrosphere.game.data.creature.type.CreatureType;
|
import electrosphere.game.data.creature.type.CreatureType;
|
||||||
import electrosphere.game.data.creature.type.SprintSystem;
|
import electrosphere.game.data.creature.type.SprintSystem;
|
||||||
import electrosphere.game.data.creature.type.attack.AttackMove;
|
import electrosphere.game.data.creature.type.attack.AttackMove;
|
||||||
@ -80,6 +81,7 @@ import electrosphere.server.datacell.utils.ServerBehaviorTreeUtils;
|
|||||||
import electrosphere.server.datacell.utils.ServerEntityTagUtils;
|
import electrosphere.server.datacell.utils.ServerEntityTagUtils;
|
||||||
import electrosphere.server.poseactor.PoseActor;
|
import electrosphere.server.poseactor.PoseActor;
|
||||||
import electrosphere.server.poseactor.PoseActorUtils;
|
import electrosphere.server.poseactor.PoseActorUtils;
|
||||||
|
import electrosphere.util.MathUtils;
|
||||||
import electrosphere.util.Utilities;
|
import electrosphere.util.Utilities;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -103,26 +105,26 @@ public class CreatureUtils {
|
|||||||
Actor creatureActor = EntityUtils.getActor(rVal);
|
Actor creatureActor = EntityUtils.getActor(rVal);
|
||||||
EntityUtils.setEntityType(rVal, ENTITY_TYPE_CREATURE);
|
EntityUtils.setEntityType(rVal, ENTITY_TYPE_CREATURE);
|
||||||
EntityUtils.setEntitySubtype(rVal, type);
|
EntityUtils.setEntitySubtype(rVal, type);
|
||||||
for(HitboxData hitboxdata : rawType.getHitboxes()){
|
|
||||||
List<Entity> hitboxList = new LinkedList<Entity>();
|
|
||||||
List<Entity> hurtboxList = new LinkedList<Entity>();
|
///
|
||||||
if(hitboxdata.getType().equals("hit")){
|
///
|
||||||
Entity hitbox = HitboxUtils.clientSpawnRegularHitbox(rVal, hitboxdata.getBone(), hitboxdata.getRadius());
|
/// HITBOX DATA
|
||||||
Globals.clientHitboxManager.registerHitbox(hitbox);
|
///
|
||||||
hitboxList.add(hitbox);
|
///
|
||||||
} else if(hitboxdata.getType().equals("hurt")){
|
HitboxCollectionState.attachHitboxState(Globals.clientSceneWrapper.getHitboxManager(), false, rVal, rawType.getHitboxes());
|
||||||
Entity hurtbox = HitboxUtils.clientSpawnRegularHurtbox(rVal, hitboxdata.getBone(), hitboxdata.getRadius());
|
|
||||||
Globals.clientHitboxManager.registerHitbox(hurtbox);
|
|
||||||
hurtboxList.add(hurtbox);
|
//
|
||||||
}
|
//
|
||||||
rVal.putData(EntityDataStrings.HITBOX_ASSOCIATED_LIST, hitboxList);
|
// PHYSICS
|
||||||
rVal.putData(EntityDataStrings.HURTBOX_ASSOCIATED_LIST, hurtboxList);
|
//
|
||||||
}
|
//
|
||||||
//Physics object
|
|
||||||
if(rawType.getCollidable() != null){
|
if(rawType.getCollidable() != null){
|
||||||
CollidableTemplate physicsTemplate = rawType.getCollidable();
|
CollidableTemplate physicsTemplate = rawType.getCollidable();
|
||||||
PhysicsEntityUtils.clientAttachCollidableTemplate(rVal, physicsTemplate);
|
PhysicsEntityUtils.clientAttachCollidableTemplate(rVal, physicsTemplate);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
// MOVEMENT SYSTEMS
|
// MOVEMENT SYSTEMS
|
||||||
@ -165,7 +167,7 @@ public class CreatureUtils {
|
|||||||
}
|
}
|
||||||
//round out end of move system
|
//round out end of move system
|
||||||
rVal.putData(EntityDataStrings.CLIENT_MOVEMENT_BT, moveTree);
|
rVal.putData(EntityDataStrings.CLIENT_MOVEMENT_BT, moveTree);
|
||||||
CreatureUtils.setFacingVector(rVal, new Vector3d(0,0,1));
|
CreatureUtils.setFacingVector(rVal, MathUtils.getOriginVector());
|
||||||
rVal.putData(EntityDataStrings.DATA_STRING_MAX_NATURAL_VELOCITY, groundMovementSystem.getMaxVelocity());
|
rVal.putData(EntityDataStrings.DATA_STRING_MAX_NATURAL_VELOCITY, groundMovementSystem.getMaxVelocity());
|
||||||
rVal.putData(EntityDataStrings.DATA_STRING_ACCELERATION, groundMovementSystem.getAcceleration());
|
rVal.putData(EntityDataStrings.DATA_STRING_ACCELERATION, groundMovementSystem.getAcceleration());
|
||||||
rVal.putData(EntityDataStrings.DATA_STRING_VELOCITY, 0f);
|
rVal.putData(EntityDataStrings.DATA_STRING_VELOCITY, 0f);
|
||||||
@ -217,14 +219,14 @@ public class CreatureUtils {
|
|||||||
airplaneMovementTree.setMaxRotationSpeed(airplaneMovementSystem.getMaxRotationSpeed());
|
airplaneMovementTree.setMaxRotationSpeed(airplaneMovementSystem.getMaxRotationSpeed());
|
||||||
//register misc stuff
|
//register misc stuff
|
||||||
rVal.putData(EntityDataStrings.CLIENT_MOVEMENT_BT, airplaneMovementTree);
|
rVal.putData(EntityDataStrings.CLIENT_MOVEMENT_BT, airplaneMovementTree);
|
||||||
CreatureUtils.setFacingVector(rVal, new Vector3d(0,0,1));
|
CreatureUtils.setFacingVector(rVal, MathUtils.getOriginVector());
|
||||||
Globals.clientScene.registerBehaviorTree(airplaneMovementTree);
|
Globals.clientScene.registerBehaviorTree(airplaneMovementTree);
|
||||||
Globals.clientScene.registerEntityToTag(rVal, EntityTags.MOVEABLE);
|
Globals.clientScene.registerEntityToTag(rVal, EntityTags.MOVEABLE);
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(rawType.getEquipPoints() != null && rawType.getEquipPoints().size() > 0){
|
if(rawType.getEquipPoints() != null && rawType.getEquipPoints().size() > 0){
|
||||||
ClientEquipState.setEquipState(rVal, new ClientEquipState(rVal,rawType.getEquipPoints()));
|
ClientEquipState.attachTree(rVal, rawType.getEquipPoints());
|
||||||
rVal.putData(EntityDataStrings.EQUIP_INVENTORY, RelationalInventoryState.buildRelationalInventoryStateFromEquipList(rawType.getEquipPoints()));
|
rVal.putData(EntityDataStrings.EQUIP_INVENTORY, RelationalInventoryState.buildRelationalInventoryStateFromEquipList(rawType.getEquipPoints()));
|
||||||
}
|
}
|
||||||
for(String token : rawType.getTokens()){
|
for(String token : rawType.getTokens()){
|
||||||
@ -366,11 +368,11 @@ public class CreatureUtils {
|
|||||||
rVal.putData(EntityDataStrings.LIFE_STATE, new LifeState(rVal, rawType.getHealthSystem()));
|
rVal.putData(EntityDataStrings.LIFE_STATE, new LifeState(rVal, rawType.getHealthSystem()));
|
||||||
Globals.clientScene.registerEntityToTag(rVal, EntityTags.LIFE_STATE);
|
Globals.clientScene.registerEntityToTag(rVal, EntityTags.LIFE_STATE);
|
||||||
//idle tree & generic stuff all creatures have
|
//idle tree & generic stuff all creatures have
|
||||||
IdleTree idleTree = new IdleTree(rVal);
|
ClientIdleTree idleTree = new ClientIdleTree(rVal);
|
||||||
rVal.putData(EntityDataStrings.TREE_IDLE, idleTree);
|
rVal.putData(EntityDataStrings.TREE_IDLE, idleTree);
|
||||||
Globals.clientScene.registerBehaviorTree(idleTree);
|
Globals.clientScene.registerBehaviorTree(idleTree);
|
||||||
Globals.clientScene.registerEntityToTag(rVal, EntityTags.CREATURE);
|
Globals.clientScene.registerEntityToTag(rVal, EntityTags.CREATURE);
|
||||||
CreatureUtils.setFacingVector(rVal, new Vector3d(0,0,1));
|
CreatureUtils.setFacingVector(rVal, MathUtils.getOriginVector());
|
||||||
rVal.putData(EntityDataStrings.DRAW_CAST_SHADOW, true);
|
rVal.putData(EntityDataStrings.DRAW_CAST_SHADOW, true);
|
||||||
return rVal;
|
return rVal;
|
||||||
}
|
}
|
||||||
@ -390,21 +392,17 @@ public class CreatureUtils {
|
|||||||
EntityCreationUtils.makeEntityPoseable(rVal, rawType.getModelPath());
|
EntityCreationUtils.makeEntityPoseable(rVal, rawType.getModelPath());
|
||||||
|
|
||||||
PoseActor creatureActor = EntityUtils.getPoseActor(rVal);
|
PoseActor creatureActor = EntityUtils.getPoseActor(rVal);
|
||||||
for(HitboxData hitboxdata : rawType.getHitboxes()){
|
//
|
||||||
List<Entity> hitboxList = new LinkedList<Entity>();
|
//
|
||||||
List<Entity> hurtboxList = new LinkedList<Entity>();
|
// Hitbox stuff
|
||||||
if(hitboxdata.getType().equals("hit")){
|
//
|
||||||
Entity hitbox = HitboxUtils.serverSpawnRegularHitbox(rVal, hitboxdata.getBone(), hitboxdata.getRadius());
|
//
|
||||||
realm.getHitboxManager().registerHitbox(hitbox);
|
HitboxCollectionState.attachHitboxState(realm.getHitboxManager(), true, rVal, rawType.getHitboxes());
|
||||||
hitboxList.add(hitbox);
|
//
|
||||||
} else if(hitboxdata.getType().equals("hurt")){
|
//
|
||||||
Entity hurtbox = HitboxUtils.serverSpawnRegularHurtbox(rVal, hitboxdata.getBone(), hitboxdata.getRadius());
|
// Physics stuff
|
||||||
realm.getHitboxManager().registerHitbox(hurtbox);
|
//
|
||||||
hurtboxList.add(hurtbox);
|
//
|
||||||
}
|
|
||||||
rVal.putData(EntityDataStrings.HITBOX_ASSOCIATED_LIST, hitboxList);
|
|
||||||
rVal.putData(EntityDataStrings.HURTBOX_ASSOCIATED_LIST, hurtboxList);
|
|
||||||
}
|
|
||||||
if(rawType.getCollidable() != null){
|
if(rawType.getCollidable() != null){
|
||||||
CollidableTemplate physicsTemplate = rawType.getCollidable();
|
CollidableTemplate physicsTemplate = rawType.getCollidable();
|
||||||
PhysicsEntityUtils.serverAttachCollidableTemplate(realm, rVal, physicsTemplate);
|
PhysicsEntityUtils.serverAttachCollidableTemplate(realm, rVal, physicsTemplate);
|
||||||
@ -451,7 +449,7 @@ public class CreatureUtils {
|
|||||||
}
|
}
|
||||||
//round out end of move system
|
//round out end of move system
|
||||||
rVal.putData(EntityDataStrings.SERVER_MOVEMENT_BT, moveTree);
|
rVal.putData(EntityDataStrings.SERVER_MOVEMENT_BT, moveTree);
|
||||||
CreatureUtils.setFacingVector(rVal, new Vector3d(0,0,1));
|
CreatureUtils.setFacingVector(rVal, MathUtils.getOriginVector());
|
||||||
rVal.putData(EntityDataStrings.DATA_STRING_MAX_NATURAL_VELOCITY, groundMovementSystem.getMaxVelocity());
|
rVal.putData(EntityDataStrings.DATA_STRING_MAX_NATURAL_VELOCITY, groundMovementSystem.getMaxVelocity());
|
||||||
rVal.putData(EntityDataStrings.DATA_STRING_ACCELERATION, groundMovementSystem.getAcceleration());
|
rVal.putData(EntityDataStrings.DATA_STRING_ACCELERATION, groundMovementSystem.getAcceleration());
|
||||||
rVal.putData(EntityDataStrings.DATA_STRING_VELOCITY, 0f);
|
rVal.putData(EntityDataStrings.DATA_STRING_VELOCITY, 0f);
|
||||||
@ -509,7 +507,7 @@ public class CreatureUtils {
|
|||||||
airplaneMovementTree.setMaxRotationSpeed(airplaneMovementSystem.getMaxRotationSpeed());
|
airplaneMovementTree.setMaxRotationSpeed(airplaneMovementSystem.getMaxRotationSpeed());
|
||||||
//register misc stuff
|
//register misc stuff
|
||||||
rVal.putData(EntityDataStrings.SERVER_MOVEMENT_BT, airplaneMovementTree);
|
rVal.putData(EntityDataStrings.SERVER_MOVEMENT_BT, airplaneMovementTree);
|
||||||
CreatureUtils.setFacingVector(rVal, new Vector3d(0,0,1));
|
CreatureUtils.setFacingVector(rVal, MathUtils.getOriginVector());
|
||||||
ServerBehaviorTreeUtils.attachBTreeToEntity(rVal, airplaneMovementTree);
|
ServerBehaviorTreeUtils.attachBTreeToEntity(rVal, airplaneMovementTree);
|
||||||
ServerEntityTagUtils.attachTagToEntity(rVal, EntityTags.MOVEABLE);
|
ServerEntityTagUtils.attachTagToEntity(rVal, EntityTags.MOVEABLE);
|
||||||
} break;
|
} break;
|
||||||
@ -664,7 +662,7 @@ public class CreatureUtils {
|
|||||||
ServerEntityTagUtils.attachTagToEntity(rVal, EntityTags.CREATURE);
|
ServerEntityTagUtils.attachTagToEntity(rVal, EntityTags.CREATURE);
|
||||||
EntityUtils.setEntityType(rVal, ENTITY_TYPE_CREATURE);
|
EntityUtils.setEntityType(rVal, ENTITY_TYPE_CREATURE);
|
||||||
EntityUtils.setEntitySubtype(rVal, type);
|
EntityUtils.setEntitySubtype(rVal, type);
|
||||||
CreatureUtils.setFacingVector(rVal, new Vector3d(0,0,1));
|
CreatureUtils.setFacingVector(rVal, MathUtils.getOriginVector());
|
||||||
rVal.putData(EntityDataStrings.DRAW_CAST_SHADOW, true);
|
rVal.putData(EntityDataStrings.DRAW_CAST_SHADOW, true);
|
||||||
|
|
||||||
//position entity
|
//position entity
|
||||||
@ -799,8 +797,8 @@ public class CreatureUtils {
|
|||||||
return (ServerAttackTree)e.getData(EntityDataStrings.TREE_SERVERATTACKTREE);
|
return (ServerAttackTree)e.getData(EntityDataStrings.TREE_SERVERATTACKTREE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IdleTree getIdleTree(Entity e){
|
public static ClientIdleTree getIdleTree(Entity e){
|
||||||
return (IdleTree)e.getData(EntityDataStrings.TREE_IDLE);
|
return (ClientIdleTree)e.getData(EntityDataStrings.TREE_IDLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SprintTree clientGetSprintTree(Entity e){
|
public static SprintTree clientGetSprintTree(Entity e){
|
||||||
|
|||||||
@ -12,7 +12,7 @@ import electrosphere.entity.EntityTags;
|
|||||||
import electrosphere.entity.EntityUtils;
|
import electrosphere.entity.EntityUtils;
|
||||||
import electrosphere.entity.ServerEntityUtils;
|
import electrosphere.entity.ServerEntityUtils;
|
||||||
import electrosphere.entity.state.client.ambientaudio.ClientAmbientAudioTree;
|
import electrosphere.entity.state.client.ambientaudio.ClientAmbientAudioTree;
|
||||||
import electrosphere.entity.state.idle.IdleTree;
|
import electrosphere.entity.state.idle.ClientIdleTree;
|
||||||
import electrosphere.entity.types.collision.CollisionObjUtils;
|
import electrosphere.entity.types.collision.CollisionObjUtils;
|
||||||
import electrosphere.entity.types.tree.ProceduralTree;
|
import electrosphere.entity.types.tree.ProceduralTree;
|
||||||
import electrosphere.game.data.foliage.type.AmbientAudio;
|
import electrosphere.game.data.foliage.type.AmbientAudio;
|
||||||
|
|||||||
@ -1,83 +0,0 @@
|
|||||||
package electrosphere.entity.types.hitbox;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import electrosphere.entity.Entity;
|
|
||||||
import electrosphere.entity.types.hitbox.HitboxUtils.HitboxPositionCallback;
|
|
||||||
|
|
||||||
public class HitboxData {
|
|
||||||
String type;
|
|
||||||
String bone;
|
|
||||||
float radius;
|
|
||||||
boolean active = false;
|
|
||||||
//used for more advanced hitbox spawning to find hitbox position on frame update
|
|
||||||
HitboxPositionCallback positionCallback;
|
|
||||||
//used to filter this hitbox to hitting only certain parent entities
|
|
||||||
List<Entity> filter;
|
|
||||||
|
|
||||||
public String getType() {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getBone() {
|
|
||||||
return bone;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getRadius() {
|
|
||||||
return radius;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isActive() {
|
|
||||||
return active;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setActive(boolean active) {
|
|
||||||
this.active = active;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setBone(String bone) {
|
|
||||||
this.bone = bone;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setType(String type) {
|
|
||||||
this.type = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRadius(float radius) {
|
|
||||||
this.radius = radius;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the position callback
|
|
||||||
* @return The position callback
|
|
||||||
*/
|
|
||||||
public HitboxPositionCallback getPositionCallback(){
|
|
||||||
return positionCallback;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the position callback
|
|
||||||
* @param positionCallback The position callback
|
|
||||||
*/
|
|
||||||
public void setPositionCallback(HitboxPositionCallback positionCallback){
|
|
||||||
this.positionCallback = positionCallback;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets an entity filter on the hitbox
|
|
||||||
* @param filter The list of parent entities to exclude from collisions
|
|
||||||
*/
|
|
||||||
public void setEntityFilter(List<Entity> filter){
|
|
||||||
this.filter = filter;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the entity filter
|
|
||||||
* @return The list of parent entities to exclude from collisions
|
|
||||||
*/
|
|
||||||
public List<Entity> getEntityFilter(){
|
|
||||||
return filter;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,35 +0,0 @@
|
|||||||
package electrosphere.entity.types.hitbox;
|
|
||||||
|
|
||||||
import electrosphere.entity.Entity;
|
|
||||||
import electrosphere.entity.EntityDataStrings;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author amaterasu
|
|
||||||
*/
|
|
||||||
public class HitboxManager {
|
|
||||||
|
|
||||||
CopyOnWriteArrayList<Entity> hitboxes = new CopyOnWriteArrayList<Entity>();
|
|
||||||
long idIncrementer = 0;
|
|
||||||
|
|
||||||
public HitboxManager(){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void registerHitbox(Entity hitbox){
|
|
||||||
hitboxes.add(hitbox);
|
|
||||||
idIncrementer++;
|
|
||||||
hitbox.putData(EntityDataStrings.COLLISION_ENTITY_ID, idIncrementer);
|
|
||||||
}
|
|
||||||
|
|
||||||
public CopyOnWriteArrayList<Entity> getAllHitboxes(){
|
|
||||||
return hitboxes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void deregisterHitbox(Entity hitbox){
|
|
||||||
hitboxes.remove(hitbox);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,447 +0,0 @@
|
|||||||
package electrosphere.entity.types.hitbox;
|
|
||||||
|
|
||||||
import electrosphere.engine.Globals;
|
|
||||||
import electrosphere.entity.Entity;
|
|
||||||
import electrosphere.entity.EntityCreationUtils;
|
|
||||||
import electrosphere.entity.EntityDataStrings;
|
|
||||||
import electrosphere.entity.EntityUtils;
|
|
||||||
import electrosphere.entity.types.attach.AttachUtils;
|
|
||||||
import electrosphere.entity.types.creature.CreatureUtils;
|
|
||||||
import electrosphere.entity.types.item.ItemUtils;
|
|
||||||
import electrosphere.entity.state.attack.ShooterTree;
|
|
||||||
import electrosphere.entity.state.life.LifeState;
|
|
||||||
import electrosphere.entity.state.life.LifeUtils;
|
|
||||||
import electrosphere.entity.state.movement.ProjectileTree;
|
|
||||||
import electrosphere.game.server.effects.ParticleEffects;
|
|
||||||
import electrosphere.server.datacell.Realm;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.joml.Matrix4f;
|
|
||||||
import org.joml.Quaterniond;
|
|
||||||
import org.joml.Quaternionf;
|
|
||||||
import org.joml.Vector3d;
|
|
||||||
import org.joml.Vector3f;
|
|
||||||
import org.joml.Vector4f;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author amaterasu
|
|
||||||
*/
|
|
||||||
public class HitboxUtils {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Spawns a hitbox entity on the client
|
|
||||||
* @param parent The parent entity to attach the hitbox to
|
|
||||||
* @param bone The bone on the parent to attach to
|
|
||||||
* @param size The radius of the hitsphere
|
|
||||||
* @return The hitbox entity
|
|
||||||
*/
|
|
||||||
public static Entity clientSpawnRegularHitbox(Entity parent, String bone, float size){
|
|
||||||
Entity rVal = EntityCreationUtils.createClientSpatialEntity();
|
|
||||||
HitboxData data = new HitboxData();
|
|
||||||
data.setActive(false);
|
|
||||||
data.setBone(bone);
|
|
||||||
data.setRadius(size);
|
|
||||||
data.setType(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HIT);
|
|
||||||
rVal.putData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT, parent);
|
|
||||||
rVal.putData(EntityDataStrings.HITBOX_DATA, data);
|
|
||||||
rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
|
|
||||||
rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true);
|
|
||||||
Globals.clientHitboxManager.registerHitbox(rVal);
|
|
||||||
return rVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Spawns a hitbox entity on the server
|
|
||||||
* @param parent The parent entity to attach the hitbox to
|
|
||||||
* @param bone The bone to attach to the hitbox to
|
|
||||||
* @param size The radius of the hitsphere
|
|
||||||
* @return The hitbox entity
|
|
||||||
*/
|
|
||||||
public static Entity serverSpawnRegularHitbox(Entity parent, String bone, float size){
|
|
||||||
Entity rVal = EntityCreationUtils.createServerEntity(Globals.realmManager.getEntityRealm(parent), new Vector3d(0,0,0));
|
|
||||||
HitboxData data = new HitboxData();
|
|
||||||
data.setActive(false);
|
|
||||||
data.setBone(bone);
|
|
||||||
data.setRadius(size);
|
|
||||||
data.setType(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HIT);
|
|
||||||
rVal.putData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT, parent);
|
|
||||||
rVal.putData(EntityDataStrings.HITBOX_DATA, data);
|
|
||||||
rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
|
|
||||||
rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true);
|
|
||||||
Globals.realmManager.getEntityRealm(parent).getHitboxManager().registerHitbox(rVal);
|
|
||||||
return rVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Spawns a hurtbox on the client
|
|
||||||
* @param parent The parent entity of the hurtbox
|
|
||||||
* @param bone The bone on the parent to attach the hurtbox to
|
|
||||||
* @param size The radius of the hurtsphere
|
|
||||||
* @return The hurtbox entity
|
|
||||||
*/
|
|
||||||
public static Entity clientSpawnRegularHurtbox(Entity parent, String bone, float size){
|
|
||||||
Entity rVal = EntityCreationUtils.createClientSpatialEntity();
|
|
||||||
HitboxData data = new HitboxData();
|
|
||||||
data.setActive(true);
|
|
||||||
data.setBone(bone);
|
|
||||||
data.setRadius(size);
|
|
||||||
data.setType(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HURT);
|
|
||||||
rVal.putData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT, parent);
|
|
||||||
rVal.putData(EntityDataStrings.HITBOX_DATA, data);
|
|
||||||
rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
|
|
||||||
rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true);
|
|
||||||
Globals.clientHitboxManager.registerHitbox(rVal);
|
|
||||||
return rVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Spawns a hurtbox on the server
|
|
||||||
* @param parent The parent entity of the hurtbox
|
|
||||||
* @param bone The bone on the parent to attach the hurtbox to
|
|
||||||
* @param size The radius of the hurtsphere
|
|
||||||
* @return The hurtbox entity
|
|
||||||
*/
|
|
||||||
public static Entity serverSpawnRegularHurtbox(Entity parent, String bone, float size){
|
|
||||||
Entity rVal = EntityCreationUtils.createServerEntity(Globals.realmManager.getEntityRealm(parent), new Vector3d(0,0,0));
|
|
||||||
HitboxData data = new HitboxData();
|
|
||||||
data.setActive(true);
|
|
||||||
data.setBone(bone);
|
|
||||||
data.setRadius(size);
|
|
||||||
data.setType(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HURT);
|
|
||||||
rVal.putData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT, parent);
|
|
||||||
rVal.putData(EntityDataStrings.HITBOX_DATA, data);
|
|
||||||
rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
|
|
||||||
rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true);
|
|
||||||
Globals.realmManager.getEntityRealm(parent).getHitboxManager().registerHitbox(rVal);
|
|
||||||
return rVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* More sophisticated function for spawning in hitboxes. Takes a position callback so it's not tied to a bone
|
|
||||||
* @param parent The parent entity of the hitbox
|
|
||||||
* @param positionCallback The position callback for keeping hitbox entity position up to date
|
|
||||||
* @param size The size of the hitbox
|
|
||||||
* @param hurtbox If true, it will instead be a hurtbox
|
|
||||||
* @param filter an optional list of parent entities to not colide with
|
|
||||||
* @return The hitbox entity
|
|
||||||
*/
|
|
||||||
public static Entity clientSpawnRegularHitbox(Entity parent, HitboxPositionCallback positionCallback, float size, boolean hurtbox, List<Entity> filter){
|
|
||||||
Entity rVal = EntityCreationUtils.createClientSpatialEntity();
|
|
||||||
HitboxData data = new HitboxData();
|
|
||||||
data.setActive(true);
|
|
||||||
data.setPositionCallback(positionCallback);
|
|
||||||
data.setRadius(size);
|
|
||||||
data.setEntityFilter(filter);
|
|
||||||
if(hurtbox){
|
|
||||||
data.setType(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HURT);
|
|
||||||
} else {
|
|
||||||
data.setType(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HIT);
|
|
||||||
}
|
|
||||||
rVal.putData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT, parent);
|
|
||||||
rVal.putData(EntityDataStrings.HITBOX_DATA, data);
|
|
||||||
rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
|
|
||||||
rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true);
|
|
||||||
Globals.clientHitboxManager.registerHitbox(rVal);
|
|
||||||
return rVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* More sophisticated function for spawning in hitboxes. Takes a position callback so it's not tied to a bone
|
|
||||||
* @param parent The parent entity of the hitbox
|
|
||||||
* @param positionCallback The position callback for keeping hitbox entity position up to date
|
|
||||||
* @param size The size of the hitbox
|
|
||||||
* @param hurtbox If true, it will instead be a hurtbox
|
|
||||||
* @param filter an optional list of parent entities to not colide with
|
|
||||||
* @return The hitbox entity
|
|
||||||
*/
|
|
||||||
public static Entity serverSpawnRegularHitbox(Entity parent, HitboxPositionCallback positionCallback, float size, boolean hurtbox, List<Entity> filter){
|
|
||||||
Entity rVal = EntityCreationUtils.createServerEntity(Globals.realmManager.getEntityRealm(parent), new Vector3d(0,0,0));
|
|
||||||
HitboxData data = new HitboxData();
|
|
||||||
data.setActive(true);
|
|
||||||
data.setPositionCallback(positionCallback);
|
|
||||||
data.setRadius(size);
|
|
||||||
data.setEntityFilter(filter);
|
|
||||||
if(hurtbox){
|
|
||||||
data.setType(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HURT);
|
|
||||||
} else {
|
|
||||||
data.setType(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HIT);
|
|
||||||
}
|
|
||||||
rVal.putData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT, parent);
|
|
||||||
rVal.putData(EntityDataStrings.HITBOX_DATA, data);
|
|
||||||
rVal.putData(EntityDataStrings.DATA_STRING_POSITION, new Vector3d(0,0,0));
|
|
||||||
rVal.putData(EntityDataStrings.DATA_STRING_DRAW, true);
|
|
||||||
Globals.realmManager.getEntityRealm(parent).getHitboxManager().registerHitbox(rVal);
|
|
||||||
return rVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void clientUpdatePosition(Entity hitbox){
|
|
||||||
Entity parent = ((Entity)hitbox.getData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT));
|
|
||||||
HitboxData hitboxData = getHitboxData(hitbox);
|
|
||||||
String boneName = hitboxData.getBone();
|
|
||||||
if(boneName != null){
|
|
||||||
Quaterniond parentRotation = EntityUtils.getRotation(parent);
|
|
||||||
Vector3f positionScale = EntityUtils.getScale(parent);
|
|
||||||
Vector3d worldPosition = new Vector3d();
|
|
||||||
Vector3f bonePosition = EntityUtils.getActor(parent).getBonePosition(boneName);
|
|
||||||
Vector3d parentPos = EntityUtils.getPosition(parent);
|
|
||||||
worldPosition.set(bonePosition.x,bonePosition.y,bonePosition.z);
|
|
||||||
Quaterniond rotation = new Quaterniond(parentRotation);
|
|
||||||
|
|
||||||
worldPosition = worldPosition.mul(positionScale);
|
|
||||||
|
|
||||||
worldPosition = worldPosition.rotate(rotation);
|
|
||||||
|
|
||||||
|
|
||||||
worldPosition.add(new Vector3f((float)parentPos.x,(float)parentPos.y,(float)parentPos.z));
|
|
||||||
|
|
||||||
EntityUtils.getPosition(hitbox).set(worldPosition);
|
|
||||||
} else {
|
|
||||||
HitboxPositionCallback positionCallback = hitboxData.getPositionCallback();
|
|
||||||
EntityUtils.getPosition(hitbox).set(positionCallback.getPosition());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void serverUpdatePosition(Entity hitbox){
|
|
||||||
Entity parent = ((Entity)hitbox.getData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT));
|
|
||||||
HitboxData hitboxData = getHitboxData(hitbox);
|
|
||||||
String boneName = hitboxData.getBone();
|
|
||||||
if(boneName != null){
|
|
||||||
Quaterniond parentRotation = EntityUtils.getRotation(parent);
|
|
||||||
Vector3f positionScale = EntityUtils.getScale(parent);
|
|
||||||
Vector3d worldPosition = new Vector3d();
|
|
||||||
Vector3f bonePosition = EntityUtils.getPoseActor(parent).getBonePosition(boneName);
|
|
||||||
Vector3d parentPos = EntityUtils.getPosition(parent);
|
|
||||||
worldPosition.set(bonePosition.x,bonePosition.y,bonePosition.z);
|
|
||||||
Quaterniond rotation = new Quaterniond(parentRotation);
|
|
||||||
|
|
||||||
worldPosition = worldPosition.mul(positionScale);
|
|
||||||
|
|
||||||
worldPosition = worldPosition.rotate(rotation);
|
|
||||||
|
|
||||||
|
|
||||||
worldPosition.add(new Vector3d(parentPos.x,parentPos.y,parentPos.z));
|
|
||||||
|
|
||||||
EntityUtils.getPosition(hitbox).set(worldPosition);
|
|
||||||
} else {
|
|
||||||
HitboxPositionCallback positionCallback = hitboxData.getPositionCallback();
|
|
||||||
EntityUtils.getPosition(hitbox).set(positionCallback.getPosition());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void clientCollideEntities(Entity generatorHitbox){
|
|
||||||
// long generatorId = (Long)generatorHitbox.getData(EntityDataStrings.COLLISION_ENTITY_ID);
|
|
||||||
|
|
||||||
//This is the entity the hitbox is attached to
|
|
||||||
Entity generatorParent = (Entity)generatorHitbox.getData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT);
|
|
||||||
|
|
||||||
for(Entity receiverHitbox : Globals.clientHitboxManager.getAllHitboxes()){
|
|
||||||
|
|
||||||
Entity receiverParent = (Entity)receiverHitbox.getData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT);
|
|
||||||
|
|
||||||
HitboxData generatorData = getHitboxData(generatorHitbox);
|
|
||||||
HitboxData receiverData = getHitboxData(receiverHitbox);
|
|
||||||
|
|
||||||
//check projectile filters
|
|
||||||
List<Entity> generatorFilter = generatorData.getEntityFilter();
|
|
||||||
if(generatorFilter != null && generatorFilter.contains(receiverParent)){
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Entity> receiverFilter = receiverData.getEntityFilter();
|
|
||||||
if(receiverFilter != null && receiverFilter.contains(generatorParent)){
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
//if there is a collision
|
|
||||||
//and the collision isn't against itself
|
|
||||||
//and both hitboxes are active
|
|
||||||
if(
|
|
||||||
receiverParent != generatorParent &&
|
|
||||||
Globals.clientSceneWrapper.getCollisionEngine().collisionSphereCheck(generatorHitbox, generatorData, receiverHitbox, receiverData) &&
|
|
||||||
generatorData.isActive() &&
|
|
||||||
receiverData.isActive()){
|
|
||||||
//if two spheres collide, grab their hitbox types (eg hurt, hit, fire, etc)
|
|
||||||
String generatorType = generatorData.getType();
|
|
||||||
String receiverType = receiverData.getType();
|
|
||||||
|
|
||||||
if(generatorType.equals(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HIT) && receiverType.equals(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HURT)){
|
|
||||||
clientDamageHitboxColision(generatorHitbox, receiverHitbox);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(generatorType.equals(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HURT) && receiverType.equals(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HIT)){
|
|
||||||
clientDamageHitboxColision(receiverHitbox, generatorHitbox);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void serverCollideEntities(Entity generatorHitbox){
|
|
||||||
// long generatorId = (Long)generatorHitbox.getData(EntityDataStrings.COLLISION_ENTITY_ID);
|
|
||||||
|
|
||||||
//This is the entity the hitbox is attached to
|
|
||||||
Entity generatorParent = (Entity)generatorHitbox.getData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT);
|
|
||||||
|
|
||||||
Realm generatorRealm = Globals.realmManager.getEntityRealm(generatorParent);
|
|
||||||
if(generatorRealm != null){
|
|
||||||
HitboxManager realmHitboxManager = generatorRealm.getHitboxManager();
|
|
||||||
|
|
||||||
for(Entity receiverHitbox : realmHitboxManager.getAllHitboxes()){
|
|
||||||
|
|
||||||
Entity receiverParent = (Entity)receiverHitbox.getData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT);
|
|
||||||
|
|
||||||
HitboxData generatorData = getHitboxData(generatorHitbox);
|
|
||||||
HitboxData receiverData = getHitboxData(receiverHitbox);
|
|
||||||
|
|
||||||
//check projectile filters
|
|
||||||
List<Entity> generatorFilter = generatorData.getEntityFilter();
|
|
||||||
if(generatorFilter != null && generatorFilter.contains(receiverParent)){
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Entity> receiverFilter = receiverData.getEntityFilter();
|
|
||||||
if(receiverFilter != null && receiverFilter.contains(generatorParent)){
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
//if there is a collision
|
|
||||||
//and the collision isn't against itself
|
|
||||||
//and both hitboxes are active
|
|
||||||
if(
|
|
||||||
receiverParent != generatorParent &&
|
|
||||||
generatorRealm.getCollisionEngine().collisionSphereCheck(generatorHitbox, generatorData, receiverHitbox, receiverData) &&
|
|
||||||
generatorData.isActive() &&
|
|
||||||
receiverData.isActive()){
|
|
||||||
//if two spheres collide, grab their hitbox types (eg hurt, hit, fire, etc)
|
|
||||||
String generatorType = generatorData.getType();
|
|
||||||
String receiverType = receiverData.getType();
|
|
||||||
|
|
||||||
if(generatorType.equals(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HIT) && receiverType.equals(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HURT)){
|
|
||||||
serverDamageHitboxColision(generatorHitbox, receiverHitbox);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(generatorType.equals(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HURT) && receiverType.equals(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HIT)){
|
|
||||||
serverDamageHitboxColision(receiverHitbox, generatorHitbox);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void clientDamageHitboxColision(Entity hitbox, Entity hurtbox){
|
|
||||||
|
|
||||||
Entity hitboxParent = (Entity)hitbox.getData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT);
|
|
||||||
Entity hurtboxParent = (Entity)hurtbox.getData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT);
|
|
||||||
|
|
||||||
//if the entity is attached to is an item, we need to compare with the parent of the item
|
|
||||||
//to make sure you don't stab yourself for instance
|
|
||||||
boolean isItem = ItemUtils.isItem(hitboxParent);//hitboxParent.containsKey(EntityDataStrings.ITEM_IS_ITEM);
|
|
||||||
Entity hitboxAttachParent = AttachUtils.getParent(hitboxParent);
|
|
||||||
|
|
||||||
if(isItem){
|
|
||||||
if(hitboxAttachParent != hurtboxParent){
|
|
||||||
LifeState lifeState = LifeUtils.getLifeState(hurtboxParent);
|
|
||||||
int currentHp = lifeState.getLifeCurrent();
|
|
||||||
int damage = ItemUtils.getWeaponDataRaw(hitboxParent).getDamage();
|
|
||||||
LifeUtils.getLifeState(hurtboxParent).damage(damage);
|
|
||||||
if(currentHp > lifeState.getLifeCurrent()){
|
|
||||||
Vector3d hurtboxPos = EntityUtils.getPosition(hurtbox);
|
|
||||||
ParticleEffects.spawnBloodsplats(new Vector3f((float)hurtboxPos.x,(float)hurtboxPos.y,(float)hurtboxPos.z).add(0,0.1f,0), 20, 40);
|
|
||||||
}
|
|
||||||
if(!LifeUtils.getLifeState(hurtboxParent).isIsAlive()){
|
|
||||||
EntityUtils.getPosition(hurtboxParent).set(Globals.spawnPoint);
|
|
||||||
LifeUtils.getLifeState(hurtboxParent).revive();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
int damage = 0;
|
|
||||||
//for entities using attacktree
|
|
||||||
if(CreatureUtils.clientGetAttackTree(hitboxParent) != null){
|
|
||||||
damage = ItemUtils.getWeaponDataRaw(hitboxParent).getDamage();
|
|
||||||
} else {
|
|
||||||
//for entities using shooter tree
|
|
||||||
if(ProjectileTree.getProjectileTree(hitboxParent) != null){
|
|
||||||
damage = (int)ProjectileTree.getProjectileTree(hitboxParent).getDamage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
LifeUtils.getLifeState(hurtboxParent).damage(damage);
|
|
||||||
if(!LifeUtils.getLifeState(hurtboxParent).isIsAlive()){
|
|
||||||
EntityUtils.getPosition(hurtboxParent).set(Globals.spawnPoint);
|
|
||||||
LifeUtils.getLifeState(hurtboxParent).revive();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void serverDamageHitboxColision(Entity hitbox, Entity hurtbox){
|
|
||||||
|
|
||||||
Entity hitboxParent = (Entity)hitbox.getData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT);
|
|
||||||
Entity hurtboxParent = (Entity)hurtbox.getData(EntityDataStrings.COLLISION_ENTITY_DATA_PARENT);
|
|
||||||
|
|
||||||
//if the entity is attached to is an item, we need to compare with the parent of the item
|
|
||||||
//to make sure you don't stab yourself for instance
|
|
||||||
boolean isItem = ItemUtils.isItem(hitboxParent);//hitboxParent.containsKey(EntityDataStrings.ITEM_IS_ITEM);
|
|
||||||
Entity hitboxAttachParent = AttachUtils.getParent(hitboxParent);
|
|
||||||
|
|
||||||
if(isItem){
|
|
||||||
if(hitboxAttachParent != hurtboxParent){
|
|
||||||
LifeState lifeState = LifeUtils.getLifeState(hurtboxParent);
|
|
||||||
int currentHp = lifeState.getLifeCurrent();
|
|
||||||
int damage = ItemUtils.getWeaponDataRaw(hitboxParent).getDamage();
|
|
||||||
LifeUtils.getLifeState(hurtboxParent).damage(damage);
|
|
||||||
if(currentHp > lifeState.getLifeCurrent()){
|
|
||||||
Vector3d hurtboxPos = EntityUtils.getPosition(hurtbox);
|
|
||||||
ParticleEffects.spawnBloodsplats(new Vector3f((float)hurtboxPos.x,(float)hurtboxPos.y,(float)hurtboxPos.z).add(0,0.1f,0), 20, 40);
|
|
||||||
}
|
|
||||||
if(!LifeUtils.getLifeState(hurtboxParent).isIsAlive()){
|
|
||||||
EntityUtils.getPosition(hurtboxParent).set(Globals.spawnPoint);
|
|
||||||
LifeUtils.getLifeState(hurtboxParent).revive();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
int damage = 0;
|
|
||||||
//for entities using attacktree
|
|
||||||
if(CreatureUtils.serverGetAttackTree(hitboxParent) != null){
|
|
||||||
damage = ItemUtils.getWeaponDataRaw(hitboxParent).getDamage();
|
|
||||||
} else {
|
|
||||||
//for entities using shooter tree
|
|
||||||
if(ProjectileTree.getProjectileTree(hitboxParent) != null){
|
|
||||||
damage = (int)ProjectileTree.getProjectileTree(hitboxParent).getDamage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
LifeUtils.getLifeState(hurtboxParent).damage(damage);
|
|
||||||
if(!LifeUtils.getLifeState(hurtboxParent).isIsAlive()){
|
|
||||||
EntityUtils.getPosition(hurtboxParent).set(Globals.spawnPoint);
|
|
||||||
LifeUtils.getLifeState(hurtboxParent).revive();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static HitboxData getHitboxData(Entity e){
|
|
||||||
return (HitboxData)e.getData(EntityDataStrings.HITBOX_DATA);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<Entity> getHitboxAssociatedList(Entity e){
|
|
||||||
return (List<Entity>)e.getData(EntityDataStrings.HITBOX_ASSOCIATED_LIST);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<Entity> getHurtboxAssociatedList(Entity e){
|
|
||||||
return (List<Entity>)e.getData(EntityDataStrings.HURTBOX_ASSOCIATED_LIST);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Intended to be implemented as an anonoymous class when needed
|
|
||||||
*/
|
|
||||||
public interface HitboxPositionCallback {
|
|
||||||
/**
|
|
||||||
* Gets the current position this hitbox should be at
|
|
||||||
* @return The position this hitbox should be at
|
|
||||||
*/
|
|
||||||
public Vector3d getPosition();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -14,6 +14,7 @@ import electrosphere.collision.CollisionBodyCreation;
|
|||||||
import electrosphere.collision.PhysicsEntityUtils;
|
import electrosphere.collision.PhysicsEntityUtils;
|
||||||
import electrosphere.collision.PhysicsUtils;
|
import electrosphere.collision.PhysicsUtils;
|
||||||
import electrosphere.collision.collidable.Collidable;
|
import electrosphere.collision.collidable.Collidable;
|
||||||
|
import electrosphere.collision.hitbox.HitboxUtils;
|
||||||
import electrosphere.engine.Globals;
|
import electrosphere.engine.Globals;
|
||||||
import electrosphere.entity.Entity;
|
import electrosphere.entity.Entity;
|
||||||
import electrosphere.entity.EntityCreationUtils;
|
import electrosphere.entity.EntityCreationUtils;
|
||||||
@ -25,9 +26,9 @@ import electrosphere.entity.state.collidable.ClientCollidableTree;
|
|||||||
import electrosphere.entity.state.collidable.ServerCollidableTree;
|
import electrosphere.entity.state.collidable.ServerCollidableTree;
|
||||||
import electrosphere.entity.state.gravity.ClientGravityTree;
|
import electrosphere.entity.state.gravity.ClientGravityTree;
|
||||||
import electrosphere.entity.state.gravity.ServerGravityTree;
|
import electrosphere.entity.state.gravity.ServerGravityTree;
|
||||||
import electrosphere.entity.types.hitbox.HitboxData;
|
import electrosphere.entity.state.hitbox.HitboxCollectionState;
|
||||||
import electrosphere.entity.types.hitbox.HitboxUtils;
|
|
||||||
import electrosphere.game.data.collidable.CollidableTemplate;
|
import electrosphere.game.data.collidable.CollidableTemplate;
|
||||||
|
import electrosphere.game.data.collidable.HitboxData;
|
||||||
import electrosphere.game.data.item.type.EquipWhitelist;
|
import electrosphere.game.data.item.type.EquipWhitelist;
|
||||||
import electrosphere.game.data.item.type.Item;
|
import electrosphere.game.data.item.type.Item;
|
||||||
import electrosphere.game.data.item.type.WeaponData;
|
import electrosphere.game.data.item.type.WeaponData;
|
||||||
@ -39,6 +40,7 @@ import electrosphere.renderer.actor.ActorUtils;
|
|||||||
import electrosphere.server.datacell.Realm;
|
import electrosphere.server.datacell.Realm;
|
||||||
import electrosphere.server.datacell.utils.ServerBehaviorTreeUtils;
|
import electrosphere.server.datacell.utils.ServerBehaviorTreeUtils;
|
||||||
import electrosphere.server.datacell.utils.ServerEntityTagUtils;
|
import electrosphere.server.datacell.utils.ServerEntityTagUtils;
|
||||||
|
import electrosphere.server.poseactor.PoseActor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utilities for working with items
|
* Utilities for working with items
|
||||||
@ -59,13 +61,7 @@ public class ItemUtils {
|
|||||||
rVal.putData(EntityDataStrings.ITEM_IS_WEAPON, true);
|
rVal.putData(EntityDataStrings.ITEM_IS_WEAPON, true);
|
||||||
WeaponData weaponData = item.getWeaponData();
|
WeaponData weaponData = item.getWeaponData();
|
||||||
if(weaponData.getHitboxes() != null){
|
if(weaponData.getHitboxes() != null){
|
||||||
List<Entity> hitboxList = new LinkedList<Entity>();
|
HitboxCollectionState.attachHitboxState(Globals.clientSceneWrapper.getHitboxManager(), false, rVal, weaponData.getHitboxes());
|
||||||
for(HitboxData hitboxdata : weaponData.getHitboxes()){
|
|
||||||
Entity hitbox = HitboxUtils.clientSpawnRegularHitbox(rVal, hitboxdata.getBone(), hitboxdata.getRadius());
|
|
||||||
Globals.clientHitboxManager.registerHitbox(hitbox);
|
|
||||||
hitboxList.add(hitbox);
|
|
||||||
}
|
|
||||||
rVal.putData(EntityDataStrings.HITBOX_ASSOCIATED_LIST,hitboxList);
|
|
||||||
}
|
}
|
||||||
rVal.putData(EntityDataStrings.ITEM_WEAPON_CLASS,weaponData.getWeaponClass());
|
rVal.putData(EntityDataStrings.ITEM_WEAPON_CLASS,weaponData.getWeaponClass());
|
||||||
rVal.putData(EntityDataStrings.ITEM_WEAPON_DATA_RAW,weaponData);
|
rVal.putData(EntityDataStrings.ITEM_WEAPON_DATA_RAW,weaponData);
|
||||||
@ -138,13 +134,7 @@ public class ItemUtils {
|
|||||||
rVal.putData(EntityDataStrings.ITEM_IS_WEAPON, true);
|
rVal.putData(EntityDataStrings.ITEM_IS_WEAPON, true);
|
||||||
WeaponData weaponData = item.getWeaponData();
|
WeaponData weaponData = item.getWeaponData();
|
||||||
if(weaponData.getHitboxes() != null){
|
if(weaponData.getHitboxes() != null){
|
||||||
List<Entity> hitboxList = new LinkedList<Entity>();
|
HitboxCollectionState.attachHitboxState(realm.getHitboxManager(), true, rVal, weaponData.getHitboxes());
|
||||||
for(HitboxData hitboxdata : weaponData.getHitboxes()){
|
|
||||||
Entity hitbox = HitboxUtils.serverSpawnRegularHitbox(rVal, hitboxdata.getBone(), hitboxdata.getRadius());
|
|
||||||
realm.getHitboxManager().registerHitbox(hitbox);
|
|
||||||
hitboxList.add(hitbox);
|
|
||||||
}
|
|
||||||
rVal.putData(EntityDataStrings.HITBOX_ASSOCIATED_LIST,hitboxList);
|
|
||||||
}
|
}
|
||||||
rVal.putData(EntityDataStrings.ITEM_WEAPON_CLASS,weaponData.getWeaponClass());
|
rVal.putData(EntityDataStrings.ITEM_WEAPON_CLASS,weaponData.getWeaponClass());
|
||||||
rVal.putData(EntityDataStrings.ITEM_WEAPON_DATA_RAW,weaponData);
|
rVal.putData(EntityDataStrings.ITEM_WEAPON_DATA_RAW,weaponData);
|
||||||
@ -233,12 +223,32 @@ public class ItemUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates an item to play its idle animation
|
||||||
|
* @param item THe item entity
|
||||||
|
*/
|
||||||
public static void updateItemActorAnimation(Entity item){
|
public static void updateItemActorAnimation(Entity item){
|
||||||
Actor actor = EntityUtils.getActor(item);
|
Actor actor = EntityUtils.getActor(item);
|
||||||
if(actor != null && item.getData(EntityDataStrings.ANIM_IDLE) != null){
|
if(actor != null && item.getData(EntityDataStrings.ANIM_IDLE) != null){
|
||||||
String idleAnim = (String)item.getData(EntityDataStrings.ANIM_IDLE);
|
String idleAnim = (String)item.getData(EntityDataStrings.ANIM_IDLE);
|
||||||
if(!actor.isPlayingAnimation(idleAnim)){
|
if(!actor.isPlayingAnimation(idleAnim)){
|
||||||
actor.playAnimation(idleAnim,1);
|
actor.playAnimation(idleAnim,1);
|
||||||
|
actor.incrementAnimationTime(0.0001);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the item's pose actor to play its idle animation on the server
|
||||||
|
* @param item The item entity
|
||||||
|
*/
|
||||||
|
public static void updateItemPoseActorAnimation(Entity item){
|
||||||
|
PoseActor actor = EntityUtils.getPoseActor(item);
|
||||||
|
if(actor != null && item.getData(EntityDataStrings.ANIM_IDLE) != null){
|
||||||
|
String idleAnim = (String)item.getData(EntityDataStrings.ANIM_IDLE);
|
||||||
|
if(!actor.isPlayingAnimation(idleAnim)){
|
||||||
|
actor.playAnimation(idleAnim,1);
|
||||||
|
actor.incrementAnimationTime(0.0001);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -378,13 +388,7 @@ public class ItemUtils {
|
|||||||
//this deregisters from all four & unhooks rigid bodies from the physics runtime
|
//this deregisters from all four & unhooks rigid bodies from the physics runtime
|
||||||
Globals.clientSceneWrapper.getCollisionEngine().destroyEntityThatHasPhysics(item);
|
Globals.clientSceneWrapper.getCollisionEngine().destroyEntityThatHasPhysics(item);
|
||||||
//destroy hitboxes
|
//destroy hitboxes
|
||||||
List<Entity> hitboxes = HitboxUtils.getHitboxAssociatedList(item);
|
HitboxCollectionState.destroyHitboxState(item);
|
||||||
if(hitboxes != null){
|
|
||||||
for(Entity hitbox : hitboxes){
|
|
||||||
Globals.clientHitboxManager.deregisterHitbox(hitbox);
|
|
||||||
HitboxUtils.getHitboxData(hitbox).setActive(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//destroy graphics
|
//destroy graphics
|
||||||
EntityUtils.cleanUpEntity(item);
|
EntityUtils.cleanUpEntity(item);
|
||||||
}
|
}
|
||||||
@ -401,13 +405,7 @@ public class ItemUtils {
|
|||||||
if(itemRealm != null){
|
if(itemRealm != null){
|
||||||
itemRealm.getCollisionEngine().destroyEntityThatHasPhysics(item);
|
itemRealm.getCollisionEngine().destroyEntityThatHasPhysics(item);
|
||||||
//destroy hitboxes
|
//destroy hitboxes
|
||||||
List<Entity> hitboxes = HitboxUtils.getHitboxAssociatedList(item);
|
HitboxCollectionState.destroyHitboxState(item);
|
||||||
if(hitboxes != null){
|
|
||||||
for(Entity hitbox : hitboxes){
|
|
||||||
itemRealm.getHitboxManager().deregisterHitbox(hitbox);
|
|
||||||
HitboxUtils.getHitboxData(hitbox).setActive(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
//destroy graphics
|
//destroy graphics
|
||||||
EntityUtils.cleanUpEntity(item);
|
EntityUtils.cleanUpEntity(item);
|
||||||
|
|||||||
@ -22,7 +22,9 @@ import electrosphere.entity.state.collidable.ClientCollidableTree;
|
|||||||
import electrosphere.entity.state.collidable.ServerCollidableTree;
|
import electrosphere.entity.state.collidable.ServerCollidableTree;
|
||||||
import electrosphere.entity.state.gravity.ClientGravityTree;
|
import electrosphere.entity.state.gravity.ClientGravityTree;
|
||||||
import electrosphere.entity.state.gravity.ServerGravityTree;
|
import electrosphere.entity.state.gravity.ServerGravityTree;
|
||||||
import electrosphere.entity.state.idle.IdleTree;
|
import electrosphere.entity.state.hitbox.HitboxCollectionState;
|
||||||
|
import electrosphere.entity.state.idle.ClientIdleTree;
|
||||||
|
import electrosphere.entity.state.idle.ServerIdleTree;
|
||||||
import electrosphere.entity.state.inventory.ClientInventoryState;
|
import electrosphere.entity.state.inventory.ClientInventoryState;
|
||||||
import electrosphere.entity.state.inventory.InventoryUtils;
|
import electrosphere.entity.state.inventory.InventoryUtils;
|
||||||
import electrosphere.entity.state.inventory.ServerInventoryState;
|
import electrosphere.entity.state.inventory.ServerInventoryState;
|
||||||
@ -44,11 +46,17 @@ public class ObjectUtils {
|
|||||||
//the entity type value
|
//the entity type value
|
||||||
public static final int ENTITY_TYPE_OBJECT = 2;
|
public static final int ENTITY_TYPE_OBJECT = 2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Spawns an object in the client scene
|
||||||
|
* @param type The type of object
|
||||||
|
* @return The object entity
|
||||||
|
*/
|
||||||
public static Entity clientSpawnBasicObject(String type){
|
public static Entity clientSpawnBasicObject(String type){
|
||||||
ObjectData rawType = Globals.gameConfigCurrent.getObjectTypeLoader().getObject(type);
|
ObjectData rawType = Globals.gameConfigCurrent.getObjectTypeLoader().getObject(type);
|
||||||
Entity rVal = EntityCreationUtils.createClientSpatialEntity();
|
Entity rVal = EntityCreationUtils.createClientSpatialEntity();
|
||||||
EntityCreationUtils.makeEntityPoseable(rVal, rawType.getModelPath());
|
if(rawType.getModelPath() != null){
|
||||||
Actor creatureActor = EntityUtils.getActor(rVal);
|
EntityCreationUtils.makeEntityDrawable(rVal, rawType.getModelPath());
|
||||||
|
}
|
||||||
//forward-searching tokens
|
//forward-searching tokens
|
||||||
boolean collisionMakeDynamic = true;
|
boolean collisionMakeDynamic = true;
|
||||||
for(String token : rawType.getTokens()){
|
for(String token : rawType.getTokens()){
|
||||||
@ -112,11 +120,14 @@ public class ObjectUtils {
|
|||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(rawType.getHitboxData() != null){
|
||||||
|
HitboxCollectionState.attachHitboxState(Globals.clientSceneWrapper.getHitboxManager(), false, rVal, rawType.getHitboxData());
|
||||||
|
}
|
||||||
//add health system
|
//add health system
|
||||||
// rVal.putData(EntityDataStrings.LIFE_STATE, new LifeState(rVal, rawType.getHealthSystem()));
|
// rVal.putData(EntityDataStrings.LIFE_STATE, new LifeState(rVal, rawType.getHealthSystem()));
|
||||||
// Globals.entityManager.registerLifeStateEntity(rVal);
|
// Globals.entityManager.registerLifeStateEntity(rVal);
|
||||||
//idle tree & generic stuff all objects have
|
//idle tree & generic stuff all objects have
|
||||||
rVal.putData(EntityDataStrings.TREE_IDLE, new IdleTree(rVal));
|
rVal.putData(EntityDataStrings.TREE_IDLE, new ClientIdleTree(rVal));
|
||||||
rVal.putData(EntityDataStrings.DRAW_CAST_SHADOW, true);
|
rVal.putData(EntityDataStrings.DRAW_CAST_SHADOW, true);
|
||||||
rVal.putData(EntityDataStrings.ENTITY_TYPE, ENTITY_TYPE_OBJECT);
|
rVal.putData(EntityDataStrings.ENTITY_TYPE, ENTITY_TYPE_OBJECT);
|
||||||
rVal.putData(EntityDataStrings.ENTITY_SUBTYPE, type);
|
rVal.putData(EntityDataStrings.ENTITY_SUBTYPE, type);
|
||||||
@ -133,9 +144,10 @@ public class ObjectUtils {
|
|||||||
public static Entity serverSpawnBasicObject(Realm realm, Vector3d position, String type){
|
public static Entity serverSpawnBasicObject(Realm realm, Vector3d position, String type){
|
||||||
ObjectData rawType = Globals.gameConfigCurrent.getObjectTypeLoader().getObject(type);
|
ObjectData rawType = Globals.gameConfigCurrent.getObjectTypeLoader().getObject(type);
|
||||||
Entity rVal = EntityCreationUtils.createServerEntity(realm, position);
|
Entity rVal = EntityCreationUtils.createServerEntity(realm, position);
|
||||||
EntityCreationUtils.makeEntityPoseable(rVal, rawType.getModelPath());
|
|
||||||
|
|
||||||
PoseActor creatureActor = EntityUtils.getPoseActor(rVal);
|
if(rawType.getModelPath() != null){
|
||||||
|
EntityCreationUtils.makeEntityPoseable(rVal, rawType.getModelPath());
|
||||||
|
}
|
||||||
//forward-searching tokens
|
//forward-searching tokens
|
||||||
boolean collisionMakeDynamic = true;
|
boolean collisionMakeDynamic = true;
|
||||||
for(String token : rawType.getTokens()){
|
for(String token : rawType.getTokens()){
|
||||||
@ -199,12 +211,11 @@ public class ObjectUtils {
|
|||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//add health system
|
if(rawType.getHitboxData() != null){
|
||||||
// rVal.putData(EntityDataStrings.LIFE_STATE, new LifeState(rVal, rawType.getHealthSystem()));
|
HitboxCollectionState.attachHitboxState(realm.getHitboxManager(), true, rVal, rawType.getHitboxData());
|
||||||
// Globals.entityManager.registerLifeStateEntity(rVal);
|
}
|
||||||
//idle tree & generic stuff all objects have
|
//idle tree & generic stuff all objects have
|
||||||
rVal.putData(EntityDataStrings.TREE_IDLE, new IdleTree(rVal));
|
ServerIdleTree.attachTree(rVal);
|
||||||
rVal.putData(EntityDataStrings.DRAW_CAST_SHADOW, true);
|
|
||||||
|
|
||||||
|
|
||||||
//position entity
|
//position entity
|
||||||
|
|||||||
@ -9,17 +9,20 @@ import org.joml.Quaternionfc;
|
|||||||
import org.joml.Vector3d;
|
import org.joml.Vector3d;
|
||||||
import org.joml.Vector3f;
|
import org.joml.Vector3f;
|
||||||
|
|
||||||
|
import electrosphere.collision.hitbox.HitboxUtils;
|
||||||
|
import electrosphere.collision.hitbox.HitboxUtils.HitboxPositionCallback;
|
||||||
import electrosphere.engine.Globals;
|
import electrosphere.engine.Globals;
|
||||||
import electrosphere.entity.Entity;
|
import electrosphere.entity.Entity;
|
||||||
import electrosphere.entity.EntityCreationUtils;
|
import electrosphere.entity.EntityCreationUtils;
|
||||||
import electrosphere.entity.EntityUtils;
|
import electrosphere.entity.EntityUtils;
|
||||||
import electrosphere.entity.ServerEntityUtils;
|
import electrosphere.entity.ServerEntityUtils;
|
||||||
|
import electrosphere.entity.state.hitbox.HitboxCollectionState;
|
||||||
import electrosphere.entity.state.movement.ProjectileTree;
|
import electrosphere.entity.state.movement.ProjectileTree;
|
||||||
import electrosphere.entity.types.hitbox.HitboxUtils;
|
import electrosphere.game.data.collidable.HitboxData;
|
||||||
import electrosphere.entity.types.hitbox.HitboxUtils.HitboxPositionCallback;
|
|
||||||
import electrosphere.game.data.projectile.ProjectileType;
|
import electrosphere.game.data.projectile.ProjectileType;
|
||||||
import electrosphere.server.datacell.Realm;
|
import electrosphere.server.datacell.Realm;
|
||||||
import electrosphere.server.datacell.utils.ServerBehaviorTreeUtils;
|
import electrosphere.server.datacell.utils.ServerBehaviorTreeUtils;
|
||||||
|
import electrosphere.util.MathUtils;
|
||||||
|
|
||||||
public class ProjectileUtils {
|
public class ProjectileUtils {
|
||||||
|
|
||||||
@ -39,7 +42,7 @@ public class ProjectileUtils {
|
|||||||
Globals.assetManager.addModelPathToQueue(model);
|
Globals.assetManager.addModelPathToQueue(model);
|
||||||
ProjectileTree tree = new ProjectileTree(rVal,maxLife,new Vector3d(initialVector),velocity);
|
ProjectileTree tree = new ProjectileTree(rVal,maxLife,new Vector3d(initialVector),velocity);
|
||||||
EntityUtils.getPosition(rVal).set(initialPosition);
|
EntityUtils.getPosition(rVal).set(initialPosition);
|
||||||
EntityUtils.getRotation(rVal).rotationTo(new Vector3d(0,0,1), new Vector3d(initialVector.x,initialVector.y,initialVector.z)).normalize();
|
EntityUtils.getRotation(rVal).rotationTo(MathUtils.getOriginVector(), new Vector3d(initialVector.x,initialVector.y,initialVector.z)).normalize();
|
||||||
Globals.clientSceneWrapper.getScene().registerBehaviorTree(tree);
|
Globals.clientSceneWrapper.getScene().registerBehaviorTree(tree);
|
||||||
return rVal;
|
return rVal;
|
||||||
}
|
}
|
||||||
@ -59,8 +62,8 @@ public class ProjectileUtils {
|
|||||||
Globals.assetManager.addModelPathToQueue(model);
|
Globals.assetManager.addModelPathToQueue(model);
|
||||||
ProjectileTree tree = new ProjectileTree(rVal,maxLife,new Vector3d(initialVector),velocity);
|
ProjectileTree tree = new ProjectileTree(rVal,maxLife,new Vector3d(initialVector),velocity);
|
||||||
EntityUtils.getPosition(rVal).set(initialPosition);
|
EntityUtils.getPosition(rVal).set(initialPosition);
|
||||||
// EntityUtils.getRotation(currentEntity).rotationTo(new Vector3f(0,0,1), new Vector3f((float)facingAngle.x,(float)facingAngle.y,(float)facingAngle.z)).mul(parentActor.getBoneRotation(targetBone)).normalize();
|
// EntityUtils.getRotation(currentEntity).rotationTo(MathUtils.ORIGIN_VECTORF, new Vector3f((float)facingAngle.x,(float)facingAngle.y,(float)facingAngle.z)).mul(parentActor.getBoneRotation(targetBone)).normalize();
|
||||||
EntityUtils.getRotation(rVal).rotationTo(new Vector3d(0,0,1), new Vector3d(initialVector.x,initialVector.y,initialVector.z)).normalize();
|
EntityUtils.getRotation(rVal).rotationTo(MathUtils.getOriginVector(), new Vector3d(initialVector.x,initialVector.y,initialVector.z)).normalize();
|
||||||
// ParticleTree particleTree = new ParticleTree(rVal, maxLife, destination, velocity, acceleration, true);
|
// ParticleTree particleTree = new ParticleTree(rVal, maxLife, destination, velocity, acceleration, true);
|
||||||
// rVal.putData(EntityDataStrings.PARTICLE_TREE, particleTree);
|
// rVal.putData(EntityDataStrings.PARTICLE_TREE, particleTree);
|
||||||
// rVal.putData(EntityDataStrings.IS_PARTICLE, true);
|
// rVal.putData(EntityDataStrings.IS_PARTICLE, true);
|
||||||
@ -82,7 +85,7 @@ public class ProjectileUtils {
|
|||||||
Entity rVal = EntityCreationUtils.createClientSpatialEntity();
|
Entity rVal = EntityCreationUtils.createClientSpatialEntity();
|
||||||
EntityCreationUtils.makeEntityDrawable(rVal, rawType.getModelPath());
|
EntityCreationUtils.makeEntityDrawable(rVal, rawType.getModelPath());
|
||||||
//initial coordinates
|
//initial coordinates
|
||||||
EntityUtils.getRotation(rVal).rotationTo(new Vector3d(0,0,1), new Vector3d(initialVector.x,initialVector.y,initialVector.z)).normalize();
|
EntityUtils.getRotation(rVal).rotationTo(MathUtils.getOriginVector(), new Vector3d(initialVector.x,initialVector.y,initialVector.z)).normalize();
|
||||||
EntityUtils.getPosition(rVal).set(initialPosition);
|
EntityUtils.getPosition(rVal).set(initialPosition);
|
||||||
//projectile behavior tree
|
//projectile behavior tree
|
||||||
ProjectileTree tree = new ProjectileTree(rVal,rawType.getMaxLife(),initialVector,rawType.getVelocity(), rawType.getDamage());
|
ProjectileTree tree = new ProjectileTree(rVal,rawType.getMaxLife(),initialVector,rawType.getVelocity(), rawType.getDamage());
|
||||||
@ -92,11 +95,15 @@ public class ProjectileUtils {
|
|||||||
List<Entity> filter = new LinkedList<Entity>();
|
List<Entity> filter = new LinkedList<Entity>();
|
||||||
filter.add(parent);
|
filter.add(parent);
|
||||||
//collidable
|
//collidable
|
||||||
HitboxUtils.clientSpawnRegularHitbox(rVal, new HitboxPositionCallback() {
|
HitboxData hitboxData = new HitboxData();
|
||||||
public Vector3d getPosition(){
|
hitboxData.setRadius(rawType.getHitboxRadius());
|
||||||
return EntityUtils.getPosition(rVal);
|
HitboxCollectionState.attachHitboxStateWithCallback(Globals.clientSceneWrapper.getHitboxManager(), Globals.clientSceneWrapper.getCollisionEngine(), rVal, hitboxData,
|
||||||
|
new HitboxPositionCallback() {
|
||||||
|
public Vector3d getPosition(){
|
||||||
|
return EntityUtils.getPosition(rVal);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, rawType.getHitboxRadius(), false, filter);
|
);
|
||||||
return rVal;
|
return rVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,7 +120,7 @@ public class ProjectileUtils {
|
|||||||
ProjectileType rawType = Globals.gameConfigCurrent.getProjectileMap().getType(projectileType);
|
ProjectileType rawType = Globals.gameConfigCurrent.getProjectileMap().getType(projectileType);
|
||||||
Entity rVal = EntityCreationUtils.createServerEntity(realm, initialPosition);
|
Entity rVal = EntityCreationUtils.createServerEntity(realm, initialPosition);
|
||||||
//initial coordinates
|
//initial coordinates
|
||||||
EntityUtils.getRotation(rVal).rotationTo(new Vector3d(0,0,1), new Vector3d(initialVector.x,initialVector.y,initialVector.z)).normalize();
|
EntityUtils.getRotation(rVal).rotationTo(MathUtils.getOriginVector(), new Vector3d(initialVector.x,initialVector.y,initialVector.z)).normalize();
|
||||||
EntityUtils.getPosition(rVal).set(initialPosition);
|
EntityUtils.getPosition(rVal).set(initialPosition);
|
||||||
//projectile behavior tree
|
//projectile behavior tree
|
||||||
ProjectileTree tree = new ProjectileTree(rVal,rawType.getMaxLife(),initialVector,rawType.getVelocity(), rawType.getDamage());
|
ProjectileTree tree = new ProjectileTree(rVal,rawType.getMaxLife(),initialVector,rawType.getVelocity(), rawType.getDamage());
|
||||||
@ -123,11 +130,15 @@ public class ProjectileUtils {
|
|||||||
List<Entity> filter = new LinkedList<Entity>();
|
List<Entity> filter = new LinkedList<Entity>();
|
||||||
filter.add(parent);
|
filter.add(parent);
|
||||||
//collidable
|
//collidable
|
||||||
HitboxUtils.serverSpawnRegularHitbox(rVal, new HitboxPositionCallback() {
|
HitboxData hitboxData = new HitboxData();
|
||||||
public Vector3d getPosition(){
|
hitboxData.setRadius(rawType.getHitboxRadius());
|
||||||
return EntityUtils.getPosition(rVal);
|
HitboxCollectionState.attachHitboxStateWithCallback(realm.getHitboxManager(), realm.getCollisionEngine(), rVal, hitboxData,
|
||||||
|
new HitboxPositionCallback() {
|
||||||
|
public Vector3d getPosition(){
|
||||||
|
return EntityUtils.getPosition(rVal);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, rawType.getHitboxRadius(), false, filter);
|
);
|
||||||
|
|
||||||
|
|
||||||
//position entity
|
//position entity
|
||||||
|
|||||||
@ -5,8 +5,7 @@ import electrosphere.logger.LoggerInterface;
|
|||||||
import electrosphere.util.FileUtils;
|
import electrosphere.util.FileUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* User-defined settings
|
||||||
* @author amaterasu
|
|
||||||
*/
|
*/
|
||||||
public class UserSettings {
|
public class UserSettings {
|
||||||
|
|
||||||
@ -41,7 +40,8 @@ public class UserSettings {
|
|||||||
int renderResolutionY;
|
int renderResolutionY;
|
||||||
//debug
|
//debug
|
||||||
//debug visuals
|
//debug visuals
|
||||||
boolean graphicsDebugDrawCollisionSpheres;
|
boolean graphicsDebugDrawCollisionSpheresClient;
|
||||||
|
boolean graphicsDebugDrawCollisionSpheresServer;
|
||||||
boolean graphicsDebugDrawPhysicsObjects;
|
boolean graphicsDebugDrawPhysicsObjects;
|
||||||
boolean graphicsDebugDrawMovementVectors;
|
boolean graphicsDebugDrawMovementVectors;
|
||||||
boolean graphicsDebugDrawNavmesh;
|
boolean graphicsDebugDrawNavmesh;
|
||||||
@ -82,8 +82,12 @@ public class UserSettings {
|
|||||||
return graphicsPerformanceDrawShadows;
|
return graphicsPerformanceDrawShadows;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean graphicsDebugDrawCollisionSpheres() {
|
public boolean getGraphicsDebugDrawCollisionSpheresClient() {
|
||||||
return graphicsDebugDrawCollisionSpheres;
|
return graphicsDebugDrawCollisionSpheresClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getGraphicsDebugDrawCollisionSpheresServer() {
|
||||||
|
return graphicsDebugDrawCollisionSpheresServer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean graphicsDebugDrawPhysicsObjects() {
|
public boolean graphicsDebugDrawPhysicsObjects() {
|
||||||
@ -131,8 +135,12 @@ public class UserSettings {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void setGraphicsDebugDrawCollisionSpheres(boolean draw){
|
public void setGraphicsDebugDrawCollisionSpheresClient(boolean draw){
|
||||||
this.graphicsDebugDrawCollisionSpheres = draw;
|
this.graphicsDebugDrawCollisionSpheresClient = draw;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGraphicsDebugDrawCollisionSpheresServer(boolean draw){
|
||||||
|
this.graphicsDebugDrawCollisionSpheresServer = draw;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setGraphicsDebugDrawPhysicsObjects(boolean draw){
|
public void setGraphicsDebugDrawPhysicsObjects(boolean draw){
|
||||||
@ -178,7 +186,8 @@ public class UserSettings {
|
|||||||
rVal.gameplayPhysicsCellRadius = 2;
|
rVal.gameplayPhysicsCellRadius = 2;
|
||||||
|
|
||||||
//graphics settings
|
//graphics settings
|
||||||
rVal.graphicsDebugDrawCollisionSpheres = false;
|
rVal.graphicsDebugDrawCollisionSpheresClient = false;
|
||||||
|
rVal.graphicsDebugDrawCollisionSpheresServer = false;
|
||||||
rVal.graphicsDebugDrawMovementVectors = false;
|
rVal.graphicsDebugDrawMovementVectors = false;
|
||||||
rVal.graphicsDebugDrawPhysicsObjects = false;
|
rVal.graphicsDebugDrawPhysicsObjects = false;
|
||||||
rVal.graphicsDebugDrawNavmesh = false;
|
rVal.graphicsDebugDrawNavmesh = false;
|
||||||
|
|||||||
145
src/main/java/electrosphere/game/data/collidable/HitboxData.java
Normal file
145
src/main/java/electrosphere/game/data/collidable/HitboxData.java
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
package electrosphere.game.data.collidable;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import electrosphere.collision.hitbox.HitboxUtils.HitboxPositionCallback;
|
||||||
|
import electrosphere.entity.Entity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data about a hitbox
|
||||||
|
*/
|
||||||
|
public class HitboxData {
|
||||||
|
|
||||||
|
//a hitbox sphere that teleports to its new position between frames
|
||||||
|
public static final String HITBOX_TYPE_HIT = "hit";
|
||||||
|
//a hurtbox sphere that teleports to its new position between frames
|
||||||
|
public static final String HITBOX_TYPE_HURT = "hurt";
|
||||||
|
//a hitbox sphere that is connected to its previous position by a capsule. The capsule is used for collision checks
|
||||||
|
public static final String HITBOX_TYPE_HIT_CONNECTED = "hit_connected";
|
||||||
|
//a hurtbox sphere that is connected to its previous position by a capsule. The capsule is used for collision checks
|
||||||
|
public static final String HITBOX_TYPE_HURT_CONNECTED = "hurt_connected";
|
||||||
|
//a block sphere that is connected to its previous position by a capsule. The capsule is used for collision checks
|
||||||
|
public static final String HITBOX_TYPE_BLOCK_CONNECTED = "block_connected";
|
||||||
|
|
||||||
|
//used for debugging -- to show whether a hitbox is colliding with it or not
|
||||||
|
public static final String HITBOX_TYPE_STATIC_CAPSULE = "static_capsule";
|
||||||
|
|
||||||
|
//the type of hitbox
|
||||||
|
String type;
|
||||||
|
|
||||||
|
//the bone it is attached to
|
||||||
|
String bone;
|
||||||
|
|
||||||
|
//the radius of the hitbox
|
||||||
|
float radius;
|
||||||
|
|
||||||
|
//the length of a static capsule hitbox
|
||||||
|
float length;
|
||||||
|
|
||||||
|
//controls whether the hitbox is active or not
|
||||||
|
boolean active = false;
|
||||||
|
|
||||||
|
//used for more advanced hitbox spawning to find hitbox position on frame update
|
||||||
|
HitboxPositionCallback positionCallback;
|
||||||
|
|
||||||
|
//used to filter this hitbox to hitting only certain parent entities
|
||||||
|
List<Entity> filter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the type of hitbox
|
||||||
|
* @return the type of hitbox
|
||||||
|
*/
|
||||||
|
public String getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the type of bone
|
||||||
|
* @return the type of bone
|
||||||
|
*/
|
||||||
|
public String getBone() {
|
||||||
|
return bone;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the radius of the hitbox
|
||||||
|
* @return the radius of the hitbox
|
||||||
|
*/
|
||||||
|
public float getRadius() {
|
||||||
|
return radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the length of hitbox if applicable
|
||||||
|
* @return The length
|
||||||
|
*/
|
||||||
|
public float getLength(){
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the hitbox is active or not
|
||||||
|
* @return true if the hitbox is active, false otherwise
|
||||||
|
*/
|
||||||
|
public boolean isActive() {
|
||||||
|
return active;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toggles the active status
|
||||||
|
* @param active if true, the hitbox will be active, if false the hitbox will be inactive
|
||||||
|
*/
|
||||||
|
public void setActive(boolean active) {
|
||||||
|
this.active = active;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the bone this hitbox is attached to
|
||||||
|
* @param bone the bone to attach the hitbox to
|
||||||
|
*/
|
||||||
|
public void setBone(String bone) {
|
||||||
|
this.bone = bone;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setType(String type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRadius(float radius) {
|
||||||
|
this.radius = radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the position callback
|
||||||
|
* @return The position callback
|
||||||
|
*/
|
||||||
|
public HitboxPositionCallback getPositionCallback(){
|
||||||
|
return positionCallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the position callback
|
||||||
|
* @param positionCallback The position callback
|
||||||
|
*/
|
||||||
|
public void setPositionCallback(HitboxPositionCallback positionCallback){
|
||||||
|
this.positionCallback = positionCallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets an entity filter on the hitbox
|
||||||
|
* @param filter The list of parent entities to exclude from collisions
|
||||||
|
*/
|
||||||
|
public void setEntityFilter(List<Entity> filter){
|
||||||
|
this.filter = filter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the entity filter
|
||||||
|
* @return The list of parent entities to exclude from collisions
|
||||||
|
*/
|
||||||
|
public List<Entity> getEntityFilter(){
|
||||||
|
return filter;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,7 +1,7 @@
|
|||||||
package electrosphere.game.data.creature.type;
|
package electrosphere.game.data.creature.type;
|
||||||
|
|
||||||
import electrosphere.entity.types.hitbox.HitboxData;
|
|
||||||
import electrosphere.game.data.collidable.CollidableTemplate;
|
import electrosphere.game.data.collidable.CollidableTemplate;
|
||||||
|
import electrosphere.game.data.collidable.HitboxData;
|
||||||
import electrosphere.game.data.creature.type.attack.AttackMove;
|
import electrosphere.game.data.creature.type.attack.AttackMove;
|
||||||
import electrosphere.game.data.creature.type.attack.AttackMoveResolver;
|
import electrosphere.game.data.creature.type.attack.AttackMoveResolver;
|
||||||
import electrosphere.game.data.creature.type.equip.EquipPoint;
|
import electrosphere.game.data.creature.type.equip.EquipPoint;
|
||||||
|
|||||||
@ -60,6 +60,14 @@ public class EquipPoint {
|
|||||||
return offsetRotation;
|
return offsetRotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the offset rotation (used primarily for debug and engine testing)
|
||||||
|
* @param offsetRotation The new offset rotation
|
||||||
|
*/
|
||||||
|
public void setOffsetRotation(List<Float> offsetRotation){
|
||||||
|
this.offsetRotation = offsetRotation;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the equip classes that are whitelisted for this equip point
|
* Gets the equip classes that are whitelisted for this equip point
|
||||||
* @return the classes
|
* @return the classes
|
||||||
|
|||||||
@ -3,9 +3,14 @@ package electrosphere.game.data.graphics;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A graphics template for an entity
|
||||||
|
*/
|
||||||
public class GraphicsTemplate {
|
public class GraphicsTemplate {
|
||||||
|
|
||||||
|
//a list of shader overrides
|
||||||
List<String> shaderOverrideMeshList;
|
List<String> shaderOverrideMeshList;
|
||||||
|
//??? TODO: investigate
|
||||||
Map<String,ShaderSet> shaderMap;
|
Map<String,ShaderSet> shaderMap;
|
||||||
|
|
||||||
public List<String> getShaderOverrideMeshList(){
|
public List<String> getShaderOverrideMeshList(){
|
||||||
|
|||||||
@ -2,27 +2,50 @@ package electrosphere.game.data.item.type;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import electrosphere.entity.types.hitbox.HitboxData;
|
import electrosphere.game.data.collidable.HitboxData;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Data about a weapon
|
||||||
|
*/
|
||||||
public class WeaponData {
|
public class WeaponData {
|
||||||
|
|
||||||
|
//the class of weapon (ie sword, bow, etc)
|
||||||
String weaponClass;
|
String weaponClass;
|
||||||
|
//the hitboxes associated with the weapon
|
||||||
List<HitboxData> hitboxes;
|
List<HitboxData> hitboxes;
|
||||||
|
//the damage the weapon does
|
||||||
int damage;
|
int damage;
|
||||||
|
//the model for the projectile
|
||||||
String projectileModel;
|
String projectileModel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the weapon class
|
||||||
|
* @return the weapon class
|
||||||
|
*/
|
||||||
public String getWeaponClass(){
|
public String getWeaponClass(){
|
||||||
return weaponClass;
|
return weaponClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the list of hitbox data
|
||||||
|
* @return the list of hitbox data
|
||||||
|
*/
|
||||||
public List<HitboxData> getHitboxes(){
|
public List<HitboxData> getHitboxes(){
|
||||||
return hitboxes;
|
return hitboxes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the projectile model
|
||||||
|
* @return the projectile model
|
||||||
|
*/
|
||||||
public String getProjectileModel(){
|
public String getProjectileModel(){
|
||||||
return projectileModel;
|
return projectileModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the damage dealt
|
||||||
|
* @return the damage dealt
|
||||||
|
*/
|
||||||
public int getDamage(){
|
public int getDamage(){
|
||||||
return damage;
|
return damage;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,37 +1,75 @@
|
|||||||
package electrosphere.game.data.object.type;
|
package electrosphere.game.data.object.type;
|
||||||
|
|
||||||
import electrosphere.entity.types.hitbox.HitboxData;
|
|
||||||
import electrosphere.game.data.collidable.CollidableTemplate;
|
import electrosphere.game.data.collidable.CollidableTemplate;
|
||||||
|
import electrosphere.game.data.collidable.HitboxData;
|
||||||
import electrosphere.game.data.graphics.GraphicsTemplate;
|
import electrosphere.game.data.graphics.GraphicsTemplate;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Metadata about a type of object
|
||||||
|
*/
|
||||||
public class ObjectData {
|
public class ObjectData {
|
||||||
|
|
||||||
|
//the id of the object
|
||||||
String objectId;
|
String objectId;
|
||||||
|
//the path for the model for this object
|
||||||
String modelPath;
|
String modelPath;
|
||||||
|
//tokens associated with this object
|
||||||
List<String> tokens;
|
List<String> tokens;
|
||||||
|
//the collidable template for this object
|
||||||
CollidableTemplate collidable;
|
CollidableTemplate collidable;
|
||||||
|
//the graphics template for this object
|
||||||
GraphicsTemplate graphicsTemplate;
|
GraphicsTemplate graphicsTemplate;
|
||||||
|
//the hitbox data for this object
|
||||||
|
List<HitboxData> hitboxData;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the id of the object
|
||||||
|
* @return the id
|
||||||
|
*/
|
||||||
public String getObjectId() {
|
public String getObjectId() {
|
||||||
return objectId;
|
return objectId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the model path of the object
|
||||||
|
* @return the model path
|
||||||
|
*/
|
||||||
public String getModelPath() {
|
public String getModelPath() {
|
||||||
return modelPath;
|
return modelPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets all tokens associated with this object
|
||||||
|
* @return the list of all tokens
|
||||||
|
*/
|
||||||
public List<String> getTokens() {
|
public List<String> getTokens() {
|
||||||
return tokens;
|
return tokens;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the collidable data for this object
|
||||||
|
* @return the collidable data
|
||||||
|
*/
|
||||||
public CollidableTemplate getCollidable(){
|
public CollidableTemplate getCollidable(){
|
||||||
return collidable;
|
return collidable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the graphics template for this object
|
||||||
|
* @return the graphics template
|
||||||
|
*/
|
||||||
public GraphicsTemplate getGraphicsTemplate(){
|
public GraphicsTemplate getGraphicsTemplate(){
|
||||||
return graphicsTemplate;
|
return graphicsTemplate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the hitbox data for this object
|
||||||
|
* @return the hitbox data
|
||||||
|
*/
|
||||||
|
public List<HitboxData> getHitboxData(){
|
||||||
|
return this.hitboxData;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,14 +7,40 @@ import java.util.Map;
|
|||||||
|
|
||||||
import electrosphere.game.data.object.type.ObjectData;
|
import electrosphere.game.data.object.type.ObjectData;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An interface for grabbing data about objects available to the game engine
|
||||||
|
*/
|
||||||
public class ObjectTypeLoader {
|
public class ObjectTypeLoader {
|
||||||
|
|
||||||
|
//the map that stores all object types by name
|
||||||
Map<String,ObjectData> objectMap = new HashMap<String,ObjectData>();
|
Map<String,ObjectData> objectMap = new HashMap<String,ObjectData>();
|
||||||
|
|
||||||
public void putObject(String name, ObjectData type){
|
//the list of all object data
|
||||||
objectMap.put(name,type);
|
List<ObjectData> objectList = new LinkedList<ObjectData>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the list of all object types loaded into memory
|
||||||
|
* @return The list
|
||||||
|
*/
|
||||||
|
public List<ObjectData> getAllObjectTypes(){
|
||||||
|
return objectList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Puts an object in the map
|
||||||
|
* @param name The name of the object
|
||||||
|
* @param type The object type data
|
||||||
|
*/
|
||||||
|
public void putObject(String name, ObjectData type){
|
||||||
|
objectMap.put(name,type);
|
||||||
|
objectList.add(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets object data by its name
|
||||||
|
* @param name The name of the object type
|
||||||
|
* @return The object data if it exists, otherwise null
|
||||||
|
*/
|
||||||
public ObjectData getObject(String name){
|
public ObjectData getObject(String name){
|
||||||
return objectMap.get(name);
|
return objectMap.get(name);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,15 +3,29 @@ package electrosphere.game.data.object.type.model;
|
|||||||
import electrosphere.game.data.object.type.ObjectData;
|
import electrosphere.game.data.object.type.ObjectData;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The raw list of object data read from disk
|
||||||
|
*/
|
||||||
public class ObjectTypeMap {
|
public class ObjectTypeMap {
|
||||||
|
|
||||||
|
//the objects stored in this file
|
||||||
List<ObjectData> objects;
|
List<ObjectData> objects;
|
||||||
|
//all children files to recursively parse for more object data
|
||||||
List<String> files;
|
List<String> files;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the list of all objects in this file
|
||||||
|
* @return the list
|
||||||
|
*/
|
||||||
public List<ObjectData> getObjects() {
|
public List<ObjectData> getObjects() {
|
||||||
return objects;
|
return objects;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the object data for an object in this file by its name
|
||||||
|
* @param name the name of the object
|
||||||
|
* @return The object data
|
||||||
|
*/
|
||||||
public ObjectData getObject(String name){
|
public ObjectData getObject(String name){
|
||||||
ObjectData rVal = null;
|
ObjectData rVal = null;
|
||||||
for(ObjectData item : objects){
|
for(ObjectData item : objects){
|
||||||
@ -23,6 +37,10 @@ public class ObjectTypeMap {
|
|||||||
return rVal;
|
return rVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the list of all children files of this file
|
||||||
|
* @return The list of all children files
|
||||||
|
*/
|
||||||
public List<String> getFiles(){
|
public List<String> getFiles(){
|
||||||
return files;
|
return files;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,46 +1,90 @@
|
|||||||
package electrosphere.logger;
|
package electrosphere.logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* A channel for logging messages
|
||||||
* @author amaterasu
|
|
||||||
*/
|
*/
|
||||||
public class Logger {
|
public class Logger {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The different logging levels
|
||||||
|
*/
|
||||||
public enum LogLevel {
|
public enum LogLevel {
|
||||||
|
LOOP_DEBUG, //this should be used for debugging messages that are executed very rapidly/every frame
|
||||||
DEBUG,
|
DEBUG,
|
||||||
INFO,
|
INFO,
|
||||||
WARNING,
|
WARNING,
|
||||||
ERROR,
|
ERROR,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//the level of this log
|
||||||
LogLevel level;
|
LogLevel level;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a logger channel
|
||||||
|
* @param level The level of message to report on this channel
|
||||||
|
*/
|
||||||
public Logger(LogLevel level){
|
public Logger(LogLevel level){
|
||||||
this.level = level;
|
this.level = level;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs a loop debug message.
|
||||||
|
* This should be used for debugging messages that are executed very rapidly/every frame
|
||||||
|
* @param message The message to report
|
||||||
|
*/
|
||||||
|
public void DEBUG_LOOP(String message){
|
||||||
|
if(level == LogLevel.LOOP_DEBUG){
|
||||||
|
System.out.println(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs a debug message.
|
||||||
|
* This should be used for debugging messages that are executed on a given condition that won't necessarily be every loop (ie all network messages)
|
||||||
|
* @param message The message to report
|
||||||
|
*/
|
||||||
public void DEBUG(String message){
|
public void DEBUG(String message){
|
||||||
if(level == LogLevel.DEBUG){
|
if(level == LogLevel.LOOP_DEBUG || level == LogLevel.DEBUG){
|
||||||
System.out.println(message);
|
System.out.println(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs an info message.
|
||||||
|
* This should be used for messages that would have interest to someone running a server (ie specific network messages, account creation, etc)
|
||||||
|
* @param message The message to report
|
||||||
|
*/
|
||||||
public void INFO(String message){
|
public void INFO(String message){
|
||||||
if(level == LogLevel.DEBUG || level == LogLevel.INFO){
|
if(level == LogLevel.LOOP_DEBUG || level == LogLevel.DEBUG || level == LogLevel.INFO){
|
||||||
System.out.println(message);
|
System.out.println(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs a warning message.
|
||||||
|
* This should be used for reporting events that happen in the engine that are concerning but don't mean the engine has failed to execute (ie a texture failed to load)
|
||||||
|
* @param message The message to report
|
||||||
|
*/
|
||||||
public void WARNING(String message){
|
public void WARNING(String message){
|
||||||
if(level == LogLevel.DEBUG || level == LogLevel.INFO || level == LogLevel.WARNING){
|
if(level == LogLevel.LOOP_DEBUG || level == LogLevel.DEBUG || level == LogLevel.INFO || level == LogLevel.WARNING){
|
||||||
System.out.println(message);
|
System.out.println(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs an error message.
|
||||||
|
* This should be used every time we throw any kind of error in the engine
|
||||||
|
* @param message The message to report
|
||||||
|
*/
|
||||||
public void ERROR(String message, Exception e){
|
public void ERROR(String message, Exception e){
|
||||||
if(level == LogLevel.DEBUG || level == LogLevel.INFO || level == LogLevel.WARNING || level == LogLevel.ERROR){
|
if(level == LogLevel.LOOP_DEBUG || level == LogLevel.DEBUG || level == LogLevel.INFO || level == LogLevel.WARNING || level == LogLevel.ERROR){
|
||||||
System.out.println(message);
|
System.err.println(message);
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,8 +12,15 @@ import electrosphere.renderer.ui.elementtypes.ContainerElement;
|
|||||||
import electrosphere.renderer.ui.elementtypes.DrawableElement;
|
import electrosphere.renderer.ui.elementtypes.DrawableElement;
|
||||||
import electrosphere.renderer.ui.elementtypes.Element;
|
import electrosphere.renderer.ui.elementtypes.Element;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utils for native windowing framework
|
||||||
|
*/
|
||||||
public class WindowUtils {
|
public class WindowUtils {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replaces the main menu contents
|
||||||
|
* @param newMenu The new contents
|
||||||
|
*/
|
||||||
public static void replaceMainMenuContents(Element newMenu){
|
public static void replaceMainMenuContents(Element newMenu){
|
||||||
Element mainMenuEl = Globals.elementManager.getWindow(WindowStrings.WINDOW_MENU_MAIN);
|
Element mainMenuEl = Globals.elementManager.getWindow(WindowStrings.WINDOW_MENU_MAIN);
|
||||||
if(mainMenuEl != null && mainMenuEl instanceof Window){
|
if(mainMenuEl != null && mainMenuEl instanceof Window){
|
||||||
@ -26,6 +33,11 @@ public class WindowUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recursively sets a window as visible or not
|
||||||
|
* @param topLevelMenu The window element
|
||||||
|
* @param visible true for visible, false for invisible
|
||||||
|
*/
|
||||||
public static void recursiveSetVisible(Element topLevelMenu, boolean visible){
|
public static void recursiveSetVisible(Element topLevelMenu, boolean visible){
|
||||||
if(topLevelMenu instanceof DrawableElement){
|
if(topLevelMenu instanceof DrawableElement){
|
||||||
((DrawableElement)topLevelMenu).setVisible(visible);
|
((DrawableElement)topLevelMenu).setVisible(visible);
|
||||||
@ -40,6 +52,29 @@ public class WindowUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the window registered to the provided string is open
|
||||||
|
* @param windowString The window string
|
||||||
|
* @return true if the window is open, false otherwise
|
||||||
|
*/
|
||||||
|
public static boolean windowIsOpen(String windowString){
|
||||||
|
Element windowElement = Globals.elementManager.getWindow(windowString);
|
||||||
|
return Globals.elementManager.getWindowList().contains(windowElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a window is open or not
|
||||||
|
* @return The window
|
||||||
|
*/
|
||||||
|
public static boolean controlBlockingWindowIsOpen(){
|
||||||
|
return windowIsOpen(WindowStrings.LEVEL_EDTIOR_SIDE_PANEL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets an inventory window string by the id of the inventory
|
||||||
|
* @param id the id
|
||||||
|
* @return the window string for said inventory window
|
||||||
|
*/
|
||||||
public static String getInventoryWindowID(int id){
|
public static String getInventoryWindowID(int id){
|
||||||
return "INVENTORY-" + id;
|
return "INVENTORY-" + id;
|
||||||
}
|
}
|
||||||
@ -76,8 +111,8 @@ public class WindowUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tries to close a window
|
* Cleans up a window visually and removes it from the element manager
|
||||||
* @param window the window to close
|
* @param window the window to clean up
|
||||||
*/
|
*/
|
||||||
public static void closeWindow(String window){
|
public static void closeWindow(String window){
|
||||||
Element windowEl = Globals.elementManager.getWindow(window);
|
Element windowEl = Globals.elementManager.getWindow(window);
|
||||||
|
|||||||
@ -1,15 +1,27 @@
|
|||||||
package electrosphere.menu.debug;
|
package electrosphere.menu.debug;
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.joml.Quaterniond;
|
||||||
|
|
||||||
import electrosphere.engine.Globals;
|
import electrosphere.engine.Globals;
|
||||||
import electrosphere.entity.Entity;
|
import electrosphere.entity.Entity;
|
||||||
import electrosphere.entity.EntityUtils;
|
import electrosphere.entity.EntityUtils;
|
||||||
|
import electrosphere.entity.state.equip.ClientEquipState;
|
||||||
|
import electrosphere.entity.types.attach.AttachUtils;
|
||||||
import electrosphere.entity.types.creature.CreatureUtils;
|
import electrosphere.entity.types.creature.CreatureUtils;
|
||||||
import electrosphere.entity.types.foliage.FoliageUtils;
|
import electrosphere.entity.types.foliage.FoliageUtils;
|
||||||
import electrosphere.entity.types.item.ItemUtils;
|
import electrosphere.entity.types.item.ItemUtils;
|
||||||
import electrosphere.renderer.RenderingEngine;
|
import electrosphere.game.data.creature.type.equip.EquipPoint;
|
||||||
|
import electrosphere.logger.LoggerInterface;
|
||||||
import electrosphere.renderer.actor.Actor;
|
import electrosphere.renderer.actor.Actor;
|
||||||
import electrosphere.renderer.actor.ActorMeshMask;
|
import electrosphere.renderer.actor.ActorMeshMask;
|
||||||
|
import electrosphere.renderer.anim.AnimChannel;
|
||||||
|
import electrosphere.renderer.anim.Animation;
|
||||||
|
import electrosphere.renderer.model.Bone;
|
||||||
import electrosphere.renderer.model.Mesh;
|
import electrosphere.renderer.model.Mesh;
|
||||||
|
import electrosphere.renderer.model.Model;
|
||||||
import electrosphere.renderer.ui.imgui.ImGuiWindow;
|
import electrosphere.renderer.ui.imgui.ImGuiWindow;
|
||||||
import electrosphere.renderer.ui.imgui.ImGuiWindow.ImGuiWindowCallback;
|
import electrosphere.renderer.ui.imgui.ImGuiWindow.ImGuiWindowCallback;
|
||||||
import imgui.ImGui;
|
import imgui.ImGui;
|
||||||
@ -19,11 +31,17 @@ import imgui.ImGui;
|
|||||||
*/
|
*/
|
||||||
public class ImGuiEntityMacros {
|
public class ImGuiEntityMacros {
|
||||||
|
|
||||||
|
//window for viewing main player entity's stats on both client and server
|
||||||
protected static ImGuiWindow clientEntityWindow;
|
protected static ImGuiWindow clientEntityWindow;
|
||||||
private static boolean filterToCreatures = false;
|
private static boolean filterToCreatures = false; //filters the entity list to just creatures
|
||||||
|
|
||||||
|
//views stats about an actor
|
||||||
protected static ImGuiWindow actorView;
|
protected static ImGuiWindow actorView;
|
||||||
static Entity actorViewEntity;
|
static Entity actorViewEntity; //the entity whose actor we're viewing in the actor window
|
||||||
|
|
||||||
|
//views stats about equip state
|
||||||
|
protected static ImGuiWindow equipStateView;
|
||||||
|
static Entity equipViewEntity; //the entity whose equip state we're viewing in the equip window
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the windows in this file
|
* Creates the windows in this file
|
||||||
@ -31,6 +49,7 @@ public class ImGuiEntityMacros {
|
|||||||
protected static void createClientEntityWindows(){
|
protected static void createClientEntityWindows(){
|
||||||
createClientEntityDebugWindow();
|
createClientEntityDebugWindow();
|
||||||
createActorViewDebugWindow();
|
createActorViewDebugWindow();
|
||||||
|
createEquipStateDebugWindow();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -54,9 +73,17 @@ public class ImGuiEntityMacros {
|
|||||||
ImGui.beginGroup();
|
ImGui.beginGroup();
|
||||||
ImGui.text("Id: " + entity.getId() + " (" + getEntityName(entity) + ")");
|
ImGui.text("Id: " + entity.getId() + " (" + getEntityName(entity) + ")");
|
||||||
if(CreatureUtils.isCreature(entity)){
|
if(CreatureUtils.isCreature(entity)){
|
||||||
if(ImGui.button("Actor View")){
|
if(EntityUtils.getActor(entity) != null){
|
||||||
actorViewEntity = entity;
|
if(ImGui.button("Actor View")){
|
||||||
actorView.setOpen(true);
|
actorViewEntity = entity;
|
||||||
|
actorView.setOpen(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(ClientEquipState.getClientEquipState(entity) != null){
|
||||||
|
if(ImGui.button("Client Equip State View")){
|
||||||
|
equipViewEntity = entity;
|
||||||
|
equipStateView.setOpen(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ImGui.endGroup();
|
ImGui.endGroup();
|
||||||
@ -64,7 +91,7 @@ public class ImGuiEntityMacros {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
clientEntityWindow.setOpen(false);
|
clientEntityWindow.setOpen(false);
|
||||||
RenderingEngine.addImGuiWindow(clientEntityWindow);
|
Globals.renderingEngine.getImGuiPipeline().addImGuiWindow(clientEntityWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -90,11 +117,88 @@ public class ImGuiEntityMacros {
|
|||||||
ImGui.text(blocked);
|
ImGui.text(blocked);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//print bone values
|
||||||
|
if(ImGui.button("Print current bone values")){
|
||||||
|
for(Bone bone : actor.getBoneValues()){
|
||||||
|
LoggerInterface.loggerRenderer.DEBUG(bone.boneID);
|
||||||
|
LoggerInterface.loggerRenderer.DEBUG("" + bone.getFinalTransform());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//print animation keys
|
||||||
|
if(ImGui.button("Print animation keys")){
|
||||||
|
Model model = Globals.assetManager.fetchModel(actor.getModelPath());
|
||||||
|
model.describeAllAnimations();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Browsable list of all animations with their data
|
||||||
|
if(ImGui.collapsingHeader("Animation Channel Data")){
|
||||||
|
Model model = Globals.assetManager.fetchModel(actor.getModelPath());
|
||||||
|
for(Animation animation : model.getAnimations()){
|
||||||
|
ImGui.text(" - " + animation.name);
|
||||||
|
for(AnimChannel channel : animation.channels){
|
||||||
|
ImGui.text("=" + channel.getNodeID() + "=");
|
||||||
|
ImGui.text("" + channel.getCurrentPosition());
|
||||||
|
ImGui.text("" + channel.getCurrentRotation());
|
||||||
|
ImGui.text("" + channel.getCurrentScale());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
actorView.setOpen(false);
|
actorView.setOpen(false);
|
||||||
RenderingEngine.addImGuiWindow(actorView);
|
Globals.renderingEngine.getImGuiPipeline().addImGuiWindow(actorView);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Client scene equip state view
|
||||||
|
*/
|
||||||
|
protected static void createEquipStateDebugWindow(){
|
||||||
|
equipStateView = new ImGuiWindow("Client Equip State View");
|
||||||
|
equipStateView.setCallback(new ImGuiWindowCallback() {
|
||||||
|
|
||||||
|
//stores the edited rotation values
|
||||||
|
float[] rotationValues = new float[]{
|
||||||
|
0,0,0
|
||||||
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void exec() {
|
||||||
|
if(equipViewEntity != null && ClientEquipState.getClientEquipState(equipViewEntity) != null){
|
||||||
|
ClientEquipState clientEquipState = ClientEquipState.getClientEquipState(equipViewEntity);
|
||||||
|
|
||||||
|
if(ImGui.collapsingHeader("All Equip Points")){
|
||||||
|
for(EquipPoint point : clientEquipState.getAllEquipPoints()){
|
||||||
|
if(ImGui.collapsingHeader(point.getEquipPointId())){
|
||||||
|
ImGui.text("Has item equipped: " + (clientEquipState.getEquippedItemAtPoint(point.getEquipPointId()) != null));
|
||||||
|
ImGui.text("Bone (Third Person): " + point.getBone());
|
||||||
|
ImGui.text("Bone (First Person): " + point.getFirstPersonBone());
|
||||||
|
ImGui.text("Rotation: " + AttachUtils.getEquipPointRotationOffset(point.getOffsetRotation()));
|
||||||
|
if(ImGui.sliderFloat3("Rotation (In Euler along x,y,z)", rotationValues, 0, (float)(Math.PI * 2))){
|
||||||
|
Quaterniond rotation = new Quaterniond().rotateXYZ(rotationValues[0], rotationValues[1], rotationValues[2]);
|
||||||
|
List<Float> newValues = new LinkedList<Float>();
|
||||||
|
newValues.add((float)rotation.x);
|
||||||
|
newValues.add((float)rotation.y);
|
||||||
|
newValues.add((float)rotation.z);
|
||||||
|
newValues.add((float)rotation.w);
|
||||||
|
point.setOffsetRotation(newValues);
|
||||||
|
Entity equippedEntity = clientEquipState.getEquippedItemAtPoint(point.getEquipPointId());
|
||||||
|
if(equippedEntity != null){
|
||||||
|
AttachUtils.setRotationOffset(equippedEntity, AttachUtils.getEquipPointRotationOffset(point.getOffsetRotation()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
equipStateView.setOpen(false);
|
||||||
|
Globals.renderingEngine.getImGuiPipeline().addImGuiWindow(equipStateView);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
8
src/main/java/electrosphere/menu/debug/ImGuiUtils.java
Normal file
8
src/main/java/electrosphere/menu/debug/ImGuiUtils.java
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
package electrosphere.menu.debug;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utilities for dealing with imgui
|
||||||
|
*/
|
||||||
|
public class ImGuiUtils {
|
||||||
|
|
||||||
|
}
|
||||||
@ -7,11 +7,13 @@ import org.ode4j.ode.DBody;
|
|||||||
|
|
||||||
import electrosphere.audio.VirtualAudioSource;
|
import electrosphere.audio.VirtualAudioSource;
|
||||||
import electrosphere.collision.PhysicsEntityUtils;
|
import electrosphere.collision.PhysicsEntityUtils;
|
||||||
|
import electrosphere.controls.ControlHandler.ControlsState;
|
||||||
import electrosphere.engine.Globals;
|
import electrosphere.engine.Globals;
|
||||||
import electrosphere.entity.Entity;
|
import electrosphere.entity.Entity;
|
||||||
import electrosphere.entity.EntityUtils;
|
import electrosphere.entity.EntityUtils;
|
||||||
|
import electrosphere.entity.state.attack.ClientAttackTree;
|
||||||
|
import electrosphere.entity.state.server.ServerPlayerViewDirTree;
|
||||||
import electrosphere.entity.types.creature.CreatureUtils;
|
import electrosphere.entity.types.creature.CreatureUtils;
|
||||||
import electrosphere.renderer.RenderingEngine;
|
|
||||||
import electrosphere.renderer.ui.imgui.ImGuiLinePlot;
|
import electrosphere.renderer.ui.imgui.ImGuiLinePlot;
|
||||||
import electrosphere.renderer.ui.imgui.ImGuiWindow;
|
import electrosphere.renderer.ui.imgui.ImGuiWindow;
|
||||||
import electrosphere.renderer.ui.imgui.ImGuiLinePlot.ImGuiLinePlotDataset;
|
import electrosphere.renderer.ui.imgui.ImGuiLinePlot.ImGuiLinePlotDataset;
|
||||||
@ -73,7 +75,15 @@ public class ImGuiWindowMacros {
|
|||||||
initFramerateGraphSeries("controls");
|
initFramerateGraphSeries("controls");
|
||||||
globalFrametimeWindow.addElement(globalFrametimePlot);
|
globalFrametimeWindow.addElement(globalFrametimePlot);
|
||||||
globalFrametimeWindow.setOpen(false);
|
globalFrametimeWindow.setOpen(false);
|
||||||
RenderingEngine.addImGuiWindow(globalFrametimeWindow);
|
Globals.renderingEngine.getImGuiPipeline().addImGuiWindow(globalFrametimeWindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the main debug window
|
||||||
|
* @return the main debug window
|
||||||
|
*/
|
||||||
|
public static ImGuiWindow getMainDebugWindow(){
|
||||||
|
return mainDebugWindow;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -156,7 +166,7 @@ public class ImGuiWindowMacros {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
audioDebugMenu.setOpen(false);
|
audioDebugMenu.setOpen(false);
|
||||||
RenderingEngine.addImGuiWindow(audioDebugMenu);
|
Globals.renderingEngine.getImGuiPipeline().addImGuiWindow(audioDebugMenu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -172,16 +182,35 @@ public class ImGuiWindowMacros {
|
|||||||
ImGui.text("Player Entity Details");
|
ImGui.text("Player Entity Details");
|
||||||
if(Globals.playerEntity != null){
|
if(Globals.playerEntity != null){
|
||||||
ImGui.text("Position: " + EntityUtils.getPosition(Globals.playerEntity));
|
ImGui.text("Position: " + EntityUtils.getPosition(Globals.playerEntity));
|
||||||
|
|
||||||
|
//server pos
|
||||||
|
int serverIdForClientEntity = Globals.clientSceneWrapper.mapClientToServerId(Globals.playerEntity.getId());
|
||||||
|
Entity serverPlayerEntity = EntityLookupUtils.getEntityById(serverIdForClientEntity);
|
||||||
|
ImGui.text("Position (Server): " + EntityUtils.getPosition(serverPlayerEntity));
|
||||||
|
|
||||||
|
//client-side tree stuff
|
||||||
DBody body = PhysicsEntityUtils.getDBody(Globals.playerEntity);
|
DBody body = PhysicsEntityUtils.getDBody(Globals.playerEntity);
|
||||||
|
ClientAttackTree attackTree = ClientAttackTree.getClientAttackTree(Globals.playerEntity);
|
||||||
if(body != null){
|
if(body != null){
|
||||||
ImGui.text("Velocity: " + body.getLinearVel());
|
ImGui.text("Velocity: " + body.getLinearVel());
|
||||||
ImGui.text("Force: " + body.getForce());
|
ImGui.text("Force: " + body.getForce());
|
||||||
ImGui.text("Angular Velocity: " + body.getAngularVel());
|
ImGui.text("Angular Velocity: " + body.getAngularVel());
|
||||||
ImGui.text("Torque: " + body.getTorque());
|
ImGui.text("Torque: " + body.getTorque());
|
||||||
ImGui.text("Move Vector: " + CreatureUtils.getFacingVector(Globals.playerEntity));
|
ImGui.text("Move Vector: " + CreatureUtils.getFacingVector(Globals.playerEntity));
|
||||||
Entity serverEntity = EntityLookupUtils.getEntityById(Globals.clientSceneWrapper.mapClientToServerId(Globals.playerEntity.getId()));
|
if(attackTree != null){
|
||||||
ImGui.text("Move Vector (Server): " + CreatureUtils.getFacingVector(serverEntity));
|
ImGui.text("Attack Tree State: " + attackTree.getState());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//server-side tree stuff
|
||||||
|
DBody serverBody = PhysicsEntityUtils.getDBody(serverPlayerEntity);
|
||||||
|
if(body != null){
|
||||||
|
ImGui.text("Velocity (Server): " + serverBody.getLinearVel());
|
||||||
|
ImGui.text("Force (Server): " + serverBody.getForce());
|
||||||
|
ImGui.text("Move Vector (Server): " + CreatureUtils.getFacingVector(serverPlayerEntity));
|
||||||
|
ImGui.text("Velocity (Server): " + CreatureUtils.getVelocity(serverPlayerEntity));
|
||||||
|
}
|
||||||
|
ImGui.text("View dir (Server): " + ServerPlayerViewDirTree.getTree(serverPlayerEntity).getPlayerViewDir());
|
||||||
}
|
}
|
||||||
if(ImGui.button("Toggle Player Camera Lock")){
|
if(ImGui.button("Toggle Player Camera Lock")){
|
||||||
Globals.cameraHandler.setTrackPlayerEntity(!Globals.cameraHandler.getTrackPlayerEntity());
|
Globals.cameraHandler.setTrackPlayerEntity(!Globals.cameraHandler.getTrackPlayerEntity());
|
||||||
@ -189,7 +218,7 @@ public class ImGuiWindowMacros {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
playerEntityWindow.setOpen(false);
|
playerEntityWindow.setOpen(false);
|
||||||
RenderingEngine.addImGuiWindow(playerEntityWindow);
|
Globals.renderingEngine.getImGuiPipeline().addImGuiWindow(playerEntityWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -208,7 +237,7 @@ public class ImGuiWindowMacros {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
fluidWindow.setOpen(false);
|
fluidWindow.setOpen(false);
|
||||||
RenderingEngine.addImGuiWindow(fluidWindow);
|
Globals.renderingEngine.getImGuiPipeline().addImGuiWindow(fluidWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -247,7 +276,7 @@ public class ImGuiWindowMacros {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
mainDebugWindow.setOpen(false);
|
mainDebugWindow.setOpen(false);
|
||||||
RenderingEngine.addImGuiWindow(mainDebugWindow);
|
Globals.renderingEngine.getImGuiPipeline().addImGuiWindow(mainDebugWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -255,6 +284,11 @@ public class ImGuiWindowMacros {
|
|||||||
*/
|
*/
|
||||||
public static void toggleMainDebugMenu(){
|
public static void toggleMainDebugMenu(){
|
||||||
mainDebugWindow.setOpen(!mainDebugWindow.isOpen());
|
mainDebugWindow.setOpen(!mainDebugWindow.isOpen());
|
||||||
|
if(mainDebugWindow.isOpen()){
|
||||||
|
Globals.controlHandler.hintUpdateControlState(ControlsState.IN_GAME_MAIN_MENU);
|
||||||
|
} else {
|
||||||
|
Globals.controlHandler.hintUpdateControlState(ControlsState.MAIN_GAME);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -51,11 +51,10 @@ public class MenuGeneratorsInGame {
|
|||||||
WindowUtils.recursiveSetVisible(Globals.elementManager.getWindow(WindowStrings.WINDOW_MENU_INGAME_MAIN), false);
|
WindowUtils.recursiveSetVisible(Globals.elementManager.getWindow(WindowStrings.WINDOW_MENU_INGAME_MAIN), false);
|
||||||
Globals.elementManager.unregisterWindow(WindowStrings.WINDOW_MENU_INGAME_MAIN);
|
Globals.elementManager.unregisterWindow(WindowStrings.WINDOW_MENU_INGAME_MAIN);
|
||||||
if(Globals.cameraHandler.getTrackPlayerEntity()){
|
if(Globals.cameraHandler.getTrackPlayerEntity()){
|
||||||
Globals.controlHandler.setHandlerState(ControlsState.MAIN_GAME);
|
Globals.controlHandler.hintUpdateControlState(ControlsState.MAIN_GAME);
|
||||||
} else {
|
} else {
|
||||||
Globals.controlHandler.setHandlerState(ControlsState.IN_GAME_FREE_CAMERA);
|
Globals.controlHandler.hintUpdateControlState(ControlsState.IN_GAME_FREE_CAMERA);
|
||||||
}
|
}
|
||||||
Globals.controlHandler.hideMouse();
|
|
||||||
return false;
|
return false;
|
||||||
}});
|
}});
|
||||||
|
|
||||||
@ -76,11 +75,10 @@ public class MenuGeneratorsInGame {
|
|||||||
WindowUtils.recursiveSetVisible(Globals.elementManager.getWindow(WindowStrings.WINDOW_MENU_INGAME_MAIN), false);
|
WindowUtils.recursiveSetVisible(Globals.elementManager.getWindow(WindowStrings.WINDOW_MENU_INGAME_MAIN), false);
|
||||||
Globals.elementManager.unregisterWindow(WindowStrings.WINDOW_MENU_INGAME_MAIN);
|
Globals.elementManager.unregisterWindow(WindowStrings.WINDOW_MENU_INGAME_MAIN);
|
||||||
if(Globals.cameraHandler.getTrackPlayerEntity()){
|
if(Globals.cameraHandler.getTrackPlayerEntity()){
|
||||||
Globals.controlHandler.setHandlerState(ControlsState.MAIN_GAME);
|
Globals.controlHandler.hintUpdateControlState(ControlsState.MAIN_GAME);
|
||||||
} else {
|
} else {
|
||||||
Globals.controlHandler.setHandlerState(ControlsState.IN_GAME_FREE_CAMERA);
|
Globals.controlHandler.hintUpdateControlState(ControlsState.IN_GAME_FREE_CAMERA);
|
||||||
}
|
}
|
||||||
Globals.controlHandler.hideMouse();
|
|
||||||
return false;
|
return false;
|
||||||
}});
|
}});
|
||||||
|
|
||||||
@ -273,15 +271,27 @@ public class MenuGeneratorsInGame {
|
|||||||
return false;
|
return false;
|
||||||
}});
|
}});
|
||||||
|
|
||||||
//label (toggle draw collision spheres)
|
//label (toggle draw client collision spheres)
|
||||||
Button toggleCollisionSpheresButton = new Button();
|
Button toggleClientCollisionSpheresButton = new Button();
|
||||||
Label toggleCollisionSpheresLabel = new Label(fontSize);
|
Label toggleClientCollisionSpheresLabel = new Label(fontSize);
|
||||||
toggleCollisionSpheresLabel.setText("Toggle draw collision spheres");
|
toggleClientCollisionSpheresLabel.setText("Toggle draw client collision spheres");
|
||||||
toggleCollisionSpheresButton.addChild(toggleCollisionSpheresLabel);
|
toggleClientCollisionSpheresButton.addChild(toggleClientCollisionSpheresLabel);
|
||||||
scrollable.addChild(toggleCollisionSpheresButton);
|
scrollable.addChild(toggleClientCollisionSpheresButton);
|
||||||
toggleCollisionSpheresButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
|
toggleClientCollisionSpheresButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
|
||||||
// Main.running = false;
|
// Main.running = false;
|
||||||
Globals.userSettings.setGraphicsDebugDrawCollisionSpheres(!Globals.userSettings.graphicsDebugDrawCollisionSpheres());
|
Globals.userSettings.setGraphicsDebugDrawCollisionSpheresClient(!Globals.userSettings.getGraphicsDebugDrawCollisionSpheresClient());
|
||||||
|
return false;
|
||||||
|
}});
|
||||||
|
|
||||||
|
//label (toggle draw server collision spheres)
|
||||||
|
Button toggleServerCollisionSpheresButton = new Button();
|
||||||
|
Label toggleServerCollisionSpheresLabel = new Label(fontSize);
|
||||||
|
toggleServerCollisionSpheresLabel.setText("Toggle draw server collision spheres");
|
||||||
|
toggleServerCollisionSpheresButton.addChild(toggleServerCollisionSpheresLabel);
|
||||||
|
scrollable.addChild(toggleServerCollisionSpheresButton);
|
||||||
|
toggleServerCollisionSpheresButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
|
||||||
|
// Main.running = false;
|
||||||
|
Globals.userSettings.setGraphicsDebugDrawCollisionSpheresServer(!Globals.userSettings.getGraphicsDebugDrawCollisionSpheresServer());
|
||||||
return false;
|
return false;
|
||||||
}});
|
}});
|
||||||
|
|
||||||
|
|||||||
@ -50,8 +50,7 @@ public class MenuGeneratorsInventory {
|
|||||||
//
|
//
|
||||||
Globals.openInventoriesCount--;
|
Globals.openInventoriesCount--;
|
||||||
if(Globals.openInventoriesCount == 0){
|
if(Globals.openInventoriesCount == 0){
|
||||||
Globals.controlHandler.setHandlerState(ControlsState.MAIN_GAME);
|
Globals.controlHandler.hintUpdateControlState(ControlsState.MAIN_GAME);
|
||||||
Globals.controlHandler.hideMouse();
|
|
||||||
}
|
}
|
||||||
//play sound effect
|
//play sound effect
|
||||||
Globals.virtualAudioSourceManager.createVirtualAudioSource("/Audio/closeMenu.ogg", VirtualAudioSourceType.UI, false);
|
Globals.virtualAudioSourceManager.createVirtualAudioSource("/Audio/closeMenu.ogg", VirtualAudioSourceType.UI, false);
|
||||||
@ -223,8 +222,7 @@ public class MenuGeneratorsInventory {
|
|||||||
//
|
//
|
||||||
Globals.openInventoriesCount--;
|
Globals.openInventoriesCount--;
|
||||||
if(Globals.openInventoriesCount == 0){
|
if(Globals.openInventoriesCount == 0){
|
||||||
Globals.controlHandler.setHandlerState(ControlsState.MAIN_GAME);
|
Globals.controlHandler.hintUpdateControlState(ControlsState.MAIN_GAME);
|
||||||
Globals.controlHandler.hideMouse();
|
|
||||||
}
|
}
|
||||||
//play sound effect
|
//play sound effect
|
||||||
Globals.virtualAudioSourceManager.createVirtualAudioSource("/Audio/closeMenu.ogg", VirtualAudioSourceType.UI, false);
|
Globals.virtualAudioSourceManager.createVirtualAudioSource("/Audio/closeMenu.ogg", VirtualAudioSourceType.UI, false);
|
||||||
|
|||||||
@ -17,6 +17,7 @@ import electrosphere.entity.types.object.ObjectUtils;
|
|||||||
import electrosphere.game.data.creature.type.CreatureType;
|
import electrosphere.game.data.creature.type.CreatureType;
|
||||||
import electrosphere.game.data.foliage.type.FoliageType;
|
import electrosphere.game.data.foliage.type.FoliageType;
|
||||||
import electrosphere.game.data.item.type.Item;
|
import electrosphere.game.data.item.type.Item;
|
||||||
|
import electrosphere.game.data.object.type.ObjectData;
|
||||||
import electrosphere.logger.LoggerInterface;
|
import electrosphere.logger.LoggerInterface;
|
||||||
import electrosphere.menu.WindowStrings;
|
import electrosphere.menu.WindowStrings;
|
||||||
import electrosphere.menu.WindowUtils;
|
import electrosphere.menu.WindowUtils;
|
||||||
@ -114,6 +115,12 @@ public class MenuGeneratorsLevelEditor {
|
|||||||
return false;
|
return false;
|
||||||
}}));
|
}}));
|
||||||
|
|
||||||
|
//spawn object button
|
||||||
|
scrollable.addChild(Button.createButton("Spawn Object", new ClickEventCallback() {public boolean execute(ClickEvent event){
|
||||||
|
fillInSpawnObjectContent(scrollable);
|
||||||
|
return false;
|
||||||
|
}}));
|
||||||
|
|
||||||
//select voxel button
|
//select voxel button
|
||||||
scrollable.addChild(Button.createButton("Select Voxel Type", new ClickEventCallback() {public boolean execute(ClickEvent event){
|
scrollable.addChild(Button.createButton("Select Voxel Type", new ClickEventCallback() {public boolean execute(ClickEvent event){
|
||||||
if(voxelWindowOpen){
|
if(voxelWindowOpen){
|
||||||
@ -235,6 +242,37 @@ public class MenuGeneratorsLevelEditor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Level editor menu content for spawning objects
|
||||||
|
* @param scrollable
|
||||||
|
*/
|
||||||
|
private static void fillInSpawnObjectContent(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(ObjectData object : Globals.gameConfigCurrent.getObjectTypeLoader().getAllObjectTypes()){
|
||||||
|
//spawn foliage button
|
||||||
|
scrollable.addChild(Button.createButton("Spawn " + object.getObjectId(), new ClickEventCallback() {public boolean execute(ClickEvent event){
|
||||||
|
LoggerInterface.loggerEngine.INFO("spawn " + object.getObjectId() + "!");
|
||||||
|
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);
|
||||||
|
ObjectUtils.serverSpawnBasicObject(realm, cursorPos, object.getObjectId());
|
||||||
|
return false;
|
||||||
|
}}));
|
||||||
|
}
|
||||||
|
|
||||||
|
mainSidePanel.applyYoga(0,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates tree view of entities in server
|
* Creates tree view of entities in server
|
||||||
* @param scrollable
|
* @param scrollable
|
||||||
|
|||||||
@ -125,6 +125,9 @@ public class MenuGeneratorsTerrainEditing {
|
|||||||
voxelLabel.setText(type.getName());
|
voxelLabel.setText(type.getName());
|
||||||
//icon/model
|
//icon/model
|
||||||
ImagePanel texturePanel = ImagePanel.createImagePanel(type.getTexture());
|
ImagePanel texturePanel = ImagePanel.createImagePanel(type.getTexture());
|
||||||
|
if(type.getTexture() != null){
|
||||||
|
Globals.assetManager.addTexturePathtoQueue(type.getTexture());
|
||||||
|
}
|
||||||
texturePanel.setWidth(VOXEL_BUTTON_TEXTURE_DIM);
|
texturePanel.setWidth(VOXEL_BUTTON_TEXTURE_DIM);
|
||||||
texturePanel.setHeight(VOXEL_BUTTON_TEXTURE_DIM);
|
texturePanel.setHeight(VOXEL_BUTTON_TEXTURE_DIM);
|
||||||
newButton.addChild(texturePanel);
|
newButton.addChild(texturePanel);
|
||||||
|
|||||||
@ -0,0 +1,57 @@
|
|||||||
|
package electrosphere.menu.mainmenu;
|
||||||
|
|
||||||
|
import org.lwjgl.util.yoga.Yoga;
|
||||||
|
|
||||||
|
import electrosphere.engine.Globals;
|
||||||
|
import electrosphere.engine.loadingthreads.LoadingThread;
|
||||||
|
import electrosphere.menu.WindowUtils;
|
||||||
|
import electrosphere.renderer.ui.elements.Button;
|
||||||
|
import electrosphere.renderer.ui.elements.FormElement;
|
||||||
|
import electrosphere.renderer.ui.elements.Label;
|
||||||
|
import electrosphere.renderer.ui.elementtypes.ClickableElement;
|
||||||
|
import electrosphere.renderer.ui.elementtypes.Element;
|
||||||
|
import electrosphere.renderer.ui.events.ClickEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates menu items for the demo version of the engine
|
||||||
|
*/
|
||||||
|
public class MenuGeneratorsDemo {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the title menu for the demo
|
||||||
|
* @return The content element to embed in a title window
|
||||||
|
*/
|
||||||
|
public static Element createTitleMenu(){
|
||||||
|
FormElement rVal = new FormElement();
|
||||||
|
//top-bottom
|
||||||
|
rVal.setJustifyContent(Yoga.YGJustifyCenter);
|
||||||
|
//left-right
|
||||||
|
rVal.setAlignItems(Yoga.YGAlignCenter);
|
||||||
|
rVal.setAlignContent(Yoga.YGAlignFlexStart);
|
||||||
|
|
||||||
|
//label (title)
|
||||||
|
Label titleLabel = new Label(1.0f);
|
||||||
|
titleLabel.setText("ORPG");
|
||||||
|
rVal.addChild(titleLabel);
|
||||||
|
|
||||||
|
//button (arena)
|
||||||
|
Button arenaButton = new Button();
|
||||||
|
Label arenaLabel = new Label(1.0f);
|
||||||
|
arenaLabel.setText("Start");
|
||||||
|
arenaButton.addChild(arenaLabel);
|
||||||
|
rVal.addChild(arenaButton);
|
||||||
|
arenaButton.setOnClick(new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
|
||||||
|
LoadingThread serverThread = new LoadingThread(LoadingThread.LOAD_LEVEL);
|
||||||
|
Globals.loadingThreadsList.add(serverThread);
|
||||||
|
Globals.RUN_CLIENT = true;
|
||||||
|
Globals.RUN_SERVER = true;
|
||||||
|
serverThread.start();
|
||||||
|
WindowUtils.replaceMainMenuContents(MenuGeneratorsArena.createArenaHostLoginMenu());
|
||||||
|
return false;
|
||||||
|
}});
|
||||||
|
arenaButton.setMarginTop(50);
|
||||||
|
|
||||||
|
return rVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -11,7 +11,6 @@ import electrosphere.entity.EntityDataStrings;
|
|||||||
import electrosphere.entity.EntityTags;
|
import electrosphere.entity.EntityTags;
|
||||||
import electrosphere.entity.EntityUtils;
|
import electrosphere.entity.EntityUtils;
|
||||||
import electrosphere.entity.state.attack.ClientAttackTree;
|
import electrosphere.entity.state.attack.ClientAttackTree;
|
||||||
import electrosphere.entity.state.attack.ServerAttackTree;
|
|
||||||
import electrosphere.entity.state.client.firstPerson.FirstPersonTree;
|
import electrosphere.entity.state.client.firstPerson.FirstPersonTree;
|
||||||
import electrosphere.entity.types.attach.AttachUtils;
|
import electrosphere.entity.types.attach.AttachUtils;
|
||||||
import electrosphere.entity.types.creature.CreatureTemplate;
|
import electrosphere.entity.types.creature.CreatureTemplate;
|
||||||
@ -96,13 +95,6 @@ public class EntityProtocol {
|
|||||||
// UPDATING PROPERTIES
|
// UPDATING PROPERTIES
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
case MOVE: {
|
|
||||||
Entity target = Globals.clientSceneWrapper.getEntityFromServerId(message.getentityID());
|
|
||||||
LoggerInterface.loggerNetworking.DEBUG("ID: " + message.getentityID());
|
|
||||||
if(target != null){
|
|
||||||
EntityUtils.getPosition(target).set(message.getpositionX(),message.getpositionY(),message.getpositionZ());
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
case SETPROPERTY: {
|
case SETPROPERTY: {
|
||||||
if(Globals.clientSceneWrapper.serverToClientMapContainsId(message.getentityID())){
|
if(Globals.clientSceneWrapper.serverToClientMapContainsId(message.getentityID())){
|
||||||
if(message.getpropertyType() == 0){
|
if(message.getpropertyType() == 0){
|
||||||
@ -143,18 +135,11 @@ public class EntityProtocol {
|
|||||||
// TODO
|
// TODO
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
case UPDATEENTITYVIEWDIR:
|
||||||
case KILL:
|
case KILL:
|
||||||
case SETPOSITION:
|
|
||||||
case SETFACING:
|
|
||||||
//to be implemented
|
//to be implemented
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
|
default:
|
||||||
case SETBEHAVIORTREE:
|
|
||||||
case SETBTREEPROPERTYDOUBLE:
|
|
||||||
case SETBTREEPROPERTYENUM:
|
|
||||||
case SETBTREEPROPERTYFLOAT:
|
|
||||||
case SETBTREEPROPERTYINT:
|
|
||||||
case SETBTREEPROPERTYSTRING:
|
|
||||||
//unused
|
//unused
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -27,7 +27,7 @@ public class InventoryProtocol {
|
|||||||
//translate equipper id
|
//translate equipper id
|
||||||
Entity equipper = Globals.clientSceneWrapper.getEntityFromServerId(message.getequipperId());
|
Entity equipper = Globals.clientSceneWrapper.getEntityFromServerId(message.getequipperId());
|
||||||
//spawn in world id
|
//spawn in world id
|
||||||
Entity inWorldEntity = ItemUtils.clientSpawnBasicItem(message.getitemTemplate());
|
Entity inWorldEntity = Globals.clientSceneWrapper.getEntityFromServerId(message.getentityId());
|
||||||
if(inWorldEntity != null){
|
if(inWorldEntity != null){
|
||||||
//translate id
|
//translate id
|
||||||
Globals.clientSceneWrapper.mapIdToId(inWorldEntity.getId(), message.getentityId());
|
Globals.clientSceneWrapper.mapIdToId(inWorldEntity.getId(), message.getentityId());
|
||||||
@ -38,7 +38,7 @@ public class InventoryProtocol {
|
|||||||
String equipPointName = message.getequipPointId();
|
String equipPointName = message.getequipPointId();
|
||||||
EquipPoint equipPoint = equipState.getEquipPoint(equipPointName);
|
EquipPoint equipPoint = equipState.getEquipPoint(equipPointName);
|
||||||
//attach
|
//attach
|
||||||
equipState.clientAttemptEquip(inWorldEntity, equipPoint);
|
equipState.attemptEquip(inWorldEntity, equipPoint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -11,18 +11,11 @@ public class LoreProtocol {
|
|||||||
|
|
||||||
protected static void handleLoreMessage(LoreMessage message){
|
protected static void handleLoreMessage(LoreMessage message){
|
||||||
switch(message.getMessageSubtype()){
|
switch(message.getMessageSubtype()){
|
||||||
case RESPONSEDATA:
|
|
||||||
break;
|
|
||||||
case RESPONSERACES:
|
case RESPONSERACES:
|
||||||
//we get back the race list as a json array, deserialize, and push into type loader
|
//we get back the race list as a json array, deserialize, and push into type loader
|
||||||
List<String> playableRaces = new Gson().fromJson(message.getdata(), List.class);
|
List<String> playableRaces = new Gson().fromJson(message.getdata(), List.class);
|
||||||
Globals.gameConfigCurrent.getCreatureTypeLoader().loadPlayableRaces(playableRaces);
|
Globals.gameConfigCurrent.getCreatureTypeLoader().loadPlayableRaces(playableRaces);
|
||||||
break;
|
break;
|
||||||
case RESPONSERACEDATA:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case REQUESTDATA:
|
|
||||||
case REQUESTRACEDATA:
|
|
||||||
case REQUESTRACES:
|
case REQUESTRACES:
|
||||||
//silently ignore
|
//silently ignore
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -9,10 +9,13 @@ public class SynchronizationProtocol {
|
|||||||
Globals.profiler.beginCpuSample("SynchronizationProtocol.handleSynchronizationMessage");
|
Globals.profiler.beginCpuSample("SynchronizationProtocol.handleSynchronizationMessage");
|
||||||
switch(message.getMessageSubtype()){
|
switch(message.getMessageSubtype()){
|
||||||
case UPDATECLIENTSTATE:
|
case UPDATECLIENTSTATE:
|
||||||
|
case UPDATECLIENTSTRINGSTATE:
|
||||||
case ATTACHTREE:
|
case ATTACHTREE:
|
||||||
case DETATCHTREE:
|
case DETATCHTREE:
|
||||||
Globals.clientSynchronizationManager.pushMessage(message);
|
Globals.clientSynchronizationManager.pushMessage(message);
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
throw new UnsupportedOperationException("Received synchronization message on the client of unsupported type: " + message.getMessageSubtype());
|
||||||
}
|
}
|
||||||
Globals.profiler.endCpuSample();
|
Globals.profiler.endCpuSample();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,23 +11,15 @@ public class EntityMessage extends NetworkMessage {
|
|||||||
CREATE,
|
CREATE,
|
||||||
SPAWNCREATURE,
|
SPAWNCREATURE,
|
||||||
SPAWNITEM,
|
SPAWNITEM,
|
||||||
SETPOSITION,
|
|
||||||
SETFACING,
|
|
||||||
MOVEUPDATE,
|
MOVEUPDATE,
|
||||||
ATTACKUPDATE,
|
ATTACKUPDATE,
|
||||||
STARTATTACK,
|
STARTATTACK,
|
||||||
MOVE,
|
|
||||||
KILL,
|
KILL,
|
||||||
DESTROY,
|
DESTROY,
|
||||||
SETBEHAVIORTREE,
|
|
||||||
SETPROPERTY,
|
SETPROPERTY,
|
||||||
SETBTREEPROPERTYINT,
|
|
||||||
SETBTREEPROPERTYFLOAT,
|
|
||||||
SETBTREEPROPERTYDOUBLE,
|
|
||||||
SETBTREEPROPERTYSTRING,
|
|
||||||
SETBTREEPROPERTYENUM,
|
|
||||||
ATTACHENTITYTOENTITY,
|
ATTACHENTITYTOENTITY,
|
||||||
SPAWNFOLIAGESEED,
|
SPAWNFOLIAGESEED,
|
||||||
|
UPDATEENTITYVIEWDIR,
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityMessageType messageType;
|
EntityMessageType messageType;
|
||||||
@ -296,18 +288,6 @@ public class EntityMessage extends NetworkMessage {
|
|||||||
return EntityMessage.canParseSpawnCreatureMessage(byteBuffer);
|
return EntityMessage.canParseSpawnCreatureMessage(byteBuffer);
|
||||||
case TypeBytes.ENTITY_MESSAGE_TYPE_SPAWNITEM:
|
case TypeBytes.ENTITY_MESSAGE_TYPE_SPAWNITEM:
|
||||||
return EntityMessage.canParseSpawnItemMessage(byteBuffer);
|
return EntityMessage.canParseSpawnItemMessage(byteBuffer);
|
||||||
case TypeBytes.ENTITY_MESSAGE_TYPE_SETPOSITION:
|
|
||||||
if(byteBuffer.getRemaining() >= TypeBytes.ENTITY_MESSAGE_TYPE_SETPOSITION_SIZE){
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
case TypeBytes.ENTITY_MESSAGE_TYPE_SETFACING:
|
|
||||||
if(byteBuffer.getRemaining() >= TypeBytes.ENTITY_MESSAGE_TYPE_SETFACING_SIZE){
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
case TypeBytes.ENTITY_MESSAGE_TYPE_MOVEUPDATE:
|
case TypeBytes.ENTITY_MESSAGE_TYPE_MOVEUPDATE:
|
||||||
if(byteBuffer.getRemaining() >= TypeBytes.ENTITY_MESSAGE_TYPE_MOVEUPDATE_SIZE){
|
if(byteBuffer.getRemaining() >= TypeBytes.ENTITY_MESSAGE_TYPE_MOVEUPDATE_SIZE){
|
||||||
return true;
|
return true;
|
||||||
@ -326,12 +306,6 @@ public class EntityMessage extends NetworkMessage {
|
|||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
case TypeBytes.ENTITY_MESSAGE_TYPE_MOVE:
|
|
||||||
if(byteBuffer.getRemaining() >= TypeBytes.ENTITY_MESSAGE_TYPE_MOVE_SIZE){
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
case TypeBytes.ENTITY_MESSAGE_TYPE_KILL:
|
case TypeBytes.ENTITY_MESSAGE_TYPE_KILL:
|
||||||
if(byteBuffer.getRemaining() >= TypeBytes.ENTITY_MESSAGE_TYPE_KILL_SIZE){
|
if(byteBuffer.getRemaining() >= TypeBytes.ENTITY_MESSAGE_TYPE_KILL_SIZE){
|
||||||
return true;
|
return true;
|
||||||
@ -344,48 +318,22 @@ public class EntityMessage extends NetworkMessage {
|
|||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
case TypeBytes.ENTITY_MESSAGE_TYPE_SETBEHAVIORTREE:
|
|
||||||
if(byteBuffer.getRemaining() >= TypeBytes.ENTITY_MESSAGE_TYPE_SETBEHAVIORTREE_SIZE){
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
case TypeBytes.ENTITY_MESSAGE_TYPE_SETPROPERTY:
|
case TypeBytes.ENTITY_MESSAGE_TYPE_SETPROPERTY:
|
||||||
if(byteBuffer.getRemaining() >= TypeBytes.ENTITY_MESSAGE_TYPE_SETPROPERTY_SIZE){
|
if(byteBuffer.getRemaining() >= TypeBytes.ENTITY_MESSAGE_TYPE_SETPROPERTY_SIZE){
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
case TypeBytes.ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYINT:
|
|
||||||
if(byteBuffer.getRemaining() >= TypeBytes.ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYINT_SIZE){
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
case TypeBytes.ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYFLOAT:
|
|
||||||
if(byteBuffer.getRemaining() >= TypeBytes.ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYFLOAT_SIZE){
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
case TypeBytes.ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYDOUBLE:
|
|
||||||
if(byteBuffer.getRemaining() >= TypeBytes.ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYDOUBLE_SIZE){
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
case TypeBytes.ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYSTRING:
|
|
||||||
return EntityMessage.canParsesetBTreePropertyStringMessage(byteBuffer);
|
|
||||||
case TypeBytes.ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYENUM:
|
|
||||||
if(byteBuffer.getRemaining() >= TypeBytes.ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYENUM_SIZE){
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
case TypeBytes.ENTITY_MESSAGE_TYPE_ATTACHENTITYTOENTITY:
|
case TypeBytes.ENTITY_MESSAGE_TYPE_ATTACHENTITYTOENTITY:
|
||||||
return EntityMessage.canParseattachEntityToEntityMessage(byteBuffer);
|
return EntityMessage.canParseattachEntityToEntityMessage(byteBuffer);
|
||||||
case TypeBytes.ENTITY_MESSAGE_TYPE_SPAWNFOLIAGESEED:
|
case TypeBytes.ENTITY_MESSAGE_TYPE_SPAWNFOLIAGESEED:
|
||||||
return EntityMessage.canParseSpawnFoliageSeedMessage(byteBuffer);
|
return EntityMessage.canParseSpawnFoliageSeedMessage(byteBuffer);
|
||||||
|
case TypeBytes.ENTITY_MESSAGE_TYPE_UPDATEENTITYVIEWDIR:
|
||||||
|
if(byteBuffer.getRemaining() >= TypeBytes.ENTITY_MESSAGE_TYPE_UPDATEENTITYVIEWDIR_SIZE){
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -554,50 +502,6 @@ public class EntityMessage extends NetworkMessage {
|
|||||||
return rVal;
|
return rVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static EntityMessage parseSetPositionMessage(CircularByteBuffer byteBuffer){
|
|
||||||
EntityMessage rVal = new EntityMessage(EntityMessageType.SETPOSITION);
|
|
||||||
stripPacketHeader(byteBuffer);
|
|
||||||
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
|
||||||
rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteBuffer));
|
|
||||||
rVal.setpositionX(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
|
||||||
rVal.setpositionY(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
|
||||||
rVal.setpositionZ(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
|
||||||
return rVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static EntityMessage constructSetPositionMessage(int entityID,long time,double positionX,double positionY,double positionZ){
|
|
||||||
EntityMessage rVal = new EntityMessage(EntityMessageType.SETPOSITION);
|
|
||||||
rVal.setentityID(entityID);
|
|
||||||
rVal.settime(time);
|
|
||||||
rVal.setpositionX(positionX);
|
|
||||||
rVal.setpositionY(positionY);
|
|
||||||
rVal.setpositionZ(positionZ);
|
|
||||||
rVal.serialize();
|
|
||||||
return rVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static EntityMessage parsesetFacingMessage(CircularByteBuffer byteBuffer){
|
|
||||||
EntityMessage rVal = new EntityMessage(EntityMessageType.SETFACING);
|
|
||||||
stripPacketHeader(byteBuffer);
|
|
||||||
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
|
||||||
rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteBuffer));
|
|
||||||
rVal.setrotationX(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
|
||||||
rVal.setrotationY(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
|
||||||
rVal.setrotationZ(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
|
||||||
return rVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static EntityMessage constructsetFacingMessage(int entityID,long time,double rotationX,double rotationY,double rotationZ){
|
|
||||||
EntityMessage rVal = new EntityMessage(EntityMessageType.SETFACING);
|
|
||||||
rVal.setentityID(entityID);
|
|
||||||
rVal.settime(time);
|
|
||||||
rVal.setrotationX(rotationX);
|
|
||||||
rVal.setrotationY(rotationY);
|
|
||||||
rVal.setrotationZ(rotationZ);
|
|
||||||
rVal.serialize();
|
|
||||||
return rVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static EntityMessage parsemoveUpdateMessage(CircularByteBuffer byteBuffer){
|
public static EntityMessage parsemoveUpdateMessage(CircularByteBuffer byteBuffer){
|
||||||
EntityMessage rVal = new EntityMessage(EntityMessageType.MOVEUPDATE);
|
EntityMessage rVal = new EntityMessage(EntityMessageType.MOVEUPDATE);
|
||||||
stripPacketHeader(byteBuffer);
|
stripPacketHeader(byteBuffer);
|
||||||
@ -611,11 +515,12 @@ public class EntityMessage extends NetworkMessage {
|
|||||||
rVal.setrotationZ(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
rVal.setrotationZ(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
||||||
rVal.setrotationW(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
rVal.setrotationW(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
||||||
rVal.setvelocity(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
rVal.setvelocity(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
||||||
|
rVal.setpropertyValueInt(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||||
rVal.settreeState(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
rVal.settreeState(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||||
return rVal;
|
return rVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static EntityMessage constructmoveUpdateMessage(int entityID,long time,double positionX,double positionY,double positionZ,double rotationX,double rotationY,double rotationZ,double rotationW,double velocity,int treeState){
|
public static EntityMessage constructmoveUpdateMessage(int entityID,long time,double positionX,double positionY,double positionZ,double rotationX,double rotationY,double rotationZ,double rotationW,double velocity,int propertyValueInt,int treeState){
|
||||||
EntityMessage rVal = new EntityMessage(EntityMessageType.MOVEUPDATE);
|
EntityMessage rVal = new EntityMessage(EntityMessageType.MOVEUPDATE);
|
||||||
rVal.setentityID(entityID);
|
rVal.setentityID(entityID);
|
||||||
rVal.settime(time);
|
rVal.settime(time);
|
||||||
@ -627,6 +532,7 @@ public class EntityMessage extends NetworkMessage {
|
|||||||
rVal.setrotationZ(rotationZ);
|
rVal.setrotationZ(rotationZ);
|
||||||
rVal.setrotationW(rotationW);
|
rVal.setrotationW(rotationW);
|
||||||
rVal.setvelocity(velocity);
|
rVal.setvelocity(velocity);
|
||||||
|
rVal.setpropertyValueInt(propertyValueInt);
|
||||||
rVal.settreeState(treeState);
|
rVal.settreeState(treeState);
|
||||||
rVal.serialize();
|
rVal.serialize();
|
||||||
return rVal;
|
return rVal;
|
||||||
@ -676,28 +582,6 @@ public class EntityMessage extends NetworkMessage {
|
|||||||
return rVal;
|
return rVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static EntityMessage parseMoveMessage(CircularByteBuffer byteBuffer){
|
|
||||||
EntityMessage rVal = new EntityMessage(EntityMessageType.MOVE);
|
|
||||||
stripPacketHeader(byteBuffer);
|
|
||||||
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
|
||||||
rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteBuffer));
|
|
||||||
rVal.setpositionX(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
|
||||||
rVal.setpositionY(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
|
||||||
rVal.setpositionZ(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
|
||||||
return rVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static EntityMessage constructMoveMessage(int entityID,long time,double positionX,double positionY,double positionZ){
|
|
||||||
EntityMessage rVal = new EntityMessage(EntityMessageType.MOVE);
|
|
||||||
rVal.setentityID(entityID);
|
|
||||||
rVal.settime(time);
|
|
||||||
rVal.setpositionX(positionX);
|
|
||||||
rVal.setpositionY(positionY);
|
|
||||||
rVal.setpositionZ(positionZ);
|
|
||||||
rVal.serialize();
|
|
||||||
return rVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static EntityMessage parseKillMessage(CircularByteBuffer byteBuffer){
|
public static EntityMessage parseKillMessage(CircularByteBuffer byteBuffer){
|
||||||
EntityMessage rVal = new EntityMessage(EntityMessageType.KILL);
|
EntityMessage rVal = new EntityMessage(EntityMessageType.KILL);
|
||||||
stripPacketHeader(byteBuffer);
|
stripPacketHeader(byteBuffer);
|
||||||
@ -728,26 +612,6 @@ public class EntityMessage extends NetworkMessage {
|
|||||||
return rVal;
|
return rVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static EntityMessage parseSetBehaviorTreeMessage(CircularByteBuffer byteBuffer){
|
|
||||||
EntityMessage rVal = new EntityMessage(EntityMessageType.SETBEHAVIORTREE);
|
|
||||||
stripPacketHeader(byteBuffer);
|
|
||||||
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
|
||||||
rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteBuffer));
|
|
||||||
rVal.settreeType(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
|
||||||
rVal.settreeStatus(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
|
||||||
return rVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static EntityMessage constructSetBehaviorTreeMessage(int entityID,long time,int treeType,int treeStatus){
|
|
||||||
EntityMessage rVal = new EntityMessage(EntityMessageType.SETBEHAVIORTREE);
|
|
||||||
rVal.setentityID(entityID);
|
|
||||||
rVal.settime(time);
|
|
||||||
rVal.settreeType(treeType);
|
|
||||||
rVal.settreeStatus(treeStatus);
|
|
||||||
rVal.serialize();
|
|
||||||
return rVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static EntityMessage parsesetPropertyMessage(CircularByteBuffer byteBuffer){
|
public static EntityMessage parsesetPropertyMessage(CircularByteBuffer byteBuffer){
|
||||||
EntityMessage rVal = new EntityMessage(EntityMessageType.SETPROPERTY);
|
EntityMessage rVal = new EntityMessage(EntityMessageType.SETPROPERTY);
|
||||||
stripPacketHeader(byteBuffer);
|
stripPacketHeader(byteBuffer);
|
||||||
@ -768,147 +632,6 @@ public class EntityMessage extends NetworkMessage {
|
|||||||
return rVal;
|
return rVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static EntityMessage parsesetBTreePropertyIntMessage(CircularByteBuffer byteBuffer){
|
|
||||||
EntityMessage rVal = new EntityMessage(EntityMessageType.SETBTREEPROPERTYINT);
|
|
||||||
stripPacketHeader(byteBuffer);
|
|
||||||
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
|
||||||
rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteBuffer));
|
|
||||||
rVal.setbTreeID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
|
||||||
rVal.setpropertyID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
|
||||||
rVal.setpropertyValueInt(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
|
||||||
return rVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static EntityMessage constructsetBTreePropertyIntMessage(int entityID,long time,int bTreeID,int propertyID,int propertyValueInt){
|
|
||||||
EntityMessage rVal = new EntityMessage(EntityMessageType.SETBTREEPROPERTYINT);
|
|
||||||
rVal.setentityID(entityID);
|
|
||||||
rVal.settime(time);
|
|
||||||
rVal.setbTreeID(bTreeID);
|
|
||||||
rVal.setpropertyID(propertyID);
|
|
||||||
rVal.setpropertyValueInt(propertyValueInt);
|
|
||||||
rVal.serialize();
|
|
||||||
return rVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static EntityMessage parsesetBTreePropertyFloatMessage(CircularByteBuffer byteBuffer){
|
|
||||||
EntityMessage rVal = new EntityMessage(EntityMessageType.SETBTREEPROPERTYFLOAT);
|
|
||||||
stripPacketHeader(byteBuffer);
|
|
||||||
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
|
||||||
rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteBuffer));
|
|
||||||
rVal.setbTreeID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
|
||||||
rVal.setpropertyID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
|
||||||
rVal.setpropertyValueFloat(ByteStreamUtils.popFloatFromByteQueue(byteBuffer));
|
|
||||||
return rVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static EntityMessage constructsetBTreePropertyFloatMessage(int entityID,long time,int bTreeID,int propertyID,float propertyValueFloat){
|
|
||||||
EntityMessage rVal = new EntityMessage(EntityMessageType.SETBTREEPROPERTYFLOAT);
|
|
||||||
rVal.setentityID(entityID);
|
|
||||||
rVal.settime(time);
|
|
||||||
rVal.setbTreeID(bTreeID);
|
|
||||||
rVal.setpropertyID(propertyID);
|
|
||||||
rVal.setpropertyValueFloat(propertyValueFloat);
|
|
||||||
rVal.serialize();
|
|
||||||
return rVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static EntityMessage parsesetBTreePropertyDoubleMessage(CircularByteBuffer byteBuffer){
|
|
||||||
EntityMessage rVal = new EntityMessage(EntityMessageType.SETBTREEPROPERTYDOUBLE);
|
|
||||||
stripPacketHeader(byteBuffer);
|
|
||||||
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
|
||||||
rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteBuffer));
|
|
||||||
rVal.setbTreeID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
|
||||||
rVal.setpropertyID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
|
||||||
rVal.setpropertyValueDouble(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
|
||||||
return rVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static EntityMessage constructsetBTreePropertyDoubleMessage(int entityID,long time,int bTreeID,int propertyID,double propertyValueDouble){
|
|
||||||
EntityMessage rVal = new EntityMessage(EntityMessageType.SETBTREEPROPERTYDOUBLE);
|
|
||||||
rVal.setentityID(entityID);
|
|
||||||
rVal.settime(time);
|
|
||||||
rVal.setbTreeID(bTreeID);
|
|
||||||
rVal.setpropertyID(propertyID);
|
|
||||||
rVal.setpropertyValueDouble(propertyValueDouble);
|
|
||||||
rVal.serialize();
|
|
||||||
return rVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean canParsesetBTreePropertyStringMessage(CircularByteBuffer byteBuffer){
|
|
||||||
int currentStreamLength = byteBuffer.getRemaining();
|
|
||||||
List<Byte> temporaryByteQueue = new LinkedList();
|
|
||||||
if(currentStreamLength < 6){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if(currentStreamLength < 14){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if(currentStreamLength < 18){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if(currentStreamLength < 22){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
int propertyValueStringSize = 0;
|
|
||||||
if(currentStreamLength < 26){
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
temporaryByteQueue.add(byteBuffer.peek(22 + 0));
|
|
||||||
temporaryByteQueue.add(byteBuffer.peek(22 + 1));
|
|
||||||
temporaryByteQueue.add(byteBuffer.peek(22 + 2));
|
|
||||||
temporaryByteQueue.add(byteBuffer.peek(22 + 3));
|
|
||||||
propertyValueStringSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue);
|
|
||||||
}
|
|
||||||
if(currentStreamLength < 26 + propertyValueStringSize){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static EntityMessage parsesetBTreePropertyStringMessage(CircularByteBuffer byteBuffer){
|
|
||||||
EntityMessage rVal = new EntityMessage(EntityMessageType.SETBTREEPROPERTYSTRING);
|
|
||||||
stripPacketHeader(byteBuffer);
|
|
||||||
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
|
||||||
rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteBuffer));
|
|
||||||
rVal.setbTreeID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
|
||||||
rVal.setpropertyID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
|
||||||
rVal.setpropertyValueString(ByteStreamUtils.popStringFromByteQueue(byteBuffer));
|
|
||||||
return rVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static EntityMessage constructsetBTreePropertyStringMessage(int entityID,long time,int bTreeID,int propertyID,String propertyValueString){
|
|
||||||
EntityMessage rVal = new EntityMessage(EntityMessageType.SETBTREEPROPERTYSTRING);
|
|
||||||
rVal.setentityID(entityID);
|
|
||||||
rVal.settime(time);
|
|
||||||
rVal.setbTreeID(bTreeID);
|
|
||||||
rVal.setpropertyID(propertyID);
|
|
||||||
rVal.setpropertyValueString(propertyValueString);
|
|
||||||
rVal.serialize();
|
|
||||||
return rVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static EntityMessage parsesetBTreePropertyEnumMessage(CircularByteBuffer byteBuffer){
|
|
||||||
EntityMessage rVal = new EntityMessage(EntityMessageType.SETBTREEPROPERTYENUM);
|
|
||||||
stripPacketHeader(byteBuffer);
|
|
||||||
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
|
||||||
rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteBuffer));
|
|
||||||
rVal.setbTreeID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
|
||||||
rVal.setpropertyID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
|
||||||
rVal.setpropertyValueInt(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
|
||||||
return rVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static EntityMessage constructsetBTreePropertyEnumMessage(int entityID,long time,int bTreeID,int propertyID,int propertyValueInt){
|
|
||||||
EntityMessage rVal = new EntityMessage(EntityMessageType.SETBTREEPROPERTYENUM);
|
|
||||||
rVal.setentityID(entityID);
|
|
||||||
rVal.settime(time);
|
|
||||||
rVal.setbTreeID(bTreeID);
|
|
||||||
rVal.setpropertyID(propertyID);
|
|
||||||
rVal.setpropertyValueInt(propertyValueInt);
|
|
||||||
rVal.serialize();
|
|
||||||
return rVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean canParseattachEntityToEntityMessage(CircularByteBuffer byteBuffer){
|
public static boolean canParseattachEntityToEntityMessage(CircularByteBuffer byteBuffer){
|
||||||
int currentStreamLength = byteBuffer.getRemaining();
|
int currentStreamLength = byteBuffer.getRemaining();
|
||||||
List<Byte> temporaryByteQueue = new LinkedList();
|
List<Byte> temporaryByteQueue = new LinkedList();
|
||||||
@ -1010,6 +733,28 @@ public class EntityMessage extends NetworkMessage {
|
|||||||
return rVal;
|
return rVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static EntityMessage parseupdateEntityViewDirMessage(CircularByteBuffer byteBuffer){
|
||||||
|
EntityMessage rVal = new EntityMessage(EntityMessageType.UPDATEENTITYVIEWDIR);
|
||||||
|
stripPacketHeader(byteBuffer);
|
||||||
|
rVal.setentityID(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||||
|
rVal.settime(ByteStreamUtils.popLongFromByteQueue(byteBuffer));
|
||||||
|
rVal.setpositionX(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
||||||
|
rVal.setpositionY(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
||||||
|
rVal.setpositionZ(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer));
|
||||||
|
return rVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static EntityMessage constructupdateEntityViewDirMessage(int entityID,long time,double positionX,double positionY,double positionZ){
|
||||||
|
EntityMessage rVal = new EntityMessage(EntityMessageType.UPDATEENTITYVIEWDIR);
|
||||||
|
rVal.setentityID(entityID);
|
||||||
|
rVal.settime(time);
|
||||||
|
rVal.setpositionX(positionX);
|
||||||
|
rVal.setpositionY(positionY);
|
||||||
|
rVal.setpositionZ(positionZ);
|
||||||
|
rVal.serialize();
|
||||||
|
return rVal;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void serialize(){
|
void serialize(){
|
||||||
byte[] intValues = new byte[8];
|
byte[] intValues = new byte[8];
|
||||||
@ -1112,62 +857,8 @@ public class EntityMessage extends NetworkMessage {
|
|||||||
rawBytes[26+creatureTemplate.length()+i] = intValues[i];
|
rawBytes[26+creatureTemplate.length()+i] = intValues[i];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SETPOSITION:
|
|
||||||
rawBytes = new byte[2+4+8+8+8+8];
|
|
||||||
//message header
|
|
||||||
rawBytes[0] = TypeBytes.MESSAGE_TYPE_ENTITY;
|
|
||||||
//entity messaage header
|
|
||||||
rawBytes[1] = TypeBytes.ENTITY_MESSAGE_TYPE_SETPOSITION;
|
|
||||||
intValues = ByteStreamUtils.serializeIntToBytes(entityID);
|
|
||||||
for(int i = 0; i < 4; i++){
|
|
||||||
rawBytes[2+i] = intValues[i];
|
|
||||||
}
|
|
||||||
intValues = ByteStreamUtils.serializeLongToBytes(time);
|
|
||||||
for(int i = 0; i < 8; i++){
|
|
||||||
rawBytes[6+i] = intValues[i];
|
|
||||||
}
|
|
||||||
intValues = ByteStreamUtils.serializeDoubleToBytes(positionX);
|
|
||||||
for(int i = 0; i < 8; i++){
|
|
||||||
rawBytes[14+i] = intValues[i];
|
|
||||||
}
|
|
||||||
intValues = ByteStreamUtils.serializeDoubleToBytes(positionY);
|
|
||||||
for(int i = 0; i < 8; i++){
|
|
||||||
rawBytes[22+i] = intValues[i];
|
|
||||||
}
|
|
||||||
intValues = ByteStreamUtils.serializeDoubleToBytes(positionZ);
|
|
||||||
for(int i = 0; i < 8; i++){
|
|
||||||
rawBytes[30+i] = intValues[i];
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SETFACING:
|
|
||||||
rawBytes = new byte[2+4+8+8+8+8];
|
|
||||||
//message header
|
|
||||||
rawBytes[0] = TypeBytes.MESSAGE_TYPE_ENTITY;
|
|
||||||
//entity messaage header
|
|
||||||
rawBytes[1] = TypeBytes.ENTITY_MESSAGE_TYPE_SETFACING;
|
|
||||||
intValues = ByteStreamUtils.serializeIntToBytes(entityID);
|
|
||||||
for(int i = 0; i < 4; i++){
|
|
||||||
rawBytes[2+i] = intValues[i];
|
|
||||||
}
|
|
||||||
intValues = ByteStreamUtils.serializeLongToBytes(time);
|
|
||||||
for(int i = 0; i < 8; i++){
|
|
||||||
rawBytes[6+i] = intValues[i];
|
|
||||||
}
|
|
||||||
intValues = ByteStreamUtils.serializeDoubleToBytes(rotationX);
|
|
||||||
for(int i = 0; i < 8; i++){
|
|
||||||
rawBytes[14+i] = intValues[i];
|
|
||||||
}
|
|
||||||
intValues = ByteStreamUtils.serializeDoubleToBytes(rotationY);
|
|
||||||
for(int i = 0; i < 8; i++){
|
|
||||||
rawBytes[22+i] = intValues[i];
|
|
||||||
}
|
|
||||||
intValues = ByteStreamUtils.serializeDoubleToBytes(rotationZ);
|
|
||||||
for(int i = 0; i < 8; i++){
|
|
||||||
rawBytes[30+i] = intValues[i];
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case MOVEUPDATE:
|
case MOVEUPDATE:
|
||||||
rawBytes = new byte[2+4+8+8+8+8+8+8+8+8+8+4];
|
rawBytes = new byte[2+4+8+8+8+8+8+8+8+8+8+4+4];
|
||||||
//message header
|
//message header
|
||||||
rawBytes[0] = TypeBytes.MESSAGE_TYPE_ENTITY;
|
rawBytes[0] = TypeBytes.MESSAGE_TYPE_ENTITY;
|
||||||
//entity messaage header
|
//entity messaage header
|
||||||
@ -1212,10 +903,14 @@ public class EntityMessage extends NetworkMessage {
|
|||||||
for(int i = 0; i < 8; i++){
|
for(int i = 0; i < 8; i++){
|
||||||
rawBytes[70+i] = intValues[i];
|
rawBytes[70+i] = intValues[i];
|
||||||
}
|
}
|
||||||
intValues = ByteStreamUtils.serializeIntToBytes(treeState);
|
intValues = ByteStreamUtils.serializeIntToBytes(propertyValueInt);
|
||||||
for(int i = 0; i < 4; i++){
|
for(int i = 0; i < 4; i++){
|
||||||
rawBytes[78+i] = intValues[i];
|
rawBytes[78+i] = intValues[i];
|
||||||
}
|
}
|
||||||
|
intValues = ByteStreamUtils.serializeIntToBytes(treeState);
|
||||||
|
for(int i = 0; i < 4; i++){
|
||||||
|
rawBytes[82+i] = intValues[i];
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case ATTACKUPDATE:
|
case ATTACKUPDATE:
|
||||||
rawBytes = new byte[2+4+8+8+8+8+8+8+8+8+4];
|
rawBytes = new byte[2+4+8+8+8+8+8+8+8+8+4];
|
||||||
@ -1271,33 +966,6 @@ public class EntityMessage extends NetworkMessage {
|
|||||||
//entity messaage header
|
//entity messaage header
|
||||||
rawBytes[1] = TypeBytes.ENTITY_MESSAGE_TYPE_STARTATTACK;
|
rawBytes[1] = TypeBytes.ENTITY_MESSAGE_TYPE_STARTATTACK;
|
||||||
break;
|
break;
|
||||||
case MOVE:
|
|
||||||
rawBytes = new byte[2+4+8+8+8+8];
|
|
||||||
//message header
|
|
||||||
rawBytes[0] = TypeBytes.MESSAGE_TYPE_ENTITY;
|
|
||||||
//entity messaage header
|
|
||||||
rawBytes[1] = TypeBytes.ENTITY_MESSAGE_TYPE_MOVE;
|
|
||||||
intValues = ByteStreamUtils.serializeIntToBytes(entityID);
|
|
||||||
for(int i = 0; i < 4; i++){
|
|
||||||
rawBytes[2+i] = intValues[i];
|
|
||||||
}
|
|
||||||
intValues = ByteStreamUtils.serializeLongToBytes(time);
|
|
||||||
for(int i = 0; i < 8; i++){
|
|
||||||
rawBytes[6+i] = intValues[i];
|
|
||||||
}
|
|
||||||
intValues = ByteStreamUtils.serializeDoubleToBytes(positionX);
|
|
||||||
for(int i = 0; i < 8; i++){
|
|
||||||
rawBytes[14+i] = intValues[i];
|
|
||||||
}
|
|
||||||
intValues = ByteStreamUtils.serializeDoubleToBytes(positionY);
|
|
||||||
for(int i = 0; i < 8; i++){
|
|
||||||
rawBytes[22+i] = intValues[i];
|
|
||||||
}
|
|
||||||
intValues = ByteStreamUtils.serializeDoubleToBytes(positionZ);
|
|
||||||
for(int i = 0; i < 8; i++){
|
|
||||||
rawBytes[30+i] = intValues[i];
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case KILL:
|
case KILL:
|
||||||
rawBytes = new byte[2+8+4];
|
rawBytes = new byte[2+8+4];
|
||||||
//message header
|
//message header
|
||||||
@ -1324,29 +992,6 @@ public class EntityMessage extends NetworkMessage {
|
|||||||
rawBytes[2+i] = intValues[i];
|
rawBytes[2+i] = intValues[i];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SETBEHAVIORTREE:
|
|
||||||
rawBytes = new byte[2+4+8+4+4];
|
|
||||||
//message header
|
|
||||||
rawBytes[0] = TypeBytes.MESSAGE_TYPE_ENTITY;
|
|
||||||
//entity messaage header
|
|
||||||
rawBytes[1] = TypeBytes.ENTITY_MESSAGE_TYPE_SETBEHAVIORTREE;
|
|
||||||
intValues = ByteStreamUtils.serializeIntToBytes(entityID);
|
|
||||||
for(int i = 0; i < 4; i++){
|
|
||||||
rawBytes[2+i] = intValues[i];
|
|
||||||
}
|
|
||||||
intValues = ByteStreamUtils.serializeLongToBytes(time);
|
|
||||||
for(int i = 0; i < 8; i++){
|
|
||||||
rawBytes[6+i] = intValues[i];
|
|
||||||
}
|
|
||||||
intValues = ByteStreamUtils.serializeIntToBytes(treeType);
|
|
||||||
for(int i = 0; i < 4; i++){
|
|
||||||
rawBytes[14+i] = intValues[i];
|
|
||||||
}
|
|
||||||
intValues = ByteStreamUtils.serializeIntToBytes(treeStatus);
|
|
||||||
for(int i = 0; i < 4; i++){
|
|
||||||
rawBytes[18+i] = intValues[i];
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SETPROPERTY:
|
case SETPROPERTY:
|
||||||
rawBytes = new byte[2+4+8+4+4];
|
rawBytes = new byte[2+4+8+4+4];
|
||||||
//message header
|
//message header
|
||||||
@ -1370,144 +1015,6 @@ public class EntityMessage extends NetworkMessage {
|
|||||||
rawBytes[18+i] = intValues[i];
|
rawBytes[18+i] = intValues[i];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SETBTREEPROPERTYINT:
|
|
||||||
rawBytes = new byte[2+4+8+4+4+4];
|
|
||||||
//message header
|
|
||||||
rawBytes[0] = TypeBytes.MESSAGE_TYPE_ENTITY;
|
|
||||||
//entity messaage header
|
|
||||||
rawBytes[1] = TypeBytes.ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYINT;
|
|
||||||
intValues = ByteStreamUtils.serializeIntToBytes(entityID);
|
|
||||||
for(int i = 0; i < 4; i++){
|
|
||||||
rawBytes[2+i] = intValues[i];
|
|
||||||
}
|
|
||||||
intValues = ByteStreamUtils.serializeLongToBytes(time);
|
|
||||||
for(int i = 0; i < 8; i++){
|
|
||||||
rawBytes[6+i] = intValues[i];
|
|
||||||
}
|
|
||||||
intValues = ByteStreamUtils.serializeIntToBytes(bTreeID);
|
|
||||||
for(int i = 0; i < 4; i++){
|
|
||||||
rawBytes[14+i] = intValues[i];
|
|
||||||
}
|
|
||||||
intValues = ByteStreamUtils.serializeIntToBytes(propertyID);
|
|
||||||
for(int i = 0; i < 4; i++){
|
|
||||||
rawBytes[18+i] = intValues[i];
|
|
||||||
}
|
|
||||||
intValues = ByteStreamUtils.serializeIntToBytes(propertyValueInt);
|
|
||||||
for(int i = 0; i < 4; i++){
|
|
||||||
rawBytes[22+i] = intValues[i];
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SETBTREEPROPERTYFLOAT:
|
|
||||||
rawBytes = new byte[2+4+8+4+4+4];
|
|
||||||
//message header
|
|
||||||
rawBytes[0] = TypeBytes.MESSAGE_TYPE_ENTITY;
|
|
||||||
//entity messaage header
|
|
||||||
rawBytes[1] = TypeBytes.ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYFLOAT;
|
|
||||||
intValues = ByteStreamUtils.serializeIntToBytes(entityID);
|
|
||||||
for(int i = 0; i < 4; i++){
|
|
||||||
rawBytes[2+i] = intValues[i];
|
|
||||||
}
|
|
||||||
intValues = ByteStreamUtils.serializeLongToBytes(time);
|
|
||||||
for(int i = 0; i < 8; i++){
|
|
||||||
rawBytes[6+i] = intValues[i];
|
|
||||||
}
|
|
||||||
intValues = ByteStreamUtils.serializeIntToBytes(bTreeID);
|
|
||||||
for(int i = 0; i < 4; i++){
|
|
||||||
rawBytes[14+i] = intValues[i];
|
|
||||||
}
|
|
||||||
intValues = ByteStreamUtils.serializeIntToBytes(propertyID);
|
|
||||||
for(int i = 0; i < 4; i++){
|
|
||||||
rawBytes[18+i] = intValues[i];
|
|
||||||
}
|
|
||||||
intValues = ByteStreamUtils.serializeFloatToBytes(propertyValueFloat);
|
|
||||||
for(int i = 0; i < 4; i++){
|
|
||||||
rawBytes[22+i] = intValues[i];
|
|
||||||
} break;
|
|
||||||
case SETBTREEPROPERTYDOUBLE:
|
|
||||||
rawBytes = new byte[2+4+8+4+4+8];
|
|
||||||
//message header
|
|
||||||
rawBytes[0] = TypeBytes.MESSAGE_TYPE_ENTITY;
|
|
||||||
//entity messaage header
|
|
||||||
rawBytes[1] = TypeBytes.ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYDOUBLE;
|
|
||||||
intValues = ByteStreamUtils.serializeIntToBytes(entityID);
|
|
||||||
for(int i = 0; i < 4; i++){
|
|
||||||
rawBytes[2+i] = intValues[i];
|
|
||||||
}
|
|
||||||
intValues = ByteStreamUtils.serializeLongToBytes(time);
|
|
||||||
for(int i = 0; i < 8; i++){
|
|
||||||
rawBytes[6+i] = intValues[i];
|
|
||||||
}
|
|
||||||
intValues = ByteStreamUtils.serializeIntToBytes(bTreeID);
|
|
||||||
for(int i = 0; i < 4; i++){
|
|
||||||
rawBytes[14+i] = intValues[i];
|
|
||||||
}
|
|
||||||
intValues = ByteStreamUtils.serializeIntToBytes(propertyID);
|
|
||||||
for(int i = 0; i < 4; i++){
|
|
||||||
rawBytes[18+i] = intValues[i];
|
|
||||||
}
|
|
||||||
intValues = ByteStreamUtils.serializeDoubleToBytes(propertyValueDouble);
|
|
||||||
for(int i = 0; i < 8; i++){
|
|
||||||
rawBytes[22+i] = intValues[i];
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SETBTREEPROPERTYSTRING:
|
|
||||||
rawBytes = new byte[2+4+8+4+4+4+propertyValueString.length()];
|
|
||||||
//message header
|
|
||||||
rawBytes[0] = TypeBytes.MESSAGE_TYPE_ENTITY;
|
|
||||||
//entity messaage header
|
|
||||||
rawBytes[1] = TypeBytes.ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYSTRING;
|
|
||||||
intValues = ByteStreamUtils.serializeIntToBytes(entityID);
|
|
||||||
for(int i = 0; i < 4; i++){
|
|
||||||
rawBytes[2+i] = intValues[i];
|
|
||||||
}
|
|
||||||
intValues = ByteStreamUtils.serializeLongToBytes(time);
|
|
||||||
for(int i = 0; i < 8; i++){
|
|
||||||
rawBytes[6+i] = intValues[i];
|
|
||||||
}
|
|
||||||
intValues = ByteStreamUtils.serializeIntToBytes(bTreeID);
|
|
||||||
for(int i = 0; i < 4; i++){
|
|
||||||
rawBytes[14+i] = intValues[i];
|
|
||||||
}
|
|
||||||
intValues = ByteStreamUtils.serializeIntToBytes(propertyID);
|
|
||||||
for(int i = 0; i < 4; i++){
|
|
||||||
rawBytes[18+i] = intValues[i];
|
|
||||||
}
|
|
||||||
intValues = ByteStreamUtils.serializeIntToBytes(propertyValueString.length());
|
|
||||||
for(int i = 0; i < 4; i++){
|
|
||||||
rawBytes[22+i] = intValues[i];
|
|
||||||
}
|
|
||||||
stringBytes = propertyValueString.getBytes();
|
|
||||||
for(int i = 0; i < propertyValueString.length(); i++){
|
|
||||||
rawBytes[26+i] = stringBytes[i];
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SETBTREEPROPERTYENUM:
|
|
||||||
rawBytes = new byte[2+4+8+4+4+4];
|
|
||||||
//message header
|
|
||||||
rawBytes[0] = TypeBytes.MESSAGE_TYPE_ENTITY;
|
|
||||||
//entity messaage header
|
|
||||||
rawBytes[1] = TypeBytes.ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYENUM;
|
|
||||||
intValues = ByteStreamUtils.serializeIntToBytes(entityID);
|
|
||||||
for(int i = 0; i < 4; i++){
|
|
||||||
rawBytes[2+i] = intValues[i];
|
|
||||||
}
|
|
||||||
intValues = ByteStreamUtils.serializeLongToBytes(time);
|
|
||||||
for(int i = 0; i < 8; i++){
|
|
||||||
rawBytes[6+i] = intValues[i];
|
|
||||||
}
|
|
||||||
intValues = ByteStreamUtils.serializeIntToBytes(bTreeID);
|
|
||||||
for(int i = 0; i < 4; i++){
|
|
||||||
rawBytes[14+i] = intValues[i];
|
|
||||||
}
|
|
||||||
intValues = ByteStreamUtils.serializeIntToBytes(propertyID);
|
|
||||||
for(int i = 0; i < 4; i++){
|
|
||||||
rawBytes[18+i] = intValues[i];
|
|
||||||
}
|
|
||||||
intValues = ByteStreamUtils.serializeIntToBytes(propertyValueInt);
|
|
||||||
for(int i = 0; i < 4; i++){
|
|
||||||
rawBytes[22+i] = intValues[i];
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ATTACHENTITYTOENTITY:
|
case ATTACHENTITYTOENTITY:
|
||||||
rawBytes = new byte[2+4+4+bone.length()+4];
|
rawBytes = new byte[2+4+4+bone.length()+4];
|
||||||
//message header
|
//message header
|
||||||
@ -1566,6 +1073,33 @@ public class EntityMessage extends NetworkMessage {
|
|||||||
rawBytes[34+creatureTemplate.length()+i] = intValues[i];
|
rawBytes[34+creatureTemplate.length()+i] = intValues[i];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case UPDATEENTITYVIEWDIR:
|
||||||
|
rawBytes = new byte[2+4+8+8+8+8];
|
||||||
|
//message header
|
||||||
|
rawBytes[0] = TypeBytes.MESSAGE_TYPE_ENTITY;
|
||||||
|
//entity messaage header
|
||||||
|
rawBytes[1] = TypeBytes.ENTITY_MESSAGE_TYPE_UPDATEENTITYVIEWDIR;
|
||||||
|
intValues = ByteStreamUtils.serializeIntToBytes(entityID);
|
||||||
|
for(int i = 0; i < 4; i++){
|
||||||
|
rawBytes[2+i] = intValues[i];
|
||||||
|
}
|
||||||
|
intValues = ByteStreamUtils.serializeLongToBytes(time);
|
||||||
|
for(int i = 0; i < 8; i++){
|
||||||
|
rawBytes[6+i] = intValues[i];
|
||||||
|
}
|
||||||
|
intValues = ByteStreamUtils.serializeDoubleToBytes(positionX);
|
||||||
|
for(int i = 0; i < 8; i++){
|
||||||
|
rawBytes[14+i] = intValues[i];
|
||||||
|
}
|
||||||
|
intValues = ByteStreamUtils.serializeDoubleToBytes(positionY);
|
||||||
|
for(int i = 0; i < 8; i++){
|
||||||
|
rawBytes[22+i] = intValues[i];
|
||||||
|
}
|
||||||
|
intValues = ByteStreamUtils.serializeDoubleToBytes(positionZ);
|
||||||
|
for(int i = 0; i < 8; i++){
|
||||||
|
rawBytes[30+i] = intValues[i];
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
serialized = true;
|
serialized = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,10 +10,6 @@ public class LoreMessage extends NetworkMessage {
|
|||||||
public enum LoreMessageType {
|
public enum LoreMessageType {
|
||||||
REQUESTRACES,
|
REQUESTRACES,
|
||||||
RESPONSERACES,
|
RESPONSERACES,
|
||||||
REQUESTRACEDATA,
|
|
||||||
RESPONSERACEDATA,
|
|
||||||
REQUESTDATA,
|
|
||||||
RESPONSEDATA,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LoreMessageType messageType;
|
LoreMessageType messageType;
|
||||||
@ -50,18 +46,6 @@ public class LoreMessage extends NetworkMessage {
|
|||||||
}
|
}
|
||||||
case TypeBytes.LORE_MESSAGE_TYPE_RESPONSERACES:
|
case TypeBytes.LORE_MESSAGE_TYPE_RESPONSERACES:
|
||||||
return LoreMessage.canParseResponseRacesMessage(byteBuffer);
|
return LoreMessage.canParseResponseRacesMessage(byteBuffer);
|
||||||
case TypeBytes.LORE_MESSAGE_TYPE_REQUESTRACEDATA:
|
|
||||||
if(byteBuffer.getRemaining() >= TypeBytes.LORE_MESSAGE_TYPE_REQUESTRACEDATA_SIZE){
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
case TypeBytes.LORE_MESSAGE_TYPE_RESPONSERACEDATA:
|
|
||||||
return LoreMessage.canParseResponseRaceDataMessage(byteBuffer);
|
|
||||||
case TypeBytes.LORE_MESSAGE_TYPE_REQUESTDATA:
|
|
||||||
return LoreMessage.canParseRequestDataMessage(byteBuffer);
|
|
||||||
case TypeBytes.LORE_MESSAGE_TYPE_RESPONSEDATA:
|
|
||||||
return LoreMessage.canParseResponseDataMessage(byteBuffer);
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -111,117 +95,6 @@ public class LoreMessage extends NetworkMessage {
|
|||||||
return rVal;
|
return rVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static LoreMessage parseRequestRaceDataMessage(CircularByteBuffer byteBuffer){
|
|
||||||
LoreMessage rVal = new LoreMessage(LoreMessageType.REQUESTRACEDATA);
|
|
||||||
stripPacketHeader(byteBuffer);
|
|
||||||
return rVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static LoreMessage constructRequestRaceDataMessage(){
|
|
||||||
LoreMessage rVal = new LoreMessage(LoreMessageType.REQUESTRACEDATA);
|
|
||||||
rVal.serialize();
|
|
||||||
return rVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean canParseResponseRaceDataMessage(CircularByteBuffer byteBuffer){
|
|
||||||
int currentStreamLength = byteBuffer.getRemaining();
|
|
||||||
List<Byte> temporaryByteQueue = new LinkedList();
|
|
||||||
int dataSize = 0;
|
|
||||||
if(currentStreamLength < 6){
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
temporaryByteQueue.add(byteBuffer.peek(2 + 0));
|
|
||||||
temporaryByteQueue.add(byteBuffer.peek(2 + 1));
|
|
||||||
temporaryByteQueue.add(byteBuffer.peek(2 + 2));
|
|
||||||
temporaryByteQueue.add(byteBuffer.peek(2 + 3));
|
|
||||||
dataSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue);
|
|
||||||
}
|
|
||||||
if(currentStreamLength < 6 + dataSize){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static LoreMessage parseResponseRaceDataMessage(CircularByteBuffer byteBuffer){
|
|
||||||
LoreMessage rVal = new LoreMessage(LoreMessageType.RESPONSERACEDATA);
|
|
||||||
stripPacketHeader(byteBuffer);
|
|
||||||
rVal.setdata(ByteStreamUtils.popStringFromByteQueue(byteBuffer));
|
|
||||||
return rVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static LoreMessage constructResponseRaceDataMessage(String data){
|
|
||||||
LoreMessage rVal = new LoreMessage(LoreMessageType.RESPONSERACEDATA);
|
|
||||||
rVal.setdata(data);
|
|
||||||
rVal.serialize();
|
|
||||||
return rVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean canParseRequestDataMessage(CircularByteBuffer byteBuffer){
|
|
||||||
int currentStreamLength = byteBuffer.getRemaining();
|
|
||||||
List<Byte> temporaryByteQueue = new LinkedList();
|
|
||||||
int dataSize = 0;
|
|
||||||
if(currentStreamLength < 6){
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
temporaryByteQueue.add(byteBuffer.peek(2 + 0));
|
|
||||||
temporaryByteQueue.add(byteBuffer.peek(2 + 1));
|
|
||||||
temporaryByteQueue.add(byteBuffer.peek(2 + 2));
|
|
||||||
temporaryByteQueue.add(byteBuffer.peek(2 + 3));
|
|
||||||
dataSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue);
|
|
||||||
}
|
|
||||||
if(currentStreamLength < 6 + dataSize){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static LoreMessage parseRequestDataMessage(CircularByteBuffer byteBuffer){
|
|
||||||
LoreMessage rVal = new LoreMessage(LoreMessageType.REQUESTDATA);
|
|
||||||
stripPacketHeader(byteBuffer);
|
|
||||||
rVal.setdata(ByteStreamUtils.popStringFromByteQueue(byteBuffer));
|
|
||||||
return rVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static LoreMessage constructRequestDataMessage(String data){
|
|
||||||
LoreMessage rVal = new LoreMessage(LoreMessageType.REQUESTDATA);
|
|
||||||
rVal.setdata(data);
|
|
||||||
rVal.serialize();
|
|
||||||
return rVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean canParseResponseDataMessage(CircularByteBuffer byteBuffer){
|
|
||||||
int currentStreamLength = byteBuffer.getRemaining();
|
|
||||||
List<Byte> temporaryByteQueue = new LinkedList();
|
|
||||||
int dataSize = 0;
|
|
||||||
if(currentStreamLength < 6){
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
temporaryByteQueue.add(byteBuffer.peek(2 + 0));
|
|
||||||
temporaryByteQueue.add(byteBuffer.peek(2 + 1));
|
|
||||||
temporaryByteQueue.add(byteBuffer.peek(2 + 2));
|
|
||||||
temporaryByteQueue.add(byteBuffer.peek(2 + 3));
|
|
||||||
dataSize = ByteStreamUtils.popIntFromByteQueue(temporaryByteQueue);
|
|
||||||
}
|
|
||||||
if(currentStreamLength < 6 + dataSize){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static LoreMessage parseResponseDataMessage(CircularByteBuffer byteBuffer){
|
|
||||||
LoreMessage rVal = new LoreMessage(LoreMessageType.RESPONSEDATA);
|
|
||||||
stripPacketHeader(byteBuffer);
|
|
||||||
rVal.setdata(ByteStreamUtils.popStringFromByteQueue(byteBuffer));
|
|
||||||
return rVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static LoreMessage constructResponseDataMessage(String data){
|
|
||||||
LoreMessage rVal = new LoreMessage(LoreMessageType.RESPONSEDATA);
|
|
||||||
rVal.setdata(data);
|
|
||||||
rVal.serialize();
|
|
||||||
return rVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void serialize(){
|
void serialize(){
|
||||||
byte[] intValues = new byte[8];
|
byte[] intValues = new byte[8];
|
||||||
@ -249,58 +122,6 @@ public class LoreMessage extends NetworkMessage {
|
|||||||
rawBytes[6+i] = stringBytes[i];
|
rawBytes[6+i] = stringBytes[i];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case REQUESTRACEDATA:
|
|
||||||
rawBytes = new byte[2];
|
|
||||||
//message header
|
|
||||||
rawBytes[0] = TypeBytes.MESSAGE_TYPE_LORE;
|
|
||||||
//entity messaage header
|
|
||||||
rawBytes[1] = TypeBytes.LORE_MESSAGE_TYPE_REQUESTRACEDATA;
|
|
||||||
break;
|
|
||||||
case RESPONSERACEDATA:
|
|
||||||
rawBytes = new byte[2+4+data.length()];
|
|
||||||
//message header
|
|
||||||
rawBytes[0] = TypeBytes.MESSAGE_TYPE_LORE;
|
|
||||||
//entity messaage header
|
|
||||||
rawBytes[1] = TypeBytes.LORE_MESSAGE_TYPE_RESPONSERACEDATA;
|
|
||||||
intValues = ByteStreamUtils.serializeIntToBytes(data.length());
|
|
||||||
for(int i = 0; i < 4; i++){
|
|
||||||
rawBytes[2+i] = intValues[i];
|
|
||||||
}
|
|
||||||
stringBytes = data.getBytes();
|
|
||||||
for(int i = 0; i < data.length(); i++){
|
|
||||||
rawBytes[6+i] = stringBytes[i];
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case REQUESTDATA:
|
|
||||||
rawBytes = new byte[2+4+data.length()];
|
|
||||||
//message header
|
|
||||||
rawBytes[0] = TypeBytes.MESSAGE_TYPE_LORE;
|
|
||||||
//entity messaage header
|
|
||||||
rawBytes[1] = TypeBytes.LORE_MESSAGE_TYPE_REQUESTDATA;
|
|
||||||
intValues = ByteStreamUtils.serializeIntToBytes(data.length());
|
|
||||||
for(int i = 0; i < 4; i++){
|
|
||||||
rawBytes[2+i] = intValues[i];
|
|
||||||
}
|
|
||||||
stringBytes = data.getBytes();
|
|
||||||
for(int i = 0; i < data.length(); i++){
|
|
||||||
rawBytes[6+i] = stringBytes[i];
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case RESPONSEDATA:
|
|
||||||
rawBytes = new byte[2+4+data.length()];
|
|
||||||
//message header
|
|
||||||
rawBytes[0] = TypeBytes.MESSAGE_TYPE_LORE;
|
|
||||||
//entity messaage header
|
|
||||||
rawBytes[1] = TypeBytes.LORE_MESSAGE_TYPE_RESPONSEDATA;
|
|
||||||
intValues = ByteStreamUtils.serializeIntToBytes(data.length());
|
|
||||||
for(int i = 0; i < 4; i++){
|
|
||||||
rawBytes[2+i] = intValues[i];
|
|
||||||
}
|
|
||||||
stringBytes = data.getBytes();
|
|
||||||
for(int i = 0; i < data.length(); i++){
|
|
||||||
rawBytes[6+i] = stringBytes[i];
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
serialized = true;
|
serialized = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -56,16 +56,6 @@ SYNCHRONIZATION_MESSAGE,
|
|||||||
rVal = EntityMessage.parseSpawnItemMessage(byteBuffer);
|
rVal = EntityMessage.parseSpawnItemMessage(byteBuffer);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TypeBytes.ENTITY_MESSAGE_TYPE_SETPOSITION:
|
|
||||||
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
|
|
||||||
rVal = EntityMessage.parseSetPositionMessage(byteBuffer);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TypeBytes.ENTITY_MESSAGE_TYPE_SETFACING:
|
|
||||||
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
|
|
||||||
rVal = EntityMessage.parsesetFacingMessage(byteBuffer);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TypeBytes.ENTITY_MESSAGE_TYPE_MOVEUPDATE:
|
case TypeBytes.ENTITY_MESSAGE_TYPE_MOVEUPDATE:
|
||||||
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
|
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
|
||||||
rVal = EntityMessage.parsemoveUpdateMessage(byteBuffer);
|
rVal = EntityMessage.parsemoveUpdateMessage(byteBuffer);
|
||||||
@ -81,11 +71,6 @@ SYNCHRONIZATION_MESSAGE,
|
|||||||
rVal = EntityMessage.parsestartAttackMessage(byteBuffer);
|
rVal = EntityMessage.parsestartAttackMessage(byteBuffer);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TypeBytes.ENTITY_MESSAGE_TYPE_MOVE:
|
|
||||||
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
|
|
||||||
rVal = EntityMessage.parseMoveMessage(byteBuffer);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TypeBytes.ENTITY_MESSAGE_TYPE_KILL:
|
case TypeBytes.ENTITY_MESSAGE_TYPE_KILL:
|
||||||
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
|
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
|
||||||
rVal = EntityMessage.parseKillMessage(byteBuffer);
|
rVal = EntityMessage.parseKillMessage(byteBuffer);
|
||||||
@ -96,41 +81,11 @@ SYNCHRONIZATION_MESSAGE,
|
|||||||
rVal = EntityMessage.parseDestroyMessage(byteBuffer);
|
rVal = EntityMessage.parseDestroyMessage(byteBuffer);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TypeBytes.ENTITY_MESSAGE_TYPE_SETBEHAVIORTREE:
|
|
||||||
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
|
|
||||||
rVal = EntityMessage.parseSetBehaviorTreeMessage(byteBuffer);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TypeBytes.ENTITY_MESSAGE_TYPE_SETPROPERTY:
|
case TypeBytes.ENTITY_MESSAGE_TYPE_SETPROPERTY:
|
||||||
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
|
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
|
||||||
rVal = EntityMessage.parsesetPropertyMessage(byteBuffer);
|
rVal = EntityMessage.parsesetPropertyMessage(byteBuffer);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TypeBytes.ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYINT:
|
|
||||||
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
|
|
||||||
rVal = EntityMessage.parsesetBTreePropertyIntMessage(byteBuffer);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TypeBytes.ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYFLOAT:
|
|
||||||
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
|
|
||||||
rVal = EntityMessage.parsesetBTreePropertyFloatMessage(byteBuffer);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TypeBytes.ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYDOUBLE:
|
|
||||||
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
|
|
||||||
rVal = EntityMessage.parsesetBTreePropertyDoubleMessage(byteBuffer);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TypeBytes.ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYSTRING:
|
|
||||||
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
|
|
||||||
rVal = EntityMessage.parsesetBTreePropertyStringMessage(byteBuffer);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TypeBytes.ENTITY_MESSAGE_TYPE_SETBTREEPROPERTYENUM:
|
|
||||||
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
|
|
||||||
rVal = EntityMessage.parsesetBTreePropertyEnumMessage(byteBuffer);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TypeBytes.ENTITY_MESSAGE_TYPE_ATTACHENTITYTOENTITY:
|
case TypeBytes.ENTITY_MESSAGE_TYPE_ATTACHENTITYTOENTITY:
|
||||||
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
|
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
|
||||||
rVal = EntityMessage.parseattachEntityToEntityMessage(byteBuffer);
|
rVal = EntityMessage.parseattachEntityToEntityMessage(byteBuffer);
|
||||||
@ -141,6 +96,11 @@ SYNCHRONIZATION_MESSAGE,
|
|||||||
rVal = EntityMessage.parseSpawnFoliageSeedMessage(byteBuffer);
|
rVal = EntityMessage.parseSpawnFoliageSeedMessage(byteBuffer);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case TypeBytes.ENTITY_MESSAGE_TYPE_UPDATEENTITYVIEWDIR:
|
||||||
|
if(EntityMessage.canParseMessage(byteBuffer,secondByte)){
|
||||||
|
rVal = EntityMessage.parseupdateEntityViewDirMessage(byteBuffer);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TypeBytes.MESSAGE_TYPE_LORE:
|
case TypeBytes.MESSAGE_TYPE_LORE:
|
||||||
@ -156,26 +116,6 @@ SYNCHRONIZATION_MESSAGE,
|
|||||||
rVal = LoreMessage.parseResponseRacesMessage(byteBuffer);
|
rVal = LoreMessage.parseResponseRacesMessage(byteBuffer);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TypeBytes.LORE_MESSAGE_TYPE_REQUESTRACEDATA:
|
|
||||||
if(LoreMessage.canParseMessage(byteBuffer,secondByte)){
|
|
||||||
rVal = LoreMessage.parseRequestRaceDataMessage(byteBuffer);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TypeBytes.LORE_MESSAGE_TYPE_RESPONSERACEDATA:
|
|
||||||
if(LoreMessage.canParseMessage(byteBuffer,secondByte)){
|
|
||||||
rVal = LoreMessage.parseResponseRaceDataMessage(byteBuffer);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TypeBytes.LORE_MESSAGE_TYPE_REQUESTDATA:
|
|
||||||
if(LoreMessage.canParseMessage(byteBuffer,secondByte)){
|
|
||||||
rVal = LoreMessage.parseRequestDataMessage(byteBuffer);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TypeBytes.LORE_MESSAGE_TYPE_RESPONSEDATA:
|
|
||||||
if(LoreMessage.canParseMessage(byteBuffer,secondByte)){
|
|
||||||
rVal = LoreMessage.parseResponseDataMessage(byteBuffer);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TypeBytes.MESSAGE_TYPE_PLAYER:
|
case TypeBytes.MESSAGE_TYPE_PLAYER:
|
||||||
@ -206,11 +146,6 @@ SYNCHRONIZATION_MESSAGE,
|
|||||||
rVal = TerrainMessage.parseResponseMetadataMessage(byteBuffer);
|
rVal = TerrainMessage.parseResponseMetadataMessage(byteBuffer);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case TypeBytes.TERRAIN_MESSAGE_TYPE_REQUESTCHUNK:
|
|
||||||
if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){
|
|
||||||
rVal = TerrainMessage.parseRequestChunkMessage(byteBuffer);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TypeBytes.TERRAIN_MESSAGE_TYPE_REQUESTEDITVOXEL:
|
case TypeBytes.TERRAIN_MESSAGE_TYPE_REQUESTEDITVOXEL:
|
||||||
if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){
|
if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){
|
||||||
rVal = TerrainMessage.parseRequestEditVoxelMessage(byteBuffer);
|
rVal = TerrainMessage.parseRequestEditVoxelMessage(byteBuffer);
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user