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 | ||||||
|  | |||||||
| @ -7,3 +7,4 @@ | |||||||
| - @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; | ||||||
|      |      | ||||||
| @ -92,15 +91,43 @@ 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 ); | ||||||
| @ -326,6 +389,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; | ||||||
|  |     } | ||||||
|  |      | ||||||
|     /** |     /** | ||||||
|      *  |      *  | ||||||
|      * @param e the entity that's trying to move |      * @param e the entity that's trying to move | ||||||
| @ -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 | ||||||
| @ -759,4 +843,48 @@ public class CollisionEngine { | |||||||
|         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; | ||||||
| @ -302,4 +303,13 @@ public class PhysicsEntityUtils { | |||||||
|         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(); | ||||||
|         /* |         /* | ||||||
| @ -356,11 +390,6 @@ public class ControlHandler { | |||||||
|         */ |         */ | ||||||
|         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; | ||||||
| @ -85,6 +85,11 @@ import electrosphere.util.FileUtils; | |||||||
|  */ |  */ | ||||||
| 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; | ||||||
| @ -67,11 +73,19 @@ public class LoadingThread extends Thread { | |||||||
|                 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"; | ||||||
| @ -283,6 +282,11 @@ public class EntityDataStrings { | |||||||
|      */ |      */ | ||||||
|     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){ | ||||||
| @ -434,6 +384,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> | ||||||
|      * <p> |      * <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: | ||||||
| @ -472,6 +445,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> | ||||||
|      * <p> |      * <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