Compare commits

...

688 Commits

Author SHA1 Message Date
FatBoy 6fe4f32302 load mesh data and structure meshes 2024-01-18 19:50:49 -06:00
FatBoy d6ad0ecbd3 load mesh data and structure meshes 2024-01-18 19:43:47 -06:00
FatBoy efdf19f22e load mesh data and structure meshes 2024-01-18 19:15:49 -06:00
FatBoy 76a71b5984 load mesh data and structure meshes 2024-01-18 19:12:52 -06:00
FatBoy cf09f447bd load mesh data and structure meshes 2024-01-18 18:53:57 -06:00
FatBoy 8dc6a0627c load mesh data and structure meshes 2024-01-17 22:03:35 -06:00
FatBoy 8b095976ef load mesh data and structure meshes 2024-01-17 21:47:15 -06:00
FatBoy 83606046ba load mesh data and structure meshes 2024-01-17 20:55:04 -06:00
FatBoy adcf3fd9b6 load mesh data and structure meshes 2024-01-17 20:34:47 -06:00
FatBoy e983a32b5d load mesh data and structure meshes 2024-01-16 20:10:10 -06:00
FatBoy 9d8f800c2a load mesh data and structure meshes 2024-01-16 10:40:07 -06:00
FatBoy 05e90d495f load mesh data and structure meshes 2024-01-16 09:59:41 -06:00
FatBoy 18f70b6d5c load mesh data and structure meshes 2024-01-16 09:51:07 -06:00
FatBoy 86c8e985be load mesh data and structure meshes 2024-01-16 09:25:31 -06:00
FatBoy b6b5db41bd load mesh data and structure meshes 2024-01-15 20:37:33 -06:00
FatBoy d573534f6d load mesh data and structure meshes 2024-01-15 20:36:11 -06:00
FatBoy 06df109a18 load mesh data and structure meshes 2024-01-15 20:28:49 -06:00
FatBoy f077370034 load mesh data and structure meshes 2024-01-15 20:09:05 -06:00
FatBoy 94e16bdf3d load mesh data and structure meshes 2024-01-15 20:07:21 -06:00
FatBoy a52f0941b7 load mesh data and structure meshes 2024-01-15 19:47:33 -06:00
FatBoy 840dc83987 load mesh data and structure meshes 2024-01-15 19:43:08 -06:00
FatBoy 5b9d1dd6eb load mesh data and structure meshes 2024-01-15 19:32:49 -06:00
FatBoy 6215e15e82 load mesh data and structure meshes 2024-01-15 19:15:41 -06:00
FatBoy e8a39e596e load mesh data and structure meshes 2024-01-15 19:08:38 -06:00
FatBoy 90b516bbb9 load mesh data and structure meshes 2024-01-15 18:57:18 -06:00
FatBoy 561170eb44 load mesh data and structure meshes 2024-01-14 19:36:54 -06:00
FatBoy 68920f150d load mesh data and structure meshes 2024-01-14 19:30:28 -06:00
FatBoy a54e8c2176 Merge remote-tracking branch 'origin/feature_mesh_collision' into feature_mesh_collision
# Conflicts:
#	src/engine/db/handlers/dbBuildingHandler.java
2024-01-14 19:10:23 -06:00
FatBoy c77f38dec1 load mesh data and structure meshes 2024-01-14 19:10:07 -06:00
FatBoy 5a57677013 Triangle check 2024-01-13 21:34:36 -06:00
FatBoy 306c64d236 Triangle check 2024-01-13 21:27:26 -06:00
FatBoy 0b05e661c7 cleanup and comment 2024-01-13 19:53:50 -06:00
FatBoy a94a400102 cleanup and comment 2024-01-13 19:51:37 -06:00
FatBoy 4bff36d7bb cleanup and comment 2024-01-07 19:14:18 -06:00
FatBoy 969b36e6fd mesh count to building info command 2024-01-07 19:11:29 -06:00
FatBoy 688553e6c6 invert X axis instead of Z axis 2024-01-07 19:07:55 -06:00
FatBoy 4f057ee851 utilize min and max Y values for meshes 2024-01-05 23:32:32 -06:00
FatBoy fd47c90f4f utilize min and max Y values for meshes 2024-01-05 23:03:51 -06:00
FatBoy 253ca2344e add Y axis of building to mesh height 2024-01-05 22:44:58 -06:00
FatBoy 95f09a255e add Y axis of building to mesh height 2024-01-05 22:41:41 -06:00
FatBoy 31ea74f98c reverse Z axis 2024-01-05 22:38:39 -06:00
FatBoy 67c474dbdf collision work 2024-01-05 20:29:11 -06:00
FatBoy c65a713bae collision work 2024-01-05 20:13:27 -06:00
FatBoy e3641872d0 added COllisionManager 2024-01-05 19:28:43 -06:00
FatBoy c25fdf3823 added COllisionManager 2024-01-05 19:21:24 -06:00
FatBoy 7c28efb47c offset cleanup 2024-01-05 19:06:56 -06:00
FatBoy c92316f03e data load fixes 2024-01-03 20:39:18 -06:00
FatBoy e330f190fe data load fixes 2024-01-03 20:11:28 -06:00
FatBoy ae52735131 data load fixes 2024-01-03 20:08:52 -06:00
FatBoy 59025c2585 collision handler 2024-01-03 19:55:12 -06:00
FatBoy 6354eb2893 collision handler 2024-01-03 19:50:40 -06:00
FatBoy 3ad97a7ce3 collision handler 2024-01-03 19:47:30 -06:00
FatBoy f8cbeb4cc6 debug dev command for collision 2024-01-03 19:33:34 -06:00
FatBoy f1e41e47cf database mesh data loaded into hashmaps 2024-01-03 19:25:59 -06:00
MagicBot 78a0416b19 Updated city planting to conform to class refactor project. 2023-12-24 09:44:01 -05:00
MagicBot eb5bc14974 Revert needs new branch. 2023-11-12 11:21:30 -05:00
MagicBot 7e99e8c7a4 Height and width flipped. 2023-11-12 11:13:27 -05:00
MagicBot 9b0f4d5aef Height and width flipped. 2023-11-12 11:09:29 -05:00
MagicBot b58049968f IDA says 256. 2023-11-12 07:36:56 -05:00
MagicBot 9bf0d3f7d1 Devcmd updated. 2023-11-11 07:10:46 -05:00
MagicBot 8300c47e4a Dev cmd updated 2023-11-08 11:59:52 -05:00
MagicBot c73fcc19f2 Dev cmd updated 2023-11-08 11:34:33 -05:00
MagicBot f93573177a Dev cmd updated 2023-11-08 11:27:44 -05:00
MagicBot fe9c6437d8 Dev cmd updated 2023-11-08 11:27:36 -05:00
MagicBot c110ffc4b1 Dev cmd updated 2023-11-02 09:08:28 -04:00
MagicBot 7af63d1519 Nominal after test. 2023-10-25 13:51:54 -04:00
MagicBot 31ba1f2c4c Height from zone center. 2023-10-25 13:46:08 -04:00
MagicBot 33afd13a8c Height from zone center. 2023-10-25 13:36:26 -04:00
MagicBot b341ffacbf Devcmd updated 2023-10-25 13:12:02 -04:00
MagicBot 0d1d1f0f37 Added raw blend value to class 2023-10-25 13:01:21 -04:00
MagicBot 3f59ed48d2 Extra parens removed 2023-10-23 14:13:06 -04:00
MagicBot de832ff497 Long cast needed 2023-10-23 14:12:59 -04:00
MagicBot 1aef82f422 Cleanup work. 2023-10-23 00:43:23 -04:00
MagicBot 065a1c9ceb Cleanup work. 2023-10-23 00:39:12 -04:00
MagicBot ff219ce696 Respawn thread configured 2023-10-23 00:32:59 -04:00
MagicBot 8bd406bcf4 Mobile implements Delayed interface 2023-10-23 00:07:48 -04:00
MagicBot 7b70b680f0 Modified sequencing 2023-10-22 12:29:52 -04:00
MagicBot c3586a70fd Modified sequencing 2023-10-22 12:15:48 -04:00
MagicBot cc7d741681 Modified sequencing 2023-10-22 12:05:06 -04:00
MagicBot ce0dfdabfb Zones with zero blend inherit from parent 2023-10-22 11:48:15 -04:00
MagicBot 737327fa8a Revert after test 2023-10-20 17:52:23 -04:00
MagicBot b1e79284e4 Thread count test 2023-10-20 17:49:29 -04:00
MagicBot 29b5955e9e Peace zone needs to come from zone tree 2023-10-20 17:33:53 -04:00
MagicBot 3986dc0686 Peace zone needs to come from zone tree 2023-10-20 17:22:57 -04:00
MagicBot 59190e33c9 Template added for player cities (0) 2023-10-20 17:09:27 -04:00
MagicBot 091b1a1d5b Start refactor to use templates 2023-10-20 17:01:42 -04:00
MagicBot cb0ba901de fix in column name 2023-10-20 16:37:42 -04:00
MagicBot 14ba9d0f7f SQL statement set. 2023-10-20 16:36:08 -04:00
MagicBot ec9bc437f3 Templates loaded at bootstrap 2023-10-20 16:33:33 -04:00
MagicBot 930aa73657 rs constructor completed 2023-10-20 16:30:41 -04:00
MagicBot cf2bf2dacf DBhandler created for templates 2023-10-20 16:11:55 -04:00
MagicBot 5a8508c16c Template collection created 2023-10-20 15:50:04 -04:00
MagicBot 5bcc0ed84d Template class created 2023-10-20 15:42:06 -04:00
MagicBot 4795a315ad Template now templteID to make room for the actual template. 2023-10-20 15:20:30 -04:00
MagicBot 6559f232a3 Dev command updated 2023-10-20 10:08:39 -04:00
MagicBot db8b33a621 No longer pre-cache players 2023-10-20 09:58:47 -04:00
MagicBot 781a4ee16d Load cities after buildings 2023-10-20 09:50:48 -04:00
MagicBot 7ce94a5166 should never pull directly form cache 2023-10-20 09:48:24 -04:00
MagicBot a487a7bd2f Removed duplicate and unused code 2023-10-20 09:41:24 -04:00
MagicBot f0fedcc049 Cleanup and reformat 2023-10-20 09:39:05 -04:00
MagicBot 3a63f98ac3 Error log added 2023-10-20 08:09:42 -04:00
MagicBot 4c994e6e55 Removed old method 2023-10-20 08:06:40 -04:00
MagicBot 1c93846ed3 Full error is output 2023-10-19 17:01:26 -04:00
MagicBot 3ef444c128 Cleanup in runafterload 2023-10-19 16:53:15 -04:00
MagicBot eaaba8ab0c Refactored assignment. 2023-10-19 16:48:39 -04:00
MagicBot 1daa45d604 New collection utilized 2023-10-19 16:44:29 -04:00
MagicBot cf7e19bfde Patrol points loaded 2023-10-19 16:24:18 -04:00
MagicBot 6a76cc7a29 Patrol points loaded 2023-10-19 16:20:43 -04:00
MagicBot fff16d2211 Comment cleanup 2023-10-19 16:10:53 -04:00
MagicBot a2df7cda22 Inlined populate world method 2023-10-19 08:47:28 -04:00
MagicBot 5858fa4de4 R8 bonus application moved to City 2023-10-19 08:20:28 -04:00
MagicBot fb6ec0caf4 Changed method used to direct bounds 2023-10-19 08:15:32 -04:00
MagicBot 944bcb7e84 Changed method used to direct bounds 2023-10-19 08:15:22 -04:00
MagicBot 4274e6a148 Cleanup of friend and condemned initialization. 2023-10-19 07:59:44 -04:00
FatBoy 5e629e7890 null checks for Building.getFriends() 2023-10-18 20:50:47 -05:00
FatBoy e991a01b50 final touch up 2023-10-18 20:21:26 -05:00
FatBoy 7a1700cec3 finalized 2023-10-18 20:17:26 -05:00
FatBoy 79eb5b9cdf stairs region corrected 2023-10-18 20:03:41 -05:00
FatBoy 7886aa6041 building and region lookup completed 2023-10-18 18:45:50 -05:00
FatBoy b928bedeb6 new region lookup 2023-10-18 18:23:14 -05:00
MagicBot beb2b47162 Collection used and old method deleted. 2023-10-18 13:03:40 -04:00
MagicBot 2cc37481ca New collection created in handled and loaded from db 2023-10-18 12:54:06 -04:00
MagicBot 5ac62d60be Collection used and old handler removed. 2023-10-18 12:38:04 -04:00
MagicBot 6fb1e2e5f1 Load collection from db 2023-10-18 12:31:39 -04:00
MagicBot 385695a610 Load collection from db 2023-10-18 12:24:32 -04:00
MagicBot 838776c471 Method made static and moved to manager. 2023-10-18 11:30:22 -04:00
MagicBot 44743b772b Every building does not need a rebuild mine method. 2023-10-18 11:21:29 -04:00
MagicBot 88f67efd51 Want to fail fast here 2023-10-18 11:04:57 -04:00
MagicBot a04bdc147f Parent zone set 2023-10-18 11:03:08 -04:00
MagicBot 145d9bafa0 Removed unused methods 2023-10-18 10:59:50 -04:00
MagicBot d2c00cce70 Removed unused methods 2023-10-18 10:38:55 -04:00
MagicBot 602f8bc843 Cleanup building initialization 2023-10-18 10:33:58 -04:00
MagicBot 89cb808481 Removed old handlers 2023-10-18 10:23:35 -04:00
MagicBot 4d290c9064 Refactored city planting to use new system. 2023-10-18 09:38:19 -04:00
MagicBot 9ee60c9361 Refactored Zone to new system 2023-10-18 09:24:56 -04:00
MagicBot 77cc91319a Refactored Zone to new system 2023-10-18 09:22:54 -04:00
MagicBot ee4009bf8d Refactored Zone to new system 2023-10-18 09:13:11 -04:00
MagicBot ff1c0bd347 Refactored Zone to new system 2023-10-18 09:08:41 -04:00
MagicBot e1add3c7e6 Refactored Zone to new system 2023-10-18 08:51:46 -04:00
MagicBot bf06734a9b Refactored Zone to new system 2023-10-18 08:42:40 -04:00
MagicBot 5ed21f9b76 Refactored Zone to new system 2023-10-18 08:33:49 -04:00
MagicBot e689cb541a Refactored Zone to new system 2023-10-18 08:25:05 -04:00
MagicBot da32765902 Change to AWO 2023-10-18 08:03:47 -04:00
MagicBot 9392ceda61 Comment cleanup 2023-10-17 17:07:52 -04:00
MagicBot 694b10d3b2 Begin refactor of cities 2023-10-17 16:32:36 -04:00
MagicBot 6b3c64faea Minions loaded for guard captain 2023-10-17 15:09:42 -04:00
MagicBot ab17dd08cd Refactor towards new bootstrap system. 2023-10-17 14:52:13 -04:00
MagicBot f889bcf927 Building handler added 2023-10-17 14:43:28 -04:00
MagicBot 34024c9fb4 New handlers created 2023-10-17 08:45:33 -04:00
MagicBot 9d5e16aa5c Removed debug command 2023-10-17 08:28:18 -04:00
MagicBot f1a2bea67c Pixel values are shorts for memory 2023-10-17 07:56:31 -04:00
FatBoy 5d4192bbcf add offset for runegate teleport regions 2023-10-16 19:56:08 -05:00
FatBoy ea6ea4b0ee teleport work 2023-10-16 19:07:34 -05:00
FatBoy 7f4d47505e teleport cleanup 2023-10-16 18:46:44 -05:00
FatBoy f9a3b17677 teleport cleanup 2023-10-16 15:10:09 -05:00
FatBoy d0374a2dea random delay between mob chase 2023-10-16 15:07:39 -05:00
FatBoy cb89cc17be update lastChase timestamp for mobs 2023-10-16 14:37:17 -05:00
FatBoy d506807a8f 1 second delay for mobs chasing target 2023-10-16 14:33:09 -05:00
FatBoy 1a0fc309f9 remove mob movement delay 2023-10-16 14:23:18 -05:00
FatBoy 5ed7662798 1 second delay for mob movements 2023-10-16 14:13:33 -05:00
FatBoy e3d6a32554 1 second delay for mob movements 2023-10-16 14:02:48 -05:00
FatBoy 6f990d488f region assignment in AbstractCharacter.setLoc 2023-10-16 13:41:18 -05:00
MagicBot 610de198e9 All 0 heightmap for PLANAR 2023-10-15 17:39:02 -04:00
MagicBot 928be0facb Named for context 2023-10-15 17:28:20 -04:00
MagicBot 80799753be Comment cleanup 2023-10-15 17:23:16 -04:00
MagicBot f9d2232a9b Comment cleanup 2023-10-15 17:22:05 -04:00
MagicBot cbd8685d4b Guild zone performance tweak 2023-10-15 16:46:48 -04:00
MagicBot 274cf08dad Comment cleanup 2023-10-15 16:43:20 -04:00
MagicBot 2cbe5f38cd Configuration moved to constructor 2023-10-15 16:40:31 -04:00
MagicBot 3d4058ad01 Height for seafloor 2023-10-15 15:57:58 -04:00
MagicBot 761ec6f4af Blend test 2023-10-15 14:55:19 -04:00
MagicBot 5900068898 Blend test 2023-10-15 14:44:32 -04:00
MagicBot 13f5e3eff2 Comment cleanup 2023-10-15 14:35:16 -04:00
MagicBot db9e950558 Comment cleanup 2023-10-15 14:30:58 -04:00
MagicBot 3f93bf08fb Test raw blend 2023-10-15 14:27:52 -04:00
MagicBot 65eebcbb5d Blend updated 2023-10-15 14:07:54 -04:00
MagicBot 6ed3495780 Blend updated 2023-10-15 13:57:18 -04:00
MagicBot 06049a7135 Dev cmd updated 2023-10-15 13:47:52 -04:00
MagicBot 12e073ca46 Dev cmd updated 2023-10-15 13:47:35 -04:00
MagicBot 4ee4054ab3 Dev cmd updated 2023-10-15 13:46:39 -04:00
MagicBot 11664a9218 Dev cmd updated 2023-10-15 13:42:28 -04:00
MagicBot d414c19904 Set parent zone properly 2023-10-15 13:31:31 -04:00
MagicBot 279a0aed91 Use half extents as offset from center 2023-10-12 07:04:27 -04:00
MagicBot c6e0e36531 Dev command updated 2023-10-12 07:01:11 -04:00
MagicBot 10b9f19036 Dev command updated 2023-10-12 06:51:01 -04:00
MagicBot ad661ea464 Dev command updated 2023-10-12 06:43:02 -04:00
MagicBot affe6b08ab Method is now called 2023-10-12 06:33:22 -04:00
MagicBot 1b2c218e83 property conforms to JSON 2023-10-12 06:19:22 -04:00
MagicBot 9e96add299 Class cleanup 2023-10-12 06:12:40 -04:00
MagicBot 9f9c3ba7f1 Ratios initialized. 2023-10-12 06:08:29 -04:00
MagicBot d15b8a5246 Opposite of 1006300 created as 1006301. 2023-10-12 06:01:55 -04:00
MagicBot c1e1c730bb Opposite of 1006300 created as 1006301. 2023-10-12 05:49:22 -04:00
MagicBot a53c68054d Only one kind of zone. 2023-10-11 17:20:23 -04:00
MagicBot 99a79df02d abs is up the chain a step 2023-10-11 17:17:18 -04:00
MagicBot 1a0f318968 abs is up the chain a step 2023-10-11 17:14:40 -04:00
MagicBot 6ac65c73d5 Method cleanup 2023-10-11 17:04:09 -04:00
MagicBot dc5a778610 Method cleanup 2023-10-11 17:00:53 -04:00
MagicBot 20d9a232cc Method cleanup 2023-10-11 17:00:01 -04:00
MagicBot 280bd61e2a Offset support for blend. 2023-10-11 16:50:52 -04:00
MagicBot dadfc15d39 Class cleanup and comments 2023-10-11 11:36:28 -04:00
MagicBot 1764041272 Class cleanup and comments 2023-10-11 11:34:37 -04:00
MagicBot b9ef4eee63 Class cleanup and comments 2023-10-11 11:32:43 -04:00
MagicBot 823061c699 Improved clamping 2023-10-11 11:23:20 -04:00
MagicBot 6809988e9c bugfix in variable assignment 2023-10-11 11:15:41 -04:00
MagicBot a1a3ea6234 Debug code added 2023-10-11 11:01:04 -04:00
MagicBot 3684296959 Assignment removed for now 2023-10-11 10:53:58 -04:00
MagicBot 68c8d91871 Assignment removed for now 2023-10-11 10:43:44 -04:00
MagicBot 7655b67338 Debug code added 2023-10-11 10:42:04 -04:00
MagicBot 68aef50283 Debug code added 2023-10-11 10:40:27 -04:00
MagicBot 6494e07e9e Test baseline 2023-10-10 12:34:21 -04:00
MagicBot 859de1004e Platform revert 2023-10-10 12:31:43 -04:00
MagicBot 0afc8a2dc5 Platform update 2023-10-10 07:59:42 -04:00
MagicBot f73184ac1e Blend cleanup 2023-10-09 10:56:39 -04:00
MagicBot 52b66be43b Blend cleanup 2023-10-09 10:47:48 -04:00
MagicBot bd208bd1ab Blend cleanup 2023-10-09 09:45:04 -04:00
MagicBot f7952008cd Blend cleanup 2023-10-09 09:35:24 -04:00
MagicBot a0c82d3f3f Blend cleanup 2023-10-09 09:32:20 -04:00
MagicBot dd01fd1688 Proper setting of maxpy 2023-10-09 09:22:41 -04:00
MagicBot d2dc95c169 Dev command updated 2023-10-09 08:44:06 -04:00
MagicBot 53f7165e24 Blend function installed 2023-10-09 07:47:50 -04:00
MagicBot c90a250ba7 Blend function installed 2023-10-09 07:05:54 -04:00
MagicBot e80dd66809 Interpolation cleanup 2023-10-09 06:20:17 -04:00
MagicBot 95558371df Method inlined 2023-10-09 06:16:25 -04:00
MagicBot 085f79cefd Sanity check added 2023-10-09 06:14:06 -04:00
MagicBot a17b9fdd13 Zone extents derived from zone 2023-10-09 06:04:37 -04:00
MagicBot 73b6854266 Map loaded updated 2023-10-09 05:44:38 -04:00
MagicBot fe8d512596 WorldAltitude for seafloor set 2023-10-09 04:51:50 -04:00
MagicBot ef8754c018 WorldAltitude for seafloor set 2023-10-09 04:48:22 -04:00
MagicBot 483ccbff00 WorldAltitude for seafloor set 2023-10-09 04:37:54 -04:00
MagicBot 07f736b8e6 WorldAltitude for seafloor set 2023-10-09 04:32:57 -04:00
MagicBot cd1de763e3 Terrain size set by zone radius 2023-10-09 04:14:51 -04:00
MagicBot d6d4008348 Error trap 2023-10-09 04:11:55 -04:00
MagicBot 4bbbbf9fa2 Error trap 2023-10-08 23:11:59 -04:00
MagicBot a3d29bb8f0 Error trap 2023-10-08 23:05:41 -04:00
MagicBot 0d58aee2fe Terrain type is capitalized 2023-10-08 22:54:40 -04:00
MagicBot bc5d0cc4a9 Terrain zone set in constructor 2023-10-08 22:49:13 -04:00
MagicBot 59c3bea2d6 Error logging added 2023-10-08 22:45:33 -04:00
MagicBot 13163ddb7e Error logging added 2023-10-08 22:44:34 -04:00
MagicBot 02a9256950 Configure player cities and PLANAR 2023-10-08 22:40:31 -04:00
MagicBot d31d6c1f95 Configure player cities and PLANAR 2023-10-08 22:36:26 -04:00
MagicBot bc099e9dc0 Constructor filled in 2023-10-08 21:51:16 -04:00
MagicBot 79bf0523a5 Constructor filled in 2023-10-08 21:50:27 -04:00
MagicBot a0d2ccb5ab Completed partial refactor. 2023-10-08 20:26:37 -04:00
MagicBot df54840a88 Completed partial refactor. 2023-10-08 09:59:13 -04:00
MagicBot 4b62517d99 Partial refactor. 2023-10-08 09:49:49 -04:00
MagicBot 0ce9ec3ae2 Output conforms with client 2023-10-08 09:32:08 -04:00
MagicBot 5279fa8fbe Dev command updated 2023-10-08 09:22:53 -04:00
MagicBot 0d75e6db9b Start terrain refactor 2023-10-08 09:18:43 -04:00
MagicBot ffb541a12e Prepare for terrain 2023-10-08 09:09:50 -04:00
MagicBot 5fdaa11367 Prepare for terrain 2023-10-08 09:04:15 -04:00
MagicBot 6b339da061 Count propagated 2023-10-07 21:03:47 -04:00
MagicBot f454fb5e1c Need float value 2023-10-07 20:55:11 -04:00
MagicBot 5db8c47aa8 Clamp value at pole 2023-10-07 20:47:35 -04:00
MagicBot e7571f3e83 Audit of zone loc 2023-10-07 20:43:17 -04:00
MagicBot d9b513e88c cell count cached 2023-10-07 20:32:08 -04:00
MagicBot 7dcde390cd Flip Flop 2023-10-07 20:19:30 -04:00
MagicBot 6a750f4eb2 Unused methods removed 2023-10-07 20:04:26 -04:00
MagicBot c6d24d25cc Method cleanup 2023-10-07 13:57:20 -04:00
MagicBot c19ec913cb Disable blend until after refactor. 2023-09-21 14:39:37 -04:00
MagicBot 438ea04a1a Comment cleanup 2023-09-20 17:26:00 -04:00
MagicBot d7044c1663 Depth less one 2023-09-20 17:24:41 -04:00
MagicBot 3497d275a8 File reformat 2023-09-20 17:21:34 -04:00
MagicBot 6fd61889a8 byte array to save memory. 2023-09-20 17:20:54 -04:00
MagicBot 85983954de Conform to database 2023-09-20 16:28:26 -04:00
MagicBot 1e9eec2c48 Heightmap is now an integer. 2023-09-20 16:24:00 -04:00
MagicBot bd97745ed1 class and table schema now conform to JSON 2023-09-20 16:07:50 -04:00
MagicBot 34d450fecf class and table schema now conform to JSON 2023-09-20 16:06:57 -04:00
MagicBot be107c0858 class and table schema now conform to JSON 2023-09-20 16:05:57 -04:00
MagicBot 8289786099 class and table schema now conform to JSON 2023-09-20 16:03:55 -04:00
MagicBot 56f159d50a class and table schema now conform to JSON 2023-09-20 16:01:01 -04:00
MagicBot 61961bab05 class and table schema now conform to JSON 2023-09-20 16:00:16 -04:00
MagicBot e0387dce00 class and table schema now conform to JSON 2023-09-20 15:53:41 -04:00
MagicBot 46b3db033b Inlined empty getters 2023-09-20 15:43:01 -04:00
MagicBot bf9fdae58b Method moved to manager. 2023-09-20 14:31:48 -04:00
MagicBot 7b8cafc8ac Cleanup of interpolation method 2023-09-20 14:20:22 -04:00
MagicBot 7793fab5d2 Unnecessary initialization. 2023-09-20 14:14:55 -04:00
MagicBot 1ddcda5c5d Logging to console 2023-09-20 14:04:55 -04:00
MagicBot 9714393538 Pixel data loaded from TARGA files 2023-09-20 13:59:32 -04:00
MagicBot d46f369599 Unused variables 2023-09-20 13:49:27 -04:00
MagicBot 2dfd2a53c2 Testing image reader 2023-09-20 13:37:43 -04:00
MagicBot e3675ec9a4 Testing image reader 2023-09-20 13:26:54 -04:00
MagicBot cb2ed0c766 Testing image reader 2023-09-20 13:23:02 -04:00
MagicBot 6638fdcaff Framework to load pixel data 2023-09-20 13:06:18 -04:00
MagicBot d0b4634429 Framework to load pixel data 2023-09-20 12:46:41 -04:00
MagicBot 1fdf1f1339 New collection defined for pixel data 2023-09-20 11:59:43 -04:00
MagicBot 6290c6d0af Start separate PLANAR from TARGA 2023-09-20 11:40:29 -04:00
MagicBot 26a3ea4b18 Release bounds after usage. 2023-09-20 11:38:39 -04:00
MagicBot c7b2245005 Unused methods removed 2023-09-20 11:35:39 -04:00
MagicBot 5ba06796b1 Interpolating from adjusted altitudes. 2023-09-18 03:19:00 -04:00
MagicBot e359b1dfdf Interpolating world altitude 2023-09-18 02:11:38 -04:00
MagicBot cbc8216fe0 Blender 2023-09-18 00:05:53 -04:00
MagicBot da238b9986 Cleanup in bounds configuration 2023-09-17 23:56:45 -04:00
MagicBot 897ddfe77a Bounds must be set before setting parent. 2023-09-17 23:53:06 -04:00
MagicBot 80f2db794f Bounds must be set before setting parent. 2023-09-17 23:46:00 -04:00
MagicBot 913a2601d5 Update to blend logic. 2023-09-17 14:02:17 -04:00
MagicBot 40c27eef79 Update to blend logic. 2023-09-17 14:00:00 -04:00
MagicBot df45e00fbd 255 to normalize 2023-09-17 13:39:42 -04:00
MagicBot a323f1ffb7 max based on min blend 2023-09-17 13:30:16 -04:00
MagicBot ea6092db8a max based on min blend 2023-09-17 13:28:23 -04:00
MagicBot 8c6eb48876 max based on min blend 2023-09-17 13:25:15 -04:00
MagicBot 37d2f8a8ad DevCmd output updated 2023-09-17 13:11:29 -04:00
MagicBot f18acf3e68 DevCmd output updated 2023-09-17 13:08:51 -04:00
MagicBot 3fb08ca2c3 Visibility promotion for a data class 2023-09-17 12:53:56 -04:00
MagicBot 83be09d643 Comment and name cleanup 2023-09-17 12:49:30 -04:00
MagicBot 6de8249fb0 Devcmd output updated. 2023-09-17 12:44:37 -04:00
MagicBot 013ddcff66 heightmap blend configuration completed. 2023-09-17 12:25:07 -04:00
MagicBot 8ece4caf1c value is halfExtent 2023-09-17 12:23:06 -04:00
MagicBot a94b12e8cd Correction to blend configuration. 2023-09-17 12:15:21 -04:00
MagicBot c38103068e Correction to blend configuration. 2023-09-17 12:13:46 -04:00
MagicBot f8caaf0e99 Correction to blend configuration. 2023-09-17 12:07:43 -04:00
MagicBot ee809ddb37 clamping cleaned up. 2023-09-17 12:01:13 -04:00
MagicBot 227bd0523e clamping cleaned up. 2023-09-17 11:59:46 -04:00
MagicBot c096b29521 parameter ordering fixed. 2023-09-17 11:57:24 -04:00
MagicBot 6a0520b126 Blend lerp implemented. 2023-09-17 11:54:57 -04:00
MagicBot 240373898a Preparation for blend lerp insertion. 2023-09-17 08:08:28 -04:00
MagicBot d33ad0cdef Preparation for blend lerp insertion. 2023-09-17 08:03:50 -04:00
MagicBot a3a3070158 Blending configuration setup in SetParent() 2023-09-17 07:42:46 -04:00
MagicBot b717c3d550 Starting work to sync heightmap model with Shadowbane. 2023-09-16 16:03:22 -04:00
MagicBot 9aa5820ac2 Cleanup of getWorldHeight() 2023-09-16 13:18:36 -04:00
MagicBot 1ac65dd9bd Tightened clamping. 2023-09-16 08:31:04 -04:00
MagicBot 797a6951a8 Tightened clamping. 2023-09-16 08:28:20 -04:00
MagicBot 7268de6e1e Test of raw heightmaps 2023-09-16 08:06:31 -04:00
MagicBot fc602ce9f4 Test of raw heightmaps 2023-09-16 08:04:49 -04:00
MagicBot 403bff27b4 Test of raw heightmaps 2023-09-16 08:01:46 -04:00
MagicBot 44b9ba911d Indices added to command output. 2023-09-15 17:29:51 -04:00
MagicBot c24f8fc85b Login check modified for testing. 2023-09-15 14:23:34 -04:00
MagicBot 75c56cbeee Devcmd output updated. 2023-09-14 14:11:26 -04:00
MagicBot 15f42c9658 Devcmd output updated. 2023-09-14 13:54:22 -04:00
MagicBot 525d0c21bb Devcmd output updated. 2023-09-14 13:41:07 -04:00
MagicBot cbf05cfe5b Devcmd output updated. 2023-09-14 13:30:46 -04:00
MagicBot aaa506a581 Divisor testing. 2023-09-14 13:21:02 -04:00
MagicBot a2fbfad00e Revert initialize. 2023-09-14 13:07:32 -04:00
MagicBot 031c52e25a Divisor test. 2023-09-14 13:03:06 -04:00
MagicBot 693dfd827c Updated dev cmd output 2023-09-14 13:01:22 -04:00
MagicBot d26a2d35bf Multiple not divide 2023-09-14 12:39:31 -04:00
MagicBot 9839de128c Variable initialized. 2023-09-14 12:38:47 -04:00
MagicBot 12872ee51e Variable initialized. 2023-09-14 12:30:54 -04:00
MagicBot 2af08d6823 Reformat file. 2023-09-14 12:29:26 -04:00
MagicBot f646075311 Static method to save memory. 2023-09-14 12:28:36 -04:00
MagicBot dfca767476 Multiple not divide. 2023-09-14 12:25:18 -04:00
MagicBot fd7b5952c2 Dev command updated 2023-09-14 12:21:12 -04:00
MagicBot 4b46eddc47 Dev command updated 2023-09-14 12:09:50 -04:00
MagicBot e26121177f World altitude set in setparent. 2023-09-14 12:07:08 -04:00
MagicBot 91eb0c314f SeAudit command created 2023-09-14 10:14:31 -04:00
MagicBot 1d7a2d4eae Added sea level info to command. 2023-09-14 10:09:10 -04:00
MagicBot e4235d4d75 Bugfix in setparent. 2023-09-14 09:13:02 -04:00
FatBoy 41a83115be safehold guard exclusion from equipment dropping 2023-09-13 22:34:57 -05:00
FatBoy 3ce887cb34 NPC are immune to all 2023-09-13 22:30:24 -05:00
FatBoy 874eb6189e NPC apply runes 2023-09-13 22:24:10 -05:00
FatBoy 5c5c491597 debug code 2023-09-13 22:10:22 -05:00
FatBoy ff78c1443c null check 2023-09-13 22:04:23 -05:00
FatBoy cdc1c2d776 region assignment 2023-09-13 21:58:20 -05:00
FatBoy a004c247ab abstract character cleanup 2023-09-13 21:57:17 -05:00
FatBoy 048e90fb8f NPC all apply "shopkeeper" rune 2023-09-13 21:56:18 -05:00
FatBoy c1498145e6 NPC rune work 2023-09-13 21:45:15 -05:00
FatBoy 7654d5183a region lookup and height offset for AbstractCharacters when setLoc is called 2023-09-13 21:28:20 -05:00
FatBoy 9b7fc0a93b region height work 2023-09-13 21:07:57 -05:00
FatBoy 200318ddcf add region height to world height in setLoc 2023-09-13 20:48:02 -05:00
FatBoy 1fdd0a1b32 initialize runes array list for NPC 2023-09-13 20:45:21 -05:00
FatBoy 8869772fa4 print effects command 2023-09-13 20:34:48 -05:00
FatBoy 96bc894962 print runes command 2023-09-13 20:27:38 -05:00
FatBoy 5a9f5f2eca NPCs apply runes from set 2023-09-13 20:22:56 -05:00
FatBoy bd9dbcbb42 NPCs load rune sets 2023-09-13 20:12:07 -05:00
FatBoy f8269bb764 character runes moved form PlayerCharacter to AbstractCharacter 2023-09-13 20:06:12 -05:00
FatBoy c215047c00 teleport method removed form PLayerCharacter to use AbstractCharacter.teleport instead 2023-09-13 20:00:23 -05:00
FatBoy a313e3f364 setRegion removal 2023-09-13 19:56:54 -05:00
FatBoy b34be1184e null region assignment 2023-09-13 19:53:13 -05:00
FatBoy e23c5527da null region assignment 2023-09-13 19:52:17 -05:00
FatBoy 847e62dd27 setLoc now handles region assignment 2023-09-13 19:51:39 -05:00
MagicBot f5d83aa259 Class cleanup of bonus code and unused methods. 2023-09-13 09:38:10 -04:00
MagicBot 4a5c0ae5a0 Cities don't actually have a location. They are a property of a zone. Let's start here. 2023-09-13 09:29:42 -04:00
MagicBot b4a4323906 Minor formatting cleanup. 2023-09-13 09:24:40 -04:00
MagicBot 48fc5af5f7 Removed unused variables from class. 2023-09-13 07:33:02 -04:00
MagicBot a1753a28ec Player cities write correct offset. 2023-09-13 07:29:29 -04:00
MagicBot fa4039cf63 Add y offset to zone altitude. 2023-09-12 16:25:46 -04:00
MagicBot 4b0814c0a1 Add y offset to zone altitude. 2023-09-12 16:24:47 -04:00
MagicBot 78d0b06b36 Revert for testing. 2023-09-12 16:22:41 -04:00
MagicBot 426bdf5df3 Removed yoffset from world altitude. 2023-09-12 16:13:27 -04:00
MagicBot 5dbad7ebd0 Player cities set to white. 2023-09-12 15:33:52 -04:00
MagicBot 6ef33c5b7f Update to world altitude calculation 2023-09-12 15:27:00 -04:00
MagicBot 3737a6eace Sea level logic updated. 2023-09-12 15:18:09 -04:00
MagicBot 967e129724 Sea level logic updated. 2023-09-12 15:09:52 -04:00
MagicBot e9d549377e Sea level logic updated. 2023-09-12 15:06:26 -04:00
MagicBot 924b8af827 Sea level logic updated. 2023-09-12 14:57:47 -04:00
MagicBot 045ee73b61 rework of world altitude calculation. 2023-09-12 14:51:04 -04:00
MagicBot 5d9d13ce07 Any argument rebuilds world altitude. 2023-09-12 13:06:46 -04:00
MagicBot 5a1347ec50 Devcmd updated 2023-09-12 13:01:32 -04:00
MagicBot c705f45856 Devcmd updated 2023-09-12 12:38:20 -04:00
MagicBot 83fc129d05 Dev command output update. 2023-09-11 15:59:08 -04:00
MagicBot d7cde3a77f Grid flip testing 2023-09-11 15:41:44 -04:00
MagicBot afb1ad8e94 Grid flip testing 2023-09-11 15:36:59 -04:00
MagicBot 15a79ee9bd devcmd output updated with grid. 2023-09-11 14:37:16 -04:00
MagicBot 68794c170b Removed usless method: added grid to cmd output. 2023-09-11 14:30:14 -04:00
MagicBot a9d84749ba Removed worthless command. 2023-09-11 14:26:06 -04:00
MagicBot dd5fc323ef bugfix in array loading 2023-09-11 14:06:22 -04:00
MagicBot cf1547d077 DevCmd Updated 2023-09-11 13:57:05 -04:00
MagicBot 9664c99e06 DevCmd Updated 2023-09-11 13:50:56 -04:00
MagicBot 17b7fb6999 Unused method 2023-09-11 13:48:16 -04:00
MagicBot 21a4db8a81 Pixels set to 0 2023-09-11 13:40:47 -04:00
MagicBot eabdabcfcd No insane bucket widths. 2023-09-11 12:38:46 -04:00
MagicBot c548383a4c Should not be putting empty maps into the collection with id 0. 2023-09-11 12:35:58 -04:00
MagicBot 7337f4be1e DevCmd update. 2023-09-11 12:14:42 -04:00
MagicBot d84f223b9d DevCmd update. 2023-09-11 12:08:39 -04:00
MagicBot 5431112186 DevCmd update. 2023-09-11 11:35:53 -04:00
MagicBot ff743151c6 DevCmd update. 2023-09-11 11:25:28 -04:00
MagicBot b923392b53 DevCmd update. 2023-09-11 11:18:22 -04:00
MagicBot 15d272c621 DevCmd update. 2023-09-11 11:17:34 -04:00
MagicBot eefa50b2c3 DevCmd update. 2023-09-11 11:14:55 -04:00
MagicBot ecc7a152f7 DevCmd update. 2023-09-11 11:08:03 -04:00
MagicBot 7bf31f9a47 Rework of class interface. 2023-09-11 11:01:09 -04:00
MagicBot 7dc970ff53 Rework of dev command; junk deleted. 2023-09-11 10:50:01 -04:00
FatBoy 97d71ec361 move to point handler revert 2023-09-11 01:36:45 -05:00
FatBoy 003b939d33 Move to point message variable naming and handler cleanup 2023-09-10 19:37:46 -05:00
FatBoy 9989cbff24 pc.teleport uneeded 2023-09-10 17:20:30 -05:00
FatBoy 426ef989f8 can no longer run to invalid targets 2023-09-10 16:45:17 -05:00
FatBoy ca6e079053 fresh start 2023-09-10 15:51:25 -05:00
FatBoy 13644fd308 use target from message in move to point 2023-09-10 15:02:26 -05:00
FatBoy 1ec76ae3fc use target from message in move to point 2023-09-10 14:58:56 -05:00
FatBoy 51d75146cc NPC added to attack message handler switch 2023-09-10 14:28:32 -05:00
FatBoy bc4222646d combat target usage 2023-09-10 14:12:01 -05:00
FatBoy c3e206e3b1 null check 2023-09-10 14:09:48 -05:00
FatBoy 04147e11cc logic for moveToPoint message handler 2023-09-10 14:08:54 -05:00
FatBoy 545cb4cddf null check for building pulled 2023-09-10 13:40:19 -05:00
FatBoy 0f948d4e2a removed redundant setCombatTarget 2023-09-10 13:39:27 -05:00
FatBoy 5fb3e0fe14 switch for target type in attack message handler 2023-09-10 13:38:07 -05:00
MagicBot fb87dfd91e TargetType declared. 2023-09-10 14:33:04 -04:00
FatBoy be8967b05f null set for target 2023-09-10 13:28:46 -05:00
FatBoy 8acfff7faa null check for target 2023-09-10 13:26:28 -05:00
FatBoy 18e1f4bd28 early exits for attack message handler 2023-09-10 13:25:08 -05:00
MagicBot 74f88a6643 Unused variable removed 2023-09-10 14:04:48 -04:00
FatBoy 47fe764cb0 early exits for attack message handler 2023-09-10 12:58:24 -05:00
MagicBot 9e53770e6c Handler added to protocol class. 2023-09-10 13:55:16 -04:00
MagicBot a9cc001791 Handler added to protocol class. 2023-09-10 13:53:12 -04:00
MagicBot c24913d124 Handler filled in with logic. 2023-09-10 13:52:04 -04:00
MagicBot 63bf0b6070 Handler created for AttackMsg 2023-09-10 13:43:28 -04:00
FatBoy 50792327a4 moveToPoint attack handling 2023-09-10 12:31:39 -05:00
FatBoy 46e67be8ca player character attacks added to city outlaws 2023-09-10 11:57:52 -05:00
FatBoy e7c3ba5eba guards and siege engines ignore idle state with no players loaded 2023-09-09 22:30:45 -05:00
FatBoy ea86ab2300 guards will revert cmbat target to null if its a player and is no longer loaded 2023-09-09 22:23:25 -05:00
FatBoy 501e8c937f guards use city player memory to determine whether they go idle or not 2023-09-09 22:10:10 -05:00
FatBoy cae5c36d84 guards will aggro siege equipment not belonging to the guild 2023-09-09 22:01:59 -05:00
FatBoy 1b92fa76e1 characters that attack city friendly buildings are added to cityOutlaws 2023-09-09 21:48:22 -05:00
FatBoy bbdb683061 players who attack buildinsg added to cityOutlaw list 2023-09-09 21:43:29 -05:00
FatBoy 2d04547c74 display seeInvis level in aiInfo command 2023-09-09 21:19:29 -05:00
FatBoy 5192c801f7 CombatUtilities cleanup 2023-09-09 20:56:19 -05:00
FatBoy d966d50bd5 removed duplicate variables in MobBase 2023-09-09 20:40:52 -05:00
FatBoy 7e20db33f2 final guard stat revisions 2023-09-09 20:37:47 -05:00
FatBoy 669ee7215b added range modification for guards 2023-09-09 20:11:00 -05:00
FatBoy 6fa00a43a4 removed unused method 2023-09-09 20:06:33 -05:00
FatBoy 4edf740179 finished modifications for guards 2023-09-09 19:57:17 -05:00
FatBoy c7abb4c920 stance modifiers for guards 2023-09-09 19:41:32 -05:00
FatBoy df3964110a stances for guards 2023-09-09 19:23:46 -05:00
FatBoy 96231260bc consolidated all guards to GuardLogic 2023-09-09 10:37:40 -05:00
FatBoy 967303d2de outlaw and hate value moved to modifyHealth 2023-09-09 10:20:25 -05:00
FatBoy 955481773d wall archer early exit for canCast 2023-09-09 09:52:47 -05:00
FatBoy d66a7049e8 guard walking bug fix 2023-09-09 09:35:03 -05:00
MagicBot e73b8d2826 Harden against null 2023-09-09 10:20:20 -04:00
MagicBot ea23003807 Hirelings removed from zone mob set 2023-09-09 10:16:36 -04:00
MagicBot 23f41f8ae7 Minions always have offset not determined by captain being alive. 2023-09-09 09:26:55 -04:00
MagicBot 3f416f83d3 Patrol points only set once. 2023-09-09 09:11:43 -04:00
MagicBot 931d1992b6 Patrol points are reset each patrol. 2023-09-09 09:10:08 -04:00
MagicBot fd927a7052 New method implemented. 2023-09-09 08:58:41 -04:00
MagicBot dd46224afe New method implemented. 2023-09-09 08:44:00 -04:00
MagicBot be2b29ccc7 New method implemented. 2023-09-09 08:38:00 -04:00
MagicBot c93e3bc947 Update to ordering of logic 2023-09-09 08:34:09 -04:00
MagicBot 7d49395c41 New method implemented. 2023-09-09 08:31:20 -04:00
MagicBot f4c9e6d7b8 Remove hireling method defined in manager. 2023-09-09 08:28:03 -04:00
MagicBot b7a907c8c8 db method to support removing all minions 2023-09-09 08:04:56 -04:00
MagicBot 36485a0f01 Formation enforced when captain is dead. 2023-09-08 12:44:36 -04:00
MagicBot efec1b4444 Load data only. 2023-09-08 12:39:04 -04:00
MagicBot bdf6500260 Outlaw moved before guild check. 2023-09-07 14:14:21 -04:00
MagicBot db4eb0579e Aggro code removed from check to send mob home. 2023-09-07 13:37:32 -04:00
MagicBot 76f33534d4 Captains force march minions 2023-09-07 13:09:25 -04:00
MagicBot 39fea5bc2f Captains order minions to patrol 2023-09-07 12:42:43 -04:00
MagicBot 660d5c1270 Captains order minions to patrol 2023-09-07 12:41:20 -04:00
MagicBot 781e2fc9b2 Comment adjusted 2023-09-07 12:27:23 -04:00
MagicBot c2a2464fe8 Errant delimiter removed. 2023-09-07 12:25:52 -04:00
MagicBot beb3c15eb3 Miniond patrol on own if captain is dead. 2023-09-07 12:24:45 -04:00
MagicBot 553010bb7b Minions get marching orders from captain 2023-09-07 12:07:39 -04:00
MagicBot 8d12bbf453 Formation offset for minions. 2023-09-07 11:48:42 -04:00
MagicBot fa7588826a Pets set to not alive when dismissing. 2023-09-07 11:15:30 -04:00
MagicBot 332f191e19 Merged switch cases. 2023-09-07 10:56:46 -04:00
MagicBot 8151382a6b Patrol points inherited from barracks not captain. 2023-09-07 10:49:07 -04:00
MagicBot ae44a21be1 Duplicate range check removed. 2023-09-07 10:40:27 -04:00
MagicBot b0ff0995de Start consolidation of guard logic 2023-09-07 10:37:09 -04:00
MagicBot e711095ecd Start consolidation of guard logic 2023-09-07 10:36:18 -04:00
MagicBot 08de97a2a8 Guild check removed from outlaw condition. 2023-09-07 09:55:55 -04:00
MagicBot 5eb6302d2a Null check is made before this method call. 2023-09-05 15:56:49 -04:00
MagicBot 2e346ae7fd Rework of combat deference to captain. 2023-09-05 15:51:14 -04:00
MagicBot 1285d12915 Consolidated cast methods. 2023-09-05 14:25:24 -04:00
MagicBot 8b5cb9258e dd roll removed 2023-09-05 14:09:48 -04:00
MagicBot ef3e3a0392 .contains check needed. 2023-09-05 13:43:09 -04:00
MagicBot 8fca6572f9 Typo in comment fixed. 2023-09-05 13:10:17 -04:00
MagicBot 33eaf0e583 Outlaws added to aiinfo. 2023-09-05 13:04:56 -04:00
MagicBot 16acd1c08c Simplify logic; variable is provided. 2023-09-05 12:55:12 -04:00
MagicBot a8e8804ce3 Attacking guard flags you as an outlaw. 2023-09-05 12:34:46 -04:00
MagicBot b8c0f997f6 Fix typo in thread name. 2023-09-05 12:30:47 -04:00
MagicBot 11e63f38b1 Update to mob retaliate logic. 2023-09-05 12:19:50 -04:00
MagicBot ff36d8f3db Modification to minion retaliate. 2023-09-05 08:27:34 -04:00
MagicBot 975542d8af sql column update. 2023-09-04 15:21:04 -04:00
MagicBot d71a9415b4 Integer object not int signature. 2023-09-04 15:09:51 -04:00
MagicBot e948da95b5 Column name updated. 2023-09-04 14:58:13 -04:00
MagicBot 9a6510c320 Minions now use copyonwrite collection. Slot agnostic. 2023-09-04 14:50:59 -04:00
MagicBot 57ff1ede97 Name is all that's needed. 2023-09-04 14:16:36 -04:00
MagicBot 7c0f2563f7 Already added to collection at this point. 2023-09-04 13:09:32 -04:00
FatBoy d11a954b40 remove test block 2023-09-03 20:41:21 -05:00
FatBoy f354339af1 null checks 2023-09-03 20:38:48 -05:00
FatBoy 89658bb77a null checks 2023-09-03 20:28:17 -05:00
FatBoy 1ff0238b6e skill loading bypass for guards 2023-09-03 20:22:01 -05:00
FatBoy e777434d57 Mob specific rune skill loading 2023-09-03 20:10:57 -05:00
FatBoy ee6efc30a3 rune skill loading broken into static method in NPCManager 2023-09-03 19:52:16 -05:00
FatBoy 0758bb5f38 SkillsBase are now cached when missing for mobs 2023-09-03 19:44:33 -05:00
FatBoy 299d5725a6 lookup using name 2023-09-03 19:31:04 -05:00
FatBoy d7c9b31ec7 indentation and comment 2023-09-03 19:24:34 -05:00
FatBoy 6c78bee5c1 null check 2023-09-03 19:24:06 -05:00
FatBoy dba0cbd5f9 skill type not name used 2023-09-03 19:22:28 -05:00
FatBoy 0752e780f2 mobs load skills 2023-09-03 19:19:18 -05:00
MagicBot c43919ce01 Level loaded into object. 2023-09-03 09:48:37 -04:00
MagicBot 0d95510b72 captain uuid added to aiInfoCmd 2023-09-03 09:15:20 -04:00
MagicBot 60fb2571a2 Support for loading of skill adjustment map. 2023-09-03 08:18:48 -04:00
MagicBot 90cbe90492 Merge remote-tracking branch 'origin/mobile-effects' into magicbox-1.5.2 2023-09-03 07:33:50 -04:00
FatBoy 95c203b0ed load and apply mobbaseSkill 2023-09-02 20:39:36 -05:00
FatBoy 449c5c5c77 infrastructure for mob skills loading 2023-09-02 20:29:03 -05:00
FatBoy 9aff208403 guard captains to move tot heir first patrol point right away 2023-09-02 19:43:40 -05:00
FatBoy 4318849127 minion relatiate handled inside retaliate function 2023-09-02 19:34:08 -05:00
FatBoy 29e8cdf699 attacking guard minion will no longer be ignored 2023-09-02 19:23:33 -05:00
MagicBot 4427dbdcad Fix in exception for werwolf/werebear (magic numbers) 2023-09-02 16:28:16 -04:00
MagicBot af4c3819b9 contract added to aiInfoCmd 2023-09-02 16:18:05 -04:00
MagicBot 39379e1ac0 Sight check moved out of cancast. 2023-09-02 16:04:40 -04:00
MagicBot 71eeb3f6b8 Variable hidden elevated to abschar. 2023-09-02 15:57:23 -04:00
MagicBot d409ef49af Can cast added to aiinfo. 2023-09-02 15:44:42 -04:00
MagicBot e7a80e9280 Comment cleanup 2023-09-02 15:33:12 -04:00
MagicBot 65c2d2ea0b Logic cleanup when dealing with contracts. 2023-09-02 15:30:10 -04:00
MagicBot 92666dca21 Invis check precedes power check. 2023-09-02 15:25:19 -04:00
MagicBot 3e1a79c248 AI info dev command updated. 2023-09-02 15:11:17 -04:00
MagicBot 73a1ce083a Unused method removed. 2023-09-02 15:00:38 -04:00
MagicBot 22dacebc5e Override unnecessary. 2023-09-02 15:00:06 -04:00
MagicBot 80d0948e24 Contract power handling now additive. 2023-09-02 14:04:47 -04:00
MagicBot 58b427b977 Contract support added to mobile ai when gathering powers. 2023-09-02 13:34:26 -04:00
MagicBot a4cab3565a Value cannot be null. Set early in runafterload. 2023-09-02 13:16:34 -04:00
MagicBot 205c9580e3 sql column name fix. 2023-09-02 12:52:55 -04:00
MagicBot 70a0ed135b Refactored mob powers to rune powers. Now uses rune_id to call into system which is derived in the getter to support minions. 2023-09-02 12:47:04 -04:00
FatBoy f556181d77 guardlist serialization displays correct minion rank 2023-09-01 22:15:29 -05:00
FatBoy d48e26904e revert last commit 2023-09-01 22:06:21 -05:00
FatBoy 19232ac405 archers added to human guards as minions 2023-09-01 22:01:09 -05:00
FatBoy 9ee2ccc8af werebear and werewolf guard can use powers 2023-09-01 21:48:57 -05:00
FatBoy 7079bb6a63 resist loading refactored as static method to NPCManager 2023-09-01 21:39:34 -05:00
FatBoy 0ab5827ee5 mobs to load equipment resists 2023-09-01 21:34:48 -05:00
FatBoy c5443f622c utilization and assignment of aiAgentType 2023-09-01 20:57:09 -05:00
FatBoy e4aa276cca cleanup old code 2023-09-01 20:42:33 -05:00
FatBoy 90ff2d679e create and use applyMobbaseEffects method, remove old unused methods 2023-09-01 20:39:31 -05:00
FatBoy da26c35d5a mobbase loads effectsList 2023-09-01 20:36:07 -05:00
MagicBot 779e3da74e Cleanup of clear minion logic. 2023-09-01 14:33:33 -04:00
MagicBot e358c08773 Removed msg from handler. 2023-09-01 14:23:55 -04:00
MagicBot 2945fa3a47 Class reformat and removal of try block. 2023-09-01 14:17:07 -04:00
MagicBot ab1541e741 Class not needed on login server. 2023-09-01 14:09:48 -04:00
MagicBot 3aeaa709a5 Comment cleanup 2023-09-01 14:07:00 -04:00
MagicBot 91e627df6b AI moved to top of runafterload. 2023-09-01 14:05:50 -04:00
MagicBot d0795e9e1c Rework of agent type init in runafterload. Only used for 2 instances from disk. 2023-09-01 13:57:58 -04:00
MagicBot 0e12dd4874 Contract powers loaded first to preserve ordering. 2023-09-01 12:57:20 -04:00
MagicBot 25c0e48181 Loot bypass now uses agent type. 2023-09-01 12:55:33 -04:00
MagicBot 0d43c3620d Value is set earlier. 2023-09-01 12:50:57 -04:00
MagicBot 2f6137f8df Minion agent type set properly. 2023-09-01 12:38:23 -04:00
FatBoy 2843b86a93 Moved agent type to top of constructor. 2023-09-01 12:29:06 -04:00
MagicBot 8235de07ff Updated output of devcmd. 2023-08-31 14:00:34 -04:00
MagicBot e2f9a4c7f0 Guard minions inherit powers from captain. 2023-08-31 13:57:46 -04:00
MagicBot 55c6e3cf93 Refactored out duplicate power collection. 2023-08-31 13:42:15 -04:00
MagicBot 11c154e564 Assignment fix and comment cleanup. 2023-08-31 08:58:55 -04:00
MagicBot 7fc0d27c3c Siege engine agent type set properly. 2023-08-31 08:31:48 -04:00
MagicBot 1ac76cfcd8 isPlayerguard refactored to derive from agenttype. 2023-08-31 08:13:37 -04:00
MagicBot c8ed04aaaf Refactor to separate persistence and write fsm to table. 2023-08-31 08:03:30 -04:00
MagicBot 6641651f3c Unused method removed. 2023-08-31 07:27:03 -04:00
MagicBot dbf164bfb2 bonus code removal 2023-08-30 15:47:08 -04:00
MagicBot 8a617c3008 Siege minion spawn time set to 15m. 2023-08-30 15:33:55 -04:00
FatBoy a50a2430ba hate value for chants to affect mobs in range 2023-08-29 21:49:02 -05:00
FatBoy 5c3c552288 usage of AIAgentType for default patrol points 2023-08-29 21:17:44 -05:00
FatBoy 69fdddfc71 hate value fix 2023-08-29 21:01:00 -05:00
FatBoy db5b988275 usage of AIAgentType for pet checks in run after load 2023-08-29 20:18:05 -05:00
FatBoy 4284757035 pet level set in run after load removed 2023-08-29 20:16:00 -05:00
FatBoy b93a47acc0 pet death and dismissal fix 2023-08-29 20:12:48 -05:00
MagicBot d59f9857ce Cleanup in pet minion 2023-08-28 00:56:13 -04:00
FatBoy 8ce212b74b Merge remote-tracking branch 'origin/mob-refactor2' into mob-refactor2 2023-08-27 23:53:12 -05:00
FatBoy e78aea5735 Assign patrol points added as static method to NPC manager 2023-08-27 23:52:40 -05:00
MagicBot 9a3c5c3f40 Siege minion assigned UUID. 2023-08-28 00:46:39 -04:00
FatBoy 60ca3f9c34 remove siege minion 2023-08-27 23:42:04 -05:00
FatBoy e7e740dff1 blocked player character specific block in minion training message handler 2023-08-27 23:23:17 -05:00
MagicBot 8343a98d77 Minion added to map after runafterload. 2023-08-28 00:08:35 -04:00
MagicBot 5862039a00 Minion added to map after runafterload. 2023-08-28 00:07:40 -04:00
MagicBot 8af989b75f Fix is patrol logic bloc conditional. 2023-08-27 23:55:02 -04:00
MagicBot 08d0e5ff75 Logic isn't needed here. 2023-08-27 23:32:23 -04:00
MagicBot 5196d10e5c Logic isn't needed here. 2023-08-27 23:31:32 -04:00
MagicBot 3392ec463d Removed unused methods. 2023-08-27 23:29:45 -04:00
MagicBot 33529404cf Logic fix in siege minions. 2023-08-27 23:25:44 -04:00
MagicBot 00e7a36013 Logic fix in siege minions. 2023-08-27 23:22:28 -04:00
FatBoy 3060b394ab removed siegeminion map from NPC 2023-08-27 22:10:13 -05:00
MagicBot a43d9022fe Siege engine slot override. 2023-08-27 22:57:11 -04:00
FatBoy 6abdc68ca5 removed un-needed cast to player character for pets 2023-08-27 21:46:44 -05:00
FatBoy 61c66b0e96 trebs slot in proper locations 2023-08-27 21:38:31 -05:00
FatBoy 36cc23457a optimized slot for siege engines 2023-08-27 21:26:00 -05:00
FatBoy d573b238de refactored mob get/set owner 2023-08-27 21:04:34 -05:00
FatBoy 8afe25fe85 siege minions added to arty captain minion map 2023-08-27 20:50:13 -05:00
MagicBot f80647ff0d Spawn time set to 15s for debug. 2023-08-27 21:42:58 -04:00
MagicBot 7e64cbabf8 Update to slotting logic. 2023-08-27 21:30:57 -04:00
MagicBot 14a06410ae Update to slotting logic. 2023-08-27 21:25:43 -04:00
MagicBot 85c2a4f4f0 Add all as hirelings 2023-08-27 21:20:00 -04:00
FatBoy da9e211ec7 SiegeEngine enum and logic added 2023-08-27 20:05:18 -05:00
MagicBot a81070c471 Pet level += 20 to conform to 24.3 2023-08-26 15:47:10 -04:00
MagicBot e3ad7efa4f Method renamed for new convention. 2023-08-26 15:35:42 -04:00
MagicBot a4dafd7155 Unused variable in signature. 2023-08-26 15:34:27 -04:00
MagicBot 645aec853e Bindloc not adjusted for pets. 2023-08-26 15:21:50 -04:00
MagicBot d8d5e4a3c4 Name set to default. 2023-08-26 15:19:17 -04:00
MagicBot 7a48c04057 Mobbase set properly. 2023-08-26 15:10:14 -04:00
MagicBot 64aaaa707e Behaviour type set for pets. 2023-08-26 15:00:43 -04:00
MagicBot 445d40dc5f Bonus code removed. 2023-08-26 14:59:25 -04:00
MagicBot ebdcb531f2 AI methods moved to ai class. 2023-08-26 14:54:43 -04:00
MagicBot c9cdb891d6 Cleanup of ownerNPC mess. 2023-08-26 14:52:18 -04:00
MagicBot f5c6c002a8 Unused method removed. 2023-08-26 13:53:32 -04:00
MagicBot d171c6bb9a Unused method removed. 2023-08-26 13:47:41 -04:00
MagicBot 1c81a4faed Wall archers static reverted. 2023-08-26 13:38:09 -04:00
MagicBot e7d1d5cb71 Constructor removed. 2023-08-26 12:38:54 -04:00
MagicBot 060d831d50 Comment for clarity. 2023-08-26 12:37:28 -04:00
MagicBot 316bd6dd01 Siege engines use slot system. 2023-08-26 12:35:14 -04:00
MagicBot 34081e5903 Ordinal comparison fix. 2023-08-26 12:21:47 -04:00
MagicBot e2d843b65e Signature refactor. 2023-08-26 12:03:33 -04:00
MagicBot a796f5fe4b More siege engine work. 2023-08-26 11:55:18 -04:00
MagicBot 51ee41c773 use of SiegeEngine Behaviour Type 2023-08-26 11:19:36 -04:00
MagicBot 7e5ed3efe5 sqrMagnitude not sqrRoot 2023-08-26 11:09:58 -04:00
MagicBot 8dd25ac315 Minions inherit patrol points form barracks. 2023-08-26 11:06:48 -04:00
MagicBot 1cdaa58e7a Wall archers set to static grid type. 2023-08-26 10:11:13 -04:00
MagicBot fa3aa24a3d Update to minion building/location mechanic. 2023-08-26 09:41:58 -04:00
MagicBot 091431d95b Dynamic set in all constructors. 2023-08-26 09:31:10 -04:00
MagicBot 1ecf0122ab Unused variable removed. 2023-08-26 09:29:12 -04:00
MagicBot 79980a1725 NoID constructor removed. 2023-08-26 06:45:34 -04:00
MagicBot 8badcc3f6e Refactored out redundant stat-xyz variables. 2023-08-26 06:24:05 -04:00
MagicBot 4d6e57257c Unused methods removed. 2023-08-26 06:19:03 -04:00
MagicBot a7a93b8500 Tweak to bindloc for minions. 2023-08-25 17:05:46 -04:00
MagicBot 85cc34fb4c AIinfo updated. 2023-08-25 16:57:25 -04:00
MagicBot 772a996b6e Tweak to behavior type setup. 2023-08-25 16:49:26 -04:00
MagicBot e67eff822d Propagate guardedCity. 2023-08-25 16:44:45 -04:00
MagicBot c39ed6120f Cleanup of bind/loc logic. 2023-08-25 16:19:04 -04:00
MagicBot c38f4e6543 Mask only needs be set once. 2023-08-25 16:01:18 -04:00
MagicBot 098433b697 Needs contract null check 2023-08-25 15:46:09 -04:00
MagicBot c8e20c905b Add to cache before setloc 2023-08-25 15:37:02 -04:00
MagicBot bd2446ba0a Minion uuid set pre configure 2023-08-25 15:34:47 -04:00
MagicBot c179e4aaf3 Don't override level or name for minions. 2023-08-25 15:29:42 -04:00
MagicBot 2f8de2a919 Worthless collection only used in 2 places. 2023-08-25 15:23:02 -04:00
MagicBot 338110973d Mobbase cannot be null. 2023-08-25 15:19:25 -04:00
MagicBot 3c9c4495bc playerGuard = true. 2023-08-25 15:14:33 -04:00
MagicBot 93476f782c Bind loc not overwritten. 2023-08-25 15:03:37 -04:00
MagicBot 3aec6ee578 More minion setup work. 2023-08-25 14:45:47 -04:00
MagicBot 3bca76d4c8 Setloc to spawn minion. 2023-08-25 14:38:09 -04:00
MagicBot b9d6f35aac Unused variable. 2023-08-25 14:35:02 -04:00
MagicBot 9b6959414a More flushing out minion support. 2023-08-25 14:33:43 -04:00
MagicBot 400dd6aa5e More granular error reporting. 2023-08-25 14:08:43 -04:00
MagicBot 14af2f6efd Minion spawning re-enabled for refactoring. 2023-08-25 14:01:47 -04:00
MagicBot 0a2de9e0d5 Contract handling cleanup. 2023-08-25 13:41:22 -04:00
MagicBot 89bfad78a6 Contract handling cleanup. 2023-08-25 13:31:56 -04:00
MagicBot 52486fa278 Contract handling cleanup. 2023-08-25 13:24:07 -04:00
MagicBot dc0e14eb21 AI added earlier in sequence for availability. 2023-08-25 13:07:47 -04:00
MagicBot 70278374e7 manager init moved to the top of method. 2023-08-25 12:57:21 -04:00
MagicBot ac3588c76a manager init moved to the top of method. 2023-08-25 12:54:03 -04:00
MagicBot ab335aef2a Enums are fragile. 2023-08-25 12:32:36 -04:00
MagicBot 719c855bdb Cleanup of inventoryManager usage. 2023-08-25 12:27:58 -04:00
MagicBot f283e50018 Disabled minions for now. 2023-08-25 12:18:36 -04:00
MagicBot 99b952ee28 Refactor towards new constructor. 2023-08-25 12:12:54 -04:00
MagicBot 24639b62c0 Refactor towards new constructor. 2023-08-25 12:11:50 -04:00
MagicBot 573cc531bf Refactor towards new constructor. 2023-08-25 11:59:59 -04:00
MagicBot 29e24bae93 Unused constructor removed. 2023-08-25 11:37:56 -04:00
MagicBot 22e4cc07c0 Separate pet and siege behaviour types. 2023-08-25 11:26:09 -04:00
MagicBot 9264347698 Minions inherit enemy/notenemy from captain. 2023-08-25 11:24:15 -04:00
MagicBot 579c26ac59 InitializeMob removed. 2023-08-23 13:19:57 -04:00
MagicBot ef577dd313 Removed catch to propagate error. 2023-08-23 13:03:59 -04:00
MagicBot 62c7e52487 Starting to whittle away at initmob method. 2023-08-23 13:01:36 -04:00
MagicBot 3534ac6477 Starting to whittle away at initmob method. 2023-08-23 12:48:34 -04:00
MagicBot 1738f7b311 Starting to whittle away at initmob method. 2023-08-23 12:38:46 -04:00
MagicBot eb25caec81 Object creation moved out of rs const. 2023-08-23 12:24:43 -04:00
MagicBot a6c60e2c04 Merge remote-tracking branch 'origin/master' into mobile-cleanup 2023-08-22 07:50:46 -04:00
MagicBot adafbdf6d3 Duplicate building and building ID values. 2023-08-21 17:20:57 -04:00
MagicBot 7eab14938d Exception for siege when slotting. 2023-08-21 17:11:20 -04:00
MagicBot 039e55673b Exception for siege when slotting. 2023-08-21 17:00:27 -04:00
MagicBot ec3a9b6cb4 Minions don't have contracts. 2023-08-21 16:50:15 -04:00
MagicBot 17a6494b2b Unused code. 2023-08-21 16:41:21 -04:00
MagicBot 0b05c7074f Slot all agents but true mobiles. 2023-08-21 16:37:52 -04:00
MagicBot 876ccc7cbf New constructor created. 2023-08-21 16:12:06 -04:00
MagicBot bdf14b8f24 Ordinal comparisons refactored. 2023-08-21 15:37:21 -04:00
MagicBot 43375a6f5b Only mobiles with contracts can be slotted. 2023-08-21 15:22:08 -04:00
MagicBot e00328ae13 Siege pets use slotting mechanic. 2023-08-21 15:09:10 -04:00
MagicBot 07c553294b Mobiles use new slotting mechanic. 2023-08-21 15:04:32 -04:00
134 changed files with 4235 additions and 5340 deletions
@@ -0,0 +1,27 @@
package engine.CollisionEngine;
import engine.math.Vector3f;
import engine.objects.Building;
import java.awt.*;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.HashMap;
public class CollisionManager {
public static HashMap<Integer, ArrayList<MeshData>> structure_meshes;
public static HashMap<Integer,ArrayList<Triangle>> mesh_triangles;
public static boolean CollisionDetected(Building building, Line2D travelLine, float charHeight, float charY){
if(building.buildingRect != null)
if(!travelLine.intersects(building.buildingRect) && !building.buildingRect.contains(travelLine.getP1()) && !building.buildingRect.contains(travelLine.getP2()))
return false;
for(Mesh mesh : building.buildingMeshes)
if(mesh.collides(travelLine))
return true;
return false;
}
}
+87
View File
@@ -0,0 +1,87 @@
package engine.CollisionEngine;
import engine.gameManager.BuildingManager;
import engine.math.Vector2f;
import engine.math.Vector3f;
import engine.math.Vector3fImmutable;
import engine.objects.Building;
import org.pmw.tinylog.Logger;
import java.awt.geom.Line2D;
import java.awt.geom.Path2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
public class Mesh {
public ArrayList<Triangle> triangles;
public Vector3f mesh_end_point;
public Vector3f mesh_ref_point;
public Vector3f mesh_location;
public float mesh_max_y;
public float mesh_min_y;
public Vector3f mesh_scale;
public int mesh_id;
public int parent_prop_id;
public int parent_structure_id;
public int parentUUID;
public Rectangle2D.Float mesh_bounds;
public MeshData meshData;
public void update(){
this.BakeTriangles();
}
public Vector3f getLocation(){
Building parentBuilding = BuildingManager.getBuilding(this.parentUUID);
int degrees = (int)Math.toDegrees(parentBuilding.getBounds().getQuaternion().angleY);
Vector3f parentLoc = new Vector3f(parentBuilding.loc.x,parentBuilding.loc.y,parentBuilding.loc.z);
Vector3f offsetLoc = parentLoc.add(this.meshData.loc);
Vector3f rotatedPoint = Vector3f.rotateAroundPoint(offsetLoc,parentLoc,degrees);
return rotatedPoint;
}
public void BakeTriangles(){
if(CollisionManager.mesh_triangles.containsKey(this.meshData.meshID) == false){
Logger.error("Failed To Bake Triangles For Mesh: " + this.meshData.meshID);
return;
}
Building parentBuilding = BuildingManager.getBuilding(this.parentUUID);
int degrees = (int)Math.toDegrees(parentBuilding.getBounds().getQuaternion().angleY);
Vector3f parentLoc = new Vector3f(parentBuilding.loc.x,parentBuilding.loc.y,parentBuilding.loc.z);
Vector3f offsetLoc = parentLoc.add(this.meshData.loc);
for(Triangle tri : CollisionManager.mesh_triangles.get(this.meshData.meshID)) {
Triangle newTri = new Triangle();
Vector3f Point1 = offsetLoc.add(new Vector3f(tri.point1.x,offsetLoc.y,tri.point1.y));
Vector3f Point2 = offsetLoc.add(new Vector3f(tri.point2.x,offsetLoc.y,tri.point2.y));
Vector3f Point3 = offsetLoc.add(new Vector3f(tri.point3.x,offsetLoc.y,tri.point3.y));
Vector3f rotatedPoint1 = Vector3f.rotateAroundPoint(Point1,offsetLoc,degrees);
Vector3f rotatedPoint2 = Vector3f.rotateAroundPoint(Point2,offsetLoc,degrees);
Vector3f rotatedPoint3 = Vector3f.rotateAroundPoint(Point3,offsetLoc,degrees);
newTri.point1 = new Point2D.Float(rotatedPoint1.x,rotatedPoint1.z);
newTri.point2 = new Point2D.Float(rotatedPoint2.x,rotatedPoint2.z);
newTri.point3 = new Point2D.Float(rotatedPoint3.x,rotatedPoint3.z);
newTri.sides = new ArrayList<>();
newTri.sides.add(new Line2D.Float(newTri.point1,newTri.point2));
newTri.sides.add(new Line2D.Float(newTri.point2,newTri.point3));
newTri.sides.add(new Line2D.Float(newTri.point3,newTri.point1));
this.triangles.add(newTri);
}
}
public Boolean collides(Line2D line){
for(Triangle tri : this.triangles)
if(tri.collides(line))
return true;
return false;
}
}
+14
View File
@@ -0,0 +1,14 @@
package engine.CollisionEngine;
import engine.math.Vector3f;
public class MeshData {
public int propID;
public int meshID;
public Vector3f loc;
public Vector3f scale;
public Vector3f refPoint;
public Vector3f endPoint;
public float maxY;
public float minY;
}
+21
View File
@@ -0,0 +1,21 @@
package engine.CollisionEngine;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.util.ArrayList;
public class Triangle {
public Point2D.Float point1;
public Point2D.Float point2;
public Point2D.Float point3;
public ArrayList<Line2D> sides;
public boolean collides(Line2D line)
{
for(Line2D side : sides)
if(side.intersectsLine(line))
return true;
return false;
}
}
+15 -13
View File
@@ -469,7 +469,7 @@ public class Enum {
// 14001 does not have a banestone to bind at // 14001 does not have a banestone to bind at
if (ruinZone.getLoadNum() == 14001) if (ruinZone.templateID == 14001)
spawnLocation = Vector3fImmutable.getRandomPointOnCircle(ruinZone.getLoc(), 30); spawnLocation = Vector3fImmutable.getRandomPointOnCircle(ruinZone.getLoc(), 30);
else else
spawnLocation = Vector3fImmutable.getRandomPointOnCircle(ruinZone.getLoc() spawnLocation = Vector3fImmutable.getRandomPointOnCircle(ruinZone.getLoc()
@@ -2310,10 +2310,10 @@ public class Enum {
ZONE(875), ZONE(875),
PLACEMENT(876); PLACEMENT(876);
public final float extents; public final float halfExtents;
CityBoundsType(float extents) { CityBoundsType(float halfExtents) {
this.extents = extents; this.halfExtents = halfExtents;
} }
} }
@@ -2822,7 +2822,6 @@ public class Enum {
public enum MobBehaviourType { public enum MobBehaviourType {
None(null, false, false, false, false, false), None(null, false, false, false, false, false),
//Power
Power(null, false, true, true, true, false), Power(null, false, true, true, true, false),
PowerHelpee(Power, false, true, true, false, true), PowerHelpee(Power, false, true, true, false, true),
PowerHelpeeWimpy(Power, true, false, true, false, false), PowerHelpeeWimpy(Power, true, false, true, false, false),
@@ -2847,6 +2846,7 @@ public class Enum {
//Independent Types //Independent Types
SimpleStandingGuard(null, false, false, false, false, false), SimpleStandingGuard(null, false, false, false, false, false),
Pet1(null, false, false, true, false, false), Pet1(null, false, false, true, false, false),
SiegeEngine(null, false, false, false, false, false),
Simple(null, false, false, true, false, false), Simple(null, false, false, true, false, false),
Helpee(null, false, true, true, false, true), Helpee(null, false, true, true, false, true),
HelpeeWimpy(null, true, false, true, false, false), HelpeeWimpy(null, true, false, true, false, false),
@@ -2857,13 +2857,12 @@ public class Enum {
HamletGuard(null, false, true, false, false, false), HamletGuard(null, false, true, false, false, false),
AggroWanderer(null, false, false, true, false, false); AggroWanderer(null, false, false, true, false, false);
private static HashMap<Integer, MobBehaviourType> _behaviourTypes = new HashMap<>(); public final MobBehaviourType BehaviourHelperType;
public MobBehaviourType BehaviourHelperType; public final boolean isWimpy;
public boolean isWimpy; public final boolean isAgressive;
public boolean isAgressive; public final boolean canRoam;
public boolean canRoam; public final boolean callsForHelp;
public boolean callsForHelp; public final boolean respondsToCallForHelp;
public boolean respondsToCallForHelp;
MobBehaviourType(MobBehaviourType helpeebehaviourType, boolean wimpy, boolean agressive, boolean canroam, boolean callsforhelp, boolean respondstocallforhelp) { MobBehaviourType(MobBehaviourType helpeebehaviourType, boolean wimpy, boolean agressive, boolean canroam, boolean callsforhelp, boolean respondstocallforhelp) {
this.BehaviourHelperType = helpeebehaviourType; this.BehaviourHelperType = helpeebehaviourType;
@@ -2878,8 +2877,11 @@ public class Enum {
public enum AIAgentType { public enum AIAgentType {
MOBILE, MOBILE,
GUARDCAPTAIN,
GUARDMINION,
GUARDWALLARCHER,
PET, PET,
CHARMED, CHARMED,
GUARD; SIEGEENGINE;
} }
} }
@@ -1,706 +0,0 @@
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
package engine.InterestManagement;
import engine.Enum;
import engine.gameManager.ConfigManager;
import engine.gameManager.DbManager;
import engine.gameManager.ZoneManager;
import engine.math.Vector2f;
import engine.math.Vector3fImmutable;
import engine.objects.AbstractWorldObject;
import engine.objects.Zone;
import engine.util.MapLoader;
import org.pmw.tinylog.Logger;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
public class HeightMap {
// Class variables
// Heightmap data for all zones.
public static final HashMap<Integer, HeightMap> heightmapByLoadNum = new HashMap<>();
// Bootstrap Tracking
public static int heightMapsCreated = 0;
public static HeightMap PlayerCityHeightMap;
// Heightmap data for this heightmap
public BufferedImage heightmapImage;
private int heightMapID;
private int maxHeight;
private int fullExtentsX;
private int fullExtentsY;
private float bucketWidthX;
private float bucketWidthY;
private int zoneLoadID;
private float seaLevel = 0;
private float outsetX;
private float outsetZ;
private int[][] pixelColorValues;
public HeightMap(ResultSet rs) throws SQLException {
this.heightMapID = rs.getInt("heightMapID");
this.maxHeight = rs.getInt("maxHeight");
int halfExtentsX = rs.getInt("xRadius");
int halfExtentsY = rs.getInt("zRadius");
this.zoneLoadID = rs.getInt("zoneLoadID");
this.seaLevel = rs.getFloat("seaLevel");
this.outsetX = rs.getFloat("outsetX");
this.outsetZ = rs.getFloat("outsetZ");
// Cache the full extents to avoid the calculation
this.fullExtentsX = halfExtentsX * 2;
this.fullExtentsY = halfExtentsY * 2;
this.heightmapImage = null;
File imageFile = new File(ConfigManager.DEFAULT_DATA_DIR + "heightmaps/" + this.heightMapID + ".bmp");
// early exit if no image file was found. Will log in caller.
if (!imageFile.exists())
return;
// load the heightmap image.
try {
this.heightmapImage = ImageIO.read(imageFile);
} catch (IOException e) {
Logger.error("***Error loading heightmap data for heightmap " + this.heightMapID + e.toString());
}
// We needed to flip the image as OpenGL and Shadowbane both use the bottom left corner as origin.
this.heightmapImage = MapLoader.flipImage(this.heightmapImage);
// Calculate the data we do not load from table
float numOfBuckets = this.heightmapImage.getWidth() - 1;
float calculatedWidth = this.fullExtentsX / numOfBuckets;
this.bucketWidthX = calculatedWidth;
this.bucketWidthY = this.bucketWidthX; // This makes no sense.
// Generate pixel array from image data
generatePixelData();
HeightMap.heightmapByLoadNum.put(this.zoneLoadID, this);
heightMapsCreated++;
}
//Created for PlayerCities
public HeightMap() {
this.heightMapID = 999999;
this.maxHeight = 5; // for real...
int halfExtentsX = (int) Enum.CityBoundsType.ZONE.extents;
int halfExtentsY = (int) Enum.CityBoundsType.ZONE.extents;
this.zoneLoadID = 0;
this.seaLevel = 0;
this.outsetX = 128;
this.outsetZ = 128;
// Cache the full extents to avoid the calculation
this.fullExtentsX = halfExtentsX * 2;
this.fullExtentsY = halfExtentsY * 2;
// load the heightmap image.
// We needed to flip the image as OpenGL and Shadowbane both use the bottom left corner as origin.
this.heightmapImage = null;
// Calculate the data we do not load from table
this.bucketWidthX = 1;
this.bucketWidthY = 1;
this.pixelColorValues = new int[this.fullExtentsX + 1][this.fullExtentsY + 1];
for (int y = 0; y <= this.fullExtentsY; y++) {
for (int x = 0; x <= this.fullExtentsX; x++) {
pixelColorValues[x][y] = 255;
}
}
HeightMap.heightmapByLoadNum.put(this.zoneLoadID, this);
}
public HeightMap(Zone zone) {
this.heightMapID = 999999;
this.maxHeight = 0;
int halfExtentsX = (int) zone.getBounds().getHalfExtents().x;
int halfExtentsY = (int) zone.getBounds().getHalfExtents().y;
this.zoneLoadID = 0;
this.seaLevel = 0;
this.outsetX = 0;
this.outsetZ = 0;
// Cache the full extents to avoid the calculation
this.fullExtentsX = halfExtentsX * 2;
this.fullExtentsY = halfExtentsY * 2;
// We needed to flip the image as OpenGL and Shadowbane both use the bottom left corner as origin.
this.heightmapImage = null;
// Calculate the data we do not load from table
this.bucketWidthX = 1;
this.bucketWidthY = 1;
this.pixelColorValues = new int[this.fullExtentsX + 1][this.fullExtentsY + 1];
for (int y = 0; y <= this.fullExtentsY; y++) {
for (int x = 0; x <= this.fullExtentsX; x++) {
pixelColorValues[x][y] = 255;
}
}
HeightMap.heightmapByLoadNum.put(this.zoneLoadID, this);
}
public static void GeneratePlayerCityHeightMap() {
HeightMap.PlayerCityHeightMap = new HeightMap();
}
public static void GenerateCustomHeightMap(Zone zone) {
HeightMap heightMap = new HeightMap(zone);
HeightMap.heightmapByLoadNum.put(zone.getLoadNum(), heightMap);
}
public static Zone getNextZoneWithTerrain(Zone zone) {
Zone nextZone = zone;
if (zone.getHeightMap() != null)
return zone;
if (zone.equals(ZoneManager.getSeaFloor()))
return zone;
while (nextZone.getHeightMap() == null)
nextZone = nextZone.getParent();
return nextZone;
}
public static float getWorldHeight(AbstractWorldObject worldObject) {
Vector2f parentLoc = new Vector2f(-1, -1);
Zone currentZone = ZoneManager.findSmallestZone(worldObject.getLoc());
if (currentZone == null)
return worldObject.getAltitude();
currentZone = getNextZoneWithTerrain(currentZone);
if (currentZone == ZoneManager.getSeaFloor())
return currentZone.getAbsY() + worldObject.getAltitude();
Zone parentZone = getNextZoneWithTerrain(currentZone.getParent());
HeightMap heightMap = currentZone.getHeightMap();
Vector2f zoneLoc = ZoneManager.worldToZoneSpace(worldObject.getLoc(), currentZone);
Vector3fImmutable localLocFromCenter = ZoneManager.worldToLocal(worldObject.getLoc(), currentZone);
if ((parentZone != null) && (parentZone.getHeightMap() != null))
parentLoc = ZoneManager.worldToZoneSpace(worldObject.getLoc(), parentZone);
float interaltitude = currentZone.getHeightMap().getInterpolatedTerrainHeight(zoneLoc);
float worldAltitude = currentZone.getWorldAltitude();
float realWorldAltitude = interaltitude + worldAltitude;
//OUTSET
if (parentZone != null) {
float parentXRadius = currentZone.getBounds().getHalfExtents().x;
float parentZRadius = currentZone.getBounds().getHalfExtents().y;
float offsetX = Math.abs((localLocFromCenter.x / parentXRadius));
float offsetZ = Math.abs((localLocFromCenter.z / parentZRadius));
float bucketScaleX = heightMap.outsetX / parentXRadius;
float bucketScaleZ = heightMap.outsetZ / parentZRadius;
if (bucketScaleX <= 0.40000001)
bucketScaleX = heightMap.outsetZ / parentXRadius;
if (bucketScaleX > 0.40000001)
bucketScaleX = 0.40000001f;
if (bucketScaleZ <= 0.40000001)
bucketScaleZ = heightMap.outsetX / parentZRadius;
if (bucketScaleZ > 0.40000001)
bucketScaleZ = 0.40000001f;
float outsideGridSizeX = 1 - bucketScaleX; //32/256
float outsideGridSizeZ = 1 - bucketScaleZ;
float weight;
double scale;
if (offsetX > outsideGridSizeX && offsetX > offsetZ) {
weight = (offsetX - outsideGridSizeX) / bucketScaleX;
scale = Math.atan2((.5 - weight) * 3.1415927, 1);
float scaleChild = (float) ((scale + 1) * .5);
float scaleParent = 1 - scaleChild;
float parentAltitude = parentZone.getHeightMap().getInterpolatedTerrainHeight(parentLoc);
float parentCenterAltitude = parentZone.getHeightMap().getInterpolatedTerrainHeight(ZoneManager.worldToZoneSpace(currentZone.getLoc(), parentZone));
parentCenterAltitude += currentZone.getYCoord();
parentCenterAltitude += interaltitude;
float firstScale = parentAltitude * scaleParent;
float secondScale = parentCenterAltitude * scaleChild;
float outsetALt = firstScale + secondScale;
outsetALt += currentZone.getParent().getWorldAltitude();
realWorldAltitude = outsetALt;
} else if (offsetZ > outsideGridSizeZ) {
weight = (offsetZ - outsideGridSizeZ) / bucketScaleZ;
scale = Math.atan2((.5 - weight) * 3.1415927, 1);
float scaleChild = (float) ((scale + 1) * .5);
float scaleParent = 1 - scaleChild;
float parentAltitude = parentZone.getHeightMap().getInterpolatedTerrainHeight(parentLoc);
float parentCenterAltitude = parentZone.getHeightMap().getInterpolatedTerrainHeight(ZoneManager.worldToZoneSpace(currentZone.getLoc(), parentZone));
parentCenterAltitude += currentZone.getYCoord();
parentCenterAltitude += interaltitude;
float firstScale = parentAltitude * scaleParent;
float secondScale = parentCenterAltitude * scaleChild;
float outsetALt = firstScale + secondScale;
outsetALt += currentZone.getParent().getWorldAltitude();
realWorldAltitude = outsetALt;
}
}
return realWorldAltitude;
}
public static float getWorldHeight(Vector3fImmutable worldLoc) {
Vector2f parentLoc = new Vector2f(-1, -1);
Zone currentZone = ZoneManager.findSmallestZone(worldLoc);
if (currentZone == null)
return 0;
currentZone = getNextZoneWithTerrain(currentZone);
if (currentZone == ZoneManager.getSeaFloor())
return currentZone.getAbsY();
Zone parentZone = getNextZoneWithTerrain(currentZone.getParent());
HeightMap heightMap = currentZone.getHeightMap();
if ((heightMap == null) || (currentZone == ZoneManager.getSeaFloor()))
return currentZone.getAbsY();
Vector2f zoneLoc = ZoneManager.worldToZoneSpace(worldLoc, currentZone);
Vector3fImmutable localLocFromCenter = ZoneManager.worldToLocal(worldLoc, currentZone);
if ((parentZone != null) && (parentZone.getHeightMap() != null))
parentLoc = ZoneManager.worldToZoneSpace(worldLoc, parentZone);
float interaltitude = currentZone.getHeightMap().getInterpolatedTerrainHeight(zoneLoc);
float worldAltitude = currentZone.getWorldAltitude();
float realWorldAltitude = interaltitude + worldAltitude;
//OUTSET
if (parentZone != null) {
// if (currentZone.getHeightMap() != null && parentZone.getHeightMap() != null && parentZone.getParent() != null && parentZone.getParent().getHeightMap() != null)
// return realWorldAltitude;
float parentXRadius = currentZone.getBounds().getHalfExtents().x;
float parentZRadius = currentZone.getBounds().getHalfExtents().y;
float offsetX = Math.abs((localLocFromCenter.x / parentXRadius));
float offsetZ = Math.abs((localLocFromCenter.z / parentZRadius));
float bucketScaleX = heightMap.outsetX / parentXRadius;
float bucketScaleZ = heightMap.outsetZ / parentZRadius;
float outsideGridSizeX = 1 - bucketScaleX; //32/256
float outsideGridSizeZ = 1 - bucketScaleZ;
float weight;
double scale;
if (offsetX > outsideGridSizeX && offsetX > offsetZ) {
weight = (offsetX - outsideGridSizeX) / bucketScaleX;
scale = Math.atan2((.5 - weight) * 3.1415927, 1);
float scaleChild = (float) ((scale + 1) * .5);
float scaleParent = 1 - scaleChild;
float parentAltitude = parentZone.getHeightMap().getInterpolatedTerrainHeight(parentLoc);
float parentCenterAltitude = parentZone.getHeightMap().getInterpolatedTerrainHeight(ZoneManager.worldToZoneSpace(currentZone.getLoc(), parentZone));
parentCenterAltitude += currentZone.getYCoord();
parentCenterAltitude += interaltitude;
float firstScale = parentAltitude * scaleParent;
float secondScale = parentCenterAltitude * scaleChild;
float outsetALt = firstScale + secondScale;
outsetALt += currentZone.getParent().getWorldAltitude();
realWorldAltitude = outsetALt;
} else if (offsetZ > outsideGridSizeZ) {
weight = (offsetZ - outsideGridSizeZ) / bucketScaleZ;
scale = Math.atan2((.5 - weight) * 3.1415927, 1);
float scaleChild = (float) ((scale + 1) * .5);
float scaleParent = 1 - scaleChild;
float parentAltitude = parentZone.getHeightMap().getInterpolatedTerrainHeight(parentLoc);
float parentCenterAltitude = parentZone.getHeightMap().getInterpolatedTerrainHeight(ZoneManager.worldToZoneSpace(currentZone.getLoc(), parentZone));
parentCenterAltitude += currentZone.getYCoord();
parentCenterAltitude += interaltitude;
float firstScale = parentAltitude * scaleParent;
float secondScale = parentCenterAltitude * scaleChild;
float outsetALt = firstScale + secondScale;
outsetALt += currentZone.getParent().getWorldAltitude();
realWorldAltitude = outsetALt;
}
}
return realWorldAltitude;
}
public static float getOutsetHeight(float interpolatedAltitude, Zone zone, Vector3fImmutable worldLocation) {
Vector2f parentLoc;
float outsetALt = 0;
if (zone.getParent() == null || zone.getParent().getHeightMap() == null)
return interpolatedAltitude + zone.getWorldAltitude();
if (zone.getParent() != null && zone.getParent().getHeightMap() != null) {
parentLoc = ZoneManager.worldToZoneSpace(worldLocation, zone.getParent());
Vector3fImmutable localLocFromCenter = ZoneManager.worldToLocal(worldLocation, zone);
float parentXRadius = zone.getBounds().getHalfExtents().x;
float parentZRadius = zone.getBounds().getHalfExtents().y;
float bucketScaleX = zone.getHeightMap().outsetX / parentXRadius;
float bucketScaleZ = zone.getHeightMap().outsetZ / parentZRadius;
float outsideGridSizeX = 1 - bucketScaleX; //32/256
float outsideGridSizeZ = 1 - bucketScaleZ;
float weight;
double scale;
float offsetX = Math.abs((localLocFromCenter.x / parentXRadius));
float offsetZ = Math.abs((localLocFromCenter.z / parentZRadius));
if (offsetX > outsideGridSizeX && offsetX > offsetZ) {
weight = (offsetX - outsideGridSizeX) / bucketScaleX;
scale = Math.atan2((.5 - weight) * 3.1415927, 1);
float scaleChild = (float) ((scale + 1) * .5);
float scaleParent = 1 - scaleChild;
float parentAltitude = zone.getParent().getHeightMap().getInterpolatedTerrainHeight(parentLoc);
float parentCenterAltitude = zone.getParent().getHeightMap().getInterpolatedTerrainHeight(ZoneManager.worldToZoneSpace(zone.getLoc(), zone.getParent()));
parentCenterAltitude += zone.getYCoord();
parentCenterAltitude += interpolatedAltitude;
float firstScale = parentAltitude * scaleParent;
float secondScale = parentCenterAltitude * scaleChild;
outsetALt = firstScale + secondScale;
outsetALt += zone.getParent().getAbsY();
} else if (offsetZ > outsideGridSizeZ) {
weight = (offsetZ - outsideGridSizeZ) / bucketScaleZ;
scale = Math.atan2((.5 - weight) * 3.1415927, 1);
float scaleChild = (float) ((scale + 1) * .5);
float scaleParent = 1 - scaleChild;
float parentAltitude = zone.getParent().getHeightMap().getInterpolatedTerrainHeight(parentLoc);
float parentCenterAltitude = zone.getHeightMap().getInterpolatedTerrainHeight(ZoneManager.worldToZoneSpace(zone.getLoc(), zone));
parentCenterAltitude += zone.getYCoord();
parentCenterAltitude += interpolatedAltitude;
float firstScale = parentAltitude * scaleParent;
float secondScale = parentCenterAltitude * scaleChild;
outsetALt = firstScale + secondScale;
outsetALt += zone.getParent().getAbsY();
}
}
return outsetALt;
}
public static Vector2f getGridOffset(Vector2f gridSquare) {
int floorX = (int) gridSquare.x;
int floorY = (int) gridSquare.y;
return new Vector2f(gridSquare.x - floorX, gridSquare.y - floorY);
}
public static void loadAlHeightMaps() {
// Load the heightmaps into staging hashmap keyed by HashMapID
DbManager.HeightMapQueries.LOAD_ALL_HEIGHTMAPS();
//generate static player city heightmap.
HeightMap.GeneratePlayerCityHeightMap();
// Clear all heightmap image data as it's no longer needed.
for (HeightMap heightMap : HeightMap.heightmapByLoadNum.values()) {
heightMap.heightmapImage = null;
}
Logger.info(HeightMap.heightmapByLoadNum.size() + " Heightmaps cached.");
}
public static boolean isLocUnderwater(Vector3fImmutable currentLoc) {
float localAltitude = HeightMap.getWorldHeight(currentLoc);
Zone zone = ZoneManager.findSmallestZone(currentLoc);
if (localAltitude < zone.getSeaLevel())
return true;
return false;
}
public Vector2f getGridSquare(Vector2f zoneLoc) {
if (zoneLoc.x < 0)
zoneLoc.setX(0);
if (zoneLoc.x > this.fullExtentsX - 1)
zoneLoc.setX((this.fullExtentsX - 1) + .9999999f);
if (zoneLoc.y < 0)
zoneLoc.setY(0);
if (zoneLoc.y > this.fullExtentsY - 1)
zoneLoc.setY((this.fullExtentsY - 1) + .9999999f);
float xBucket = (zoneLoc.x / this.bucketWidthX);
float yBucket = (zoneLoc.y / this.bucketWidthY);
return new Vector2f(xBucket, yBucket);
}
public float getInterpolatedTerrainHeight(Vector2f zoneLoc) {
Vector2f gridSquare;
if (zoneLoc.x < 0 || zoneLoc.x > this.fullExtentsX)
return -1;
if (zoneLoc.y < 0 || zoneLoc.y > this.fullExtentsY)
return -1;
int maxX = (int) (this.fullExtentsX / this.bucketWidthX);
int maxY = (int) (this.fullExtentsY / this.bucketWidthY);
//flip the Y so it grabs from the bottom left instead of top left.
//zoneLoc.setY(maxZoneHeight - zoneLoc.y);
gridSquare = getGridSquare(zoneLoc);
int gridX = (int) gridSquare.x;
int gridY = (int) (gridSquare.y);
if (gridX > maxX)
gridX = maxX;
if (gridY > maxY)
gridY = maxY;
float offsetX = (gridSquare.x - gridX);
float offsetY = gridSquare.y - gridY;
//get height of the 4 vertices.
float topLeftHeight = 0;
float topRightHeight = 0;
float bottomLeftHeight = 0;
float bottomRightHeight = 0;
int nextY = gridY + 1;
int nextX = gridX + 1;
if (nextY > maxY)
nextY = gridY;
if (nextX > maxX)
nextX = gridX;
topLeftHeight = pixelColorValues[gridX][gridY];
topRightHeight = pixelColorValues[nextX][gridY];
bottomLeftHeight = pixelColorValues[gridX][nextY];
bottomRightHeight = pixelColorValues[nextX][nextY];
float interpolatedHeight;
interpolatedHeight = topRightHeight * (1 - offsetY) * (offsetX);
interpolatedHeight += (bottomRightHeight * offsetY * offsetX);
interpolatedHeight += (bottomLeftHeight * (1 - offsetX) * offsetY);
interpolatedHeight += (topLeftHeight * (1 - offsetX) * (1 - offsetY));
interpolatedHeight *= (float) this.maxHeight / 256; // Scale height
return interpolatedHeight;
}
public float getInterpolatedTerrainHeight(Vector3fImmutable zoneLoc3f) {
Vector2f zoneLoc = new Vector2f(zoneLoc3f.x, zoneLoc3f.z);
Vector2f gridSquare;
if (zoneLoc.x < 0 || zoneLoc.x > this.fullExtentsX)
return -1;
if (zoneLoc.y < 0 || zoneLoc.y > this.fullExtentsY)
return -1;
//flip the Y so it grabs from the bottom left instead of top left.
//zoneLoc.setY(maxZoneHeight - zoneLoc.y);
gridSquare = getGridSquare(zoneLoc);
int gridX = (int) gridSquare.x;
int gridY = (int) (gridSquare.y);
float offsetX = (gridSquare.x - gridX);
float offsetY = gridSquare.y - gridY;
//get height of the 4 vertices.
float topLeftHeight = pixelColorValues[gridX][gridY];
float topRightHeight = pixelColorValues[gridX + 1][gridY];
float bottomLeftHeight = pixelColorValues[gridX][gridY + 1];
float bottomRightHeight = pixelColorValues[gridX + 1][gridY + 1];
float interpolatedHeight;
interpolatedHeight = topRightHeight * (1 - offsetY) * (offsetX);
interpolatedHeight += (bottomRightHeight * offsetY * offsetX);
interpolatedHeight += (bottomLeftHeight * (1 - offsetX) * offsetY);
interpolatedHeight += (topLeftHeight * (1 - offsetX) * (1 - offsetY));
interpolatedHeight *= (float) this.maxHeight / 256; // Scale height
return interpolatedHeight;
}
private void generatePixelData() {
Color color;
// Generate altitude lookup table for this heightmap
this.pixelColorValues = new int[this.heightmapImage.getWidth()][this.heightmapImage.getHeight()];
for (int y = 0; y < this.heightmapImage.getHeight(); y++) {
for (int x = 0; x < this.heightmapImage.getWidth(); x++) {
color = new Color(this.heightmapImage.getRGB(x, y));
pixelColorValues[x][y] = color.getRed();
}
}
}
public float getScaledHeightForColor(float color) {
return (color / 256) * this.maxHeight;
}
public float getBucketWidthX() {
return bucketWidthX;
}
public float getBucketWidthY() {
return bucketWidthY;
}
public int getHeightMapID() {
return heightMapID;
}
public BufferedImage getHeightmapImage() {
return heightmapImage;
}
public float getSeaLevel() {
return seaLevel;
}
}
@@ -140,7 +140,7 @@ public enum InterestManager implements Runnable {
else { else {
if (pc != null) if (pc != null)
if (pcc.getSeeInvis() < pc.getHidden()) if (pcc.getSeeInvis() < pc.hidden)
continue; continue;
if (!cc.sendMsg(uom)) { if (!cc.sendMsg(uom)) {
@@ -340,7 +340,7 @@ public enum InterestManager implements Runnable {
if (loadedPlayer.getObjectUUID() == player.getObjectUUID()) if (loadedPlayer.getObjectUUID() == player.getObjectUUID())
continue; continue;
if (player.getSeeInvis() < loadedPlayer.getHidden()) if (player.getSeeInvis() < loadedPlayer.hidden)
continue; continue;
if (loadedPlayer.safemodeInvis()) if (loadedPlayer.safemodeInvis())
@@ -372,7 +372,7 @@ public enum InterestManager implements Runnable {
if (playerLoadedObject.getObjectType().equals(GameObjectType.PlayerCharacter)) { if (playerLoadedObject.getObjectType().equals(GameObjectType.PlayerCharacter)) {
PlayerCharacter loadedPlayer = (PlayerCharacter) playerLoadedObject; PlayerCharacter loadedPlayer = (PlayerCharacter) playerLoadedObject;
if (player.getSeeInvis() < loadedPlayer.getHidden()) if (player.getSeeInvis() < loadedPlayer.hidden)
toRemove.add(playerLoadedObject); toRemove.add(playerLoadedObject);
else if (loadedPlayer.safemodeInvis()) else if (loadedPlayer.safemodeInvis())
toRemove.add(playerLoadedObject); toRemove.add(playerLoadedObject);
@@ -437,7 +437,7 @@ public enum InterestManager implements Runnable {
// dont load if invis // dont load if invis
if (player.getSeeInvis() < awopc.getHidden()) if (player.getSeeInvis() < awopc.hidden)
continue; continue;
lcm = new LoadCharacterMsg(awopc, PlayerCharacter.hideNonAscii()); lcm = new LoadCharacterMsg(awopc, PlayerCharacter.hideNonAscii());
@@ -467,7 +467,7 @@ public enum InterestManager implements Runnable {
if (awonpc.despawned == true) if (awonpc.despawned == true)
continue; continue;
awonpc.playerAgroMap.put(player.getObjectUUID(), false); awonpc.playerAgroMap.put(player.getObjectUUID(), 0f);
((Mob) awonpc).setCombatTarget(null); ((Mob) awonpc).setCombatTarget(null);
lcm = new LoadCharacterMsg(awonpc, PlayerCharacter.hideNonAscii()); lcm = new LoadCharacterMsg(awonpc, PlayerCharacter.hideNonAscii());
@@ -480,7 +480,7 @@ public enum InterestManager implements Runnable {
if (!awonpc.isAlive()) if (!awonpc.isAlive())
continue; continue;
awonpc.playerAgroMap.put(player.getObjectUUID(), false); awonpc.playerAgroMap.put(player.getObjectUUID(), 0f);
if ((awonpc.agentType.equals(Enum.AIAgentType.MOBILE))) if ((awonpc.agentType.equals(Enum.AIAgentType.MOBILE)))
((Mob) awonpc).setCombatTarget(null); ((Mob) awonpc).setCombatTarget(null);
+230
View File
@@ -0,0 +1,230 @@
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
package engine.InterestManagement;
import engine.gameManager.ZoneManager;
import engine.math.Vector2f;
import engine.math.Vector3fImmutable;
import engine.objects.Zone;
import org.pmw.tinylog.Logger;
import java.util.HashMap;
import static java.lang.Math.PI;
public class Terrain {
public static final HashMap<Integer, short[][]> _heightmap_pixel_cache = new HashMap<>();
public short[][] terrain_pixel_data;
public Vector2f terrain_size = new Vector2f();
public Vector2f cell_size = new Vector2f();
public Vector2f cell_count = new Vector2f();
public float terrain_scale;
public Vector2f blend_values = new Vector2f();
public Vector2f blend_ratio = new Vector2f();
public int heightmap;
Zone zone;
public Terrain(Zone zone) {
this.zone = zone;
this.heightmap = this.zone.template.terrain_image;
// Configure PLANAR zones to use the same 16x16 pixel image
// that all similar terrains share. (See JSON)
if (this.zone.template.terrain_type.equals("PLANAR"))
this.heightmap = 1006300; // all 0
// Load pixel data for this terrain from cache
this.terrain_pixel_data = Terrain._heightmap_pixel_cache.get(heightmap);
if (terrain_pixel_data == null)
Logger.error("Pixel map empty for zone: " + this.zone.getObjectUUID() + ":" + this.zone.zoneName);
// Configure terrain based on zone properties
this.terrain_size.x = this.zone.major_radius * 2;
this.terrain_size.y = this.zone.minor_radius * 2;
this.cell_count.x = this.terrain_pixel_data.length - 1;
this.cell_count.y = this.terrain_pixel_data[0].length - 1;
this.cell_size.x = terrain_size.x / this.cell_count.x;
this.cell_size.y = terrain_size.y / this.cell_count.y;
// Blending configuration. These ratios are used to calculate
// the blending area between child and parent terrains when
// they are stitched together.
this.blend_values.x = this.zone.template.max_blend;
this.blend_values.y = this.zone.template.min_blend;
Vector2f major_blend = new Vector2f(this.blend_values.x / this.zone.major_radius,
this.blend_values.y / this.zone.major_radius);
Vector2f minor_blend = new Vector2f(this.blend_values.x / this.zone.minor_radius,
this.blend_values.y / this.zone.minor_radius);
if (major_blend.y > 0.4f)
blend_ratio.x = major_blend.y;
else
blend_ratio.x = Math.min(major_blend.x, 0.4f);
if (minor_blend.y > 0.4f)
blend_ratio.y = minor_blend.y;
else
blend_ratio.y = Math.min(minor_blend.x, 0.4f);
// Scale coefficient for this terrain
this.terrain_scale = this.zone.template.terrain_max_y / 255f;
}
public static Zone getNextZoneWithTerrain(Zone zone) {
// Not all zones have a terrain. Some are for display only
// and heights returned are from the parent heightmap. This
// is controlled in the JSON via the has_terrain_gen field.
Zone terrain_zone = zone;
if (zone == null)
return ZoneManager.seaFloor;
if (zone.terrain != null)
return zone;
if (zone.equals(ZoneManager.seaFloor))
return zone;
while (terrain_zone.terrain == null)
terrain_zone = terrain_zone.parent;
return terrain_zone;
}
public static float getWorldHeight(Zone zone, Vector3fImmutable world_loc) {
// Retrieve the next zone with a terrain defined.
Zone terrainZone = getNextZoneWithTerrain(zone);
Zone parentZone = getNextZoneWithTerrain(zone.parent);
// Transform world loc into zone space coordinate system
Vector2f terrainLoc = ZoneManager.worldToTerrainSpace(world_loc, terrainZone);
Vector2f parentLoc = ZoneManager.worldToTerrainSpace(world_loc, parentZone);
// Offset from origin needed for blending function
Vector2f terrainOffset = ZoneManager.worldToZoneOffset(world_loc, terrainZone);
// Interpolate height for this position in both terrains
float interpolatedChildHeight = terrainZone.terrain.getInterpolatedTerrainHeight(terrainLoc);
interpolatedChildHeight += terrainZone.global_height;
float interpolatedParentTerrainHeight = parentZone.terrain.getInterpolatedTerrainHeight(parentLoc);
interpolatedParentTerrainHeight += parentZone.global_height;
// Blend between terrains
float blendCoefficient = terrainZone.terrain.getTerrainBlendCoefficient(terrainOffset);
float terrainHeight = interpolatedChildHeight * blendCoefficient;
terrainHeight += interpolatedParentTerrainHeight * (1 - blendCoefficient);
return terrainHeight;
}
public static float getWorldHeight(Vector3fImmutable world_loc) {
Zone currentZone = ZoneManager.findSmallestZone(world_loc);
return getWorldHeight(currentZone, world_loc);
}
public Vector2f getTerrainCell(Vector2f terrain_loc) {
// Calculate terrain cell with offset
Vector2f terrain_cell = new Vector2f(terrain_loc.x / this.cell_size.x, terrain_loc.y / this.cell_size.y);
// Clamp values when standing directly on pole
terrain_cell.x = Math.max(0, Math.min(this.cell_count.x - 1, terrain_cell.x));
terrain_cell.y = Math.max(0, Math.min(this.cell_count.y - 1, terrain_cell.y));
return terrain_cell;
}
public float getInterpolatedTerrainHeight(Vector2f terrain_loc) {
float interpolatedHeight;
// Early exit for guild zones
if (this.zone.guild_zone)
return 5.0f;
// Determine terrain and offset from top left vertex
Vector2f terrain_cell = getTerrainCell(terrain_loc);
int pixel_x = (int) Math.floor(terrain_cell.x);
int pixel_y = (int) Math.floor(terrain_cell.y);
Vector2f pixel_offset = new Vector2f(terrain_cell.x % 1, terrain_cell.y % 1);
// 4 surrounding vertices from the pixel array.
short top_left_pixel = terrain_pixel_data[pixel_x][pixel_y];
short top_right_pixel = terrain_pixel_data[pixel_x + 1][pixel_y];
short bottom_left_pixel = terrain_pixel_data[pixel_x][pixel_y + 1];
short bottom_right_pixel = terrain_pixel_data[pixel_x + 1][pixel_y + 1];
// Interpolate between the 4 vertices
interpolatedHeight = top_left_pixel * (1 - pixel_offset.x) * (1 - pixel_offset.y);
interpolatedHeight += top_right_pixel * (1 - pixel_offset.y) * (pixel_offset.x);
interpolatedHeight += (bottom_left_pixel * (1 - pixel_offset.x) * pixel_offset.y);
interpolatedHeight += (bottom_right_pixel * pixel_offset.y * pixel_offset.x);
interpolatedHeight *= this.terrain_scale; // Scale height
return interpolatedHeight;
}
public float getTerrainBlendCoefficient(Vector2f zone_offset) {
// Normalize terrain offset
Vector2f normalizedOffset = new Vector2f(Math.abs(zone_offset.x) / this.zone.template.major_radius,
Math.abs(zone_offset.y) / this.zone.template.minor_radius);
float blendCoefficient;
if (normalizedOffset.x <= 1 - blend_ratio.x || normalizedOffset.x <= normalizedOffset.y) {
if (normalizedOffset.y < 1 - blend_ratio.y)
return 1;
blendCoefficient = (normalizedOffset.y - (1 - blend_ratio.y)) / blend_ratio.y;
} else
blendCoefficient = (normalizedOffset.x - (1 - blend_ratio.x)) / blend_ratio.x;
blendCoefficient = (float) Math.atan((0.5f - blendCoefficient) * PI);
return (blendCoefficient + 1) * 0.5f;
}
}
+1 -1
View File
@@ -67,7 +67,7 @@ public class CityRecord extends DataRecord {
cityRecord.locX = cityRecord.city.getTOL().getLoc().x; cityRecord.locX = cityRecord.city.getTOL().getLoc().x;
cityRecord.locY = -cityRecord.city.getTOL().getLoc().z; // flip sign on 'y' coordinate cityRecord.locY = -cityRecord.city.getTOL().getLoc().z; // flip sign on 'y' coordinate
cityRecord.zoneHash = cityRecord.city.getParent().getHash(); cityRecord.zoneHash = cityRecord.city.getParent().hash;
if (cityRecord.eventType.equals(Enum.RecordEventType.CREATE)) if (cityRecord.eventType.equals(Enum.RecordEventType.CREATE))
cityRecord.establishedDatetime = cityRecord.city.established; cityRecord.establishedDatetime = cityRecord.city.established;
+1 -1
View File
@@ -52,7 +52,7 @@ public class MineRecord extends DataRecord {
mineRecord.eventType = eventType; mineRecord.eventType = eventType;
} }
mineRecord.zoneHash = mine.getParentZone().getHash(); mineRecord.zoneHash = mine.getParentZone().hash;
if (character.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) { if (character.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) {
player = (PlayerCharacter) character; player = (PlayerCharacter) character;
+1 -1
View File
@@ -281,7 +281,7 @@ public class PvpRecord extends DataRecord {
outStatement.setInt(8, this.victim.getLevel()); outStatement.setInt(8, this.victim.getLevel());
outStatement.setString(9, DataWarehouse.hasher.encrypt(zone.getObjectUUID())); outStatement.setString(9, DataWarehouse.hasher.encrypt(zone.getObjectUUID()));
outStatement.setString(10, zone.getName()); outStatement.setString(10, zone.zoneName);
outStatement.setFloat(11, this.location.getX()); outStatement.setFloat(11, this.location.getX());
outStatement.setFloat(12, -this.location.getZ()); // flip sign on 'y' coordinate outStatement.setFloat(12, -this.location.getZ()); // flip sign on 'y' coordinate
outStatement.setBoolean(13, this.pvpExp); outStatement.setBoolean(13, this.pvpExp);
+213 -44
View File
@@ -9,16 +9,25 @@
package engine.db.handlers; package engine.db.handlers;
import engine.CollisionEngine.CollisionManager;
import engine.CollisionEngine.MeshData;
import engine.CollisionEngine.Triangle;
import engine.Enum; import engine.Enum;
import engine.Enum.DbObjectType; import engine.Enum.DbObjectType;
import engine.Enum.ProtectionState; import engine.Enum.ProtectionState;
import engine.Enum.TaxType; import engine.Enum.TaxType;
import engine.gameManager.BuildingManager;
import engine.gameManager.DbManager; import engine.gameManager.DbManager;
import engine.math.Vector2f;
import engine.math.Vector3f;
import engine.math.Vector3fImmutable; import engine.math.Vector3fImmutable;
import engine.objects.*; import engine.objects.*;
import org.joda.time.DateTime; import org.joda.time.DateTime;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.sql.Connection; import java.sql.Connection;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
@@ -26,7 +35,9 @@ import java.sql.SQLException;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.ZoneId; import java.time.ZoneId;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;
public class dbBuildingHandler extends dbHandlerBase { public class dbBuildingHandler extends dbHandlerBase {
@@ -88,14 +99,12 @@ public class dbBuildingHandler extends dbHandlerBase {
return removeFromBuildings(b); return removeFromBuildings(b);
} }
public ArrayList<Building> GET_ALL_BUILDINGS_FOR_ZONE(Zone zone) { public ArrayList<Building> GET_ALL_BUILDINGS() {
ArrayList<Building> buildings = new ArrayList<>(); ArrayList<Building> buildings = new ArrayList<>();
try (Connection connection = DbManager.getConnection(); try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT `obj_building`.*, `object`.`parent` FROM `object` INNER JOIN `obj_building` ON `obj_building`.`UID` = `object`.`UID` WHERE `object`.`parent` = ?;")) { PreparedStatement preparedStatement = connection.prepareStatement("SELECT `obj_building`.*, `object`.`parent` FROM `object` INNER JOIN `obj_building` ON `obj_building`.`UID` = `object`.`UID` ORDER BY `object`.`UID` ASC;")) {
preparedStatement.setLong(1, zone.getObjectUUID());
ResultSet rs = preparedStatement.executeQuery(); ResultSet rs = preparedStatement.executeQuery();
buildings = getObjectsFromRs(rs, 1000); buildings = getObjectsFromRs(rs, 1000);
@@ -425,26 +434,28 @@ public class dbBuildingHandler extends dbHandlerBase {
return false; return false;
} }
public void LOAD_ALL_FRIENDS_FOR_BUILDING(Building building) { public void LOAD_BUILDING_FRIENDS() {
if (building == null)
return;
try (Connection connection = DbManager.getConnection(); try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `dyn_building_friends` WHERE `buildingUID` = ?")) { PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `dyn_building_friends`")) {
preparedStatement.setInt(1, building.getObjectUUID());
ResultSet rs = preparedStatement.executeQuery(); ResultSet rs = preparedStatement.executeQuery();
while (rs.next()) { while (rs.next()) {
BuildingFriends friend = new BuildingFriends(rs); BuildingFriends friend = new BuildingFriends(rs);
switch (friend.getFriendType()) {
// Create map if it does not yet exist
if (!BuildingManager._buildingFriends.containsKey(friend.buildingUID))
BuildingManager._buildingFriends.put(friend.buildingUID, new ConcurrentHashMap<>());
switch (friend.friendType) {
case 7: case 7:
building.getFriends().put(friend.getPlayerUID(), friend); BuildingManager._buildingFriends.get(friend.buildingUID).put(friend.playerUID, friend);
break; break;
case 8: case 8:
case 9: case 9:
building.getFriends().put(friend.getGuildUID(), friend); BuildingManager._buildingFriends.get(friend.buildingUID).put(friend.guildUID, friend);
break; break;
} }
} }
@@ -455,26 +466,29 @@ public class dbBuildingHandler extends dbHandlerBase {
} }
public void LOAD_ALL_CONDEMNED_FOR_BUILDING(Building building) { public void LOAD_BUILDING_CONDEMNED() {
if (building == null)
return;
try (Connection connection = DbManager.getConnection(); try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `dyn_building_condemned` WHERE `buildingUID` = ?")) { PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `dyn_building_condemned`")) {
preparedStatement.setInt(1, building.getObjectUUID());
ResultSet rs = preparedStatement.executeQuery(); ResultSet rs = preparedStatement.executeQuery();
while (rs.next()) { while (rs.next()) {
Condemned condemned = new Condemned(rs); Condemned condemned = new Condemned(rs);
switch (condemned.getFriendType()) {
// Create map if it does not yet exist
if (!BuildingManager._buildingCondemned.containsKey(condemned.buildingUUID))
BuildingManager._buildingCondemned.put(condemned.buildingUUID, new ConcurrentHashMap<>());
switch (condemned.friendType) {
case 2: case 2:
building.getCondemned().put(condemned.getPlayerUID(), condemned); BuildingManager._buildingCondemned.get(condemned.buildingUUID).put(condemned.playerUID, condemned);
break; break;
case 4: case 4:
case 5: case 5:
building.getCondemned().put(condemned.getGuildUID(), condemned); BuildingManager._buildingCondemned.get(condemned.buildingUUID).put(condemned.guildUID, condemned);
break; break;
} }
} }
@@ -484,35 +498,27 @@ public class dbBuildingHandler extends dbHandlerBase {
} }
} }
public ArrayList<Vector3fImmutable> LOAD_PATROL_POINTS(Building building) { public void LOAD_BARRACKS_PATROL_POINTS() {
if (building == null)
return null;
ArrayList<Vector3fImmutable> patrolPoints = new ArrayList<>();
try (Connection connection = DbManager.getConnection(); try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `dyn_building_patrol_points` WHERE `buildingUID` = ?")) { PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `dyn_building_patrol_points`")) {
preparedStatement.setInt(1, building.getObjectUUID());
ResultSet rs = preparedStatement.executeQuery(); ResultSet rs = preparedStatement.executeQuery();
while (rs.next()) { while (rs.next()) {
float x1 = rs.getFloat("patrolX");
float y1 = rs.getFloat("patrolY"); int buildingUUID = rs.getInt("buildingUID");
float z1 = rs.getFloat("patrolZ");
Vector3fImmutable patrolPoint = new Vector3fImmutable(x1, y1, z1); if (!BuildingManager._buildingPatrolPoints.containsKey(buildingUUID))
patrolPoints.add(patrolPoint); BuildingManager._buildingPatrolPoints.put(buildingUUID, new ArrayList<>());
Vector3fImmutable patrolPoint = new Vector3fImmutable(rs.getFloat("patrolX"), rs.getFloat("patrolY"), rs.getFloat("patrolZ"));
BuildingManager._buildingPatrolPoints.get(buildingUUID).add(patrolPoint);
} }
} catch (SQLException e) { } catch (SQLException e) {
Logger.error(e); Logger.error(e);
} }
return patrolPoints;
} }
public boolean ADD_TO_CONDEMNLIST(final long parentUID, final long playerUID, final long guildID, final int friendType) { public boolean ADD_TO_CONDEMNLIST(final long parentUID, final long playerUID, final long guildID, final int friendType) {
@@ -722,10 +728,10 @@ public class dbBuildingHandler extends dbHandlerBase {
+ "WHERE`buildingUID` = ? AND `playerUID` = ? AND `guildUID` = ? AND `friendType` = ?")) { + "WHERE`buildingUID` = ? AND `playerUID` = ? AND `guildUID` = ? AND `friendType` = ?")) {
preparedStatement.setBoolean(1, active); preparedStatement.setBoolean(1, active);
preparedStatement.setInt(2, condemn.getParent()); preparedStatement.setInt(2, condemn.buildingUUID);
preparedStatement.setInt(3, condemn.getPlayerUID()); preparedStatement.setInt(3, condemn.playerUID);
preparedStatement.setInt(4, condemn.getGuildUID()); preparedStatement.setInt(4, condemn.guildUID);
preparedStatement.setInt(5, condemn.getFriendType()); preparedStatement.setInt(5, condemn.friendType);
return (preparedStatement.executeUpdate() > 0); return (preparedStatement.executeUpdate() > 0);
@@ -852,4 +858,167 @@ public class dbBuildingHandler extends dbHandlerBase {
return false; return false;
} }
public void LOAD_MESH_DATA(){
CollisionManager.structure_meshes = new HashMap<>();
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `final_structure_meshes`")) {
ResultSet rs = preparedStatement.executeQuery();
while (rs.next()) {
MeshData md = new MeshData();
md.propID = rs.getInt("propID");
md.meshID = rs.getInt("meshID");
md.loc = new Vector3f(rs.getFloat("locX"), rs.getFloat("locY"),rs.getFloat("locz"));
md.scale = new Vector3f(rs.getFloat("scaleX"), rs.getFloat("scaleY"),rs.getFloat("scaleZ"));
md.refPoint = new Vector3f(rs.getFloat("refX"), rs.getFloat("refY"),rs.getFloat("refZ"));
md.endPoint = new Vector3f(rs.getFloat("endX"), rs.getFloat("endY"),rs.getFloat("endZ"));
md.minY = rs.getFloat("minY");
md.maxY = rs.getFloat("maxY");
if(CollisionManager.structure_meshes.containsKey(rs.getInt("propID"))){
CollisionManager.structure_meshes.get(rs.getInt("propID")).add(md);
} else{
ArrayList<MeshData> meshData = new ArrayList<>();
meshData.add(md);
CollisionManager.structure_meshes.put(rs.getInt("propID"),meshData);
}
}
} catch (SQLException e) {
Logger.error(e);
}
}
public void LOAD_MESH_TRIANGLE_DATA(){
CollisionManager.mesh_triangles = new HashMap<>();
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `final_mesh_triangles`")) {
ResultSet rs = preparedStatement.executeQuery();
while (rs.next()) {
Triangle tri = new Triangle();
tri.point1 = new Point2D.Float(rs.getFloat("P1X"),rs.getFloat("P1Z"));
tri.point2 = new Point2D.Float(rs.getFloat("P2X"),rs.getFloat("P2Z"));
tri.point3 = new Point2D.Float(rs.getFloat("P3X"),rs.getFloat("P3Z"));
if(CollisionManager.mesh_triangles.containsKey(rs.getInt("meshID"))){
CollisionManager.mesh_triangles.get(rs.getInt("meshID")).add(tri);
} else{
ArrayList<Triangle> triData = new ArrayList<>();
triData.add(tri);
CollisionManager.mesh_triangles.put(rs.getInt("meshID"),triData);
}
}
} catch (SQLException e) {
Logger.error(e);
}
}
public void LOAD_PROP_MESHES() {
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_structure_meshes`")) {
ResultSet rs = preparedStatement.executeQuery();
BuildingManager.prop_meshes = new HashMap<>();
while (rs.next()) {
if(BuildingManager.prop_meshes.containsKey(rs.getInt("propID")) == false){
ArrayList<Integer> meshList = new ArrayList<>();
meshList.add(rs.getInt("meshID"));
BuildingManager.prop_meshes.put(rs.getInt("propID"),meshList);
}
else
{
ArrayList<Integer> meshes = BuildingManager.prop_meshes.get(rs.getInt("propID"));
meshes.add(rs.getInt("meshID"));
//BuildingManager.prop_meshes.get(rs.getInt("propID")).add(rs.getInt("meshID"));
}
}
} catch (SQLException e) {
Logger.error(e);
}
}
public void LOAD_MESH_DATA_OLD() {
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_mesh_triangles`")) {
ResultSet rs = preparedStatement.executeQuery();
BuildingManager.mesh_triangle_points = new HashMap<>();
while (rs.next()) {
ArrayList<Float> floatPoints = new ArrayList<>();
for(String f : rs.getString("vertices").split(";"))
{
floatPoints.add(Float.parseFloat(f));
}
ArrayList<Vector3f> triPoints = new ArrayList<>();
for(int i = 0; i < floatPoints.size(); i += 3){
triPoints.add(new Vector3f(floatPoints.get(i),floatPoints.get(i+1),floatPoints.get(i+2)));
}
if(BuildingManager.mesh_triangle_points.containsKey(rs.getInt("meshID")) == false){
ArrayList<ArrayList<Vector3f>> newPoints = new ArrayList<>();
newPoints.add(triPoints);
BuildingManager.mesh_triangle_points.put(rs.getInt("meshID"),newPoints);
}
else
{
BuildingManager.mesh_triangle_points.get(rs.getInt("meshID")).add(triPoints);
}
}
} catch (SQLException e) {
Logger.error(e);
}
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_mesh_heights`")) {
ResultSet rs = preparedStatement.executeQuery();
BuildingManager.mesh_heights = new HashMap<>();
while (rs.next()) {
if(BuildingManager.mesh_heights.containsKey(rs.getInt("meshID")) == false){
Vector2f heights = new Vector2f(rs.getFloat("maxY"),rs.getFloat("minY"));
BuildingManager.mesh_heights.put(rs.getInt("meshID"),heights);
}
}
} catch (SQLException e) {
Logger.error(e);
}
}
public void LOAD_MESH_BOUNDING_BOXES() {
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_mesh_bounding_boxes`")) {
ResultSet rs = preparedStatement.executeQuery();
BuildingManager.mesh_bounding_boxes = new HashMap<>();
while (rs.next()) {
int meshID = rs.getInt("meshId");
if(BuildingManager.mesh_bounding_boxes.containsKey(meshID) == false){
float endX = Float.parseFloat(rs.getString("mesh_end_point").split(";")[0]);
float endZ = Float.parseFloat(rs.getString("mesh_end_point").split(";")[1]);
float refX = Float.parseFloat(rs.getString("mesh_ref_point").split(";")[0]);
float refZ = Float.parseFloat(rs.getString("mesh_ref_point").split(";")[1]);
Vector2f topLeft = new Vector2f(refX,refZ);
float width = Math.abs(Math.abs(endX)-Math.abs(refX));
float height = Math.abs(Math.abs(endZ)-Math.abs(refZ));
Rectangle2D boundRect = new Rectangle2D.Float();
boundRect.setRect(topLeft.x,topLeft.y,width,height);
BuildingManager.mesh_bounding_boxes.put(meshID,boundRect);
}
}
} catch (SQLException e) {
Logger.error(e);
}
}
} }
+5 -4
View File
@@ -34,16 +34,19 @@ public class dbCityHandler extends dbHandlerBase {
case "zone": case "zone":
Zone zone = new Zone(rs); Zone zone = new Zone(rs);
DbManager.addToCache(zone); DbManager.addToCache(zone);
zone.runAfterLoad();
list.add(zone); list.add(zone);
break; break;
case "building": case "building":
Building building = new Building(rs); Building building = new Building(rs);
DbManager.addToCache(building); DbManager.addToCache(building);
building.runAfterLoad();
list.add(building); list.add(building);
break; break;
case "city": case "city":
City city = new City(rs); City city = new City(rs);
DbManager.addToCache(city); DbManager.addToCache(city);
city.runAfterLoad();
list.add(city); list.add(city);
break; break;
} }
@@ -96,14 +99,12 @@ public class dbCityHandler extends dbHandlerBase {
return objectList; return objectList;
} }
public ArrayList<City> GET_CITIES_BY_ZONE(final int objectUUID) { public ArrayList<City> GET_ALL_CITIES() {
ArrayList<City> cityList = new ArrayList<>(); ArrayList<City> cityList = new ArrayList<>();
try (Connection connection = DbManager.getConnection(); try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT `obj_city`.*, `object`.`parent` FROM `obj_city` INNER JOIN `object` ON `object`.`UID` = `obj_city`.`UID` WHERE `object`.`parent`=?;")) { PreparedStatement preparedStatement = connection.prepareStatement("SELECT `obj_city`.*, `object`.`parent` FROM `obj_city` INNER JOIN `object` ON `object`.`UID` = `obj_city`.`UID` ORDER BY `object`.`UID` ASC;")) {
preparedStatement.setLong(1, objectUUID);
ResultSet rs = preparedStatement.executeQuery(); ResultSet rs = preparedStatement.executeQuery();
cityList = getObjectsFromRs(rs, 100); cityList = getObjectsFromRs(rs, 100);
@@ -1,43 +0,0 @@
package engine.db.handlers;
import engine.InterestManagement.HeightMap;
import engine.gameManager.DbManager;
import org.pmw.tinylog.Logger;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class dbHeightMapHandler extends dbHandlerBase {
public dbHeightMapHandler() {
}
public void LOAD_ALL_HEIGHTMAPS() {
HeightMap thisHeightmap;
HeightMap.heightMapsCreated = 0;
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_zone_heightmap INNER JOIN static_zone_size ON static_zone_size.loadNum = static_zone_heightmap.zoneLoadID")) {
ResultSet rs = preparedStatement.executeQuery();
while (rs.next()) {
thisHeightmap = new HeightMap(rs);
if (thisHeightmap.getHeightmapImage() == null) {
Logger.info("Imagemap for " + thisHeightmap.getHeightMapID() + " was null");
continue;
}
}
} catch (SQLException e) {
Logger.error(e);
}
}
}
+47 -43
View File
@@ -11,7 +11,6 @@ package engine.db.handlers;
import engine.gameManager.DbManager; import engine.gameManager.DbManager;
import engine.objects.Mob; import engine.objects.Mob;
import engine.objects.Zone;
import org.joda.time.DateTime; import org.joda.time.DateTime;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
@@ -28,31 +27,27 @@ public class dbMobHandler extends dbHandlerBase {
this.localObjectType = engine.Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); this.localObjectType = engine.Enum.GameObjectType.valueOf(this.localClass.getSimpleName());
} }
public Mob ADD_MOB(Mob toAdd) { public Mob PERSIST(Mob toAdd) {
Mob mobile = null; Mob mobile = null;
try (Connection connection = DbManager.getConnection(); try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("CALL `mob_CREATE`(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);")) { PreparedStatement preparedStatement = connection.prepareStatement("CALL `mob_CREATE`(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);")) {
preparedStatement.setLong(1, toAdd.getParentZoneID()); preparedStatement.setLong(1, toAdd.parentZoneUUID);
preparedStatement.setInt(2, toAdd.getMobBaseID()); preparedStatement.setInt(2, toAdd.loadID);
preparedStatement.setInt(3, toAdd.getGuildUUID()); preparedStatement.setInt(3, toAdd.guildUUID);
preparedStatement.setFloat(4, toAdd.getSpawnX()); preparedStatement.setFloat(4, toAdd.bindLoc.x);
preparedStatement.setFloat(5, toAdd.getSpawnY()); preparedStatement.setFloat(5, toAdd.bindLoc.y);
preparedStatement.setFloat(6, toAdd.getSpawnZ()); preparedStatement.setFloat(6, toAdd.bindLoc.z);
preparedStatement.setInt(7, 0); preparedStatement.setInt(7, 0);
preparedStatement.setFloat(8, toAdd.getSpawnRadius()); preparedStatement.setFloat(8, toAdd.spawnRadius);
preparedStatement.setInt(9, toAdd.getTrueSpawnTime()); preparedStatement.setInt(9, toAdd.spawnDelay);
preparedStatement.setInt(10, toAdd.contractUUID);
if (toAdd.getContract() != null) preparedStatement.setInt(11, toAdd.buildingUUID);
preparedStatement.setInt(10, toAdd.getContract().getContractID()); preparedStatement.setInt(12, toAdd.level);
else preparedStatement.setString(13, toAdd.firstName);
preparedStatement.setInt(10, 0); preparedStatement.setString(14, toAdd.behaviourType.toString());
preparedStatement.setInt(11, toAdd.getBuildingID());
preparedStatement.setInt(12, toAdd.getLevel());
preparedStatement.setString(13, toAdd.getFirstName());
ResultSet rs = preparedStatement.executeQuery(); ResultSet rs = preparedStatement.executeQuery();
@@ -69,6 +64,23 @@ public class dbMobHandler extends dbHandlerBase {
return mobile; return mobile;
} }
public ArrayList<Mob> GET_ALL_MOBS() {
ArrayList<Mob> mobileList = new ArrayList<>();
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT `obj_mob`.*, `object`.`parent` FROM `object` INNER JOIN `obj_mob` ON `obj_mob`.`UID` = `object`.`UID` ORDER BY `object`.`UID` ASC;")) {
ResultSet rs = preparedStatement.executeQuery();
mobileList = getObjectsFromRs(rs, 1000);
} catch (SQLException e) {
Logger.error(e);
}
return mobileList;
}
public boolean updateUpgradeTime(Mob mob, DateTime upgradeDateTime) { public boolean updateUpgradeTime(Mob mob, DateTime upgradeDateTime) {
try (Connection connection = DbManager.getConnection(); try (Connection connection = DbManager.getConnection();
@@ -106,17 +118,17 @@ public class dbMobHandler extends dbHandlerBase {
return row_count; return row_count;
} }
public void LOAD_PATROL_POINTS(Mob captain) { public void LOAD_GUARD_MINIONS(Mob guardCaptain) {
try (Connection connection = DbManager.getConnection(); try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `dyn_guards` WHERE `captainUID` = ?")) { PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `dyn_guards` WHERE `captainUID` = ?")) {
preparedStatement.setInt(1, captain.getObjectUUID()); preparedStatement.setInt(1, guardCaptain.getObjectUUID());
ResultSet rs = preparedStatement.executeQuery(); ResultSet rs = preparedStatement.executeQuery();
while (rs.next()) { while (rs.next()) {
String name = rs.getString("name"); String minionName = rs.getString("minionName");
Mob toCreate = Mob.createGuardMob(captain, captain.getGuild(), captain.getParentZone(), captain.building.getLoc(), captain.getLevel(), name); Mob toCreate = Mob.createGuardMinion(guardCaptain, guardCaptain.getLevel(), minionName);
if (toCreate == null) if (toCreate == null)
return; return;
@@ -131,15 +143,13 @@ public class dbMobHandler extends dbHandlerBase {
} }
} }
public boolean ADD_TO_GUARDS(final long captainUID, final int mobBaseID, final String name, final int slot) { public boolean ADD_GUARD_MINION(final long captainUID, final String minionName) {
try (Connection connection = DbManager.getConnection(); try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("INSERT INTO `dyn_guards` (`captainUID`, `mobBaseID`,`name`, `slot`) VALUES (?,?,?,?)")) { PreparedStatement preparedStatement = connection.prepareStatement("INSERT INTO `dyn_guards` (`captainUID`, `minionName`) VALUES (?,?)")) {
preparedStatement.setLong(1, captainUID); preparedStatement.setLong(1, captainUID);
preparedStatement.setInt(2, mobBaseID); preparedStatement.setString(2, minionName);
preparedStatement.setString(3, name);
preparedStatement.setInt(4, slot);
return (preparedStatement.executeUpdate() > 0); return (preparedStatement.executeUpdate() > 0);
@@ -149,14 +159,13 @@ public class dbMobHandler extends dbHandlerBase {
} }
} }
public boolean REMOVE_FROM_GUARDS(final long captainUID, final int mobBaseID, final int slot) { public boolean REMOVE_GUARD_MINION(final long captainUID, final String minionName) {
try (Connection connection = DbManager.getConnection(); try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("DELETE FROM `dyn_guards` WHERE `captainUID`=? AND `mobBaseID`=? AND `slot` =?")) { PreparedStatement preparedStatement = connection.prepareStatement("DELETE FROM `dyn_guards` WHERE `captainUID`=? AND `minionName`=? LIMIT 1;")) {
preparedStatement.setLong(1, captainUID); preparedStatement.setLong(1, captainUID);
preparedStatement.setInt(2, mobBaseID); preparedStatement.setString(2, minionName);
preparedStatement.setInt(3, slot);
return (preparedStatement.executeUpdate() > 0); return (preparedStatement.executeUpdate() > 0);
@@ -166,24 +175,19 @@ public class dbMobHandler extends dbHandlerBase {
} }
} }
public boolean REMOVE_ALL_MINIONS(final long captainUID) {
public ArrayList<Mob> GET_ALL_MOBS_FOR_ZONE(Zone zone) {
ArrayList<Mob> mobileList = new ArrayList<>();
try (Connection connection = DbManager.getConnection(); try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT `obj_mob`.*, `object`.`parent` FROM `object` INNER JOIN `obj_mob` ON `obj_mob`.`UID` = `object`.`UID` WHERE `object`.`parent` = ?;")) { PreparedStatement preparedStatement = connection.prepareStatement("DELETE FROM `dyn_guards` WHERE `captainUID`=?;")) {
preparedStatement.setLong(1, zone.getObjectUUID()); preparedStatement.setLong(1, captainUID);
ResultSet rs = preparedStatement.executeQuery(); return (preparedStatement.executeUpdate() > 0);
mobileList = getObjectsFromRs(rs, 1000);
} catch (SQLException e) { } catch (SQLException e) {
Logger.error(e); Logger.error(e);
return false;
} }
return mobileList;
} }
public Mob GET_MOB(final int objectUUID) { public Mob GET_MOB(final int objectUUID) {
+2 -5
View File
@@ -15,7 +15,6 @@ import engine.math.Vector3fImmutable;
import engine.objects.NPC; import engine.objects.NPC;
import engine.objects.NPCProfits; import engine.objects.NPCProfits;
import engine.objects.ProducedItem; import engine.objects.ProducedItem;
import engine.objects.Zone;
import org.joda.time.DateTime; import org.joda.time.DateTime;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
@@ -94,14 +93,12 @@ public class dbNPCHandler extends dbHandlerBase {
return row_count; return row_count;
} }
public ArrayList<NPC> GET_ALL_NPCS_FOR_ZONE(Zone zone) { public ArrayList<NPC> GET_ALL_NPCS() {
ArrayList<NPC> npcList = new ArrayList<>(); ArrayList<NPC> npcList = new ArrayList<>();
try (Connection connection = DbManager.getConnection(); try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT `obj_npc`.*, `object`.`parent` FROM `object` INNER JOIN `obj_npc` ON `obj_npc`.`UID` = `object`.`UID` WHERE `object`.`parent` = ?;")) { PreparedStatement preparedStatement = connection.prepareStatement("SELECT `obj_npc`.*, `object`.`parent` FROM `object` INNER JOIN `obj_npc` ON `obj_npc`.`UID` = `object`.`UID` ORDER BY `object`.`UID` ASC;")) {
preparedStatement.setLong(1, zone.getObjectUUID());
ResultSet rs = preparedStatement.executeQuery(); ResultSet rs = preparedStatement.executeQuery();
npcList = getObjectsFromRs(rs, 1000); npcList = getObjectsFromRs(rs, 1000);
@@ -15,15 +15,9 @@ import engine.gameManager.PowersManager;
import engine.objects.Mob; import engine.objects.Mob;
import engine.objects.PreparedStatementShared; import engine.objects.PreparedStatementShared;
import engine.powers.EffectsBase; import engine.powers.EffectsBase;
import engine.powers.MobPowerEntry;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
public class dbPowerHandler extends dbHandlerBase { public class dbPowerHandler extends dbHandlerBase {
@@ -86,43 +80,4 @@ public class dbPowerHandler extends dbHandlerBase {
} }
} }
public static HashMap<Integer, ArrayList<MobPowerEntry>> LOAD_MOB_POWERS() {
HashMap<Integer, ArrayList<MobPowerEntry>> mobPowers = new HashMap<>();
MobPowerEntry mobPowerEntry;
int mobbaseID;
int recordsRead = 0;
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_npc_mobbase_powers ORDER BY `id` ASC;")) {
ResultSet rs = preparedStatement.executeQuery();
while (rs.next()) {
recordsRead++;
mobbaseID = rs.getInt("mobbaseUUID");
mobPowerEntry = new MobPowerEntry(rs);
if (mobPowers.get(mobbaseID) == null) {
ArrayList<MobPowerEntry> powerList = new ArrayList<>();
powerList.add(mobPowerEntry);
mobPowers.put(mobbaseID, powerList);
} else {
ArrayList<MobPowerEntry> powerList = mobPowers.get(mobbaseID);
powerList.add(mobPowerEntry);
mobPowers.put(mobbaseID, powerList);
}
}
} catch (SQLException e) {
Logger.error(e);
return mobPowers;
}
Logger.info("read: " + recordsRead + " cached: " + mobPowers.size());
return mobPowers;
}
} }
@@ -11,6 +11,8 @@ package engine.db.handlers;
import engine.gameManager.DbManager; import engine.gameManager.DbManager;
import engine.objects.RuneBase; import engine.objects.RuneBase;
import engine.powers.RunePowerEntry;
import engine.powers.RuneSkillAdjustEntry;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
import java.sql.Connection; import java.sql.Connection;
@@ -27,6 +29,84 @@ public class dbRuneBaseHandler extends dbHandlerBase {
this.localObjectType = engine.Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); this.localObjectType = engine.Enum.GameObjectType.valueOf(this.localClass.getSimpleName());
} }
public static HashMap<Integer, ArrayList<RunePowerEntry>> LOAD_RUNE_POWERS() {
HashMap<Integer, ArrayList<RunePowerEntry>> mobPowers = new HashMap<>();
RunePowerEntry runePowerEntry;
int rune_id;
int recordsRead = 0;
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_rune_powers")) {
ResultSet rs = preparedStatement.executeQuery();
while (rs.next()) {
recordsRead++;
rune_id = rs.getInt("rune_id");
runePowerEntry = new RunePowerEntry(rs);
if (mobPowers.get(rune_id) == null) {
ArrayList<RunePowerEntry> runePowerList = new ArrayList<>();
runePowerList.add(runePowerEntry);
mobPowers.put(rune_id, runePowerList);
} else {
ArrayList<RunePowerEntry> powerList = mobPowers.get(rune_id);
powerList.add(runePowerEntry);
mobPowers.put(rune_id, powerList);
}
}
} catch (SQLException e) {
Logger.error(e);
return mobPowers;
}
Logger.info("read: " + recordsRead + " cached: " + mobPowers.size());
return mobPowers;
}
public static HashMap<Integer, ArrayList<RuneSkillAdjustEntry>> LOAD_RUNE_SKILL_ADJUSTS() {
HashMap<Integer, ArrayList<RuneSkillAdjustEntry>> runeSkillAdjusts = new HashMap<>();
RuneSkillAdjustEntry runeSkillAdjustEntry;
int rune_id;
int recordsRead = 0;
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_rune_skill_adjusts")) {
ResultSet rs = preparedStatement.executeQuery();
while (rs.next()) {
recordsRead++;
rune_id = rs.getInt("rune_id");
runeSkillAdjustEntry = new RuneSkillAdjustEntry(rs);
if (runeSkillAdjusts.get(rune_id) == null) {
ArrayList<RuneSkillAdjustEntry> skillAdjustList = new ArrayList<>();
skillAdjustList.add(runeSkillAdjustEntry);
runeSkillAdjusts.put(rune_id, skillAdjustList);
} else {
ArrayList<RuneSkillAdjustEntry> powerList = runeSkillAdjusts.get(rune_id);
powerList.add(runeSkillAdjustEntry);
runeSkillAdjusts.put(rune_id, powerList);
}
}
} catch (SQLException e) {
Logger.error(e);
return runeSkillAdjusts;
}
Logger.info("read: " + recordsRead + " cached: " + runeSkillAdjusts.size());
return runeSkillAdjusts;
}
public void GET_RUNE_REQS(final RuneBase rb) { public void GET_RUNE_REQS(final RuneBase rb) {
try (Connection connection = DbManager.getConnection(); try (Connection connection = DbManager.getConnection();
+36 -45
View File
@@ -12,8 +12,8 @@ package engine.db.handlers;
import engine.Enum; import engine.Enum;
import engine.gameManager.DbManager; import engine.gameManager.DbManager;
import engine.gameManager.ZoneManager; import engine.gameManager.ZoneManager;
import engine.math.Vector2f;
import engine.objects.Zone; import engine.objects.Zone;
import engine.objects.ZoneTemplate;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
import java.sql.Connection; import java.sql.Connection;
@@ -29,25 +29,21 @@ public class dbZoneHandler extends dbHandlerBase {
this.localObjectType = Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); this.localObjectType = Enum.GameObjectType.valueOf(this.localClass.getSimpleName());
} }
public ArrayList<Zone> GET_ALL_NODES(Zone zone) { public ArrayList<Zone> GET_ALL_ZONES() {
ArrayList<Zone> wsmList = new ArrayList<>();
wsmList.addAll(zone.getNodes()); ArrayList<Zone> zoneList = new ArrayList<>();
if (zone.absX == 0.0f) {
zone.absX = zone.getXCoord(); try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT `obj_zone`.*, `object`.`parent` FROM `object` INNER JOIN `obj_zone` ON `obj_zone`.`UID` = `object`.`UID` ORDER BY `object`.`UID` ASC;")) {
ResultSet rs = preparedStatement.executeQuery();
zoneList = getObjectsFromRs(rs, 2000);
} catch (SQLException e) {
Logger.error(e);
} }
if (zone.absY == 0.0f) {
zone.absY = zone.getYCoord(); return zoneList;
}
if (zone.absZ == 0.0f) {
zone.absZ = zone.getZCoord();
}
for (Zone child : zone.getNodes()) {
child.absX = child.getXCoord() + zone.absX;
child.absY = child.getYCoord() + zone.absY;
child.absZ = child.getZCoord() + zone.absZ;
wsmList.addAll(this.GET_ALL_NODES(child));
}
return wsmList;
} }
public Zone GET_BY_UID(long ID) { public Zone GET_BY_UID(long ID) {
@@ -72,43 +68,38 @@ public class dbZoneHandler extends dbHandlerBase {
return zone; return zone;
} }
public ArrayList<Zone> GET_MAP_NODES(final int objectUUID) { public void LOAD_ALL_ZONE_TEMPLATES() {
ArrayList<Zone> zoneList = new ArrayList<>();
try (Connection connection = DbManager.getConnection(); try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT `obj_zone`.*, `object`.`parent` FROM `object` INNER JOIN `obj_zone` ON `obj_zone`.`UID` = `object`.`UID` WHERE `object`.`parent` = ?;")) { PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_zone_templates")) {
preparedStatement.setLong(1, objectUUID);
ResultSet rs = preparedStatement.executeQuery();
zoneList = getObjectsFromRs(rs, 2000);
} catch (SQLException e) {
Logger.error(e);
}
return zoneList;
}
public void LOAD_ZONE_EXTENTS() {
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_zone_size`;")) {
ResultSet rs = preparedStatement.executeQuery(); ResultSet rs = preparedStatement.executeQuery();
while (rs.next()) { while (rs.next()) {
Vector2f zoneSize = new Vector2f(); ZoneTemplate zoneTemplate = new ZoneTemplate(rs);
int loadNum = rs.getInt("loadNum"); ZoneManager._zone_templates.put(zoneTemplate.templateID, zoneTemplate);
zoneSize.x = rs.getFloat("xRadius");
zoneSize.y = rs.getFloat("zRadius");
ZoneManager._zone_size_data.put(loadNum, zoneSize);
} }
// Add player city
ZoneTemplate zoneTemplate = new ZoneTemplate();
zoneTemplate.templateID = 0;
zoneTemplate.sea_level_type = "PARENT";
zoneTemplate.sea_level = 0;
zoneTemplate.max_blend = 128;
zoneTemplate.min_blend = 128;
zoneTemplate.terrain_max_y = 5;
zoneTemplate.major_radius = (int) Enum.CityBoundsType.ZONE.halfExtents;
zoneTemplate.minor_radius = (int) Enum.CityBoundsType.ZONE.halfExtents;
zoneTemplate.terrain_type = "PLANAR";
ZoneManager._zone_templates.put(zoneTemplate.templateID, zoneTemplate);
} catch (SQLException e) { } catch (SQLException e) {
Logger.error(e); Logger.error(e);
} }
} }
public boolean DELETE_ZONE(final Zone zone) { public boolean DELETE_ZONE(final Zone zone) {
+4 -3
View File
@@ -9,6 +9,7 @@
package engine.devcmd.cmds; package engine.devcmd.cmds;
import engine.Enum;
import engine.Enum.GameObjectType; import engine.Enum.GameObjectType;
import engine.devcmd.AbstractDevCmd; import engine.devcmd.AbstractDevCmd;
import engine.gameManager.ChatManager; import engine.gameManager.ChatManager;
@@ -43,7 +44,7 @@ public class AddMobCmd extends AbstractDevCmd {
MobBase mb = (MobBase) mobbaseAGO; MobBase mb = (MobBase) mobbaseAGO;
int loadID = mb.getObjectUUID(); int loadID = mb.getObjectUUID();
Mob mob = Mob.createMob(loadID, Vector3fImmutable.getRandomPointInCircle(pc.getLoc(), 100), Mob mob = Mob.createMob(loadID, Vector3fImmutable.getRandomPointInCircle(pc.getLoc(), 100),
null, true, zone, null, 0, "", 1); null, zone, null, null, "", 1, Enum.AIAgentType.MOBILE);
if (mob != null) { if (mob != null) {
mob.updateDatabase(); mob.updateDatabase();
this.setResult(String.valueOf(mob.getDBID())); this.setResult(String.valueOf(mob.getDBID()));
@@ -77,14 +78,14 @@ public class AddMobCmd extends AbstractDevCmd {
return; return;
} }
if (zone.isPlayerCity()) { if (zone.guild_zone) {
throwbackError(pc, "Cannot use ./mob on Player cities. Try ./servermob instead."); throwbackError(pc, "Cannot use ./mob on Player cities. Try ./servermob instead.");
return; return;
} }
Mob mob = Mob.createMob(loadID, pc.getLoc(), Mob mob = Mob.createMob(loadID, pc.getLoc(),
null, true, zone, null, 0, "", 1); null, zone, null, null, "", 1, Enum.AIAgentType.MOBILE);
if (mob != null) { if (mob != null) {
mob.updateDatabase(); mob.updateDatabase();
ChatManager.chatSayInfo(pc, ChatManager.chatSayInfo(pc,
@@ -1,70 +0,0 @@
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
package engine.devcmd.cmds;
import engine.InterestManagement.HeightMap;
import engine.devcmd.AbstractDevCmd;
import engine.gameManager.ZoneManager;
import engine.math.Vector2f;
import engine.math.Vector3fImmutable;
import engine.objects.AbstractGameObject;
import engine.objects.PlayerCharacter;
import engine.objects.Zone;
public class AuditHeightMapCmd extends AbstractDevCmd {
public AuditHeightMapCmd() {
super("auditheightmap");
}
@Override
protected void _doCmd(PlayerCharacter pcSender, String[] words,
AbstractGameObject target) {
int count = Integer.parseInt(words[0]);
long start = System.currentTimeMillis();
for (int i = 0; i < count; i++) {
Zone currentZone = ZoneManager.findSmallestZone(pcSender.getLoc());
Vector3fImmutable currentLoc = Vector3fImmutable.getRandomPointInCircle(currentZone.getLoc(), currentZone.getBounds().getHalfExtents().x < currentZone.getBounds().getHalfExtents().y ? currentZone.getBounds().getHalfExtents().x : currentZone.getBounds().getHalfExtents().y);
Vector2f zoneLoc = ZoneManager.worldToZoneSpace(currentLoc, currentZone);
if (currentZone != null && currentZone.getHeightMap() != null) {
float altitude = currentZone.getHeightMap().getInterpolatedTerrainHeight(zoneLoc);
float outsetAltitude = HeightMap.getOutsetHeight(altitude, currentZone, pcSender.getLoc());
}
}
long end = System.currentTimeMillis();
long delta = end - start;
this.throwbackInfo(pcSender, "Audit Heightmap took " + delta + " ms to run " + count + " times!");
}
@Override
protected String _getUsageString() {
return "' /auditmobs [zone.UUID]'";
}
@Override
protected String _getHelpString() {
return "Audits all the mobs in a zone.";
}
}
+3 -3
View File
@@ -40,8 +40,8 @@ public class AuditMobsCmd extends AbstractDevCmd {
if (size >= count) { if (size >= count) {
plusplus++; plusplus++;
throwbackInfo(pcSender, zoneMicro.getName() + " at location " + zoneMicro.getLoc().toString() + " has " + size + " mobs. "); throwbackInfo(pcSender, zoneMicro.zoneName + " at location " + zoneMicro.getLoc().toString() + " has " + size + " mobs. ");
System.out.println(zoneMicro.getName() + " at location " + zoneMicro.getLoc().toString() + " has " + size + " mobs. "); System.out.println(zoneMicro.zoneName + " at location " + zoneMicro.getLoc().toString() + " has " + size + " mobs. ");
} }
@@ -80,7 +80,7 @@ public class AuditMobsCmd extends AbstractDevCmd {
//ConcurrentHashMap<Mob, Long> respawnMap = Mob.getRespawnMap(); //ConcurrentHashMap<Mob, Long> respawnMap = Mob.getRespawnMap();
// ConcurrentHashMap<Mob, Long> despawnMap = Mob.getDespawnMap(); // ConcurrentHashMap<Mob, Long> despawnMap = Mob.getDespawnMap();
throwbackInfo(pcSender, zone.getName() + ", numMobs: " + zone.zoneMobSet.size()); throwbackInfo(pcSender, zone.zoneName + ", numMobs: " + zone.zoneMobSet.size());
throwbackInfo(pcSender, "UUID, dbID, inRespawnMap, isAlive, activeAI, Loc"); throwbackInfo(pcSender, "UUID, dbID, inRespawnMap, isAlive, activeAI, Loc");
+60
View File
@@ -0,0 +1,60 @@
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
package engine.devcmd.cmds;
import engine.CollisionEngine.Mesh;
import engine.Enum;
import engine.devcmd.AbstractDevCmd;
import engine.objects.*;
public class ColliderCmd extends AbstractDevCmd {
public ColliderCmd() {
super("collider");
}
@Override
protected void _doCmd(PlayerCharacter pc, String[] words,
AbstractGameObject target) {
String newline = "\r\n ";
String output;
if(target.getObjectType().equals(Enum.GameObjectType.Building) == false){
throwbackInfo(pc,"Please Select A Building To Show Collider Data");
}
Building building = (Building)target;
output = "Collision Info:" + newline;
output += "Total Meshes: " + building.buildingMeshes.size() + newline;
for(Mesh mesh : building.buildingMeshes){
output += "-----------------------------" + newline;
output += "Mesh ID: " + mesh.mesh_id + newline;
output += "Mesh Location: " + mesh.mesh_location + newline;
output += "Mesh Scale: " + mesh.mesh_scale + newline;
output += "Mesh Min/Max: " + mesh.mesh_min_y + "/" + mesh.mesh_max_y + newline;
output += "Mesh Triangle Count: " + mesh.triangles.size() + newline;
output += "Mesh Rect: " + mesh.mesh_bounds + newline;
output += "-----------------------------" + newline;
}
throwbackInfo(pc,output);
}
@Override
protected String _getHelpString() {
return "Displays Information About Colliders";
}
@Override
protected String _getUsageString() {
return "' /collider displays collision info when selected on a building";
}
}
+45 -172
View File
@@ -9,11 +9,10 @@
package engine.devcmd.cmds; package engine.devcmd.cmds;
import engine.InterestManagement.HeightMap; import engine.InterestManagement.Terrain;
import engine.devcmd.AbstractDevCmd; import engine.devcmd.AbstractDevCmd;
import engine.gameManager.ZoneManager; import engine.gameManager.ZoneManager;
import engine.math.Vector2f; import engine.math.Vector2f;
import engine.math.Vector3fImmutable;
import engine.objects.AbstractGameObject; import engine.objects.AbstractGameObject;
import engine.objects.PlayerCharacter; import engine.objects.PlayerCharacter;
import engine.objects.Zone; import engine.objects.Zone;
@@ -22,205 +21,79 @@ public class GetHeightCmd extends AbstractDevCmd {
public GetHeightCmd() { public GetHeightCmd() {
super("getHeight"); super("getHeight");
this.addCmdString("height");
} }
@Override @Override
protected void _doCmd(PlayerCharacter pc, String[] words, protected void _doCmd(PlayerCharacter playerCharacter, String[] words,
AbstractGameObject target) { AbstractGameObject target) {
boolean end = true; Zone currentZone;
Zone parentZone;
Zone heightmapZone;
float height = HeightMap.getWorldHeight(pc); currentZone = ZoneManager.findSmallestZone(playerCharacter.getLoc());
heightmapZone = Terrain.getNextZoneWithTerrain(currentZone);
parentZone = Terrain.getNextZoneWithTerrain(currentZone.parent);
this.throwbackInfo(pc, "Altitude : " + height); Vector2f childZoneLoc = ZoneManager.worldToTerrainSpace(playerCharacter.getLoc(), heightmapZone);
Vector2f childZoneOffset = ZoneManager.worldToZoneOffset(playerCharacter.getLoc(), heightmapZone);
Vector2f normalizedOffset = new Vector2f(Math.abs(childZoneOffset.x) / heightmapZone.template.major_radius,
Math.abs(childZoneOffset.y) / heightmapZone.template.minor_radius);
Vector2f parentZoneLoc = ZoneManager.worldToTerrainSpace(playerCharacter.getLoc(), parentZone);
this.throwbackInfo(pc, "Character Height: " + pc.getCharacterHeight()); float childHeight = heightmapZone.terrain.getInterpolatedTerrainHeight(childZoneLoc);
this.throwbackInfo(pc, "Character Height to start swimming: " + pc.centerHeight); childHeight = childHeight + heightmapZone.global_height;
Zone zone = ZoneManager.findSmallestZone(pc.getLoc()); float parentHeight = parentZone.terrain.getInterpolatedTerrainHeight(parentZoneLoc);
this.throwbackInfo(pc, "Water Level : " + zone.getSeaLevel()); parentHeight += parentZone.global_height;
this.throwbackInfo(pc, "Character Water Level Above : " + (pc.getCharacterHeight() + height - zone.getSeaLevel()));
if (end) float blendedHeight = Terrain.getWorldHeight(currentZone, playerCharacter.getLoc());
return;
Vector2f gridSquare; Vector2f terrainCell = heightmapZone.terrain.getTerrainCell(childZoneLoc);
Vector2f gridOffset; Vector2f cell_offset = new Vector2f(terrainCell.x % 1, terrainCell.y % 1);
Vector2f parentGrid;
Vector2f parentLoc = new Vector2f(-1, -1);
Zone currentZone = ZoneManager.findSmallestZone(pc.getLoc()); terrainCell.x = (float) Math.floor(terrainCell.x);
terrainCell.y = (float) Math.floor(terrainCell.y);
if (currentZone == null)
return;
Zone parentZone = currentZone.getParent();
HeightMap heightMap = currentZone.getHeightMap();
//find the next parents heightmap if the currentzone heightmap is null. short top_left_pixel = heightmapZone.terrain.terrain_pixel_data[(int) terrainCell.x][(int) terrainCell.y];
while (heightMap == null) { short top_right_pixel = heightmapZone.terrain.terrain_pixel_data[(int) terrainCell.x + 1][(int) terrainCell.y];
short bottom_left_pixel = heightmapZone.terrain.terrain_pixel_data[(int) terrainCell.x][(int) terrainCell.y + 1];
short bottom_right_pixel = heightmapZone.terrain.terrain_pixel_data[(int) terrainCell.x + 1][(int) terrainCell.y + 1];
if (currentZone == ZoneManager.getSeaFloor()) { this.throwbackInfo(playerCharacter, "Current Zone : " + currentZone.zoneName);
this.throwbackInfo(pc, "Could not find a heightmap to get height."); this.throwbackInfo(playerCharacter, "Heightmap Zone : " + heightmapZone.zoneName);
break; this.throwbackInfo(playerCharacter, "Parent Zone: " + parentZone.zoneName);
}
this.throwbackError(pc, "Heightmap does not exist for " + currentZone.getName()); this.throwbackInfo(playerCharacter, "Player loc: " + "[" + playerCharacter.loc.x + "]" + "[" + playerCharacter.loc.y + "]" + "[" + playerCharacter.loc.z + "]");
this.throwbackInfo(pc, "Using parent zone instead: ");
currentZone = currentZone.getParent();
heightMap = currentZone.getHeightMap();
}
this.throwbackInfo(playerCharacter, "Terrain Cell : " + "[" + terrainCell.x + "]" + "[" + terrainCell.y + "]");
this.throwbackInfo(playerCharacter, "Cell Offset : " + "[" + cell_offset.x + "]" + "[" + cell_offset.y + "]");
this.throwbackInfo(playerCharacter, "Pixels : " + "[" + top_left_pixel + "]" + "[" + top_right_pixel + "]");
this.throwbackInfo(playerCharacter, "Pixels : " + "[" + bottom_left_pixel + "]" + "[" + bottom_right_pixel + "]");
if ((heightMap == null) || (currentZone == ZoneManager.getSeaFloor())) { this.throwbackInfo(playerCharacter, "Child Zone Offset: " + "[" + childZoneOffset.x + "]" + "[" + childZoneOffset.y + "]");
this.throwbackInfo(pc, currentZone.getName() + " has no heightmap "); this.throwbackInfo(playerCharacter, "Normalized offset: " + "[" + normalizedOffset.x + "]" + "[" + normalizedOffset.y + "]");
this.throwbackInfo(pc, "Current altitude: " + currentZone.absY); this.throwbackInfo(playerCharacter, "template blend Values: (max/min): " + heightmapZone.template.max_blend + " /" + heightmapZone.template.min_blend);
return; this.throwbackInfo(playerCharacter, "terrain values (max/min): " + heightmapZone.terrain.blend_values.x + " /" + heightmapZone.terrain.blend_values.y);
} this.throwbackInfo(playerCharacter, "Blend coefficient: " + heightmapZone.terrain.getTerrainBlendCoefficient(childZoneOffset));
Vector2f zoneLoc = ZoneManager.worldToZoneSpace(pc.getLoc(), currentZone); this.throwbackInfo(playerCharacter, "------------");
Vector3fImmutable seaFloorLocalLoc = ZoneManager.worldToLocal(pc.getLoc(), ZoneManager.getSeaFloor());
this.throwbackInfo(pc, "SeaFloor Local : " + seaFloorLocalLoc.x + " , " + seaFloorLocalLoc.y);
this.throwbackInfo(pc, "Local Zone Location : " + zoneLoc.x + " , " + zoneLoc.y);
Vector3fImmutable localLocFromCenter = ZoneManager.worldToLocal(pc.getLoc(), currentZone);
Vector3fImmutable parentLocFromCenter = ZoneManager.worldToLocal(pc.getLoc(), currentZone.getParent());
this.throwbackInfo(pc, "Local Zone Location from center : " + localLocFromCenter);
this.throwbackInfo(pc, "parent Zone Location from center : " + parentLocFromCenter);
Vector2f parentZoneLoc = ZoneManager.worldToZoneSpace(pc.getLoc(), currentZone.getParent());
this.throwbackInfo(pc, "Parent Zone Location from Bottom Left : " + parentZoneLoc);
if ((parentZone != null) && (parentZone.getHeightMap() != null)) {
parentLoc = ZoneManager.worldToZoneSpace(pc.getLoc(), parentZone);
parentGrid = parentZone.getHeightMap().getGridSquare(parentLoc);
} else
parentGrid = new Vector2f(-1, -1);
gridSquare = heightMap.getGridSquare(zoneLoc);
gridOffset = HeightMap.getGridOffset(gridSquare);
float interaltitude = currentZone.getHeightMap().getInterpolatedTerrainHeight(zoneLoc);
this.throwbackInfo(pc, currentZone.getName());
this.throwbackInfo(pc, "Current Grid Square: " + gridSquare.x + " , " + gridSquare.y);
this.throwbackInfo(pc, "Grid Offset: " + gridOffset.x + " , " + gridOffset.y);
this.throwbackInfo(pc, "Parent Grid: " + parentGrid.x + " , " + parentGrid.y);
if (parentGrid.x != -1) {
float parentAltitude = parentZone.getHeightMap().getInterpolatedTerrainHeight(parentLoc);
this.throwbackInfo(pc, "Parent ALTITUDE: " + (parentAltitude));
this.throwbackInfo(pc, "Parent Interpolation: " + (parentAltitude + parentZone.getWorldAltitude()));
}
this.throwbackInfo(pc, "interpolated height: " + interaltitude);
this.throwbackInfo(pc, "interpolated height with World: " + (interaltitude + currentZone.getWorldAltitude()));
float realWorldAltitude = interaltitude + currentZone.getWorldAltitude();
//OUTSET
if (parentZone != null) {
float parentXRadius = currentZone.getBounds().getHalfExtents().x;
float parentZRadius = currentZone.getBounds().getHalfExtents().y;
float offsetX = Math.abs((localLocFromCenter.x / parentXRadius));
float offsetZ = Math.abs((localLocFromCenter.z / parentZRadius));
float bucketScaleX = 100 / parentXRadius;
float bucketScaleZ = 200 / parentZRadius;
float outsideGridSizeX = 1 - bucketScaleX; //32/256
float outsideGridSizeZ = 1 - bucketScaleZ;
float weight;
double scale;
if (offsetX > outsideGridSizeX && offsetX > offsetZ) {
weight = (offsetX - outsideGridSizeX) / bucketScaleX;
scale = Math.atan2((.5 - weight) * 3.1415927, 1);
float scaleChild = (float) ((scale + 1) * .5);
float scaleParent = 1 - scaleChild;
float parentAltitude = parentZone.getHeightMap().getInterpolatedTerrainHeight(parentLoc);
float parentCenterAltitude = parentZone.getHeightMap().getInterpolatedTerrainHeight(ZoneManager.worldToZoneSpace(currentZone.getLoc(), parentZone));
parentCenterAltitude += currentZone.getYCoord();
parentCenterAltitude += interaltitude;
float firstScale = parentAltitude * scaleParent;
float secondScale = parentCenterAltitude * scaleChild;
float outsetALt = firstScale + secondScale;
outsetALt += currentZone.getParent().getAbsY();
realWorldAltitude = outsetALt;
} else if (offsetZ > outsideGridSizeZ) {
weight = (offsetZ - outsideGridSizeZ) / bucketScaleZ;
scale = Math.atan2((.5 - weight) * 3.1415927, 1);
float scaleChild = (float) ((scale + 1) * .5);
float scaleParent = 1 - scaleChild;
float parentAltitude = parentZone.getHeightMap().getInterpolatedTerrainHeight(parentLoc);
float parentCenterAltitude = parentZone.getHeightMap().getInterpolatedTerrainHeight(ZoneManager.worldToZoneSpace(currentZone.getLoc(), parentZone));
parentCenterAltitude += currentZone.getYCoord();
parentCenterAltitude += interaltitude;
float firstScale = parentAltitude * scaleParent;
float secondScale = parentCenterAltitude * scaleChild;
float outsetALt = firstScale + secondScale;
outsetALt += currentZone.getParent().getAbsY();
realWorldAltitude = outsetALt;
}
}
float strMod = pc.statStrBase - 40;
strMod *= .00999999998f;
strMod += 1f;
float radius = 0;
switch (pc.getRaceID()) {
case 2017:
radius = 3.1415927f;
case 2000:
}
strMod *= 1.5707964f;
strMod += 3.1415927f;
strMod -= .5f;
realWorldAltitude += strMod;
this.throwbackInfo(pc, "interpolated height with World: " + realWorldAltitude);
this.throwbackInfo(playerCharacter, "Child Height at loc: " + Math.ceil(childHeight));
this.throwbackInfo(playerCharacter, "Parent Height at loc: " + Math.ceil(parentHeight));
this.throwbackInfo(playerCharacter, "Blended Height (Ceil): " + blendedHeight + " (" + Math.ceil(blendedHeight) + ")");
} }
@Override @Override
protected String _getHelpString() { protected String _getHelpString() {
return "Temporarily Changes SubRace"; return "Queries heightmap engine";
} }
@Override @Override
protected String _getUsageString() { protected String _getUsageString() {
return "' /subrace mobBaseID"; return "' /getheight";
} }
} }
+1 -1
View File
@@ -48,7 +48,7 @@ public class GetOffsetCmd extends AbstractDevCmd {
float difY = pcSender.getLoc().y - zone.absY; float difY = pcSender.getLoc().y - zone.absY;
float difZ = pcSender.getLoc().z - zone.absZ; float difZ = pcSender.getLoc().z - zone.absZ;
throwbackInfo(pcSender, zone.getName() + ": (x: " + difX + ", y: " + difY + ", z: " + difZ + ')'); throwbackInfo(pcSender, zone.zoneName + ": (x: " + difX + ", y: " + difY + ", z: " + difZ + ')');
} }
@Override @Override
+1 -1
View File
@@ -51,7 +51,7 @@ public class GetZoneCmd extends AbstractDevCmd {
} }
for (Zone zone : allIn) for (Zone zone : allIn)
throwbackInfo(pcSender, zone.getName() + "; UUID: " + zone.getObjectUUID() + ", loadNum: " + zone.getLoadNum()); throwbackInfo(pcSender, zone.zoneName + "; UUID: " + zone.getObjectUUID() + ", loadNum: " + zone.templateID);
} }
@Override @Override
+3 -3
View File
@@ -81,7 +81,7 @@ public class GotoCmd extends AbstractDevCmd {
continue; continue;
Zone zone = city.getParent(); Zone zone = city.getParent();
if (zone != null) { if (zone != null) {
if (zone.isNPCCity() || zone.isPlayerCity()) if (zone.isNPCCity || zone.guild_zone)
loc = Vector3fImmutable.getRandomPointOnCircle(zone.getLoc(), MBServerStatics.TREE_TELEPORT_RADIUS); loc = Vector3fImmutable.getRandomPointOnCircle(zone.getLoc(), MBServerStatics.TREE_TELEPORT_RADIUS);
else else
loc = zone.getLoc(); loc = zone.getLoc();
@@ -97,10 +97,10 @@ public class GotoCmd extends AbstractDevCmd {
Zone zone = (Zone) zoneAgo; Zone zone = (Zone) zoneAgo;
if (zone == null) if (zone == null)
continue; continue;
if (!zone.getName().equalsIgnoreCase(cityName)) if (!zone.zoneName.equalsIgnoreCase(cityName))
continue; continue;
if (zone != null) { if (zone != null) {
if (zone.isNPCCity() || zone.isPlayerCity()) if (zone.isNPCCity || zone.guild_zone)
loc = Vector3fImmutable.getRandomPointOnCircle(zone.getLoc(), MBServerStatics.TREE_TELEPORT_RADIUS); loc = Vector3fImmutable.getRandomPointOnCircle(zone.getLoc(), MBServerStatics.TREE_TELEPORT_RADIUS);
else else
loc = zone.getLoc(); loc = zone.getLoc();
+2 -2
View File
@@ -40,7 +40,7 @@ public class HotzoneCmd extends AbstractDevCmd {
String input = data.toString().trim(); String input = data.toString().trim();
if (input.length() == 0) { if (input.length() == 0) {
outString = "Current hotZone: " + ZoneManager.hotZone.getName() + "\r\n"; outString = "Current hotZone: " + ZoneManager.hotZone.zoneName + "\r\n";
outString += "Available hotZones: " + ZoneManager.availableHotZones(); outString += "Available hotZones: " + ZoneManager.availableHotZones();
throwbackInfo(playerCharacter, outString); throwbackInfo(playerCharacter, outString);
return; return;
@@ -48,7 +48,7 @@ public class HotzoneCmd extends AbstractDevCmd {
if (input.equalsIgnoreCase("random")) { if (input.equalsIgnoreCase("random")) {
ZoneManager.generateAndSetRandomHotzone(); ZoneManager.generateAndSetRandomHotzone();
outString = "New hotZone: " + ZoneManager.hotZone.getName() + "\r\n"; outString = "New hotZone: " + ZoneManager.hotZone.zoneName + "\r\n";
outString += "Available hotZones: " + ZoneManager.availableHotZones(); outString += "Available hotZones: " + ZoneManager.availableHotZones();
throwbackInfo(playerCharacter, outString); throwbackInfo(playerCharacter, outString);
return; return;
+6 -4
View File
@@ -9,6 +9,7 @@
package engine.devcmd.cmds; package engine.devcmd.cmds;
import engine.CollisionEngine.Mesh;
import engine.Enum; import engine.Enum;
import engine.Enum.BuildingGroup; import engine.Enum.BuildingGroup;
import engine.Enum.GameObjectType; import engine.Enum.GameObjectType;
@@ -244,7 +245,6 @@ public class InfoCmd extends AbstractDevCmd {
for (Regions regions : targetBuilding.getBounds().getRegions()) { for (Regions regions : targetBuilding.getBounds().getRegions()) {
//TODO ADD REGION INFO //TODO ADD REGION INFO
} }
break; break;
case PlayerCharacter: case PlayerCharacter:
output += newline; output += newline;
@@ -387,7 +387,7 @@ public class InfoCmd extends AbstractDevCmd {
output += newline; output += newline;
output += "EquipSet: " + targetNPC.getEquipmentSetID(); output += "EquipSet: " + targetNPC.getEquipmentSetID();
output += newline; output += newline;
output += "Parent Zone LoadNum : " + targetNPC.getParentZone().getLoadNum(); output += "Parent Zone LoadNum : " + targetNPC.getParentZone().templateID;
} }
@@ -440,7 +440,9 @@ public class InfoCmd extends AbstractDevCmd {
output += "isSummonedPet: true"; output += "isSummonedPet: true";
else else
output += "isSummonedPet: false"; output += "isSummonedPet: false";
PlayerCharacter owner = targetMob.getOwner();
PlayerCharacter owner = (PlayerCharacter) targetMob.guardCaptain;
if (owner != null) if (owner != null)
output += " owner: " + owner.getObjectUUID(); output += " owner: " + owner.getObjectUUID();
output += newline; output += newline;
@@ -471,7 +473,7 @@ public class InfoCmd extends AbstractDevCmd {
output += "EquipSet: " + targetMob.equipmentSetID; output += "EquipSet: " + targetMob.equipmentSetID;
output += newline; output += newline;
try { try {
output += "Parent Zone LoadNum : " + targetMob.getParentZone().getLoadNum(); output += "Parent Zone LoadNum : " + targetMob.getParentZone().templateID;
} catch (Exception ex) { } catch (Exception ex) {
//who cares //who cares
} }
+3 -3
View File
@@ -111,12 +111,12 @@ public class MakeBaneCmd extends AbstractDevCmd {
return; return;
} }
if (!zone.isPlayerCity()) { if (!zone.guild_zone) {
throwbackError(pc, "This is not a player city."); throwbackError(pc, "This is not a player city.");
return; return;
} }
City city = City.getCity(zone.getPlayerCityUUID()); City city = City.getCity(zone.playerCityUUID);
if (city == null) { if (city == null) {
throwbackError(pc, "Unable to find the city associated with this zone."); throwbackError(pc, "Unable to find the city associated with this zone.");
return; return;
@@ -167,7 +167,7 @@ public class MakeBaneCmd extends AbstractDevCmd {
return; return;
} }
stone.addEffectBit((1 << 19)); stone.addEffectBit((1 << 19));
stone.setRank((byte) rank); BuildingManager.setRank(stone, (byte) rank);
stone.setMaxHitPoints(blueprint.getMaxHealth(stone.getRank())); stone.setMaxHitPoints(blueprint.getMaxHealth(stone.getRank()));
stone.setCurrentHitPoints(stone.getMaxHitPoints()); stone.setCurrentHitPoints(stone.getMaxHitPoints());
BuildingManager.setUpgradeDateTime(stone, null, 0); BuildingManager.setUpgradeDateTime(stone, null, 0);
@@ -0,0 +1,67 @@
// ·. · · · · .
// · ·
// · ·
//
// · · ·
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
package engine.devcmd.cmds;
import engine.devcmd.AbstractDevCmd;
import engine.objects.*;
import java.util.HashMap;
/**
*
*/
public class PrintEffectsCmd extends AbstractDevCmd {
public PrintEffectsCmd() {
super("printeffects");
// super("printstats", MBServerStatics.ACCESS_LEVEL_ADMIN);
}
public static ItemBase getWeaponBase(int slot, HashMap<Integer, MobEquipment> equip) {
if (equip.containsKey(slot)) {
MobEquipment item = equip.get(slot);
if (item != null && item.getItemBase() != null) {
return item.getItemBase();
}
}
return null;
}
@Override
protected void _doCmd(PlayerCharacter pc, String[] words,
AbstractGameObject target) {
AbstractCharacter tar;
if (target != null && target instanceof AbstractCharacter) {
tar = (AbstractCharacter) target;
String newline = "\r\n ";
String output = "Effects For Character: " + tar.getName() + newline;
for(String effect : tar.effects.keySet()){
output += effect + newline;
}
throwbackInfo(pc, output);
}
}
@Override
protected String _getHelpString() {
return "Returns the player's current stats";
}
@Override
protected String _getUsageString() {
return "' /printstats'";
}
}
+67
View File
@@ -0,0 +1,67 @@
// ·. · · · · .
// · ·
// · ·
//
// · · ·
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
package engine.devcmd.cmds;
import engine.devcmd.AbstractDevCmd;
import engine.objects.*;
import java.util.HashMap;
/**
*
*/
public class PrintRunesCmd extends AbstractDevCmd {
public PrintRunesCmd() {
super("printrunes");
// super("printstats", MBServerStatics.ACCESS_LEVEL_ADMIN);
}
public static ItemBase getWeaponBase(int slot, HashMap<Integer, MobEquipment> equip) {
if (equip.containsKey(slot)) {
MobEquipment item = equip.get(slot);
if (item != null && item.getItemBase() != null) {
return item.getItemBase();
}
}
return null;
}
@Override
protected void _doCmd(PlayerCharacter pc, String[] words,
AbstractGameObject target) {
AbstractCharacter tar;
if (target != null && target instanceof AbstractCharacter) {
tar = (AbstractCharacter) target;
String newline = "\r\n ";
String output = "Applied Runes For Character: " + ((AbstractCharacter) target).getName() + newline;
for(CharacterRune rune : ((AbstractCharacter)target).runes){
output += rune.getRuneBaseID() + " " + rune.getRuneBase().getName() + newline;
}
throwbackInfo(pc, output);
}
}
@Override
protected String _getHelpString() {
return "Returns the player's current stats";
}
@Override
protected String _getUsageString() {
return "' /printstats'";
}
}
+13 -9
View File
@@ -103,15 +103,19 @@ public class PrintStatsCmd extends AbstractDevCmd {
main = getWeaponBase(1, equip); main = getWeaponBase(1, equip);
ItemBase off = null; ItemBase off = null;
if (equip != null) if(equip != null){
getWeaponBase(2, equip); if(equip.get(2) != null && !equip.get(2).getItemBase().isShield()){
if (main == null && off == null) { //off hand weapon
out += "Main Hand: atr: " + tar.getAtrHandOne() + ", damage: " + tar.getMinDamageHandOne() + " to " + tar.getMaxDamageHandOne() + ", speed: " + tar.getSpeedHandOne() + ", range: 6" + newline; out += "Attack Rating: " + tar.atrHandTwo + newline;
} else { out += "Damage: " + tar.minDamageHandTwo + " - " + tar.maxDamageHandTwo + newline;
if (main != null) out += "Range: " + tar.rangeHandTwo + newline;
out += "Main Hand: atr: " + tar.getAtrHandOne() + ", damage: " + tar.getMinDamageHandOne() + " to " + tar.getMaxDamageHandOne() + ", speed: " + tar.getSpeedHandOne() + ", range: " + main.getRange() + newline; out += "Attack Speed: " + tar.speedHandTwo + newline;
if (off != null) } else{
out += "Main Hand: atr: " + tar.getAtrHandTwo() + ", damage: " + tar.getMinDamageHandTwo() + " to " + tar.getMaxDamageHandTwo() + ", speed: " + tar.getSpeedHandTwo() + ", range: " + off.getRange() + newline; out += "Attack Rating: " + tar.atrHandOne + newline;
out += "Damage: " + tar.minDamageHandOne + " - " + tar.maxDamageHandOne + newline;
out += "Range: " + tar.rangeHandOne + newline;
out += "Attack Speed: " + tar.speedHandOne + newline;
}
} }
out += "isAlive: " + tar.isAlive() + ", Combat: " + tar.isCombat() + newline; out += "isAlive: " + tar.isAlive() + ", Combat: " + tar.isCombat() + newline;
+14 -9
View File
@@ -42,7 +42,7 @@ public class PurgeObjectsCmd extends AbstractDevCmd {
private static void PurgeWalls(Zone zone, PlayerCharacter pc) { private static void PurgeWalls(Zone zone, PlayerCharacter pc) {
if (!zone.isPlayerCity()) if (!zone.guild_zone)
return; return;
for (Building building : zone.zoneBuildingSet) { for (Building building : zone.zoneBuildingSet) {
@@ -59,22 +59,25 @@ public class PurgeObjectsCmd extends AbstractDevCmd {
if (npc != null) { if (npc != null) {
for (Mob mob : npc.getSiegeMinionMap().keySet()) { for (Integer minionUUID : npc.minions) {
Mob mob = Mob.getMob(minionUUID);
WorldGrid.RemoveWorldObject(mob); WorldGrid.RemoveWorldObject(mob);
WorldGrid.removeObject(mob, pc); WorldGrid.removeObject(mob, pc);
//Mob.getRespawnMap().remove(mob);
if (mob.getParentZone() != null) if (mob.getParentZone() != null)
mob.getParentZone().zoneMobSet.remove(mob); mob.getParentZone().zoneMobSet.remove(mob);
} }
DbManager.NPCQueries.DELETE_NPC(npc); DbManager.NPCQueries.DELETE_NPC(npc);
DbManager.removeFromCache(GameObjectType.NPC, DbManager.removeFromCache(GameObjectType.NPC,
npc.getObjectUUID()); npc.getObjectUUID());
WorldGrid.RemoveWorldObject(npc); WorldGrid.RemoveWorldObject(npc);
} else if (mobA != null) { } else if (mobA != null) {
for (Mob mob : mobA.getSiegeMinionMap().keySet()) { for (Integer minionUUID : mobA.minions) {
Mob mob = Mob.getMob(minionUUID);
WorldGrid.RemoveWorldObject(mob); WorldGrid.RemoveWorldObject(mob);
WorldGrid.removeObject(mob, pc); WorldGrid.removeObject(mob, pc);
//Mob.getRespawnMap().remove(mob);
if (mob.getParentZone() != null) if (mob.getParentZone() != null)
mob.getParentZone().zoneMobSet.remove(mob); mob.getParentZone().zoneMobSet.remove(mob);
} }
@@ -151,10 +154,11 @@ public class PurgeObjectsCmd extends AbstractDevCmd {
if (npc != null) { if (npc != null) {
for (Mob mob : npc.getSiegeMinionMap().keySet()) { for (Integer minionUUID : npc.minions) {
Mob mob = Mob.getMob(minionUUID);
WorldGrid.RemoveWorldObject(mob); WorldGrid.RemoveWorldObject(mob);
WorldGrid.removeObject(mob, pc); WorldGrid.removeObject(mob, pc);
//Mob.getRespawnMap().remove(mob);
if (mob.getParentZone() != null) if (mob.getParentZone() != null)
mob.getParentZone().zoneMobSet.remove(mob); mob.getParentZone().zoneMobSet.remove(mob);
} }
@@ -163,10 +167,11 @@ public class PurgeObjectsCmd extends AbstractDevCmd {
npc.getObjectUUID()); npc.getObjectUUID());
WorldGrid.RemoveWorldObject(npc); WorldGrid.RemoveWorldObject(npc);
} else if (mobA != null) { } else if (mobA != null) {
for (Mob mob : mobA.getSiegeMinionMap().keySet()) { for (Integer minionUUID : mobA.minions) {
Mob mob = Mob.getMob(minionUUID);
WorldGrid.RemoveWorldObject(mob); WorldGrid.RemoveWorldObject(mob);
WorldGrid.removeObject(mob, pc); WorldGrid.removeObject(mob, pc);
//Mob.getRespawnMap().remove(mob);
if (mob.getParentZone() != null) if (mob.getParentZone() != null)
mob.getParentZone().zoneMobSet.remove(mob); mob.getParentZone().zoneMobSet.remove(mob);
} }
+3 -3
View File
@@ -60,12 +60,12 @@ public class RealmInfoCmd extends AbstractDevCmd {
outString += ")"; outString += ")";
outString += newline; outString += newline;
outString += " Zone: " + serverZone.getName(); outString += " Zone: " + serverZone.zoneName;
outString += newline; outString += newline;
if (serverZone.getParent() != null) if (serverZone.parent != null)
outString += " Parent: " + serverZone.getParent().getName(); outString += " Parent: " + serverZone.parent.zoneName;
else else
outString += "Parent: NONE"; outString += "Parent: NONE";
+20 -35
View File
@@ -9,11 +9,12 @@
package engine.devcmd.cmds; package engine.devcmd.cmds;
import engine.CollisionEngine.Mesh;
import engine.devcmd.AbstractDevCmd; import engine.devcmd.AbstractDevCmd;
import engine.objects.AbstractGameObject; import engine.gameManager.BuildingManager;
import engine.objects.PlayerCharacter; import engine.objects.*;
import java.lang.reflect.Field; import java.awt.geom.Point2D;
public class RegionCmd extends AbstractDevCmd { public class RegionCmd extends AbstractDevCmd {
@@ -25,43 +26,27 @@ public class RegionCmd extends AbstractDevCmd {
protected void _doCmd(PlayerCharacter pc, String[] words, protected void _doCmd(PlayerCharacter pc, String[] words,
AbstractGameObject target) { AbstractGameObject target) {
String newline = "\r\n ";
String output;
output = "Target Region Information:" + newline;
if (pc.region == null) { Building building = BuildingManager.getBuildingAtLocation(((AbstractCharacter) target).loc);
if(building == null){
this.throwbackInfo(pc, "No Building At This Location.") ;
}
Regions region = ((AbstractCharacter)target).region;
if (region == null) {
this.throwbackInfo(pc, "No Region Found."); this.throwbackInfo(pc, "No Region Found.");
return;
} }
if(region != null) {
String newLine = System.getProperty("line.separator"); output += "Player Info: " + ((AbstractCharacter) target).getName() + newline;
String result = ""; output += "Region Building: " + building.getName() + newline;
result += (pc.region.getClass().getSimpleName()); output += "Region Height: " + region.lerpY((AbstractCharacter)target) + newline;
result += (" {"); output += "is Stairs: " + region.isStairs() + newline;
result += (newLine); output += "is Outside: " + region.isOutside();
Field[] fields = pc.region.getClass().getDeclaredFields(); this.throwbackInfo(pc, output);
//print field names paired with their values
for (Field field : fields) {
field.setAccessible(true);
result += (" ");
try {
if (field.getName().contains("Furniture"))
continue;
result += (field.getName());
result += (": ");
//requires access to private field:
result += (field.get(pc.region).toString());
} catch (IllegalAccessException ex) {
System.out.println(ex);
} }
result.trim();
result += (newLine);
}
result += ("}");
this.throwbackInfo(pc, result.toString());
} }
@Override @Override
+2 -2
View File
@@ -34,12 +34,12 @@ public class RemoveBaneCmd extends AbstractDevCmd {
return; return;
} }
if (!zone.isPlayerCity()) { if (!zone.guild_zone) {
throwbackError(pc, "This is not a player city."); throwbackError(pc, "This is not a player city.");
return; return;
} }
City city = City.getCity(zone.getPlayerCityUUID()); City city = City.getCity(zone.playerCityUUID);
if (city == null) { if (city == null) {
throwbackError(pc, "Unable to find the city associated with this zone."); throwbackError(pc, "Unable to find the city associated with this zone.");
return; return;
+11 -43
View File
@@ -11,7 +11,6 @@ package engine.devcmd.cmds;
import engine.Enum.BuildingGroup; import engine.Enum.BuildingGroup;
import engine.Enum.DbObjectType; import engine.Enum.DbObjectType;
import engine.Enum.GameObjectType;
import engine.InterestManagement.WorldGrid; import engine.InterestManagement.WorldGrid;
import engine.devcmd.AbstractDevCmd; import engine.devcmd.AbstractDevCmd;
import engine.gameManager.BuildingManager; import engine.gameManager.BuildingManager;
@@ -131,56 +130,23 @@ public class RemoveObjectCmd extends AbstractDevCmd {
building.disableSpire(false); building.disableSpire(false);
if ((building.getBlueprint() != null) && (building.getBlueprint().getBuildingGroup() == BuildingGroup.WAREHOUSE)) { if ((building.getBlueprint() != null) && (building.getBlueprint().getBuildingGroup() == BuildingGroup.WAREHOUSE)) {
City city = City.getCity(building.getParentZone().getPlayerCityUUID()); City city = City.getCity(building.getParentZone().playerCityUUID);
if (city != null) { if (city != null) {
city.setWarehouseBuildingID(0); city.setWarehouseBuildingID(0);
} }
Warehouse.warehouseByBuildingUUID.remove(building.getObjectUUID()); Warehouse.warehouseByBuildingUUID.remove(building.getObjectUUID());
} }
//remove cached shrines. //remove cached shrines.
if ((building.getBlueprintUUID() != 0) if ((building.getBlueprintUUID() != 0)
&& (building.getBlueprint().getBuildingGroup() == BuildingGroup.SHRINE)) && (building.getBlueprint().getBuildingGroup() == BuildingGroup.SHRINE))
Shrine.RemoveShrineFromCacheByBuilding(building); Shrine.RemoveShrineFromCacheByBuilding(building);
for (AbstractCharacter ac : building.getHirelings().keySet()) { // Remove hirelings for this building
NPC npc = null;
Mob mobA = null;
if (ac.getObjectType() == GameObjectType.NPC) for (AbstractCharacter abstractCharacter : building.getHirelings().keySet())
npc = (NPC) ac; BuildingManager.removeHireling(building, abstractCharacter);
else if (ac.getObjectType() == GameObjectType.Mob)
mobA = (Mob) ac;
if (npc != null) {
for (Mob mob : npc.getSiegeMinionMap().keySet()) {
WorldGrid.RemoveWorldObject(mob);
WorldGrid.removeObject(mob, pc);
//Mob.getRespawnMap().remove(mob);
if (mob.getParentZone() != null)
mob.getParentZone().zoneMobSet.remove(mob);
}
DbManager.NPCQueries.DELETE_NPC(npc);
DbManager.removeFromCache(npc);
WorldGrid.RemoveWorldObject(npc);
WorldGrid.removeObject(npc, pc);
} else if (mobA != null) {
for (Mob mob : mobA.getSiegeMinionMap().keySet()) {
WorldGrid.RemoveWorldObject(mob);
WorldGrid.removeObject(mob, pc);
//Mob.getRespawnMap().remove(mob);
if (mob.getParentZone() != null)
mob.getParentZone().zoneMobSet.remove(mob);
}
DbManager.MobQueries.DELETE_MOB(mobA);
DbManager.removeFromCache(mobA);
WorldGrid.RemoveWorldObject(mobA);
WorldGrid.removeObject(mobA, pc);
}
}
Zone zone = building.getParentZone(); Zone zone = building.getParentZone();
DbManager.BuildingQueries.DELETE_FROM_DATABASE(building); DbManager.BuildingQueries.DELETE_FROM_DATABASE(building);
DbManager.removeFromCache(building); DbManager.removeFromCache(building);
@@ -209,11 +175,13 @@ public class RemoveObjectCmd extends AbstractDevCmd {
if (npc.building != null) if (npc.building != null)
npc.building.getHirelings().remove(npc); npc.building.getHirelings().remove(npc);
for (Mob mob : npc.getSiegeMinionMap().keySet()) { for (Integer minionUUID : npc.minions) {
WorldGrid.RemoveWorldObject(mob); Mob minionMob = Mob.getMob(minionUUID);
WorldGrid.removeObject(mob, pc); WorldGrid.RemoveWorldObject(minionMob);
if (mob.getParentZone() != null) WorldGrid.removeObject(minionMob, pc);
mob.getParentZone().zoneMobSet.remove(mob);
if (minionMob.getParentZone() != null)
minionMob.getParentZone().zoneMobSet.remove(minionMob);
} }
DbManager.NPCQueries.DELETE_NPC(npc); DbManager.NPCQueries.DELETE_NPC(npc);
+2 -2
View File
@@ -41,12 +41,12 @@ public class SetBaneActiveCmd extends AbstractDevCmd {
return; return;
} }
if (!zone.isPlayerCity()) { if (!zone.guild_zone) {
throwbackError(pc, "This is not a player city."); throwbackError(pc, "This is not a player city.");
return; return;
} }
City city = City.getCity(zone.getPlayerCityUUID()); City city = City.getCity(zone.playerCityUUID);
if (city == null) { if (city == null) {
throwbackError(pc, "Unable to find the city associated with this zone."); throwbackError(pc, "Unable to find the city associated with this zone.");
return; return;
@@ -31,9 +31,9 @@ public class SetForceRenameCityCmd extends AbstractDevCmd {
if (zone == null) if (zone == null)
return; return;
boolean rename = words[0].equalsIgnoreCase("true") ? true : false; boolean rename = words[0].equalsIgnoreCase("true") ? true : false;
if (zone.getPlayerCityUUID() == 0) if (zone.playerCityUUID == 0)
return; return;
City city = City.getCity(zone.getPlayerCityUUID()); City city = City.getCity(zone.playerCityUUID);
if (city == null) if (city == null)
return; return;
city.setForceRename(rename); city.setForceRename(rename);
+3 -4
View File
@@ -57,7 +57,7 @@ public class SetRankCmd extends AbstractDevCmd {
Blueprint blueprint = targetBuilding.getBlueprint(); Blueprint blueprint = targetBuilding.getBlueprint();
if (blueprint == null) { if (blueprint == null) {
targetBuilding.setRank(targetRank); BuildingManager.setRank(targetBuilding, targetRank);
ChatManager.chatSayInfo(player, "Building ranked without blueprint" + targetBuilding.getObjectUUID()); ChatManager.chatSayInfo(player, "Building ranked without blueprint" + targetBuilding.getObjectUUID());
return; return;
} }
@@ -68,9 +68,8 @@ public class SetRankCmd extends AbstractDevCmd {
} }
// Set the current targetRank // Set the current targetRank
int lastMeshID = targetBuilding.getMeshUUID();
targetBuilding.setRank(targetRank);
BuildingManager.setRank(targetBuilding, targetRank);
ChatManager.chatSayInfo(player, "Rank set for building with ID " + targetBuilding.getObjectUUID() + " to rank " + targetRank); ChatManager.chatSayInfo(player, "Rank set for building with ID " + targetBuilding.getObjectUUID() + " to rank " + targetRank);
break; break;
case NPC: case NPC:
@@ -114,7 +113,7 @@ public class SetRankCmd extends AbstractDevCmd {
// Set the current targetRank // Set the current targetRank
int lastMeshID = targetBuilding.getMeshUUID(); int lastMeshID = targetBuilding.getMeshUUID();
targetBuilding.setRank(targetRank); BuildingManager.setRank(targetBuilding, targetRank);
if (lastMeshID != targetBuilding.getMeshUUID()) if (lastMeshID != targetBuilding.getMeshUUID())
targetBuilding.refresh(true); targetBuilding.refresh(true);
+1 -1
View File
@@ -159,7 +159,7 @@ public class SetSubRaceCmd extends AbstractDevCmd {
// pum.setEffectID(token); // pum.setEffectID(token);
// pum.setSourceType(pc.getObjectType().ordinal()); // pum.setSourceType(pc.getObjectType().ordinal());
// pum.setSourceID(pc.getObjectUUID()); // pum.setSourceID(pc.getObjectUUID());
// pum.setTargetType(pc.getObjectType().ordinal()); // pum.setStartLocType(pc.getObjectType().ordinal());
// pum.setTargetID(pc.getObjectUUID()); // pum.setTargetID(pc.getObjectUUID());
// pum.setNumTrains(40); // pum.setNumTrains(40);
// pum.setDuration(-1); // pum.setDuration(-1);
+2 -1
View File
@@ -1,5 +1,6 @@
package engine.devcmd.cmds; package engine.devcmd.cmds;
import engine.Enum;
import engine.devcmd.AbstractDevCmd; import engine.devcmd.AbstractDevCmd;
import engine.gameManager.ZoneManager; import engine.gameManager.ZoneManager;
import engine.math.Vector3fImmutable; import engine.math.Vector3fImmutable;
@@ -110,7 +111,7 @@ public class SplatMobCmd extends AbstractDevCmd {
mobile = Mob.createMob(_mobileUUID, mobile = Mob.createMob(_mobileUUID,
Vector3fImmutable.getRandomPointInCircle(_currentLocation, _targetRange), Vector3fImmutable.getRandomPointInCircle(_currentLocation, _targetRange),
null, true, serverZone, null, 0, "", 1); null, serverZone, null, null, "", 1, Enum.AIAgentType.MOBILE);
if (mobile != null) { if (mobile != null) {
mobile.updateDatabase(); mobile.updateDatabase();
+1 -1
View File
@@ -40,7 +40,7 @@ public class SummonCmd extends AbstractDevCmd {
Zone zone = ZoneManager.findSmallestZone(pc.getLoc()); Zone zone = ZoneManager.findSmallestZone(pc.getLoc());
String location = "Somewhere"; String location = "Somewhere";
if (zone != null) if (zone != null)
location = zone.getName(); location = zone.zoneName;
RecvSummonsRequestMsg rsrm = new RecvSummonsRequestMsg(pc.getObjectType().ordinal(), pc.getObjectUUID(), pc.getFirstName(), RecvSummonsRequestMsg rsrm = new RecvSummonsRequestMsg(pc.getObjectType().ordinal(), pc.getObjectUUID(), pc.getFirstName(),
location, false); location, false);
toSummon.getClientConnection().sendMsg(rsrm); toSummon.getClientConnection().sendMsg(rsrm);
+17 -20
View File
@@ -73,44 +73,41 @@ public class ZoneInfoCmd extends AbstractDevCmd {
output = "Target Information:" + newline; output = "Target Information:" + newline;
output += StringUtils.addWS("UUID: " + objectUUID, 20); output += StringUtils.addWS("UUID: " + objectUUID, 20);
output += newline; output += newline;
output += "name: " + zone.getName(); output += "name: " + zone.zoneName;
output += newline; output += newline;
output += "loadNum: " + zone.getLoadNum(); output += "loadNum: " + zone.templateID;
if (zone.getParent() != null) { if (zone.parent != null) {
output += StringUtils.addWS(", parent: " + zone.getParent().getObjectUUID(), 30); output += StringUtils.addWS(", parent: " + zone.parent.getObjectUUID(), 30);
output += "Parentabs: x: " + zone.getParent().getAbsX() + ", y: " + zone.getParent().getAbsY() + ", z: " + zone.getParent().getAbsZ(); output += "Parentabs: x: " + zone.parent.absX + ", y: " + zone.parent.absY + ", z: " + zone.parent.absZ;
} else } else
output += StringUtils.addWS(", parent: none", 30); output += StringUtils.addWS(", parent: none", 30);
output += newline; output += newline;
output += "absLoc: x: " + zone.getAbsX() + ", y: " + zone.getAbsY() + ", z: " + zone.getAbsZ(); output += "absLoc: x: " + zone.absX + ", y: " + zone.absY + ", z: " + zone.absZ;
output += newline; output += newline;
output += "offset: x: " + zone.getXCoord() + ", y: " + zone.getYCoord() + ", z: " + zone.getZCoord(); output += "offset: x: " + zone.xOffset + ", y: " + zone.yOffset + ", z: " + zone.zOffset;
output += newline; output += newline;
output += "radius: x: " + zone.getBounds().getHalfExtents().x + ", z: " + zone.getBounds().getHalfExtents().y; output += "radius: x: " + zone.bounds.getHalfExtents().x + ", z: " + zone.bounds.getHalfExtents().y;
output += newline; output += newline;
if (zone.getHeightMap() != null) { if (zone.terrain != null) {
output += "HeightMap ID: " + zone.getHeightMap().getHeightMapID(); output += "Terrain image: " + zone.template.terrain_image;
output += newline; output += newline;
output += "Bucket Width X : " + zone.getHeightMap().getBucketWidthX();
output += newline;
output += "Bucket Width Y : " + zone.getHeightMap().getBucketWidthY();
} }
output += "radius: x: " + zone.getBounds().getHalfExtents().x + ", z: " + zone.getBounds().getHalfExtents().y;
output += "radius: x: " + zone.bounds.getHalfExtents().x + ", z: " + zone.bounds.getHalfExtents().y;
output += newline; output += newline;
// output += "minLvl = " + zone.getMinLvl() + " | maxLvl = " + zone.getMaxLvl(); // output += "minLvl = " + zone.getMinLvl() + " | maxLvl = " + zone.getMaxLvl();
output += newline; output += newline;
output += "Sea Level = " + zone.getSeaLevel(); output += "Sea Level = " + zone.sea_level;
output += newline; output += newline;
output += "World Altitude = " + zone.getWorldAltitude(); output += "World Altitude = " + zone.global_height;
throwbackInfo(player, output); throwbackInfo(player, output);
City city = ZoneManager.getCityAtLocation(player.getLoc()); City city = ZoneManager.getCityAtLocation(player.getLoc());
output += newline; output += newline;
output += (city == null) ? "None" : city.getParent().getName(); output += (city == null) ? "None" : city.getParent().zoneName;
if (city != null) { if (city != null) {
@@ -123,14 +120,14 @@ public class ZoneInfoCmd extends AbstractDevCmd {
} else { } else {
output = "children:"; output = "children:";
ArrayList<Zone> nodes = zone.getNodes(); ArrayList<Zone> nodes = zone.nodes;
if (nodes.isEmpty()) if (nodes.isEmpty())
output += " none"; output += " none";
for (Zone child : nodes) { for (Zone child : nodes) {
output += newline; output += newline;
output += child.getName() + " (" + child.getLoadNum() + ')'; output += child.zoneName + " (" + child.templateID + ')';
} }
} }
throwbackInfo(player, output); throwbackInfo(player, output);
+1 -1
View File
@@ -40,7 +40,7 @@ public class ZoneSetCmd extends AbstractDevCmd {
zone = ZoneManager.findSmallestZone(playerCharacter.getLoc()); zone = ZoneManager.findSmallestZone(playerCharacter.getLoc());
throwbackInfo(playerCharacter, zone.getName() + " (" + zone.getLoadNum() + ") " + zone.getObjectUUID()); throwbackInfo(playerCharacter, zone.zoneName + " (" + zone.templateID + ") " + zone.getObjectUUID());
// NPC // NPC
+77 -13
View File
@@ -9,12 +9,17 @@
package engine.devcmd.cmds; package engine.devcmd.cmds;
import engine.Enum;
import engine.Enum.GameObjectType; import engine.Enum.GameObjectType;
import engine.devcmd.AbstractDevCmd; import engine.devcmd.AbstractDevCmd;
import engine.gameManager.PowersManager;
import engine.mobileAI.MobAI;
import engine.objects.AbstractGameObject; import engine.objects.AbstractGameObject;
import engine.objects.Mob; import engine.objects.Mob;
import engine.objects.PlayerCharacter; import engine.objects.PlayerCharacter;
import engine.powers.RunePowerEntry;
import java.util.ArrayList;
import java.util.Map; import java.util.Map;
@@ -56,18 +61,39 @@ public class aiInfoCmd extends AbstractDevCmd {
Mob mob = (Mob) target; Mob mob = (Mob) target;
output = "Mob AI Information:" + newline; output = "Mob AI Information:" + newline;
output += mob.getName() + newline; output += mob.getName() + newline;
if (mob.BehaviourType != null) { output += mob.agentType.toString() + newline;
output += "BehaviourType: " + mob.BehaviourType.toString() + newline;
if (mob.BehaviourType.BehaviourHelperType != null) { int contractID = 0;
output += "Behaviour Helper Type: " + mob.BehaviourType.BehaviourHelperType.toString() + newline;
if (mob.isPlayerGuard() == true) {
if (mob.agentType.equals(Enum.AIAgentType.GUARDMINION))
contractID = mob.guardCaptain.contract.getContractID();
else
contractID = mob.contract.getContractID();
}
if (contractID != 0) {
if (mob.agentType.equals(Enum.AIAgentType.GUARDMINION)) {
output += "Captain Contract: " + contractID + newline;
output += "Captain UUID: " + mob.guardCaptain.getObjectUUID() + newline;
} else
output += "Contract: " + contractID + newline;
}
if (mob.behaviourType != null) {
output += "BehaviourType: " + mob.behaviourType.toString() + newline;
if (mob.behaviourType.BehaviourHelperType != null) {
output += "Behaviour Helper Type: " + mob.behaviourType.BehaviourHelperType.toString() + newline;
} else { } else {
output += "Behaviour Helper Type: NULL" + newline; output += "Behaviour Helper Type: NULL" + newline;
} }
output += "Wimpy: " + mob.BehaviourType.isWimpy + newline; output += "Wimpy: " + mob.behaviourType.isWimpy + newline;
output += "Agressive: " + mob.BehaviourType.isAgressive + newline; output += "Agressive: " + mob.behaviourType.isAgressive + newline;
output += "Can Roam: " + mob.BehaviourType.canRoam + newline; output += "Can Roam: " + mob.behaviourType.canRoam + newline;
output += "Calls For Help: " + mob.BehaviourType.callsForHelp + newline; output += "Calls For Help: " + mob.behaviourType.callsForHelp + newline;
output += "Responds To Call For Help: " + mob.BehaviourType.respondsToCallForHelp + newline; output += "Responds To Call For Help: " + mob.behaviourType.respondsToCallForHelp + newline;
} else { } else {
output += "BehaviourType: NULL" + newline; output += "BehaviourType: NULL" + newline;
} }
@@ -76,16 +102,54 @@ public class aiInfoCmd extends AbstractDevCmd {
if (mob.playerAgroMap.size() > 0) { if (mob.playerAgroMap.size() > 0) {
output += "Players Loaded:" + newline; output += "Players Loaded:" + newline;
} }
for (Map.Entry<Integer, Boolean> entry : mob.playerAgroMap.entrySet()) { for (Map.Entry<Integer, Float> entry : mob.playerAgroMap.entrySet()) {
output += "Player ID: " + entry.getKey() + " Hate Value: " + (PlayerCharacter.getPlayerCharacter(entry.getKey())).getHateValue() + newline; output += "Player ID: " + entry.getKey() + " Hate Value: " + entry.getValue() + newline;
} }
if (mob.getCombatTarget() != null) if (mob.getCombatTarget() != null)
output += "Current Target: " + mob.getCombatTarget().getName() + newline; output += "Current Target: " + mob.getCombatTarget().getName() + newline;
else else
output += "Current Target: NULL" + newline; output += "Current Target: NULL" + newline;
for (int token : mob.mobPowers.keySet()) if (mob.guardedCity != null)
output += token + newline; output += "Patrolling: " + mob.guardedCity.getCityName() + newline;
output += "See Invis Level: " + mob.mobBase.getSeeInvis() + newline;
output += "Can Cast: " + MobAI.canCast(mob) + newline;
output += "Powers:" + newline;
ArrayList<RunePowerEntry> powerEntries = new ArrayList<>(PowersManager.getPowersForRune(mob.getMobBaseID()));
// Additional powers may come from the contract ID. This is to support
// powers for player guards irrespective of the mobbase used.
if (mob.isPlayerGuard()) {
ArrayList<RunePowerEntry> contractEntries = new ArrayList<>();
if (mob.contract != null)
contractEntries = new ArrayList<>(PowersManager.getPowersForRune(mob.contractUUID));
if (mob.agentType.equals(Enum.AIAgentType.GUARDMINION))
contractEntries = new ArrayList<>(PowersManager.getPowersForRune(mob.guardCaptain.contractUUID));
powerEntries.addAll(contractEntries);
}
for (RunePowerEntry runePowerEntry : powerEntries)
output += PowersManager.getPowerByToken(runePowerEntry.token).getName() + newline;
// List outlaws defined for this player guard's city
if (mob.isPlayerGuard()) {
ArrayList<Integer> outlaws = new ArrayList(mob.guardedCity.cityOutlaws);
if (outlaws.isEmpty() == false)
output += "Outlaws: " + newline;
for (Integer outlawUUID : outlaws)
output += outlawUUID + newline;
}
throwbackInfo(playerCharacter, output); throwbackInfo(playerCharacter, output);
} }
+284 -51
View File
@@ -9,15 +9,21 @@
package engine.gameManager; package engine.gameManager;
import engine.CollisionEngine.CollisionManager;
import engine.CollisionEngine.MeshData;
import engine.Enum; import engine.Enum;
import engine.Enum.BuildingGroup; import engine.Enum.BuildingGroup;
import engine.Enum.GameObjectType; import engine.Enum.GameObjectType;
import engine.InterestManagement.InterestManager; import engine.InterestManagement.InterestManager;
import engine.InterestManagement.WorldGrid; import engine.InterestManagement.WorldGrid;
import engine.CollisionEngine.Mesh;
import engine.CollisionEngine.Triangle;
import engine.job.JobContainer; import engine.job.JobContainer;
import engine.job.JobScheduler; import engine.job.JobScheduler;
import engine.jobs.UpgradeBuildingJob; import engine.jobs.UpgradeBuildingJob;
import engine.math.Bounds; import engine.math.Bounds;
import engine.math.Vector2f;
import engine.math.Vector3f;
import engine.math.Vector3fImmutable; import engine.math.Vector3fImmutable;
import engine.net.client.ClientConnection; import engine.net.client.ClientConnection;
import engine.net.client.msg.ErrorPopupMsg; import engine.net.client.msg.ErrorPopupMsg;
@@ -27,19 +33,32 @@ import engine.objects.*;
import engine.server.MBServerStatics; import engine.server.MBServerStatics;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.ZoneId; import java.time.ZoneId;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
public enum BuildingManager { public enum BuildingManager {
BUILDINGMANAGER; BUILDINGMANAGER;
public static HashMap<Integer,ArrayList<Integer>> prop_meshes = new HashMap<>();
public static HashMap<Integer, Vector2f> mesh_heights = new HashMap<>();
public static HashMap<Integer,ArrayList<ArrayList<Vector3f>>> mesh_triangle_points = new HashMap<>();
public static HashMap<Integer, Rectangle2D> mesh_bounding_boxes = new HashMap<>();
public static HashMap<Integer, ArrayList<BuildingLocation>> _stuckLocations = new HashMap<>(); public static HashMap<Integer, ArrayList<BuildingLocation>> _stuckLocations = new HashMap<>();
public static HashMap<Integer, ArrayList<BuildingLocation>> _slotLocations = new HashMap<>(); public static HashMap<Integer, ArrayList<BuildingLocation>> _slotLocations = new HashMap<>();
public static HashMap<Integer, ConcurrentHashMap<Integer, BuildingFriends>> _buildingFriends = new HashMap<>();
public static HashMap<Integer, ConcurrentHashMap<Integer, Condemned>> _buildingCondemned = new HashMap<>();
public static HashMap<Integer, ArrayList<Vector3fImmutable>> _buildingPatrolPoints = new HashMap<>();
public static int getAvailableSlot(Building building) { public static int getAvailableSlot(Building building) {
ArrayList<BuildingLocation> slotLocations = _slotLocations.get(building.meshUUID); ArrayList<BuildingLocation> slotLocations = _slotLocations.get(building.meshUUID);
@@ -104,7 +123,6 @@ public enum BuildingManager {
if (building == null) if (building == null)
return false; return false;
if (building.getRank() == -1) if (building.getRank() == -1)
return false; return false;
@@ -112,26 +130,25 @@ public enum BuildingManager {
return true; return true;
//individual friend. //individual friend.
if (building.getFriends().get(player.getObjectUUID()) != null) if (building.getFriends() != null && building.getFriends().get(player.getObjectUUID()) != null)
return true; return true;
//Admin's can access stuff //Admins can access stuff
if (player.isCSR()) if (player.isCSR())
return true; return true;
//Guild stuff //Guild stuff
if (building.getGuild().isGuildLeader(player.getObjectUUID()))
if (building.getGuild() != null && building.getGuild().isGuildLeader(player.getObjectUUID()))
return true; return true;
if (building.getFriends().get(player.getGuild().getObjectUUID()) != null if (building.getFriends().get(player.getGuild().getObjectUUID()) != null
&& building.getFriends().get(player.getGuild().getObjectUUID()).getFriendType() == 8) && building.getFriends().get(player.getGuild().getObjectUUID()).friendType == 8)
return true; return true;
if (building.getFriends().get(player.getGuild().getObjectUUID()) != null if (building.getFriends().get(player.getGuild().getObjectUUID()) != null
&& building.getFriends().get(player.getGuild().getObjectUUID()).getFriendType() == 9 && building.getFriends().get(player.getGuild().getObjectUUID()).friendType == 9
&& GuildStatusController.isInnerCouncil(player.getGuildStatus())) && GuildStatusController.isInnerCouncil(player.getGuildStatus()))
return true; return true;
@@ -308,6 +325,72 @@ public enum BuildingManager {
} }
public static void removeHireling(Building building, AbstractCharacter hireling) {
if (hireling.getObjectType().equals(GameObjectType.Mob)) {
Mob guardCaptain = (Mob) hireling;
// Clear minions from database if a guard captain
if (guardCaptain.agentType.equals(Enum.AIAgentType.GUARDCAPTAIN))
DbManager.MobQueries.REMOVE_ALL_MINIONS(hireling.getObjectUUID());
}
// Clear minions from world
for (Integer minionUUID : hireling.minions) {
Mob minionMob = Mob.getMob(minionUUID);
DbManager.removeFromCache(minionMob);
WorldGrid.RemoveWorldObject(minionMob);
WorldGrid.unloadObject(minionMob);
if (minionMob.getParentZone() != null)
minionMob.getParentZone().zoneMobSet.remove(minionMob);
}
// Remove hireling from building
building.getHirelings().remove(hireling);
// Remove from zone mob set
if (hireling.getObjectType().equals(GameObjectType.Mob)) {
Mob hirelingMob = (Mob) hireling;
if (hirelingMob.getParentZone() != null)
if (hirelingMob.getParentZone().zoneMobSet.contains(hirelingMob))
hirelingMob.getParentZone().zoneMobSet.remove(hireling);
}
if (hireling.getObjectType().equals(GameObjectType.NPC)) {
NPC hirelingNPC = (NPC) hireling;
if (hirelingNPC.getParentZone() != null)
if (hirelingNPC.getParentZone().zoneNPCSet.contains(hirelingNPC))
hirelingNPC.getParentZone().zoneNPCSet.remove(hireling);
}
// Unload hireling from world
DbManager.removeFromCache(hireling);
WorldGrid.RemoveWorldObject(hireling);
WorldGrid.removeObject(hireling);
// Delete hireling from database
if (hireling.getObjectType().equals(GameObjectType.Mob))
DbManager.MobQueries.DELETE_MOB((Mob) hireling);
else
DbManager.NPCQueries.DELETE_NPC((NPC) hireling);
}
public static void cleanupHirelings(Building building) { public static void cleanupHirelings(Building building) {
// Early exit: Cannot have hirelings in a building // Early exit: Cannot have hirelings in a building
@@ -320,42 +403,18 @@ public enum BuildingManager {
if (building.getRank() < 1) { if (building.getRank() < 1) {
for (AbstractCharacter slottedNPC : building.getHirelings().keySet()) { for (AbstractCharacter slottedNPC : building.getHirelings().keySet())
BuildingManager.removeHireling(building, slottedNPC);
if (slottedNPC.getObjectType() == Enum.GameObjectType.NPC)
((NPC) slottedNPC).remove();
else if (slottedNPC.getObjectType() == Enum.GameObjectType.Mob)
NPCManager.removeMobileFromBuilding(((Mob) slottedNPC), building);
}
return; return;
} }
// Delete hireling if building has deranked. // Delete hireling if building has deranked.
for (AbstractCharacter hireling : building.getHirelings().keySet()) { for (AbstractCharacter hireling : building.getHirelings().keySet()) {
NPC npc = null;
Mob mob = null;
if (hireling.getObjectType() == Enum.GameObjectType.NPC)
npc = (NPC) hireling;
else if (hireling.getObjectType() == Enum.GameObjectType.Mob)
mob = (Mob) hireling;
if (building.getHirelings().get(hireling) > building.getBlueprint().getSlotsForRank(building.getRank())) if (building.getHirelings().get(hireling) > building.getBlueprint().getSlotsForRank(building.getRank()))
BuildingManager.removeHireling(building, hireling);
if (npc != null) {
if (!npc.remove())
Logger.error("Failed to remove npc " + npc.getObjectUUID()
+ "from Building " + building.getObjectUUID());
else
building.getHirelings().remove(npc);
} else if (mob != null) {
if (!NPCManager.removeMobileFromBuilding(mob, building))
Logger.error("Failed to remove npc " + npc.getObjectUUID()
+ "from Building " + building.getObjectUUID());
else
building.getHirelings().remove(npc);
}
} }
@@ -452,18 +511,18 @@ public enum BuildingManager {
Condemned condemn = building.getCondemned().get(player.getObjectUUID()); Condemned condemn = building.getCondemned().get(player.getObjectUUID());
if (condemn != null && condemn.isActive()) if (condemn != null && condemn.active)
return true; return true;
if (player.getGuild() != null) { if (player.getGuild() != null) {
Condemned guildCondemn = building.getCondemned().get(player.getGuild().getObjectUUID()); Condemned guildCondemn = building.getCondemned().get(player.getGuild().getObjectUUID());
if (guildCondemn != null && guildCondemn.isActive()) if (guildCondemn != null && guildCondemn.active)
return true; return true;
Condemned nationCondemn = building.getCondemned().get(player.getGuild().getNation().getObjectUUID()); Condemned nationCondemn = building.getCondemned().get(player.getGuild().getNation().getObjectUUID());
return nationCondemn != null && nationCondemn.isActive() && nationCondemn.getFriendType() == Condemned.NATION; return nationCondemn != null && nationCondemn.active && nationCondemn.friendType == Condemned.NATION;
} else { } else {
//TODO ADD ERRANT KOS CHECK //TODO ADD ERRANT KOS CHECK
} }
@@ -471,18 +530,18 @@ public enum BuildingManager {
Condemned condemn = building.getCondemned().get(player.getObjectUUID()); Condemned condemn = building.getCondemned().get(player.getObjectUUID());
if (condemn != null && condemn.isActive()) if (condemn != null && condemn.active)
return false; return false;
if (player.getGuild() != null) { if (player.getGuild() != null) {
Condemned guildCondemn = building.getCondemned().get(player.getGuild().getObjectUUID()); Condemned guildCondemn = building.getCondemned().get(player.getGuild().getObjectUUID());
if (guildCondemn != null && guildCondemn.isActive()) if (guildCondemn != null && guildCondemn.active)
return false; return false;
Condemned nationCondemn = building.getCondemned().get(player.getGuild().getNation().getObjectUUID()); Condemned nationCondemn = building.getCondemned().get(player.getGuild().getNation().getObjectUUID());
return nationCondemn == null || !nationCondemn.isActive() || nationCondemn.getFriendType() != Condemned.NATION; return nationCondemn == null || !nationCondemn.active || nationCondemn.friendType != Condemned.NATION;
} else { } else {
//TODO ADD ERRANT KOS CHECK //TODO ADD ERRANT KOS CHECK
} }
@@ -530,41 +589,63 @@ public enum BuildingManager {
else else
rank = 10; rank = 10;
Mob mob; Mob mobile;
NPC npc; NPC npc;
if (NPC.ISWallArcher(contract)) { if (NPC.ISWallArcher(contract)) {
mob = Mob.createMob(contract.getMobbaseID(), Vector3fImmutable.ZERO, contractOwner.getGuild(), true, zone, building, contract.getContractID(), pirateName, rank); mobile = Mob.createMob(contract.getMobbaseID(), Vector3fImmutable.ZERO, contractOwner.getGuild(), zone, building, contract, pirateName, rank, Enum.AIAgentType.GUARDWALLARCHER);
if (mob == null) if (mobile == null)
return false; return false;
mob.setLoc(mob.getLoc()); // Configure AI and write new mobile to disk
mobile.behaviourType = Enum.MobBehaviourType.GuardWallArcher;
mobile = DbManager.MobQueries.PERSIST(mobile);
// Spawn new mobile
mobile.setLoc(mobile.getLoc());
return true; return true;
} }
if (NPC.ISGuardCaptain(contract.getContractID())) { if (NPC.ISGuardCaptain(contract.getContractID())) {
mob = Mob.createMob(contract.getMobbaseID(), Vector3fImmutable.ZERO, contractOwner.getGuild(), true, zone, building, contract.getContractID(), pirateName, rank); mobile = Mob.createMob(contract.getMobbaseID(), Vector3fImmutable.ZERO, contractOwner.getGuild(), zone, building, contract, pirateName, rank, Enum.AIAgentType.GUARDCAPTAIN);
if (mob == null) if (mobile == null)
return false; return false;
mob.setLoc(mob.getLoc()); // Configure AI and write new mobile to disk
mobile.behaviourType = Enum.MobBehaviourType.GuardCaptain;
mobile = DbManager.MobQueries.PERSIST(mobile);
// Spawn new mobile
mobile.setLoc(mobile.getLoc());
return true; return true;
} }
if (contract.getContractID() == 910) { if (contract.getContractID() == 910) {
//guard dog //guard dog
mob = Mob.createMob(contract.getMobbaseID(), Vector3fImmutable.ZERO, contractOwner.getGuild(), true, zone, building, contract.getContractID(), pirateName, rank); mobile = Mob.createMob(contract.getMobbaseID(), Vector3fImmutable.ZERO, contractOwner.getGuild(), zone, building, contract, pirateName, rank, Enum.AIAgentType.GUARDCAPTAIN);
if (mob == null) if (mobile == null)
return false; return false;
mob.setLoc(mob.getLoc()); // Configure AI and write new mobile to disk
mobile.behaviourType = Enum.MobBehaviourType.GuardCaptain;
mobile = DbManager.MobQueries.PERSIST(mobile);
// Spawn new mobile
mobile.setLoc(mobile.getLoc());
return true; return true;
} }
@@ -787,4 +868,156 @@ public enum BuildingManager {
} }
} }
public static void rebuildMine(Building mineBuilding) {
setRank(mineBuilding, 1);
mineBuilding.meshUUID = mineBuilding.getBlueprint().getMeshForRank(mineBuilding.rank);
// New rank mean new max hit points.
mineBuilding.healthMax = mineBuilding.getBlueprint().getMaxHealth(mineBuilding.rank);
mineBuilding.setCurrentHitPoints(mineBuilding.healthMax);
mineBuilding.getBounds().setBounds(mineBuilding);
}
public static void setRank(Building building, int rank) {
int newMeshUUID;
boolean success;
// If this building has no blueprint then set rank and exit immediatly.
if (building.blueprintUUID == 0 || building.getBlueprint() != null && building.getBlueprint().getBuildingGroup().equals(BuildingGroup.MINE)) {
building.rank = rank;
DbManager.BuildingQueries.CHANGE_RANK(building.getObjectUUID(), rank);
return;
}
// Delete any upgrade jobs before doing anything else. It won't quite work
// if in a few lines we happen to delete this building.
JobContainer jc = building.getTimers().get("UPGRADE");
if (jc != null) {
if (!JobScheduler.getInstance().cancelScheduledJob(jc))
Logger.error("failed to cancel existing upgrade job.");
}
// Attempt write to database, or delete the building
// if we are destroying it.
if (rank == -1)
success = DbManager.BuildingQueries.DELETE_FROM_DATABASE(building);
else
success = DbManager.BuildingQueries.updateBuildingRank(building, rank);
if (success == false) {
Logger.error("Error writing to database UUID: " + building.getObjectUUID());
return;
}
building.isDeranking.compareAndSet(false, true);
// Change the building's rank
building.rank = rank;
// New rank means new mesh
newMeshUUID = building.getBlueprint().getMeshForRank(building.rank);
building.meshUUID = newMeshUUID;
// New rank mean new max hitpoints.
building.healthMax = building.getBlueprint().getMaxHealth(building.rank);
building.setCurrentHitPoints(building.healthMax);
if (building.getUpgradeDateTime() != null)
setUpgradeDateTime(building, null, 0);
// If we destroyed this building make sure to turn off
// protection
if (building.rank == -1)
building.protectionState = Enum.ProtectionState.NONE;
if ((building.getBlueprint().getBuildingGroup() == BuildingGroup.TOL)
&& (building.rank == 8))
building.meshUUID = Realm.getRealmMesh(building.getCity());
// update object to clients
building.refresh(true);
if (building.getBounds() != null)
building.getBounds().setBounds(building);
// Cleanup hirelings resulting from rank change
cleanupHirelings(building);
//rebake colliders for change in rank
//BuildingManager.BakeBuildingMeshes(building);
BuildingManager.BakeBuildingColliders(building);
building.isDeranking.compareAndSet(true, false);
}
public static Building getBuildingAtLocation(Vector3fImmutable loc) {
for (AbstractWorldObject awo : WorldGrid.getObjectsInRangePartial(loc, 64, MBServerStatics.MASK_BUILDING)) {
Building building = (Building) awo;
if (building == null)
continue;
if (Bounds.collide(loc, building.getBounds()))
return building;
}
return null;
}
public static void BakeBuildingColliders(Building building){
if(CollisionManager.structure_meshes.containsKey(building.meshUUID) == false) {
Logger.error("No Meshes Found For Structure: " + building.meshUUID);
return;
}
//create the empty array of meshes
building.buildingMeshes = new ArrayList<>();
//create the actual meshes from the stored mesh data
for(MeshData meshData : CollisionManager.structure_meshes.get(building.meshUUID)){
if(meshData.meshID == 0)
continue;
int degrees = (int)Math.toDegrees(building.getBounds().getQuaternion().angleY);
Mesh generatedMesh = new Mesh();
generatedMesh.meshData = meshData;
Vector3f buildingLoc = new Vector3f(building.loc.x,building.loc.y,building.loc.z);
Vector3f offset_mesh_loc = buildingLoc.add(meshData.loc);
Vector3f offset_mesh_end = buildingLoc.add(meshData.endPoint);
Vector3f offset_mesh_ref = buildingLoc.add(meshData.refPoint);
generatedMesh.mesh_location = Vector3f.rotateAroundPoint(offset_mesh_loc,buildingLoc,degrees);
generatedMesh.mesh_end_point = Vector3f.rotateAroundPoint(offset_mesh_end,buildingLoc,degrees);
generatedMesh.mesh_ref_point = Vector3f.rotateAroundPoint(offset_mesh_ref,buildingLoc,degrees);
generatedMesh.mesh_max_y = building.loc.y + meshData.maxY;
generatedMesh.mesh_min_y = building.loc.y + meshData.minY;
generatedMesh.mesh_scale = meshData.scale;
generatedMesh.mesh_id = meshData.meshID;
generatedMesh.parent_prop_id = meshData.propID;
generatedMesh.parent_structure_id = building.meshUUID;
generatedMesh.parentUUID = building.getObjectUUID();
generatedMesh.update();
building.buildingMeshes.add(generatedMesh);
}
}
} }
+1 -1
View File
@@ -788,7 +788,7 @@ public enum ChatManager {
it.remove(); it.remove();
else { else {
PlayerCharacter pcc = (PlayerCharacter) awo; PlayerCharacter pcc = (PlayerCharacter) awo;
if (pcc.getSeeInvis() < pc.getHidden()) if (pcc.getSeeInvis() < pc.hidden)
it.remove(); it.remove();
} }
} }
+92 -179
View File
@@ -30,8 +30,6 @@ import java.util.HashSet;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
import static engine.math.FastMath.sqr;
public enum CombatManager { public enum CombatManager {
COMBATMANAGER; COMBATMANAGER;
@@ -41,63 +39,6 @@ public enum CombatManager {
/** /**
* Message sent by player to attack something. * Message sent by player to attack something.
*/ */
public static void setAttackTarget(AttackCmdMsg msg, ClientConnection origin) throws MsgSendException {
PlayerCharacter player;
int targetType;
AbstractWorldObject target;
if (TargetedActionMsg.un2cnt == 60 || TargetedActionMsg.un2cnt == 70)
return;
player = SessionManager.getPlayerCharacter(origin);
if (player == null)
return;
//source must match player this account belongs to
if (player.getObjectUUID() != msg.getSourceID() || player.getObjectType().ordinal() != msg.getSourceType()) {
Logger.error("Msg Source ID " + msg.getSourceID() + " Does not Match Player ID " + player.getObjectUUID());
return;
}
targetType = msg.getTargetType();
if (targetType == GameObjectType.PlayerCharacter.ordinal()) {
target = PlayerCharacter.getFromCache(msg.getTargetID());
} else if (targetType == GameObjectType.Building.ordinal()) {
target = BuildingManager.getBuildingFromCache(msg.getTargetID());
} else if (targetType == GameObjectType.Mob.ordinal()) {
target = Mob.getFromCache(msg.getTargetID());
} else {
player.setCombatTarget(null);
return; //not valid type to attack
}
// quit of the combat target is already the current combat target
// or there is no combat target
if (target == null)
return;
//set sources target
player.setCombatTarget(target);
//put in combat if not already
if (!player.isCombat())
toggleCombat(true, origin);
//make character stand if sitting
if (player.isSit())
toggleSit(false, origin);
AttackTarget(player, target);
}
public static void AttackTarget(PlayerCharacter playerCharacter, AbstractWorldObject target) { public static void AttackTarget(PlayerCharacter playerCharacter, AbstractWorldObject target) {
@@ -141,11 +82,6 @@ public enum CombatManager {
if (off == null) if (off == null)
CombatManager.createTimer(playerCharacter, MBServerStatics.SLOT_OFFHAND, 1, true); // attack in 0.1 of a second CombatManager.createTimer(playerCharacter, MBServerStatics.SLOT_OFFHAND, 1, true); // attack in 0.1 of a second
} }
City playerCity = ZoneManager.getCityAtLocation(playerCharacter.getLoc());
if (playerCity != null && playerCity.getGuild().getNation().equals(playerCharacter.getGuild().getNation()) == false && playerCity.cityOutlaws.contains(playerCharacter.getObjectUUID()) == false)
playerCity.cityOutlaws.add(playerCharacter.getObjectUUID());
} }
public static void setAttackTarget(PetAttackMsg msg, ClientConnection origin) throws MsgSendException { public static void setAttackTarget(PetAttackMsg msg, ClientConnection origin) throws MsgSendException {
@@ -523,7 +459,7 @@ public enum CombatManager {
/** /**
* Attempt to attack target * Attempt to attack target
*/ */
private static void attack(AbstractCharacter ac, AbstractWorldObject target, Item weapon, ItemBase wb, boolean mainHand) { private static void attack(AbstractCharacter attacker, AbstractWorldObject target, Item weapon, ItemBase wb, boolean mainHand) {
float atr; float atr;
int minDamage, maxDamage; int minDamage, maxDamage;
@@ -531,20 +467,20 @@ public enum CombatManager {
try { try {
if (ac == null) if (attacker == null)
return; return;
if (target == null) if (target == null)
return; return;
if (mainHand) { if (mainHand) {
atr = ac.getAtrHandOne(); atr = attacker.getAtrHandOne();
minDamage = ac.getMinDamageHandOne(); minDamage = attacker.getMinDamageHandOne();
maxDamage = ac.getMaxDamageHandOne(); maxDamage = attacker.getMaxDamageHandOne();
} else { } else {
atr = ac.getAtrHandTwo(); atr = attacker.getAtrHandTwo();
minDamage = ac.getMinDamageHandTwo(); minDamage = attacker.getMinDamageHandTwo();
maxDamage = ac.getMaxDamageHandTwo(); maxDamage = attacker.getMaxDamageHandTwo();
} }
boolean tarIsRat = false; boolean tarIsRat = false;
@@ -563,9 +499,9 @@ public enum CombatManager {
//Dont think we need to do this anymore. //Dont think we need to do this anymore.
if (tarIsRat) if (tarIsRat)
if (ac.getBonuses().getFloatPercentAll(ModType.Slay, SourceType.Rat) != 0) { //strip away current % dmg buffs then add with rat % if (attacker.getBonuses().getFloatPercentAll(ModType.Slay, SourceType.Rat) != 0) { //strip away current % dmg buffs then add with rat %
float percent = 1 + ac.getBonuses().getFloatPercentAll(ModType.Slay, SourceType.Rat); float percent = 1 + attacker.getBonuses().getFloatPercentAll(ModType.Slay, SourceType.Rat);
minDamage *= percent; minDamage *= percent;
maxDamage *= percent; maxDamage *= percent;
@@ -576,24 +512,24 @@ public enum CombatManager {
//subtract stamina //subtract stamina
if (wb == null) if (wb == null)
ac.modifyStamina(-0.5f, ac, true); attacker.modifyStamina(-0.5f, attacker, true);
else { else {
float stam = wb.getWeight() / 3; float stam = wb.getWeight() / 3;
stam = (stam < 1) ? 1 : stam; stam = (stam < 1) ? 1 : stam;
ac.modifyStamina(-(stam), ac, true); attacker.modifyStamina(-(stam), attacker, true);
} }
ac.cancelOnAttackSwing(); attacker.cancelOnAttackSwing();
errorTrack = 2; errorTrack = 2;
//set last time this player has attacked something. //set last time this player has attacked something.
if (target.getObjectType().equals(GameObjectType.PlayerCharacter) && target.getObjectUUID() != ac.getObjectUUID() && ac.getObjectType() == GameObjectType.PlayerCharacter) { if (target.getObjectType().equals(GameObjectType.PlayerCharacter) && target.getObjectUUID() != attacker.getObjectUUID() && attacker.getObjectType() == GameObjectType.PlayerCharacter) {
ac.setTimeStamp("LastCombatPlayer", System.currentTimeMillis()); attacker.setTimeStamp("LastCombatPlayer", System.currentTimeMillis());
((PlayerCharacter) target).setTimeStamp("LastCombatPlayer", System.currentTimeMillis()); ((PlayerCharacter) target).setTimeStamp("LastCombatPlayer", System.currentTimeMillis());
} else } else
ac.setTimeStamp("LastCombatMob", System.currentTimeMillis()); attacker.setTimeStamp("LastCombatMob", System.currentTimeMillis());
errorTrack = 3; errorTrack = 3;
@@ -604,42 +540,16 @@ public enum CombatManager {
if (target.getObjectType().equals(GameObjectType.Building)) { if (target.getObjectType().equals(GameObjectType.Building)) {
if (BuildingManager.getBuildingFromCache(target.getObjectUUID()) == null) { if (BuildingManager.getBuildingFromCache(target.getObjectUUID()) == null) {
ac.setCombatTarget(null); attacker.setCombatTarget(null);
return; return;
} }
defense = 0; defense = 0;
Building building = (Building) target;
if (building.getParentZone() != null && building.getParentZone().isPlayerCity()) {
if (System.currentTimeMillis() > building.getTimeStamp("CallForHelp")) {
building.getTimestamps().put("CallForHelp", System.currentTimeMillis() + 15000);
for (Mob mob : building.getParentZone().zoneMobSet) {
if (!mob.isPlayerGuard())
continue;
if (mob.getCombatTarget() != null)
continue;
if (mob.getGuild() != null && building.getGuild() != null)
if (!Guild.sameGuild(mob.getGuild().getNation(), building.getGuild().getNation()))
continue;
if (mob.getLoc().distanceSquared2D(building.getLoc()) > sqr(300))
continue;
mob.setCombatTarget(ac);
}
}
}
} else { } else {
AbstractCharacter tar = (AbstractCharacter) target; AbstractCharacter tar = (AbstractCharacter) target;
defense = tar.getDefenseRating(); defense = tar.getDefenseRating();
handleRetaliate(tar, ac); //Handle target attacking back if in combat and has no other target handleRetaliate(tar, attacker); //Handle target attacking back if in combat and has no other target
} }
errorTrack = 4; errorTrack = 4;
@@ -665,11 +575,11 @@ public enum CombatManager {
if (roll < chance) { if (roll < chance) {
if (ac.getObjectType().equals(GameObjectType.PlayerCharacter)) if (attacker.getObjectType().equals(GameObjectType.PlayerCharacter))
updateAttackTimers((PlayerCharacter) ac, target, true); updateAttackTimers((PlayerCharacter) attacker, target, true);
boolean skipPassives = false; boolean skipPassives = false;
PlayerBonuses bonuses = ac.getBonuses(); PlayerBonuses bonuses = attacker.getBonuses();
if (bonuses != null && bonuses.getBool(ModType.IgnorePassiveDefense, SourceType.None)) if (bonuses != null && bonuses.getBool(ModType.IgnorePassiveDefense, SourceType.None))
skipPassives = true; skipPassives = true;
@@ -684,26 +594,26 @@ public enum CombatManager {
// Apply Weapon power effect if any. don't try to apply twice if // Apply Weapon power effect if any. don't try to apply twice if
// dual wielding. Perform after passive test for sync purposes. // dual wielding. Perform after passive test for sync purposes.
if (ac.getObjectType().equals(GameObjectType.PlayerCharacter) && (mainHand || wb.isTwoHanded())) { if (attacker.getObjectType().equals(GameObjectType.PlayerCharacter) && (mainHand || wb.isTwoHanded())) {
dpj = ((PlayerCharacter) ac).getWeaponPower(); dpj = ((PlayerCharacter) attacker).getWeaponPower();
if (dpj != null) { if (dpj != null) {
PlayerBonuses bonus = ac.getBonuses(); PlayerBonuses bonus = attacker.getBonuses();
float attackRange = getWeaponRange(wb, bonus); float attackRange = getWeaponRange(wb, bonus);
dpj.attack(target, attackRange); dpj.attack(target, attackRange);
if (dpj.getPower() != null && (dpj.getPowerToken() == -1851459567 || dpj.getPowerToken() == -1851489518)) if (dpj.getPower() != null && (dpj.getPowerToken() == -1851459567 || dpj.getPowerToken() == -1851489518))
((PlayerCharacter) ac).setWeaponPower(dpj); ((PlayerCharacter) attacker).setWeaponPower(dpj);
} }
} }
//check to apply second backstab. //check to apply second backstab.
if (ac.getObjectType().equals(GameObjectType.PlayerCharacter) && !mainHand) { if (attacker.getObjectType().equals(GameObjectType.PlayerCharacter) && !mainHand) {
dpj = ((PlayerCharacter) ac).getWeaponPower(); dpj = ((PlayerCharacter) attacker).getWeaponPower();
if (dpj != null && dpj.getPower() != null && (dpj.getPowerToken() == -1851459567 || dpj.getPowerToken() == -1851489518)) { if (dpj != null && dpj.getPower() != null && (dpj.getPowerToken() == -1851459567 || dpj.getPowerToken() == -1851489518)) {
float attackRange = getWeaponRange(wb, bonuses); float attackRange = getWeaponRange(wb, bonuses);
@@ -723,24 +633,24 @@ public enum CombatManager {
//Handle Block passive //Handle Block passive
if (testPassive(ac, tarAc, "Block") && canTestBlock(ac, target)) { if (testPassive(attacker, tarAc, "Block") && canTestBlock(attacker, target)) {
if (!target.isAlive()) if (!target.isAlive())
return; return;
sendPassiveDefenseMessage(ac, wb, target, MBServerStatics.COMBAT_SEND_BLOCK, dpj, mainHand); sendPassiveDefenseMessage(attacker, wb, target, MBServerStatics.COMBAT_SEND_BLOCK, dpj, mainHand);
passiveFired = true; passiveFired = true;
} }
//Handle Parry passive //Handle Parry passive
if (!passiveFired) if (!passiveFired)
if (canTestParry(ac, target) && testPassive(ac, tarAc, "Parry")) { if (canTestParry(attacker, target) && testPassive(attacker, tarAc, "Parry")) {
if (!target.isAlive()) if (!target.isAlive())
return; return;
sendPassiveDefenseMessage(ac, wb, target, MBServerStatics.COMBAT_SEND_PARRY, dpj, mainHand); sendPassiveDefenseMessage(attacker, wb, target, MBServerStatics.COMBAT_SEND_PARRY, dpj, mainHand);
passiveFired = true; passiveFired = true;
} }
@@ -751,12 +661,12 @@ public enum CombatManager {
//Handle Dodge passive //Handle Dodge passive
if (!passiveFired) if (!passiveFired)
if (testPassive(ac, tarAc, "Dodge")) { if (testPassive(attacker, tarAc, "Dodge")) {
if (!target.isAlive()) if (!target.isAlive())
return; return;
sendPassiveDefenseMessage(ac, wb, target, MBServerStatics.COMBAT_SEND_DODGE, dpj, mainHand); sendPassiveDefenseMessage(attacker, wb, target, MBServerStatics.COMBAT_SEND_DODGE, dpj, mainHand);
passiveFired = true; passiveFired = true;
} }
} }
@@ -772,7 +682,7 @@ public enum CombatManager {
//if target is player, set last attack timestamp //if target is player, set last attack timestamp
if (target.getObjectType().equals(GameObjectType.PlayerCharacter)) if (target.getObjectType().equals(GameObjectType.PlayerCharacter))
updateAttackTimers((PlayerCharacter) target, ac, false); updateAttackTimers((PlayerCharacter) target, attacker, false);
//Get damage Type //Get damage Type
@@ -780,7 +690,7 @@ public enum CombatManager {
if (wb != null) if (wb != null)
damageType = wb.getDamageType(); damageType = wb.getDamageType();
else if (ac.getObjectType().equals(GameObjectType.Mob) && ((Mob) ac).isSiege()) else if (attacker.getObjectType().equals(GameObjectType.Mob) && ((Mob) attacker).isSiege())
damageType = DamageType.Siege; damageType = DamageType.Siege;
else else
damageType = DamageType.Crush; damageType = DamageType.Crush;
@@ -799,7 +709,7 @@ public enum CombatManager {
//make sure target is not immune to damage type; //make sure target is not immune to damage type;
if (resists != null && resists.immuneTo(damageType)) { if (resists != null && resists.immuneTo(damageType)) {
sendCombatMessage(ac, target, 0f, wb, dpj, mainHand); sendCombatMessage(attacker, target, 0f, wb, dpj, mainHand);
return; return;
} }
@@ -810,9 +720,9 @@ public enum CombatManager {
float damage; float damage;
if (wb != null) if (wb != null)
damage = calculateDamage(ac, tarAc, minDamage, maxDamage, damageType, resists); damage = calculateDamage(attacker, tarAc, minDamage, maxDamage, damageType, resists);
else else
damage = calculateDamage(ac, tarAc, minDamage, maxDamage, damageType, resists); damage = calculateDamage(attacker, tarAc, minDamage, maxDamage, damageType, resists);
float d = 0f; float d = 0f;
@@ -825,40 +735,35 @@ public enum CombatManager {
if (tarAc.isSit()) if (tarAc.isSit())
damage *= 2.5f; //increase damage if sitting damage *= 2.5f; //increase damage if sitting
if (tarAc.getObjectType() == GameObjectType.Mob) {
ac.setHateValue(damage * MBServerStatics.PLAYER_COMBAT_HATE_MODIFIER);
((Mob) tarAc).handleDirectAggro(ac);
}
if (tarAc.getHealth() > 0) if (tarAc.getHealth() > 0)
d = tarAc.modifyHealth(-damage, ac, false); d = tarAc.modifyHealth(-damage, attacker, false);
} else if (target.getObjectType().equals(GameObjectType.Building)) { } else if (target.getObjectType().equals(GameObjectType.Building)) {
if (BuildingManager.getBuildingFromCache(target.getObjectUUID()) == null) { if (BuildingManager.getBuildingFromCache(target.getObjectUUID()) == null) {
ac.setCombatTarget(null); attacker.setCombatTarget(null);
return; return;
} }
if (target.getHealth() > 0) if (target.getHealth() > 0)
d = ((Building) target).modifyHealth(-damage, ac); d = ((Building) target).modifyHealth(-damage, attacker);
} }
errorTrack = 13; errorTrack = 13;
//Test to see if any damage needs done to weapon or armor //Test to see if any damage needs done to weapon or armor
testItemDamage(ac, target, weapon, wb); testItemDamage(attacker, target, weapon, wb);
// if target is dead, we got the killing blow, remove attack timers on our weapons // if target is dead, we got the killing blow, remove attack timers on our weapons
if (tarAc != null && !tarAc.isAlive()) if (tarAc != null && !tarAc.isAlive())
removeAttackTimers(ac); removeAttackTimers(attacker);
//test double death fix //test double death fix
if (d != 0) if (d != 0)
sendCombatMessage(ac, target, damage, wb, dpj, mainHand); //send damage message sendCombatMessage(attacker, target, damage, wb, dpj, mainHand); //send damage message
errorTrack = 14; errorTrack = 14;
@@ -885,7 +790,7 @@ public enum CombatManager {
int procChance = ThreadLocalRandom.current().nextInt(100); int procChance = ThreadLocalRandom.current().nextInt(100);
if (procChance < MBServerStatics.PROC_CHANCE) if (procChance < MBServerStatics.PROC_CHANCE)
((WeaponProcEffectModifier) aem).applyProc(ac, target); ((WeaponProcEffectModifier) aem).applyProc(attacker, target);
} }
} }
@@ -897,52 +802,52 @@ public enum CombatManager {
//handle damage shields //handle damage shields
if (ac.isAlive() && tarAc != null && tarAc.isAlive()) if (attacker.isAlive() && tarAc != null && tarAc.isAlive())
handleDamageShields(ac, tarAc, damage); handleDamageShields(attacker, tarAc, damage);
} else { } else {
// Apply Weapon power effect if any. // Apply Weapon power effect if any.
// don't try to apply twice if dual wielding. // don't try to apply twice if dual wielding.
if (ac.getObjectType().equals(GameObjectType.PlayerCharacter) && (mainHand || wb.isTwoHanded())) { if (attacker.getObjectType().equals(GameObjectType.PlayerCharacter) && (mainHand || wb.isTwoHanded())) {
dpj = ((PlayerCharacter) ac).getWeaponPower(); dpj = ((PlayerCharacter) attacker).getWeaponPower();
if (dpj != null) { if (dpj != null) {
PowersBase wp = dpj.getPower(); PowersBase wp = dpj.getPower();
if (wp.requiresHitRoll() == false) { if (wp.requiresHitRoll() == false) {
PlayerBonuses bonus = ac.getBonuses(); PlayerBonuses bonus = attacker.getBonuses();
float attackRange = getWeaponRange(wb, bonus); float attackRange = getWeaponRange(wb, bonus);
dpj.attack(target, attackRange); dpj.attack(target, attackRange);
} else } else
((PlayerCharacter) ac).setWeaponPower(null); ((PlayerCharacter) attacker).setWeaponPower(null);
} }
} }
if (target.getObjectType() == GameObjectType.Mob) if (target.getObjectType() == GameObjectType.Mob)
((Mob) target).handleDirectAggro(ac); ((Mob) target).handleDirectAggro(attacker);
errorTrack = 17; errorTrack = 17;
//miss, Send miss message //miss, Send miss message
sendCombatMessage(ac, target, 0f, wb, dpj, mainHand); sendCombatMessage(attacker, target, 0f, wb, dpj, mainHand);
//if attacker is player, set last attack timestamp //if attacker is player, set last attack timestamp
if (ac.getObjectType().equals(GameObjectType.PlayerCharacter)) if (attacker.getObjectType().equals(GameObjectType.PlayerCharacter))
updateAttackTimers((PlayerCharacter) ac, target, true); updateAttackTimers((PlayerCharacter) attacker, target, true);
} }
errorTrack = 18; errorTrack = 18;
//cancel effects that break on attack or attackSwing //cancel effects that break on attack or attackSwing
ac.cancelOnAttack(); attacker.cancelOnAttack();
} catch (Exception e) { } catch (Exception e) {
Logger.error(ac.getName() + ' ' + errorTrack + ' ' + e); Logger.error(attacker.getName() + ' ' + errorTrack + ' ' + e);
} }
} }
@@ -1220,7 +1125,7 @@ public enum CombatManager {
toggleCombat(msg.getToggle(), origin); toggleCombat(msg.getToggle(), origin);
} }
private static void toggleCombat(boolean toggle, ClientConnection origin) { public static void toggleCombat(boolean toggle, ClientConnection origin) {
PlayerCharacter pc = SessionManager.getPlayerCharacter(origin); PlayerCharacter pc = SessionManager.getPlayerCharacter(origin);
@@ -1237,7 +1142,7 @@ public enum CombatManager {
DispatchMessage.dispatchMsgToInterestArea(pc, rwss, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, false, false); DispatchMessage.dispatchMsgToInterestArea(pc, rwss, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, false, false);
} }
private static void toggleSit(boolean toggle, ClientConnection origin) { public static void toggleSit(boolean toggle, ClientConnection origin) {
PlayerCharacter pc = SessionManager.getPlayerCharacter(origin); PlayerCharacter pc = SessionManager.getPlayerCharacter(origin);
@@ -1267,61 +1172,69 @@ public enum CombatManager {
} }
//Called when character takes damage. //Called when character takes damage.
public static void handleRetaliate(AbstractCharacter tarAc, AbstractCharacter ac) { public static void handleRetaliate(AbstractCharacter target, AbstractCharacter attacker) {
if (ac == null || tarAc == null) if (attacker == null || target == null)
return; return;
if (ac.equals(tarAc)) if (attacker.equals(target))
return; return;
if (tarAc.isMoving() && tarAc.getObjectType().equals(GameObjectType.PlayerCharacter)) if (target.isMoving() && target.getObjectType().equals(GameObjectType.PlayerCharacter))
return; return;
if (!tarAc.isAlive() || !ac.isAlive()) if (!target.isAlive() || !attacker.isAlive())
return; return;
boolean isCombat = tarAc.isCombat(); boolean isCombat = target.isCombat();
//If target in combat and has no target, then attack back //If target in combat and has no target, then attack back
AbstractWorldObject awoCombTar = tarAc.getCombatTarget(); AbstractWorldObject awoCombTar = target.getCombatTarget();
if ((tarAc.isCombat() && awoCombTar == null) || (isCombat && awoCombTar != null && (!awoCombTar.isAlive() || tarAc.isCombat() && NotInRange(tarAc, awoCombTar, tarAc.getRange()))) || (tarAc != null && tarAc.getObjectType() == GameObjectType.Mob && ((Mob) tarAc).isSiege())) if ((target.isCombat() && awoCombTar == null) || (isCombat && awoCombTar != null && (!awoCombTar.isAlive() || target.isCombat() && NotInRange(target, awoCombTar, target.getRange()))) || (target != null && target.getObjectType() == GameObjectType.Mob && ((Mob) target).isSiege()))
if (tarAc.getObjectType().equals(GameObjectType.PlayerCharacter)) { // we are in combat with no valid target if (target.getObjectType().equals(GameObjectType.PlayerCharacter)) { // we are in combat with no valid target
PlayerCharacter pc = (PlayerCharacter) tarAc; PlayerCharacter pc = (PlayerCharacter) target;
tarAc.setCombatTarget(ac); target.setCombatTarget(attacker);
pc.setLastTarget(ac.getObjectType(), ac.getObjectUUID()); pc.setLastTarget(attacker.getObjectType(), attacker.getObjectUUID());
if (tarAc.getTimers() != null) if (target.getTimers() != null)
if (!tarAc.getTimers().containsKey("Attack" + MBServerStatics.SLOT_MAINHAND)) if (!target.getTimers().containsKey("Attack" + MBServerStatics.SLOT_MAINHAND))
CombatManager.AttackTarget((PlayerCharacter) tarAc, tarAc.getCombatTarget()); CombatManager.AttackTarget((PlayerCharacter) target, target.getCombatTarget());
} }
//Handle pet retaliate if assist is on and pet doesn't have a target. //Handle pet retaliate if assist is on and pet doesn't have a target.
if (tarAc.getObjectType().equals(GameObjectType.PlayerCharacter)) { if (target.getObjectType().equals(GameObjectType.PlayerCharacter)) {
Mob pet = ((PlayerCharacter) tarAc).getPet(); Mob pet = ((PlayerCharacter) target).getPet();
if (pet != null && pet.assist && pet.getCombatTarget() == null) if (pet != null && pet.assist && pet.getCombatTarget() == null)
pet.setCombatTarget(ac); pet.setCombatTarget(attacker);
} }
//Handle Mob Retaliate. //Handle Mob Retaliate.
if (tarAc.getObjectType() == GameObjectType.Mob) { if (target.getObjectType() == GameObjectType.Mob) {
Mob retaliater = (Mob) tarAc; Mob attackedMobile = (Mob) target;
if (retaliater.getCombatTarget() != null && !retaliater.isSiege()) //handle minion informing his captain of an attack
if (attackedMobile.agentType.equals(AIAgentType.GUARDMINION) && attackedMobile.guardCaptain != null && attackedMobile.guardCaptain.isAlive()) {
if (attackedMobile.guardCaptain.combatTarget == null)
attackedMobile.guardCaptain.setCombatTarget(attacker);
}
// Mobile already has a target; don't switch.
if (attackedMobile.getCombatTarget() != null && !attackedMobile.isSiege())
return; return;
if (ac.getObjectType() == GameObjectType.Mob && retaliater.isSiege()) attackedMobile.setCombatTarget(attacker);
return;
retaliater.setCombatTarget(ac);
} }
} }
-1
View File
@@ -70,7 +70,6 @@ public enum DbManager {
public static final dbBlueprintHandler BlueprintQueries = new dbBlueprintHandler(); public static final dbBlueprintHandler BlueprintQueries = new dbBlueprintHandler();
public static final dbBoonHandler BoonQueries = new dbBoonHandler(); public static final dbBoonHandler BoonQueries = new dbBoonHandler();
public static final dbShrineHandler ShrineQueries = new dbShrineHandler(); public static final dbShrineHandler ShrineQueries = new dbShrineHandler();
public static final dbHeightMapHandler HeightMapQueries = new dbHeightMapHandler();
public static final dbRunegateHandler RunegateQueries = new dbRunegateHandler(); public static final dbRunegateHandler RunegateQueries = new dbRunegateHandler();
public static final dbPowerHandler PowerQueries = new dbPowerHandler(); public static final dbPowerHandler PowerQueries = new dbPowerHandler();
+3 -2
View File
@@ -46,9 +46,11 @@ public enum DevCmdManager {
DevCmdManager.registerDevCmd(new GetZoneCmd()); DevCmdManager.registerDevCmd(new GetZoneCmd());
DevCmdManager.registerDevCmd(new ZoneSetCmd()); DevCmdManager.registerDevCmd(new ZoneSetCmd());
DevCmdManager.registerDevCmd(new PrintBankCmd()); DevCmdManager.registerDevCmd(new PrintBankCmd());
DevCmdManager.registerDevCmd(new PrintEffectsCmd());
DevCmdManager.registerDevCmd(new PrintEquipCmd()); DevCmdManager.registerDevCmd(new PrintEquipCmd());
DevCmdManager.registerDevCmd(new PrintInventoryCmd()); DevCmdManager.registerDevCmd(new PrintInventoryCmd());
DevCmdManager.registerDevCmd(new PrintVaultCmd()); DevCmdManager.registerDevCmd(new PrintVaultCmd());
DevCmdManager.registerDevCmd(new PrintRunesCmd());
DevCmdManager.registerDevCmd(new PrintStatsCmd()); DevCmdManager.registerDevCmd(new PrintStatsCmd());
DevCmdManager.registerDevCmd(new PrintSkillsCmd()); DevCmdManager.registerDevCmd(new PrintSkillsCmd());
DevCmdManager.registerDevCmd(new PrintPowersCmd()); DevCmdManager.registerDevCmd(new PrintPowersCmd());
@@ -128,7 +130,6 @@ public enum DevCmdManager {
DevCmdManager.registerDevCmd(new SetForceRenameCityCmd()); DevCmdManager.registerDevCmd(new SetForceRenameCityCmd());
DevCmdManager.registerDevCmd(new GotoObj()); DevCmdManager.registerDevCmd(new GotoObj());
DevCmdManager.registerDevCmd(new convertLoc()); DevCmdManager.registerDevCmd(new convertLoc());
DevCmdManager.registerDevCmd(new AuditHeightMapCmd());
DevCmdManager.registerDevCmd(new UnloadFurnitureCmd()); DevCmdManager.registerDevCmd(new UnloadFurnitureCmd());
DevCmdManager.registerDevCmd(new SetNpcEquipSetCmd()); DevCmdManager.registerDevCmd(new SetNpcEquipSetCmd());
DevCmdManager.registerDevCmd(new SetBuildingAltitudeCmd()); DevCmdManager.registerDevCmd(new SetBuildingAltitudeCmd());
@@ -139,11 +140,11 @@ public enum DevCmdManager {
DevCmdManager.registerDevCmd(new BoundsCmd()); DevCmdManager.registerDevCmd(new BoundsCmd());
DevCmdManager.registerDevCmd(new GotoBoundsCmd()); DevCmdManager.registerDevCmd(new GotoBoundsCmd());
DevCmdManager.registerDevCmd(new RegionCmd()); DevCmdManager.registerDevCmd(new RegionCmd());
DevCmdManager.registerDevCmd(new ColliderCmd());
DevCmdManager.registerDevCmd(new SetMaintCmd()); DevCmdManager.registerDevCmd(new SetMaintCmd());
DevCmdManager.registerDevCmd(new ApplyBonusCmd()); DevCmdManager.registerDevCmd(new ApplyBonusCmd());
DevCmdManager.registerDevCmd(new AuditFailedItemsCmd()); DevCmdManager.registerDevCmd(new AuditFailedItemsCmd());
DevCmdManager.registerDevCmd(new SlotTestCmd()); DevCmdManager.registerDevCmd(new SlotTestCmd());
} }
private static void registerDevCmd(AbstractDevCmd cmd) { private static void registerDevCmd(AbstractDevCmd cmd) {
+3 -1
View File
@@ -86,7 +86,7 @@ public enum LootManager {
if(ib == null) if(ib == null)
break; break;
if (ib.isDiscRune() || ib.getName().toLowerCase().contains("of the gods")) { if (ib.isDiscRune() || ib.getName().toLowerCase().contains("of the gods")) {
ChatSystemMsg chatMsg = new ChatSystemMsg(null, mob.getName() + " in " + mob.getParentZone().getName() + " has found the " + ib.getName() + ". Are you tough enough to take it?"); ChatSystemMsg chatMsg = new ChatSystemMsg(null, mob.getName() + " in " + mob.getParentZone().zoneName + " has found the " + ib.getName() + ". Are you tough enough to take it?");
chatMsg.setMessageType(10); chatMsg.setMessageType(10);
chatMsg.setChannel(Enum.ChatChannelType.SYSTEM.getChannelID()); chatMsg.setChannel(Enum.ChatChannelType.SYSTEM.getChannelID());
DispatchMessage.dispatchMsgToAll(chatMsg); DispatchMessage.dispatchMsgToAll(chatMsg);
@@ -330,6 +330,8 @@ public enum LootManager {
public static void GenerateEquipmentDrop(Mob mob) { public static void GenerateEquipmentDrop(Mob mob) {
if(mob.behaviourType.equals(Enum.MobBehaviourType.HamletGuard))
return; // safehold guards don't drop their equipment
//do equipment here //do equipment here
int dropCount = 0; int dropCount = 0;
if (mob.getEquip() != null) if (mob.getEquip() != null)
+17 -31
View File
@@ -116,8 +116,8 @@ public enum MovementManager {
// if inside a building, convert both locations from the building local reference frame to the world reference frame // if inside a building, convert both locations from the building local reference frame to the world reference frame
if (msg.getTargetID() > 0) { if (msg.getInBuildingUUID() > 0) {
Building building = BuildingManager.getBuildingFromCache(msg.getTargetID()); Building building = BuildingManager.getBuildingFromCache(msg.getInBuildingUUID());
if (building != null) { if (building != null) {
Vector3fImmutable convertLocEnd = new Vector3fImmutable(ZoneManager.convertLocalToWorld(building, endLocation)); Vector3fImmutable convertLocEnd = new Vector3fImmutable(ZoneManager.convertLocalToWorld(building, endLocation));
@@ -128,8 +128,8 @@ public enum MovementManager {
// } // }
// else { // else {
toMove.setInBuilding(msg.getInBuilding()); toMove.setInBuilding(msg.getInBuilding());
toMove.setInFloorID(msg.getUnknown01()); toMove.setInFloorID(msg.getInBuildingFloor());
toMove.setInBuildingID(msg.getTargetID()); toMove.setInBuildingID(msg.getInBuildingUUID());
msg.setStartCoord(ZoneManager.convertWorldToLocal(building, toMove.getLoc())); msg.setStartCoord(ZoneManager.convertWorldToLocal(building, toMove.getLoc()));
if (toMove.getObjectType() == GameObjectType.PlayerCharacter) { if (toMove.getObjectType() == GameObjectType.PlayerCharacter) {
@@ -174,9 +174,9 @@ public enum MovementManager {
msg.setStartCoord(ZoneManager.convertWorldToLocal(Regions.GetBuildingForRegion(toMove.region), toMove.getLoc())); msg.setStartCoord(ZoneManager.convertWorldToLocal(Regions.GetBuildingForRegion(toMove.region), toMove.getLoc()));
msg.setEndCoord(ZoneManager.convertWorldToLocal(regionBuilding, endLocation)); msg.setEndCoord(ZoneManager.convertWorldToLocal(regionBuilding, endLocation));
msg.setInBuilding(toMove.region.level); msg.setInBuilding(toMove.region.level);
msg.setUnknown01(toMove.region.room); msg.setInBuildingFloor(toMove.region.room);
msg.setTargetType(GameObjectType.Building.ordinal()); msg.setStartLocType(GameObjectType.Building.ordinal());
msg.setTargetID(regionBuilding.getObjectUUID()); msg.setInBuildingUUID(regionBuilding.getObjectUUID());
} }
} else { } else {
@@ -185,8 +185,8 @@ public enum MovementManager {
toMove.setInBuilding(-1); toMove.setInBuilding(-1);
msg.setStartCoord(toMove.getLoc()); msg.setStartCoord(toMove.getLoc());
msg.setEndCoord(endLocation); msg.setEndCoord(endLocation);
msg.setTargetType(0); msg.setStartLocType(0);
msg.setTargetID(0); msg.setInBuildingUUID(0);
} }
//checks sync between character and server, if out of sync, teleport player to original position and return. //checks sync between character and server, if out of sync, teleport player to original position and return.
@@ -233,7 +233,7 @@ public enum MovementManager {
toMove.cancelOnMove(); toMove.cancelOnMove();
//cancel any attacks for manual move. //cancel any attacks for manual move.
if ((toMove.getObjectType() == GameObjectType.PlayerCharacter) && msg.getUnknown02() == 0) if ((toMove.getObjectType() == GameObjectType.PlayerCharacter) && msg.getInitiatedFromAttack() == 0)
toMove.setCombatTarget(null); toMove.setCombatTarget(null);
@@ -267,7 +267,7 @@ public enum MovementManager {
Zone serverZone = null; Zone serverZone = null;
serverZone = ZoneManager.findSmallestZone(player.getLoc()); serverZone = ZoneManager.findSmallestZone(player.getLoc());
cityObject = (City) DbManager.getFromCache(GameObjectType.City, serverZone.getPlayerCityUUID()); cityObject = (City) DbManager.getFromCache(GameObjectType.City, serverZone.playerCityUUID);
// Do not send group messages if player is on grid // Do not send group messages if player is on grid
@@ -464,34 +464,20 @@ public enum MovementManager {
} }
} }
public static void translocate(AbstractCharacter teleporter, Vector3fImmutable targetLoc, Regions region) { public static void translocate(AbstractCharacter teleporter, Vector3fImmutable targetLoc) {
if (targetLoc == null) if (targetLoc == null)
return; return;
Vector3fImmutable oldLoc = new Vector3fImmutable(teleporter.getLoc());
teleporter.stopMovement(targetLoc); teleporter.stopMovement(targetLoc);
teleporter.setRegion(region); Vector3fImmutable oldLoc = new Vector3fImmutable(teleporter.getLoc());
teleporter.setLoc(targetLoc);
//mobs ignore region sets for now.
if (teleporter.getObjectType().equals(GameObjectType.Mob)) {
teleporter.setInBuildingID(0);
teleporter.setInBuilding(-1);
teleporter.setInFloorID(-1);
TeleportToPointMsg msg = new TeleportToPointMsg(teleporter, targetLoc.getX(), targetLoc.getY(), targetLoc.getZ(), 0, -1, -1);
DispatchMessage.dispatchMsgToInterestArea(oldLoc, teleporter, msg, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, false, false);
return;
}
TeleportToPointMsg msg = new TeleportToPointMsg(teleporter, targetLoc.getX(), targetLoc.getY(), targetLoc.getZ(), 0, -1, -1);
//we shouldnt need to send teleport message to new area, as loadjob should pick it up.
// DispatchMessage.dispatchMsgToInterestArea(teleporter, msg, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false);
DispatchMessage.dispatchMsgToInterestArea(oldLoc, teleporter, msg, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false);
if (teleporter.getObjectType().equals(GameObjectType.PlayerCharacter)) if (teleporter.getObjectType().equals(GameObjectType.PlayerCharacter))
InterestManager.INTERESTMANAGER.HandleLoadForTeleport((PlayerCharacter) teleporter); InterestManager.INTERESTMANAGER.HandleLoadForTeleport((PlayerCharacter) teleporter);
TeleportToPointMsg msg = new TeleportToPointMsg(teleporter, teleporter.loc.getX(), teleporter.loc.getY(), teleporter.loc.getZ(), 0, -1, -1);
DispatchMessage.dispatchMsgToInterestArea(oldLoc, teleporter, msg, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false);
} }
private static void syncLoc(AbstractCharacter ac, Vector3fImmutable clientLoc, boolean useClientLoc) { private static void syncLoc(AbstractCharacter ac, Vector3fImmutable clientLoc, boolean useClientLoc) {
+264 -160
View File
@@ -5,13 +5,17 @@ import engine.InterestManagement.WorldGrid;
import engine.math.Quaternion; import engine.math.Quaternion;
import engine.math.Vector3f; import engine.math.Vector3f;
import engine.math.Vector3fImmutable; import engine.math.Vector3fImmutable;
import engine.mobileAI.MobAI;
import engine.net.Dispatch; import engine.net.Dispatch;
import engine.net.DispatchMessage; import engine.net.DispatchMessage;
import engine.net.client.msg.PetMsg; import engine.net.client.msg.PetMsg;
import engine.objects.*; import engine.objects.*;
import engine.powers.EffectsBase; import engine.powers.EffectsBase;
import engine.powers.PowersBase;
import engine.powers.RuneSkillAdjustEntry;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
import javax.smartcardio.ATR;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
@@ -23,92 +27,6 @@ public enum NPCManager {
NPC_MANAGER; NPC_MANAGER;
public static HashMap<Integer, ArrayList<Integer>> _runeSetMap = new HashMap<>(); public static HashMap<Integer, ArrayList<Integer>> _runeSetMap = new HashMap<>();
public static void LoadAllRuneSets() {
_runeSetMap = DbManager.ItemBaseQueries.LOAD_RUNES_FOR_NPC_AND_MOBS();
}
public static void LoadAllBootySets() {
LootManager._bootySetMap = DbManager.LootQueries.LOAD_BOOTY_TABLES();
}
public static void applyRuneSetEffects(Mob mob) {
// Early exit
if (mob.runeSet == 0)
return;
//Apply all rune effects.
if (NPCManager._runeSetMap.get(mob.runeSet).contains(252623)) {
mob.isPlayerGuard = true;
}
// Only captains have contracts
if (mob.contract != null || mob.isPlayerGuard)
applyEffectsForRune(mob, 252621);
// Apply effects from RuneSet
if (mob.runeSet != 0)
for (int runeID : _runeSetMap.get(mob.runeSet))
applyEffectsForRune(mob, runeID);
// Not sure why but apply Warrior effects for some reason?
applyEffectsForRune(mob, 2518);
}
public static void applyEffectsForRune(AbstractCharacter character, int runeID) {
EffectsBase effectsBase;
RuneBase sourceRune = RuneBase.getRuneBase(runeID);
// Race runes are in the runeset but not in runebase for some reason
if (sourceRune == null)
return;
for (MobBaseEffects mbe : sourceRune.getEffectsList()) {
effectsBase = PowersManager.getEffectByToken(mbe.getToken());
if (effectsBase == null) {
Logger.info("Mob: " + character.getObjectUUID() + " EffectsBase Null for Token " + mbe.getToken());
continue;
}
//check to upgrade effects if needed.
if (character.effects.containsKey(Integer.toString(effectsBase.getUUID()))) {
if (mbe.getReqLvl() > (int) character.level)
continue;
Effect eff = character.effects.get(Integer.toString(effectsBase.getUUID()));
if (eff == null)
continue;
//Current effect is a higher rank, dont apply.
if (eff.getTrains() > mbe.getRank())
continue;
//new effect is of a higher rank. remove old effect and apply new one.
eff.cancelJob();
character.addEffectNoTimer(Integer.toString(effectsBase.getUUID()), effectsBase, mbe.getRank(), true);
} else {
if (mbe.getReqLvl() > (int) character.level)
continue;
character.addEffectNoTimer(Integer.toString(effectsBase.getUUID()), effectsBase, mbe.getRank(), true);
}
}
}
public static void dismissNecroPet(Mob necroPet, boolean updateOwner) { public static void dismissNecroPet(Mob necroPet, boolean updateOwner) {
necroPet.setCombatTarget(null); necroPet.setCombatTarget(null);
@@ -127,10 +45,12 @@ public enum NPCManager {
DbManager.removeFromCache(necroPet); DbManager.removeFromCache(necroPet);
PlayerCharacter petOwner = necroPet.getOwner();
PlayerCharacter petOwner = (PlayerCharacter) necroPet.guardCaptain;
if (petOwner != null) { if (petOwner != null) {
necroPet.setOwner(null);
necroPet.guardCaptain = null;
petOwner.setPet(null); petOwner.setPet(null);
if (updateOwner == false) if (updateOwner == false)
@@ -202,78 +122,6 @@ public enum NPCManager {
playerCharacter.necroPets.clear(); playerCharacter.necroPets.clear();
} }
public static void removeSiegeMinions(Mob mobile) {
for (Mob toRemove : mobile.siegeMinionMap.keySet()) {
if (mobile.isMoving()) {
mobile.stopMovement(mobile.getLoc());
if (toRemove.parentZone != null)
toRemove.parentZone.zoneMobSet.remove(toRemove);
}
try {
toRemove.clearEffects();
} catch (Exception e) {
Logger.error(e.getMessage());
}
if (toRemove.parentZone != null)
toRemove.parentZone.zoneMobSet.remove(toRemove);
WorldGrid.RemoveWorldObject(toRemove);
WorldGrid.removeObject(toRemove);
DbManager.removeFromCache(toRemove);
PlayerCharacter petOwner = toRemove.getOwner();
if (petOwner != null) {
petOwner.setPet(null);
toRemove.setOwner(null);
PetMsg petMsg = new PetMsg(5, null);
Dispatch dispatch = Dispatch.borrow(petOwner, petMsg);
DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.PRIMARY);
}
}
}
public static boolean removeMobileFromBuilding(Mob mobile, Building building) {
// Remove npc from it's building
try {
mobile.clearEffects();
} catch (Exception e) {
Logger.error(e.getMessage());
}
if (mobile.parentZone != null)
mobile.parentZone.zoneMobSet.remove(mobile);
if (building != null) {
building.getHirelings().remove(mobile);
removeSiegeMinions(mobile);
}
// Delete npc from database
if (DbManager.MobQueries.DELETE_MOB(mobile) == 0)
return false;
// Remove npc from the simulation
mobile.removeFromCache();
DbManager.removeFromCache(mobile);
WorldGrid.RemoveWorldObject(mobile);
WorldGrid.removeObject(mobile);
return true;
}
public static void loadAllPirateNames() { public static void loadAllPirateNames() {
DbManager.NPCQueries.LOAD_PIRATE_NAMES(); DbManager.NPCQueries.LOAD_PIRATE_NAMES();
@@ -340,9 +188,18 @@ public enum NPCManager {
else else
buildingSlot = BuildingManager.getAvailableSlot(abstractCharacter.building); buildingSlot = BuildingManager.getAvailableSlot(abstractCharacter.building);
// Override slot for siege engines
if (abstractCharacter.getObjectType().equals(Enum.GameObjectType.Mob) && ((Mob) abstractCharacter).behaviourType.equals(Enum.MobBehaviourType.SiegeEngine)) {
Mob siegeMobile = (Mob) abstractCharacter;
buildingSlot = siegeMobile.guardCaptain.minions.size() + 2;
}
if (buildingSlot == -1) if (buildingSlot == -1)
Logger.error("No available slot for NPC: " + abstractCharacter.getObjectUUID()); Logger.error("No available slot for NPC: " + abstractCharacter.getObjectUUID());
// Pets are regular mobiles not hirelings (Siege engines)
if (abstractCharacter.contract != null)
abstractCharacter.building.getHirelings().put(abstractCharacter, buildingSlot); abstractCharacter.building.getHirelings().put(abstractCharacter, buildingSlot);
// Override bind and location for this npc derived // Override bind and location for this npc derived
@@ -370,4 +227,251 @@ public enum NPCManager {
return buildingSlot; return buildingSlot;
} }
public static void AssignPatrolPoints(Mob mob) {
mob.patrolPoints = new ArrayList<>();
for (int i = 0; i < 5; ++i) {
float patrolRadius = mob.getSpawnRadius();
if (patrolRadius > 256)
patrolRadius = 256;
if (patrolRadius < 60)
patrolRadius = 60;
Vector3fImmutable newPatrolPoint = Vector3fImmutable.getRandomPointInCircle(mob.getBindLoc(), patrolRadius);
mob.patrolPoints.add(newPatrolPoint);
if (i == 1) {
mob.setLoc(newPatrolPoint);
mob.endLoc = newPatrolPoint;
}
}
}
public static void applyGuardStanceModifiers(Mob guard){
float damageModifier = 1;
float attackRatingModifier = 1;
float defenseModifier = 1;
float attackSpeedModifier = 1;
float powerDamageModifier = 1;
//handle stance modifiers for guard mob
if(guard.agentType.equals(Enum.AIAgentType.GUARDWALLARCHER)){
//apply rogue bonuses
attackRatingModifier += 0.5f;
defenseModifier += 0.5f;
damageModifier += 0.5f;
attackSpeedModifier -= 0.36f;
}else {
Integer contractID;
if (guard.agentType.equals(Enum.AIAgentType.GUARDMINION)) {
contractID = guard.guardCaptain.contract.getContractID();
} else{
contractID = guard.contract.getContractID();
}
if (Enum.MinionType.ContractToMinionMap.get(contractID) != null && Enum.MinionType.ContractToMinionMap.get(contractID).isMage()){
//apply mage offensive Stance
powerDamageModifier += 0.5f;
} else{
//apply fighter offensive stance
damageModifier += 0.5f;
attackSpeedModifier -= 0.36f;
}
}
guard.minDamageHandOne *= damageModifier;
guard.minDamageHandTwo *= damageModifier;
guard.maxDamageHandOne *= damageModifier;
guard.maxDamageHandTwo *= damageModifier;
guard.atrHandOne *= attackRatingModifier;
guard.atrHandTwo *= attackRatingModifier;
guard.defenseRating *= defenseModifier;
guard.speedHandOne *= attackSpeedModifier;
guard.speedHandTwo *= attackSpeedModifier;
//TODO figure out how to apply +50% powerdamage to mage guards
}
public static void setDamageAndSpeedForGuard(Mob guard){
float rankModifier = 1 + (guard.getRank() * 0.1f);
int primaryStat = 0;
if(guard.equip == null) {
guard.minDamageHandOne = (int)((guard.mobBase.getDamageMin()) * rankModifier);
guard.maxDamageHandOne = (int)((guard.mobBase.getDamageMax()) * rankModifier);
guard.speedHandOne = 30.0f;
}else{
if(guard.equip.containsKey(1)){
//has main hand weapon
ItemBase weapon = guard.equip.get(1).getItemBase();
if(weapon.isStrBased())
primaryStat = guard.getStatStrCurrent();
else
primaryStat = guard.getStatDexCurrent();
guard.minDamageHandOne = (int)((guard.mobBase.getDamageMin() + weapon.getMinDamage()) * rankModifier) + primaryStat;
guard.maxDamageHandOne = (int)((guard.mobBase.getDamageMax() + weapon.getMaxDamage()) * rankModifier) + primaryStat;
guard.speedHandOne = weapon.getSpeed();
guard.rangeHandOne = weapon.getRange();
} else if(guard.equip.containsKey(2) && !guard.equip.get(2).getItemBase().isShield()){
//has off hand weapon
ItemBase weapon = guard.equip.get(2).getItemBase();
if(weapon.isStrBased())
primaryStat = guard.getStatStrCurrent();
else
primaryStat = guard.getStatDexCurrent();
guard.minDamageHandTwo = (int)((guard.mobBase.getDamageMin() + weapon.getMinDamage()) * rankModifier) + primaryStat;
guard.maxDamageHandTwo = (int)((guard.mobBase.getDamageMax() + weapon.getMaxDamage()) * rankModifier) + primaryStat;
guard.speedHandTwo = weapon.getSpeed();
guard.rangeHandTwo = weapon.getRange();
} else {
primaryStat = guard.getStatStrCurrent();
guard.minDamageHandOne = (int)((guard.mobBase.getDamageMin()) * rankModifier) + primaryStat;
guard.maxDamageHandOne = (int)((guard.mobBase.getDamageMax()) * rankModifier) + primaryStat;
guard.speedHandOne = 30.0f;
guard.rangeHandOne = 3;
}
}
}
public static void setDefenseForGuard(Mob guard){
int dexterity = guard.getStatDexCurrent();
if(dexterity < 1)
dexterity = 1;
int baseDef = guard.mobBase.getDefenseRating();
int armorDefense = 0;
for(MobEquipment equipped : guard.equip.values())
if(equipped.getItemBase().isArmor() || equipped.getItemBase().isShield())
armorDefense += equipped.getItemBase().getDefense();
guard.defenseRating = dexterity + baseDef + armorDefense;
}
public static void setAttackRatingForGuard(Mob guard) {
int strength = guard.getStatStrCurrent();
int baseAtr = guard.mobBase.getAttackRating();
if (guard.equip.get(1) != null)
guard.atrHandOne = baseAtr + (int) ((strength * 0.5f) + (guard.equip.get(1).getItemBase().getPercentRequired() * 4) + (guard.equip.get(1).getItemBase().getPercentRequired() * 3));
else if (guard.equip.get(2) != null && !guard.equip.get(2).getItemBase().isShield())
guard.atrHandTwo = baseAtr + (int) ((strength * 0.5f) + (guard.equip.get(2).getItemBase().getPercentRequired() * 4) + (guard.equip.get(2).getItemBase().getPercentRequired() * 3));
else
guard.atrHandOne = baseAtr;
}
public static void setMaxHealthForGuard(Mob guard){
//values derived fom reading memory address for health on client when selecting player guards
switch(guard.getRank()){
default:
guard.healthMax = 750; //rank 1
break;
case 2:
guard.healthMax = 2082;
break;
case 3:
guard.healthMax = 2740;
break;
case 4:
guard.healthMax = 3414;
break;
case 5:
guard.healthMax = 4080;
break;
case 6:
guard.healthMax = 4746;
break;
case 7:
guard.healthMax = 5412;
break;
}
}
public static void applyMobbaseEffects(Mob mob) {
EffectsBase effectsBase;
for (MobBaseEffects mbe : mob.mobBase.effectsList) {
effectsBase = PowersManager.getEffectByToken(mbe.getToken());
if (effectsBase == null) {
Logger.info("Mob: " + mob.getObjectUUID() + " EffectsBase Null for Token " + mbe.getToken());
continue;
}
//check to upgrade effects if needed.
if (mob.effects.containsKey(Integer.toString(effectsBase.getUUID()))) {
if (mbe.getReqLvl() > (int) mob.level)
continue;
Effect eff = mob.effects.get(Integer.toString(effectsBase.getUUID()));
if (eff == null)
continue;
//Current effect is a higher rank, dont apply.
if (eff.getTrains() > mbe.getRank())
continue;
//new effect is of a higher rank. remove old effect and apply new one.
eff.cancelJob();
mob.addEffectNoTimer(Integer.toString(effectsBase.getUUID()), effectsBase, mbe.getRank(), true);
} else {
if (mbe.getReqLvl() > (int) mob.level)
continue;
mob.addEffectNoTimer(Integer.toString(effectsBase.getUUID()), effectsBase, mbe.getRank(), true);
}
}
}
public static void applyEquipmentResists(Mob mob){
if(mob.equip != null){
for(MobEquipment equipped : mob.equip.values()){
ItemBase itemBase = equipped.getItemBase();
if(itemBase.isHeavyArmor() || itemBase.isLightArmor() || itemBase.isMediumArmor()){
mob.resists.setResist(Enum.DamageType.Crush, mob.resists.getResist(Enum.DamageType.Crush,0) + itemBase.getCrushResist());
mob.resists.setResist(Enum.DamageType.Slash, mob.resists.getResist(Enum.DamageType.Slash,0) + itemBase.getCrushResist());
mob.resists.setResist(Enum.DamageType.Pierce, mob.resists.getResist(Enum.DamageType.Pierce,0) + itemBase.getCrushResist());
}
}
}
}
public static void applyMobbaseSkill(Mob mob) {
SkillsBase baseSkill = DbManager.SkillsBaseQueries.GET_BASE_BY_TOKEN(mob.mobBase.getMobBaseStats().getBaseSkill());
if(baseSkill != null)
mob.getSkills().put(baseSkill.getName(),new CharacterSkill(baseSkill,mob,mob.mobBase.getMobBaseStats().getBaseSkillAmount()));
}
public static void applyRuneSkills(Mob mob, int runeID){
//load mob skill adjustments from mobbase rune
if(PowersManager._allRuneSkillAdjusts.containsKey(runeID))
for(RuneSkillAdjustEntry entry : PowersManager._allRuneSkillAdjusts.get(runeID)) {
if(SkillsBase.getFromCache(entry.skill_type) == null)
SkillsBase.putInCache(DbManager.SkillsBaseQueries.GET_BASE_BY_NAME(entry.skill_type));
SkillsBase skillBase = SkillsBase.getFromCache(entry.skill_type);
if(skillBase == null)
continue;
if (entry.level <= mob.level)
if (mob.skills.containsKey(entry.name) == false)
mob.skills.put(entry.skill_type, new CharacterSkill(skillBase, mob, entry.rank));
else
mob.skills.put(entry.skill_type, new CharacterSkill(skillBase, mob, entry.rank + mob.skills.get(entry.skill_type).getNumTrains()));
}
}
public static void applyRunesForNPC(NPC npc){
npc.runes = new ArrayList<>();
RuneBase shopkeeperBase = RuneBase.getRuneBase(252620);
CharacterRune shopkeeper = new CharacterRune(shopkeeperBase,npc.getObjectUUID());
npc.runes.add(shopkeeper);
if(NPCManager._runeSetMap.containsKey(npc.runeSetID)) {
for (int runeID : _runeSetMap.get(npc.runeSetID)) {
RuneBase rb = RuneBase.getRuneBase(runeID);
if(rb != null) {
CharacterRune toApply = new CharacterRune(rb, npc.getObjectUUID());
npc.runes.add(toApply);
}
}
}
}
} }
+15 -12
View File
@@ -9,7 +9,7 @@
package engine.gameManager; package engine.gameManager;
import engine.Enum.*; import engine.Enum.*;
import engine.InterestManagement.HeightMap; import engine.InterestManagement.Terrain;
import engine.InterestManagement.WorldGrid; import engine.InterestManagement.WorldGrid;
import engine.db.handlers.dbEffectsBaseHandler; import engine.db.handlers.dbEffectsBaseHandler;
import engine.db.handlers.dbPowerHandler; import engine.db.handlers.dbPowerHandler;
@@ -53,13 +53,10 @@ public enum PowersManager {
public static HashMap<Integer, AbstractPowerAction> powerActionsByID = new HashMap<>(); public static HashMap<Integer, AbstractPowerAction> powerActionsByID = new HashMap<>();
public static HashMap<String, Integer> ActionTokenByIDString = new HashMap<>(); public static HashMap<String, Integer> ActionTokenByIDString = new HashMap<>();
public static HashMap<String, Integer> AnimationOverrides = new HashMap<>(); public static HashMap<String, Integer> AnimationOverrides = new HashMap<>();
public static HashMap<Integer, ArrayList<MobPowerEntry>> AllMobPowers; public static HashMap<Integer, ArrayList<RunePowerEntry>> _allRunePowers;
public static HashMap<Integer, ArrayList<RuneSkillAdjustEntry>> _allRuneSkillAdjusts;
private static JobScheduler js; private static JobScheduler js;
private PowersManager() {
}
public static void initPowersManager(boolean fullPowersLoad) { public static void initPowersManager(boolean fullPowersLoad) {
if (fullPowersLoad) if (fullPowersLoad)
@@ -103,6 +100,16 @@ public enum PowersManager {
} }
} }
public static ArrayList<RunePowerEntry> getPowersForRune(int rune_id) {
ArrayList<RunePowerEntry> powerEntries = PowersManager._allRunePowers.get(rune_id);
if (powerEntries == null)
powerEntries = new ArrayList<>();
return powerEntries;
}
// This pre-loads all powers and effects // This pre-loads all powers and effects
public static void InitializePowers() { public static void InitializePowers() {
@@ -839,8 +846,6 @@ public enum PowersManager {
return; return;
} }
playerCharacter.setHateValue(pb.getHateValue(trains));
//Send Cast Message. //Send Cast Message.
// PerformActionMsg castMsg = new PerformActionMsg(msg); // PerformActionMsg castMsg = new PerformActionMsg(msg);
// castMsg.setNumTrains(9999); // castMsg.setNumTrains(9999);
@@ -891,8 +896,6 @@ public enum PowersManager {
//Power is aiding a target, handle aggro if combat target is a Mob. //Power is aiding a target, handle aggro if combat target is a Mob.
if (!pb.isHarmful() && target.getObjectType() == GameObjectType.PlayerCharacter) { if (!pb.isHarmful() && target.getObjectType() == GameObjectType.PlayerCharacter) {
PlayerCharacter pcTarget = (PlayerCharacter) target; PlayerCharacter pcTarget = (PlayerCharacter) target;
if (!pb.isHarmful())
Mob.HandleAssistedAggro(playerCharacter, pcTarget);
} }
// update target of used power timer // update target of used power timer
@@ -1769,7 +1772,7 @@ public enum PowersManager {
} else { } else {
targetLoc = tl; targetLoc = tl;
try { try {
targetLoc = targetLoc.setY(HeightMap.getWorldHeight(targetLoc)); //on ground targetLoc = targetLoc.setY(Terrain.getWorldHeight(targetLoc)); //on ground
} catch (Exception e) { } catch (Exception e) {
Logger.error(e); Logger.error(e);
targetLoc = tl; targetLoc = tl;
@@ -1971,7 +1974,7 @@ public enum PowersManager {
} else { } else {
targetLoc = tl; targetLoc = tl;
try { try {
targetLoc = targetLoc.setY(HeightMap.getWorldHeight(targetLoc)); //on ground targetLoc = targetLoc.setY(Terrain.getWorldHeight(targetLoc)); //on ground
} catch (Exception e) { } catch (Exception e) {
Logger.error(e); Logger.error(e);
} }
+85 -105
View File
@@ -9,8 +9,7 @@
package engine.gameManager; package engine.gameManager;
import engine.Enum; import engine.Enum;
import engine.db.archive.CityRecord; import engine.InterestManagement.Terrain;
import engine.db.archive.DataWarehouse;
import engine.math.Bounds; import engine.math.Bounds;
import engine.math.Vector2f; import engine.math.Vector2f;
import engine.math.Vector3f; import engine.math.Vector3f;
@@ -18,6 +17,7 @@ import engine.math.Vector3fImmutable;
import engine.objects.Building; import engine.objects.Building;
import engine.objects.City; import engine.objects.City;
import engine.objects.Zone; import engine.objects.Zone;
import engine.objects.ZoneTemplate;
import engine.server.MBServerStatics; import engine.server.MBServerStatics;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
@@ -36,6 +36,8 @@ public enum ZoneManager {
ZONEMANAGER; ZONEMANAGER;
public static HashMap<Integer, ZoneTemplate> _zone_templates = new HashMap<>();
public static final Set<Zone> macroZones = Collections.newSetFromMap(new ConcurrentHashMap<>()); public static final Set<Zone> macroZones = Collections.newSetFromMap(new ConcurrentHashMap<>());
private static final ConcurrentHashMap<Integer, Zone> zonesByID = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD); private static final ConcurrentHashMap<Integer, Zone> zonesByID = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD);
private static final ConcurrentHashMap<Integer, Zone> zonesByUUID = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD); private static final ConcurrentHashMap<Integer, Zone> zonesByUUID = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD);
@@ -45,9 +47,9 @@ public enum ZoneManager {
public static Instant hotZoneLastUpdate; public static Instant hotZoneLastUpdate;
public static Zone hotZone = null; public static Zone hotZone = null;
public static int hotZoneCycle = 0; // Used with HOTZONE_DURATION from config. public static int hotZoneCycle = 0; // Used with HOTZONE_DURATION from config.
public static HashMap<Integer, Vector2f> _zone_size_data = new HashMap<>();
/* Instance variables */ /* Instance variables */
private static Zone seaFloor = null; public static Zone seaFloor = null;
// Find all zones coordinates fit into, starting with Sea Floor // Find all zones coordinates fit into, starting with Sea Floor
@@ -60,8 +62,8 @@ public enum ZoneManager {
if (zone != null) { if (zone != null) {
allIn.add(zone); allIn.add(zone);
while (zone.getParent() != null) { while (zone.parent != null) {
zone = zone.getParent(); zone = zone.parent;
allIn.add(zone); allIn.add(zone);
} }
} }
@@ -70,7 +72,7 @@ public enum ZoneManager {
// Find smallest zone coordinates fit into. // Find smallest zone coordinates fit into.
public static final Zone findSmallestZone(final Vector3fImmutable loc) { public static Zone findSmallestZone(final Vector3fImmutable loc) {
Zone zone = ZoneManager.seaFloor; Zone zone = ZoneManager.seaFloor;
@@ -83,13 +85,13 @@ public enum ZoneManager {
childFound = false; childFound = false;
ArrayList<Zone> nodes = zone.getNodes(); ArrayList<Zone> nodes = zone.nodes;
// Logger.info("soze", "" + nodes.size()); // Logger.info("soze", "" + nodes.size());
if (nodes != null) if (nodes != null)
for (Zone child : nodes) { for (Zone child : nodes) {
if (Bounds.collide(loc, child.getBounds()) == true) { if (Bounds.collide(loc, child.bounds)) {
zone = child; zone = child;
childFound = true; childFound = true;
break; break;
@@ -99,16 +101,6 @@ public enum ZoneManager {
return zone; return zone;
} }
public static void addZone(final int zoneID, final Zone zone) {
ZoneManager.zonesByID.put(zoneID, zone);
ZoneManager.zonesByUUID.put(zone.getObjectUUID(), zone);
ZoneManager.zonesByName.put(zone.getName().toLowerCase(), zone);
}
// Returns the number of available hotZones // Returns the number of available hotZones
// remaining in this cycle (1am) // remaining in this cycle (1am)
@@ -129,8 +121,8 @@ public enum ZoneManager {
public static void resetHotZones() { public static void resetHotZones() {
for (Zone zone : ZoneManager.macroZones) for (Zone zone : ZoneManager.macroZones)
if (zone.hasBeenHotzone) if (zone.wasHotzonw)
zone.hasBeenHotzone = false; zone.wasHotzonw = false;
} }
@@ -147,18 +139,18 @@ public enum ZoneManager {
return ZoneManager.zonesByName.get(zoneName); return ZoneManager.zonesByName.get(zoneName);
} }
public static final Collection<Zone> getAllZones() { public static Collection<Zone> getAllZones() {
return ZoneManager.zonesByUUID.values(); return ZoneManager.zonesByUUID.values();
} }
public static final void setHotZone(final Zone zone) { public static void setHotZone(final Zone zone) {
if (!zone.isMacroZone()) if (!zone.isMacroZone())
return; return;
ZoneManager.hotZone = zone; ZoneManager.hotZone = zone;
ZoneManager.hotZoneCycle = 1; // Used with HOTZONE_DURATION from config. ZoneManager.hotZoneCycle = 1; // Used with HOTZONE_DURATION from config.
zone.hasBeenHotzone = true; zone.wasHotzonw = true;
ZoneManager.hotZoneLastUpdate = LocalDateTime.now().withMinute(0).withSecond(0).atZone(ZoneId.systemDefault()).toInstant(); ZoneManager.hotZoneLastUpdate = LocalDateTime.now().withMinute(0).withSecond(0).atZone(ZoneId.systemDefault()).toInstant();
} }
@@ -168,37 +160,32 @@ public enum ZoneManager {
if (ZoneManager.hotZone == null) if (ZoneManager.hotZone == null)
return false; return false;
return (Bounds.collide(loc, ZoneManager.hotZone.getBounds()) == true); return (Bounds.collide(loc, ZoneManager.hotZone.bounds));
} }
public static Zone getSeaFloor() { public static void populateZoneCollections(final Zone zone) {
return ZoneManager.seaFloor;
}
public static void setSeaFloor(final Zone value) {
ZoneManager.seaFloor = value;
}
public static final void populateWorldZones(final Zone zone) {
int loadNum = zone.getLoadNum();
// Zones are added to separate // Zones are added to separate
// collections for quick access // collections for quick access
// based upon their type. // based upon their type.
ZoneManager.zonesByID.put(zone.templateID, zone);
ZoneManager.zonesByUUID.put(zone.getObjectUUID(), zone);
ZoneManager.zonesByName.put(zone.zoneName.toLowerCase(), zone);
if (zone.isMacroZone()) { if (zone.isMacroZone()) {
addMacroZone(zone); addMacroZone(zone);
return; return;
} }
if (zone.guild_zone) {
if (zone.isPlayerCity()) { ZoneManager.playerCityZones.add(zone);
addPlayerCityZone(zone);
return; return;
} }
if (zone.isNPCCity()) if (zone.isNPCCity)
addNPCCityZone(zone); addNPCCityZone(zone);
} }
@@ -208,15 +195,10 @@ public enum ZoneManager {
} }
private static void addNPCCityZone(final Zone zone) { private static void addNPCCityZone(final Zone zone) {
zone.setNPCCity(true); zone.isNPCCity = true;
ZoneManager.npcCityZones.add(zone); ZoneManager.npcCityZones.add(zone);
} }
public static final void addPlayerCityZone(final Zone zone) {
zone.setPlayerCity(true);
ZoneManager.playerCityZones.add(zone);
}
public static final void generateAndSetRandomHotzone() { public static final void generateAndSetRandomHotzone() {
Zone hotZone; Zone hotZone;
@@ -249,23 +231,23 @@ public enum ZoneManager {
public static final boolean validHotZone(Zone zone) { public static final boolean validHotZone(Zone zone) {
if (zone.getSafeZone() == (byte) 1) if (zone.peace_zone == (byte) 1)
return false; // no safe zone hotzones// if (this.hotzone == null) return false; // no safe zone hotzones// if (this.hotzone == null)
if (zone.getNodes().isEmpty())
return false;
if (zone.equals(ZoneManager.seaFloor)) if (zone.equals(ZoneManager.seaFloor))
return false; return false;
if (zone.nodes.isEmpty())
return false;
//no duplicate hotZones //no duplicate hotZones
if (zone.hasBeenHotzone == true) if (zone.wasHotzonw == true)
return false; return false;
// Enforce min level // Enforce min level
if (zone.minLvl < Integer.parseInt(ConfigManager.MB_HOTZONE_MIN_LEVEL.getValue())) if (zone.min_level < Integer.parseInt(ConfigManager.MB_HOTZONE_MIN_LEVEL.getValue()))
return false; return false;
if (ZoneManager.hotZone != null) if (ZoneManager.hotZone != null)
@@ -277,55 +259,50 @@ public enum ZoneManager {
// Converts world coordinates to coordinates local to a given zone. // Converts world coordinates to coordinates local to a given zone.
public static Vector3fImmutable worldToLocal(Vector3fImmutable worldVector, public static Vector3fImmutable worldToLocal(Vector3fImmutable worldVector,
Zone serverZone) { Zone zone) {
Vector3fImmutable localCoords; Vector3fImmutable localCoords;
localCoords = new Vector3fImmutable(worldVector.x - serverZone.absX, localCoords = new Vector3fImmutable(worldVector.x - zone.absX,
worldVector.y - serverZone.absY, worldVector.z worldVector.y - zone.absY, worldVector.z
- serverZone.absZ); - zone.absZ);
return localCoords; return localCoords;
} }
public static Vector2f worldToZoneSpace(Vector3fImmutable worldVector, public static Vector2f worldToZoneOffset(Vector3fImmutable worldLoc,
Zone serverZone) { Zone zone) {
Vector2f zoneLoc;
zoneLoc = new Vector2f(worldLoc.x, worldLoc.z).subtract(zone.getLoc().x, zone.getLoc().z);
zoneLoc.y *= -1;
return zoneLoc;
}
public static Vector2f worldToTerrainSpace(Vector3fImmutable worldLoc,
Zone zone) {
Vector2f localCoords; Vector2f localCoords;
Vector2f zoneOrigin; Vector2f zoneOrigin;
// Top left corner of zone is calculated in world space by the center and it's extents. // Top left corner of zone is calculated in world space by the center and it's extents.
zoneOrigin = new Vector2f(serverZone.getLoc().x, serverZone.getLoc().z); zoneOrigin = new Vector2f(zone.getLoc().x, zone.getLoc().z);
zoneOrigin = zoneOrigin.subtract(new Vector2f(serverZone.getBounds().getHalfExtents().x, serverZone.getBounds().getHalfExtents().y)); zoneOrigin = zoneOrigin.subtract(new Vector2f(zone.bounds.getHalfExtents().x, zone.bounds.getHalfExtents().y));
// Local coordinate in world space translated to an offset from the calculated zone origin. // Local coordinate in world space translated to an offset from the calculated zone origin.
localCoords = new Vector2f(worldVector.x, worldVector.z); localCoords = new Vector2f(worldLoc.x, worldLoc.z);
localCoords = localCoords.subtract(zoneOrigin); localCoords = localCoords.subtract(zoneOrigin);
localCoords.setY((serverZone.getBounds().getHalfExtents().y * 2) - localCoords.y);
// TODO : Make sure this value does not go outside the zone's bounds.
return localCoords; return localCoords;
} }
// Converts local zone coordinates to world coordinates // Converts local zone coordinates to world coordinates
public static Vector3fImmutable localToWorld(Vector3fImmutable worldVector,
Zone serverZone) {
Vector3fImmutable worldCoords;
worldCoords = new Vector3fImmutable(worldVector.x + serverZone.absX,
worldVector.y + serverZone.absY, worldVector.z
+ serverZone.absZ);
return worldCoords;
}
/** /**
* Converts from local (relative to this building) to world. * Converts from local (relative to this building) to world.
@@ -341,9 +318,10 @@ public enum ZoneManager {
if (building.getBounds().getQuaternion() == null) if (building.getBounds().getQuaternion() == null)
return building.getLoc(); return building.getLoc();
// handle building rotation
Vector3fImmutable rotatedLocal = Vector3fImmutable.rotateAroundPoint(Vector3fImmutable.ZERO, localPos, building.getBounds().getQuaternion()); Vector3fImmutable rotatedLocal = Vector3fImmutable.rotateAroundPoint(Vector3fImmutable.ZERO, localPos, building.getBounds().getQuaternion());
// handle building rotation
// handle building translation // handle building translation
return building.getLoc().add(rotatedLocal.x, rotatedLocal.y, rotatedLocal.z); return building.getLoc().add(rotatedLocal.x, rotatedLocal.y, rotatedLocal.z);
@@ -353,12 +331,10 @@ public enum ZoneManager {
//used for regions, Building bounds not set yet. //used for regions, Building bounds not set yet.
public static Vector3f convertLocalToWorld(Building building, Vector3f localPos, Bounds bounds) { public static Vector3f convertLocalToWorld(Building building, Vector3f localPos, Bounds bounds) {
// convert from SB rotation value to radians // handle building rotation
Vector3f rotatedLocal = Vector3f.rotateAroundPoint(Vector3f.ZERO, localPos, bounds.getQuaternion()); Vector3f rotatedLocal = Vector3f.rotateAroundPoint(Vector3f.ZERO, localPos, bounds.getQuaternion());
// handle building rotation
// handle building translation // handle building translation
return new Vector3f(building.getLoc().add(rotatedLocal.x, rotatedLocal.y, rotatedLocal.z)); return new Vector3f(building.getLoc().add(rotatedLocal.x, rotatedLocal.y, rotatedLocal.z));
@@ -381,13 +357,11 @@ public enum ZoneManager {
public static City getCityAtLocation(Vector3fImmutable worldLoc) { public static City getCityAtLocation(Vector3fImmutable worldLoc) {
Zone currentZone; Zone currentZone;
ArrayList<Zone> zoneList;
City city;
currentZone = ZoneManager.findSmallestZone(worldLoc); currentZone = ZoneManager.findSmallestZone(worldLoc);
if (currentZone.isPlayerCity()) if (currentZone.guild_zone)
return City.getCity(currentZone.getPlayerCityUUID()); return City.getCity(currentZone.playerCityUUID);
return null; return null;
} }
@@ -410,16 +384,16 @@ public enum ZoneManager {
treeBounds = Bounds.borrow(); treeBounds = Bounds.borrow();
treeBounds.setBounds(new Vector2f(positionX, positionZ), new Vector2f(Enum.CityBoundsType.PLACEMENT.extents, Enum.CityBoundsType.PLACEMENT.extents), 0.0f); treeBounds.setBounds(new Vector2f(positionX, positionZ), new Vector2f(Enum.CityBoundsType.PLACEMENT.halfExtents, Enum.CityBoundsType.PLACEMENT.halfExtents), 0.0f);
zoneList = currentZone.getNodes(); zoneList = currentZone.nodes;
for (Zone zone : zoneList) { for (Zone zone : zoneList) {
if (zone.isContinent()) if (zone.isContinent())
continue; continue;
if (Bounds.collide(treeBounds, zone.getBounds(), 0.0f)) if (Bounds.collide(treeBounds, zone.bounds, 0.0f))
validLocation = false; validLocation = false;
} }
@@ -427,30 +401,36 @@ public enum ZoneManager {
return validLocation; return validLocation;
} }
public static void loadCities(Zone zone) { public static float calculateGlobalZoneHeight(Zone zone) {
ArrayList<City> cities = DbManager.CityQueries.GET_CITIES_BY_ZONE(zone.getObjectUUID()); float worldAltitude = MBServerStatics.SEA_FLOOR_ALTITUDE;
for (City city : cities) { // Seafloor
city.setParent(zone); if (ZoneManager.seaFloor.equals(zone))
city.setObjectTypeMask(MBServerStatics.MASK_CITY); return worldAltitude;
city.setLoc(city.getLoc()); // huh?
//not player city, must be npc city.. // Children of seafloor
if (!zone.isPlayerCity()) if (ZoneManager.seaFloor.equals(zone.parent))
zone.setNPCCity(true); return worldAltitude + zone.yOffset;
if ((ConfigManager.serverType.equals(Enum.ServerType.WORLDSERVER)) && (city.getHash() == null)) { // return height from heightmap engine at zone location
city.setHash(); worldAltitude = Terrain.getWorldHeight(zone.parent, zone.getLoc());
if (DataWarehouse.recordExists(Enum.DataRecordType.CITY, city.getObjectUUID()) == false) { // Add zone offset to value
CityRecord cityRecord = CityRecord.borrow(city, Enum.RecordEventType.CREATE);
DataWarehouse.pushToWarehouse(cityRecord); worldAltitude += zone.yOffset;
}
} return worldAltitude;
} }
public static boolean isLocUnderwater(Vector3fImmutable currentLoc) {
float localAltitude = Terrain.getWorldHeight(currentLoc);
Zone zone = findSmallestZone(currentLoc);
return localAltitude < zone.sea_level;
} }
} }
+2 -2
View File
@@ -29,7 +29,7 @@ public class EndFearJob extends AbstractEffectJob {
if (this.target == null || (!(this.target instanceof Mob))) if (this.target == null || (!(this.target instanceof Mob)))
return; return;
((Mob) this.target).setFearedObject(null); ((Mob) this.target).fearedObject = null;
} }
@Override @Override
@@ -40,6 +40,6 @@ public class EndFearJob extends AbstractEffectJob {
if (this.target == null || (!(this.target instanceof Mob))) if (this.target == null || (!(this.target instanceof Mob)))
return; return;
((Mob) this.target).setFearedObject(null); ((Mob) this.target).fearedObject = null;
} }
} }
-2
View File
@@ -61,8 +61,6 @@ public class FinishSummonsJob extends AbstractScheduleJob {
return; return;
} }
if (this.source.region != null)
this.target.setRegion(this.source.region);
//teleport target to source //teleport target to source
target.teleport(source.getLoc()); target.teleport(source.getLoc());
} }
+2 -1
View File
@@ -1,5 +1,6 @@
package engine.jobs; package engine.jobs;
import engine.gameManager.BuildingManager;
import engine.job.AbstractScheduleJob; import engine.job.AbstractScheduleJob;
import engine.objects.Building; import engine.objects.Building;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
@@ -39,7 +40,7 @@ public class UpgradeBuildingJob extends AbstractScheduleJob {
// SetCurrentRank also changes the mesh and maxhp // SetCurrentRank also changes the mesh and maxhp
// accordingly for buildings with blueprints // accordingly for buildings with blueprints
rankingBuilding.setRank(rankingBuilding.getRank() + 1); BuildingManager.setRank(rankingBuilding, rankingBuilding.getRank() + 1);
// Reload the object // Reload the object
+3 -2
View File
@@ -422,7 +422,7 @@ public class Bounds {
this.origin.set(building.getLoc().x, building.getLoc().z); this.origin.set(building.getLoc().x, building.getLoc().z);
// Magicbane uses half halfExtents // Magicbane uses halfExtents
if (meshBounds == null) { if (meshBounds == null) {
halfExtentX = 1; halfExtentX = 1;
@@ -438,8 +438,10 @@ public class Bounds {
// The rotation is reset after the new aabb is calculated. // The rotation is reset after the new aabb is calculated.
this.rotation = building.getRot().y; this.rotation = building.getRot().y;
// Caclculate and set the new half halfExtents for the rotated bounding box // Caclculate and set the new half halfExtents for the rotated bounding box
// and reset the rotation to 0 for this bounds. // and reset the rotation to 0 for this bounds.
this.halfExtents.set(halfExtentX, (halfExtentY)); this.halfExtents.set(halfExtentX, (halfExtentY));
this.rotation = 0; this.rotation = 0;
@@ -453,7 +455,6 @@ public class Bounds {
this.halfExtents.set(blueprint.getExtents()); this.halfExtents.set(blueprint.getExtents());
this.flipExtents = Bounds.calculateFlipExtents(this); this.flipExtents = Bounds.calculateFlipExtents(this);
this.setRegions(building); this.setRegions(building);
this.setColliders(building); this.setColliders(building);
+225 -308
View File
@@ -15,6 +15,7 @@ import engine.gameManager.*;
import engine.math.Vector3f; import engine.math.Vector3f;
import engine.math.Vector3fImmutable; import engine.math.Vector3fImmutable;
import engine.mobileAI.Threads.MobAIThread; import engine.mobileAI.Threads.MobAIThread;
import engine.mobileAI.Threads.Respawner;
import engine.mobileAI.utilities.CombatUtilities; import engine.mobileAI.utilities.CombatUtilities;
import engine.mobileAI.utilities.MovementUtilities; import engine.mobileAI.utilities.MovementUtilities;
import engine.net.DispatchMessage; import engine.net.DispatchMessage;
@@ -23,6 +24,7 @@ import engine.net.client.msg.PowerProjectileMsg;
import engine.objects.*; import engine.objects.*;
import engine.powers.ActionsBase; import engine.powers.ActionsBase;
import engine.powers.PowersBase; import engine.powers.PowersBase;
import engine.powers.RunePowerEntry;
import engine.server.MBServerStatics; import engine.server.MBServerStatics;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
@@ -49,17 +51,19 @@ public class MobAI {
return; return;
} }
if (target.getObjectType().equals(Enum.GameObjectType.PlayerCharacter) &&
!mob.canSee((AbstractCharacter) target)) {
mob.setCombatTarget(null);
return;
}
if (target.getObjectType() == Enum.GameObjectType.PlayerCharacter && canCast(mob)) { if (target.getObjectType() == Enum.GameObjectType.PlayerCharacter && canCast(mob)) {
if (mob.isPlayerGuard() == false && MobCast(mob)) { if (MobCast(mob)) {
mob.updateLocation(); mob.updateLocation();
return; return;
} }
if (mob.isPlayerGuard() == true && GuardCast(mob)) {
mob.updateLocation();
return;
}
} }
if (!CombatUtilities.inRangeToAttack(mob, target)) if (!CombatUtilities.inRangeToAttack(mob, target))
@@ -96,7 +100,7 @@ public class MobAI {
return; return;
} }
if (mob.BehaviourType.callsForHelp) if (mob.behaviourType.callsForHelp)
MobCallForHelp(mob); MobCallForHelp(mob);
if (!MovementUtilities.inRangeDropAggro(mob, target)) { if (!MovementUtilities.inRangeDropAggro(mob, target)) {
@@ -165,7 +169,7 @@ public class MobAI {
if (playercity != null) if (playercity != null)
for (Mob guard : playercity.getParent().zoneMobSet) for (Mob guard : playercity.getParent().zoneMobSet)
if (guard.BehaviourType != null && guard.BehaviourType.ordinal() == Enum.MobBehaviourType.GuardCaptain.ordinal()) if (guard.agentType.equals(Enum.AIAgentType.GUARDCAPTAIN))
if (guard.getCombatTarget() == null && !guard.getGuild().equals(mob.getGuild())) if (guard.getCombatTarget() == null && !guard.getGuild().equals(mob.getGuild()))
guard.setCombatTarget(mob); guard.setCombatTarget(mob);
@@ -249,18 +253,22 @@ public class MobAI {
try { try {
//make sure mob is out of combat stance
int patrolDelay = ThreadLocalRandom.current().nextInt((int) (MobAIThread.AI_PATROL_DIVISOR * 0.5f), MobAIThread.AI_PATROL_DIVISOR) + MobAIThread.AI_PATROL_DIVISOR; int patrolDelay = ThreadLocalRandom.current().nextInt((int) (MobAIThread.AI_PATROL_DIVISOR * 0.5f), MobAIThread.AI_PATROL_DIVISOR) + MobAIThread.AI_PATROL_DIVISOR;
//early exit while waiting to patrol again // early exit while waiting to patrol again.
// Minions are force marched if captain is alive
boolean forced = mob.agentType.equals(Enum.AIAgentType.GUARDMINION) &&
mob.guardCaptain.isAlive();
if (mob.stopPatrolTime + (patrolDelay * 1000) > System.currentTimeMillis()) if (mob.stopPatrolTime + (patrolDelay * 1000) > System.currentTimeMillis())
if (!forced)
return; return;
//guard captains inherit barracks patrol points dynamically //guards inherit barracks patrol points dynamically
if (mob.BehaviourType.ordinal() == Enum.MobBehaviourType.GuardCaptain.ordinal()) { if (mob.patrolPoints == null || mob.patrolPoints.isEmpty())
if (mob.agentType.equals(Enum.AIAgentType.GUARDCAPTAIN) || mob.agentType.equals(Enum.AIAgentType.GUARDMINION)) {
Building barracks = mob.building; Building barracks = mob.building;
@@ -275,24 +283,28 @@ public class MobAI {
if (mob.lastPatrolPointIndex > mob.patrolPoints.size() - 1) if (mob.lastPatrolPointIndex > mob.patrolPoints.size() - 1)
mob.lastPatrolPointIndex = 0; mob.lastPatrolPointIndex = 0;
// Minions are given marching orders by the captain if he is alive
if (mob.agentType.equals(Enum.AIAgentType.GUARDMINION)) {
Mob captain = (Mob) mob.guardCaptain;
mob.destination = captain.destination.add(Formation.getOffset(2, mob.guardCaptain.minions.indexOf(mob.getObjectUUID()) + 3));
mob.lastPatrolPointIndex = captain.lastPatrolPointIndex;
} else {
mob.destination = mob.patrolPoints.get(mob.lastPatrolPointIndex); mob.destination = mob.patrolPoints.get(mob.lastPatrolPointIndex);
mob.lastPatrolPointIndex += 1; mob.lastPatrolPointIndex += 1;
}
// Captain orders minions to patrol
if (mob.agentType.equals(Enum.AIAgentType.GUARDCAPTAIN))
for (Integer minionUUID : mob.minions) {
Mob minion = Mob.getMob(minionUUID);
if (minion.isAlive() && minion.combatTarget == null)
MobAI.Patrol(minion);
}
MovementUtilities.aiMove(mob, mob.destination, true); MovementUtilities.aiMove(mob, mob.destination, true);
if (mob.BehaviourType.equals(Enum.MobBehaviourType.GuardCaptain))
for (Entry<Mob, Integer> minion : mob.siegeMinionMap.entrySet())
//make sure mob is out of combat stance
if (minion.getKey().despawned == false) {
if (MovementUtilities.canMove(minion.getKey())) {
Vector3f minionOffset = Formation.getOffset(2, minion.getValue() + 3);
minion.getKey().updateLocation();
Vector3fImmutable formationPatrolPoint = new Vector3fImmutable(mob.destination.x + minionOffset.x, mob.destination.y, mob.destination.z + minionOffset.z);
MovementUtilities.aiMove(minion.getKey(), formationPatrolPoint, true);
}
}
} catch (Exception e) { } catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: AttackTarget" + " " + e.getMessage()); Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: AttackTarget" + " " + e.getMessage());
} }
@@ -300,6 +312,8 @@ public class MobAI {
public static boolean canCast(Mob mob) { public static boolean canCast(Mob mob) {
int contractID = 0;
try { try {
// Performs validation to determine if a // Performs validation to determine if a
@@ -308,26 +322,27 @@ public class MobAI {
if (mob == null) if (mob == null)
return false; return false;
if(mob.isPlayerGuard == true){ if (mob.isPlayerGuard() == true) {
int contractID; if(mob.agentType.equals(Enum.AIAgentType.GUARDWALLARCHER))
return false; //wall archers don't cast
if(mob.BehaviourType.equals(Enum.MobBehaviourType.GuardMinion)) if (mob.agentType.equals(Enum.AIAgentType.GUARDMINION))
contractID = mob.npcOwner.contract.getContractID(); contractID = mob.guardCaptain.contract.getContractID();
else else
contractID = mob.contract.getContractID(); contractID = mob.contract.getContractID();
if(Enum.MinionType.ContractToMinionMap.get(contractID).isMage() == false) // exception allowing werewolf and werebear guard captains to cast
if (Enum.MinionType.ContractToMinionMap.get(contractID).isMage() == false && contractID != 980103 && contractID != 980104)
return false; return false;
} }
if (mob.mobPowers.isEmpty()) // Mobile has no powers defined in mobbase or contract..
if (PowersManager.getPowersForRune(mob.getMobBaseID()).isEmpty() &&
PowersManager.getPowersForRune(contractID).isEmpty())
return false; return false;
if (!mob.canSee((PlayerCharacter) mob.getCombatTarget())) {
mob.setCombatTarget(null);
return false;
}
if (mob.nextCastTime == 0) if (mob.nextCastTime == 0)
mob.nextCastTime = System.currentTimeMillis(); mob.nextCastTime = System.currentTimeMillis();
@@ -346,47 +361,67 @@ public class MobAI {
// and casts it on the current target (or itself). Validation // and casts it on the current target (or itself). Validation
// (including empty lists) is done previously within canCast(); // (including empty lists) is done previously within canCast();
ArrayList<Integer> powerTokens; ArrayList<RunePowerEntry> powerEntries;
ArrayList<Integer> purgeTokens; ArrayList<RunePowerEntry> purgeEntries;
AbstractCharacter target = (AbstractCharacter) mob.getCombatTarget(); AbstractCharacter target = (AbstractCharacter) mob.getCombatTarget();
if (mob.BehaviourType.callsForHelp) if (mob.behaviourType.callsForHelp)
MobCallForHelp(mob); MobCallForHelp(mob);
// Generate a list of tokens from the mob powers for this mobile. // Generate a list of tokens from the mob powers for this mobile.
powerTokens = new ArrayList<>(mob.mobPowers.keySet()); powerEntries = new ArrayList<>(PowersManager.getPowersForRune(mob.getMobBaseID()));
purgeTokens = new ArrayList<>(); purgeEntries = new ArrayList<>();
// Additional powers may come from the contract ID. This is to support
// powers for player guards irrespective of the mobbase used.
if (mob.isPlayerGuard()) {
ArrayList<RunePowerEntry> contractEntries = new ArrayList<>();
if (mob.contract != null)
contractEntries = PowersManager.getPowersForRune(mob.contractUUID);
if (mob.agentType.equals(Enum.AIAgentType.GUARDMINION))
contractEntries = PowersManager.getPowersForRune(mob.guardCaptain.contractUUID);
powerEntries.addAll(contractEntries);
}
// If player has this effect on them currently then remove // If player has this effect on them currently then remove
// this token from our list. // this token from our list.
for (int powerToken : powerTokens) { for (RunePowerEntry runePowerEntry : powerEntries) {
PowersBase powerBase = PowersManager.getPowerByToken(powerToken); PowersBase powerBase = PowersManager.getPowerByToken(runePowerEntry.token);
for (ActionsBase actionBase : powerBase.getActions()) { for (ActionsBase actionBase : powerBase.getActions()) {
String stackType = actionBase.stackType; String stackType = actionBase.stackType;
if (target.getEffects() != null && target.getEffects().containsKey(stackType)) if (target.getEffects() != null && target.getEffects().containsKey(stackType))
purgeTokens.add(powerToken); purgeEntries.add(runePowerEntry);
} }
} }
powerTokens.removeAll(purgeTokens); powerEntries.removeAll(purgeEntries);
// Sanity check // Sanity check
if (powerTokens.isEmpty()) if (powerEntries.isEmpty())
return false; return false;
// Pick random spell from our list of powers // Pick random spell from our list of powers
int powerToken = powerTokens.get(ThreadLocalRandom.current().nextInt(powerTokens.size())); RunePowerEntry runePowerEntry = powerEntries.get(ThreadLocalRandom.current().nextInt(powerEntries.size()));
int powerRank = mob.mobPowers.get(powerToken);
PowersBase mobPower = PowersManager.getPowerByToken(powerToken); PowersBase mobPower = PowersManager.getPowerByToken(runePowerEntry.token);
int powerRank = runePowerEntry.rank;
if (mob.isPlayerGuard())
powerRank = getGuardPowerRank(mob);
//check for hit-roll //check for hit-roll
@@ -411,7 +446,7 @@ public class MobAI {
msg.setUnknown04(2); msg.setUnknown04(2);
PowersManager.finishUseMobPower(msg, mob, 0, 0); PowersManager.finishUseMobPower(msg, mob, 0, 0);
long randomCooldown = (long)((ThreadLocalRandom.current().nextInt(10,15) * 1000) * MobAIThread.AI_CAST_FREQUENCY); long randomCooldown = (long) ((ThreadLocalRandom.current().nextInt(10, 15) * 1000) * MobAIThread.AI_CAST_FREQUENCY);
mob.nextCastTime = System.currentTimeMillis() + randomCooldown; mob.nextCastTime = System.currentTimeMillis() + randomCooldown;
return true; return true;
@@ -422,64 +457,10 @@ public class MobAI {
return false; return false;
} }
public static boolean GuardCast(Mob mob) { public static int getGuardPowerRank(Mob mob) {
try {
// Method picks a random spell from a mobile's list of powers
// and casts it on the current target (or itself). Validation
// (including empty lists) is done previously within canCast();
ArrayList<Integer> powerTokens;
ArrayList<Integer> purgeTokens;
AbstractCharacter target = (AbstractCharacter) mob.getCombatTarget();
if (mob.BehaviourType.callsForHelp)
MobCallForHelp(mob);
// Generate a list of tokens from the mob powers for this mobile.
powerTokens = new ArrayList<>(mob.mobPowers.keySet());
purgeTokens = new ArrayList<>();
// If player has this effect on them currently then remove
// this token from our list.
for (int powerToken : powerTokens) {
PowersBase powerBase = PowersManager.getPowerByToken(powerToken);
for (ActionsBase actionBase : powerBase.getActions()) {
String stackType = actionBase.stackType;
if (target.getEffects() != null && target.getEffects().containsKey(stackType))
purgeTokens.add(powerToken);
}
}
powerTokens.removeAll(purgeTokens);
// Sanity check
if (powerTokens.isEmpty())
return false;
int powerToken = 0;
int nukeRoll = ThreadLocalRandom.current().nextInt(1,100);
if (nukeRoll < 55) {
//use direct damage spell
powerToken = powerTokens.get(powerTokens.size() - 1);
} else {
//use random spell
powerToken = powerTokens.get(ThreadLocalRandom.current().nextInt(powerTokens.size()));
}
int powerRank = 1; int powerRank = 1;
switch(mob.getRank()){ switch (mob.getRank()) {
case 1: case 1:
powerRank = 10; powerRank = 10;
break; break;
@@ -502,47 +483,7 @@ public class MobAI {
powerRank = 40; powerRank = 40;
break; break;
} }
return powerRank;
PowersBase mobPower = PowersManager.getPowerByToken(powerToken);
//check for hit-roll
if (mobPower.requiresHitRoll)
if (CombatUtilities.triggerDefense(mob, mob.getCombatTarget()))
return false;
// Cast the spell
if (CombatUtilities.inRange2D(mob, mob.getCombatTarget(), mobPower.getRange())) {
PerformActionMsg msg;
if (!mobPower.isHarmful() || mobPower.targetSelf) {
if (mobPower.category.equals("DISPEL")) {
PowersManager.useMobPower(mob, target, mobPower, powerRank);
msg = PowersManager.createPowerMsg(mobPower, powerRank, mob, target);
} else {
PowersManager.useMobPower(mob, mob, mobPower, powerRank);
msg = PowersManager.createPowerMsg(mobPower, powerRank, mob, mob);
}
} else {
PowersManager.useMobPower(mob, target, mobPower, powerRank);
msg = PowersManager.createPowerMsg(mobPower, powerRank, mob, target);
}
msg.setUnknown04(2);
PowersManager.finishUseMobPower(msg, mob, 0, 0);
long randomCooldown = (long)((ThreadLocalRandom.current().nextInt(10,15) * 1000) * MobAIThread.AI_CAST_FREQUENCY);
mob.nextCastTime = System.currentTimeMillis() + randomCooldown;
return true;
}
} catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: MobCast" + " " + e.getMessage());
}
return false;
} }
public static void MobCallForHelp(Mob mob) { public static void MobCallForHelp(Mob mob) {
@@ -564,7 +505,7 @@ public class MobAI {
Zone mobCamp = mob.getParentZone(); Zone mobCamp = mob.getParentZone();
for (Mob helper : mobCamp.zoneMobSet) { for (Mob helper : mobCamp.zoneMobSet) {
if (helper.BehaviourType.respondsToCallForHelp && helper.BehaviourType.BehaviourHelperType.equals(mob.BehaviourType)) { if (helper.behaviourType.respondsToCallForHelp && helper.behaviourType.BehaviourHelperType.equals(mob.behaviourType)) {
helper.setCombatTarget(mob.getCombatTarget()); helper.setCombatTarget(mob.getCombatTarget());
callGotResponse = true; callGotResponse = true;
} }
@@ -606,10 +547,10 @@ public class MobAI {
//override for guards //override for guards
if (mob.despawned && mob.isPlayerGuard) { if (mob.despawned && mob.isPlayerGuard()) {
if (mob.BehaviourType.ordinal() == Enum.MobBehaviourType.GuardMinion.ordinal()) { if (mob.agentType.equals(Enum.AIAgentType.GUARDMINION)) {
if (mob.npcOwner.isAlive() == false || ((Mob) mob.npcOwner).despawned == true) { if (mob.guardCaptain.isAlive() == false || ((Mob) mob.guardCaptain).despawned == true) {
//minions don't respawn while guard captain is dead //minions don't respawn while guard captain is dead
@@ -625,7 +566,7 @@ public class MobAI {
//check to send mob home for player guards to prevent exploit of dragging guards away and then teleporting //check to send mob home for player guards to prevent exploit of dragging guards away and then teleporting
if (mob.BehaviourType.ordinal() != Enum.MobBehaviourType.Pet1.ordinal()) if (!mob.agentType.equals(Enum.AIAgentType.PET))
CheckToSendMobHome(mob); CheckToSendMobHome(mob);
return; return;
@@ -638,15 +579,23 @@ public class MobAI {
return; return;
} }
//no players loaded, no need to proceed //no players loaded, no need to proceed unless it's a player guard
boolean bypassLoadedPlayerCheck = false;
if(mob.isPlayerGuard() || mob.isSiege()) {
bypassLoadedPlayerCheck = true;
if(mob.combatTarget != null && mob.combatTarget.getObjectType().equals(Enum.GameObjectType.PlayerCharacter))
if(mob.combatTarget.loc.distanceSquared(mob.loc) > 10000)
mob.setCombatTarget(null);
}
if (mob.playerAgroMap.isEmpty()) { if (mob.playerAgroMap.isEmpty() && !bypassLoadedPlayerCheck) {
if(mob.getCombatTarget() != null) if (mob.getCombatTarget() != null)
mob.setCombatTarget(null); mob.setCombatTarget(null);
return; return;
} }
if (mob.BehaviourType.ordinal() != Enum.MobBehaviourType.Pet1.ordinal())
if (mob.agentType.equals(Enum.AIAgentType.PET) == false)
CheckToSendMobHome(mob); CheckToSendMobHome(mob);
if (mob.getCombatTarget() != null) { if (mob.getCombatTarget() != null) {
@@ -673,17 +622,14 @@ public class MobAI {
} }
} }
switch (mob.BehaviourType) { switch (mob.behaviourType) {
case GuardCaptain: case GuardCaptain:
GuardCaptainLogic(mob);
break;
case GuardMinion: case GuardMinion:
GuardMinionLogic(mob);
break;
case GuardWallArcher: case GuardWallArcher:
GuardWallArcherLogic(mob); GuardLogic(mob);
break; break;
case Pet1: case Pet1:
case SiegeEngine:
PetLogic(mob); PetLogic(mob);
break; break;
case HamletGuard: case HamletGuard:
@@ -707,12 +653,12 @@ public class MobAI {
if (!aiAgent.isAlive()) if (!aiAgent.isAlive())
return; return;
ConcurrentHashMap<Integer, Boolean> loadedPlayers = aiAgent.playerAgroMap; ConcurrentHashMap<Integer, Float> loadedPlayers = aiAgent.playerAgroMap;
for (Entry playerEntry : loadedPlayers.entrySet()) { for (Entry playerEntry : loadedPlayers.entrySet()) {
int playerID = (int) playerEntry.getKey(); int playerID = (int) playerEntry.getKey();
PlayerCharacter loadedPlayer = PlayerCharacter.getFromCache(playerID); PlayerCharacter loadedPlayer = PlayerCharacter.getPlayerCharacter(playerID);
//Player is null, let's remove them from the list. //Player is null, let's remove them from the list.
@@ -747,7 +693,6 @@ public class MobAI {
aiAgent.setCombatTarget(loadedPlayer); aiAgent.setCombatTarget(loadedPlayer);
return; return;
} }
} }
if (aiAgent.getCombatTarget() == null) { if (aiAgent.getCombatTarget() == null) {
@@ -782,47 +727,45 @@ public class MobAI {
mob.updateLocation(); mob.updateLocation();
switch (mob.BehaviourType) { switch (mob.behaviourType) {
case Pet1: case Pet1:
if (mob.getOwner() == null)
if (mob.guardCaptain == null)
return; return;
if (!mob.playerAgroMap.containsKey(mob.getOwner().getObjectUUID())) { //mob no longer has its owner loaded, translate pet to owner
//mob no longer has its owner loaded, translocate pet to owner if (!mob.playerAgroMap.containsKey(mob.guardCaptain.getObjectUUID())) {
MovementManager.translocate(mob, mob.guardCaptain.getLoc());
MovementManager.translocate(mob, mob.getOwner().getLoc(), null);
return; return;
} }
if (mob.getCombatTarget() == null) { if (mob.getCombatTarget() == null) {
//move back to owner //move back to owner
if (CombatUtilities.inRange2D(mob, mob.getOwner(), 6)) if (CombatUtilities.inRange2D(mob, mob.guardCaptain, 6))
return; return;
mob.destination = mob.getOwner().getLoc(); mob.destination = mob.guardCaptain.getLoc();
MovementUtilities.moveToLocation(mob, mob.destination, 5); MovementUtilities.moveToLocation(mob, mob.destination, 5, false);
} else } else
chaseTarget(mob); chaseTarget(mob);
break; break;
case GuardMinion:
if (!mob.npcOwner.isAlive() || ((Mob) mob.npcOwner).despawned)
randomGuardPatrolPoint(mob);
else {
if (mob.getCombatTarget() != null) {
chaseTarget(mob);
}
}
break;
default: default:
if (mob.getCombatTarget() == null) { if (mob.getCombatTarget() == null) {
if (!mob.isMoving())
if (!mob.isMoving()) {
// Minions only patrol on their own if captain is dead.
if (mob.agentType.equals(Enum.AIAgentType.GUARDMINION) == false)
Patrol(mob); Patrol(mob);
else { else if (mob.guardCaptain.isAlive() == false)
Patrol(mob);
} else
mob.stopPatrolTime = System.currentTimeMillis(); mob.stopPatrolTime = System.currentTimeMillis();
}
} else { } else {
chaseTarget(mob); chaseTarget(mob);
} }
@@ -871,11 +814,9 @@ public class MobAI {
} }
} }
} }
} else if (System.currentTimeMillis() > (aiAgent.deathTime + (aiAgent.spawnTime * 1000))) { } else if (System.currentTimeMillis() > aiAgent.deathTime + (aiAgent.spawnDelay * 1000L)) {
aiAgent.respawnTime = aiAgent.deathTime + (aiAgent.spawnDelay * 1000L);
if (Zone.respawnQue.contains(aiAgent) == false) { Respawner.respawnQueue.put(aiAgent);
Zone.respawnQue.add(aiAgent);
}
} }
} catch (Exception e) { } catch (Exception e) {
Logger.info(aiAgent.getObjectUUID() + " " + aiAgent.getName() + " Failed At: CheckForRespawn" + " " + e.getMessage()); Logger.info(aiAgent.getObjectUUID() + " " + aiAgent.getName() + " Failed At: CheckForRespawn" + " " + e.getMessage());
@@ -893,7 +834,8 @@ public class MobAI {
if (mob.getCombatTarget() == null) if (mob.getCombatTarget() == null)
return; return;
if (mob.getCombatTarget().getObjectType().equals(Enum.GameObjectType.PlayerCharacter) && MovementUtilities.inRangeDropAggro(mob, (PlayerCharacter) mob.getCombatTarget()) == false && mob.BehaviourType.ordinal() != Enum.MobBehaviourType.Pet1.ordinal()) { if (mob.getCombatTarget().getObjectType().equals(Enum.GameObjectType.PlayerCharacter) && MovementUtilities.inRangeDropAggro(mob, (PlayerCharacter) mob.getCombatTarget()) == false &&
mob.agentType.equals(Enum.AIAgentType.PET) == false) {
mob.setCombatTarget(null); mob.setCombatTarget(null);
return; return;
@@ -909,15 +851,6 @@ public class MobAI {
private static void CheckToSendMobHome(Mob mob) { private static void CheckToSendMobHome(Mob mob) {
try { try {
if (mob.BehaviourType.isAgressive) {
if (mob.isPlayerGuard()) {
if (mob.BehaviourType.ordinal() == Enum.MobBehaviourType.GuardCaptain.ordinal())
CheckForPlayerGuardAggro(mob);
} else {
CheckForAggro(mob);
}
}
if (mob.getCombatTarget() != null && CombatUtilities.inRange2D(mob, mob.getCombatTarget(), MobAIThread.AI_BASE_AGGRO_RANGE * 0.5f)) if (mob.getCombatTarget() != null && CombatUtilities.inRange2D(mob, mob.getCombatTarget(), MobAIThread.AI_BASE_AGGRO_RANGE * 0.5f))
return; return;
@@ -932,13 +865,15 @@ public class MobAI {
PowersManager.useMobPower(mob, mob, recall, 40); PowersManager.useMobPower(mob, mob, recall, 40);
mob.setCombatTarget(null); mob.setCombatTarget(null);
if (mob.BehaviourType.ordinal() == Enum.MobBehaviourType.GuardCaptain.ordinal() && mob.isAlive()) { if (mob.agentType.equals(Enum.AIAgentType.GUARDCAPTAIN) && mob.isAlive()) {
//guard captain pulls his minions home with him //guard captain pulls his minions home with him
for (Entry<Mob, Integer> minion : mob.siegeMinionMap.entrySet()) { for (Integer minionUUID : mob.minions) {
PowersManager.useMobPower(minion.getKey(), minion.getKey(), recall, 40); Mob minion = Mob.getMob(minionUUID);
minion.getKey().setCombatTarget(null);
PowersManager.useMobPower(minion, minion, recall, 40);
minion.setCombatTarget(null);
} }
} }
} }
@@ -948,8 +883,8 @@ public class MobAI {
PowersManager.useMobPower(mob, mob, recall, 40); PowersManager.useMobPower(mob, mob, recall, 40);
mob.setCombatTarget(null); mob.setCombatTarget(null);
for (Entry playerEntry : mob.playerAgroMap.entrySet()) for (Integer playerEntry : mob.playerAgroMap.keySet())
PlayerCharacter.getFromCache((int) playerEntry.getKey()).setHateValue(0); mob.playerAgroMap.put(playerEntry, 0f);
} }
} catch (Exception e) { } catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: CheckToSendMobHome" + " " + e.getMessage()); Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: CheckToSendMobHome" + " " + e.getMessage());
@@ -960,16 +895,17 @@ public class MobAI {
try { try {
float rangeSquared = mob.getRange() * mob.getRange(); if(mob.getTimestamps().containsKey("lastChase") == false)
float distanceSquared = mob.getLoc().distanceSquared2D(mob.getCombatTarget().getLoc()); mob.getTimestamps().put("lastChase",System.currentTimeMillis());
else if(System.currentTimeMillis() < mob.getTimestamps().get("lastChase").longValue() + (750 + ThreadLocalRandom.current().nextInt(0,500)))
return;
if(mob.isMoving() == true && distanceSquared < rangeSquared - 50) { mob.getTimestamps().put("lastChase",System.currentTimeMillis());
mob.destination = mob.getLoc();
MovementUtilities.moveToLocation(mob, mob.destination, 0); if (CombatUtilities.inRange2D(mob, mob.getCombatTarget(), mob.getRange()) == false) {
} else if (CombatUtilities.inRange2D(mob, mob.getCombatTarget(), mob.getRange()) == false) {
if (mob.getRange() > 15) { if (mob.getRange() > 15) {
mob.destination = mob.getCombatTarget().getLoc(); mob.destination = mob.getCombatTarget().getLoc();
MovementUtilities.moveToLocation(mob, mob.destination, 0); MovementUtilities.moveToLocation(mob, mob.destination, 0, false);
} else { } else {
//check if building //check if building
@@ -978,11 +914,11 @@ public class MobAI {
case PlayerCharacter: case PlayerCharacter:
case Mob: case Mob:
mob.destination = MovementUtilities.GetDestinationToCharacter(mob, (AbstractCharacter) mob.getCombatTarget()); mob.destination = MovementUtilities.GetDestinationToCharacter(mob, (AbstractCharacter) mob.getCombatTarget());
MovementUtilities.moveToLocation(mob, mob.destination, mob.getRange() + 1); MovementUtilities.moveToLocation(mob, mob.destination, mob.getRange() + 1, false);
break; break;
case Building: case Building:
mob.destination = mob.getCombatTarget().getLoc(); mob.destination = mob.getCombatTarget().getLoc();
MovementUtilities.moveToLocation(mob, mob.getCombatTarget().getLoc(), 0); MovementUtilities.moveToLocation(mob, mob.getCombatTarget().getLoc(), 0, false);
break; break;
} }
} }
@@ -1003,17 +939,17 @@ public class MobAI {
//dont scan self. //dont scan self.
if (mob.equals(awoMob) || (mob.agentType.equals(Enum.AIAgentType.GUARD)) == true) if (mob.equals(awoMob) || (mob.agentType.equals(Enum.AIAgentType.GUARDCAPTAIN)) == true)
continue; continue;
Mob aggroMob = (Mob) awoMob; Mob aggroMob = (Mob) awoMob;
//don't attack other guards //don't attack other guards
if ((aggroMob.agentType.equals(Enum.AIAgentType.GUARD))) if ((aggroMob.agentType.equals(Enum.AIAgentType.GUARDCAPTAIN)))
continue; continue;
if(aggroMob.BehaviourType.equals(Enum.MobBehaviourType.Pet1)) if (aggroMob.agentType.equals(Enum.AIAgentType.PET))
continue; continue;
if (mob.getLoc().distanceSquared2D(aggroMob.getLoc()) > sqr(50)) if (mob.getLoc().distanceSquared2D(aggroMob.getLoc()) > sqr(50))
@@ -1026,40 +962,13 @@ public class MobAI {
} }
} }
public static void GuardCaptainLogic(Mob mob) { public static void GuardLogic(Mob mob) {
try { try {
if (mob.getCombatTarget() == null)
CheckForPlayerGuardAggro(mob);
AbstractWorldObject newTarget = ChangeTargetFromHateValue(mob);
if (newTarget != null) {
if (newTarget.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) {
if (GuardCanAggro(mob, (PlayerCharacter) newTarget))
mob.setCombatTarget(newTarget);
} else
mob.setCombatTarget(newTarget);
}
CheckMobMovement(mob);
CheckForAttack(mob);
} catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: GuardCaptainLogic" + " " + e.getMessage());
}
}
public static void GuardMinionLogic(Mob mob) {
try {
if (!mob.npcOwner.isAlive()) {
if (mob.getCombatTarget() == null) { if (mob.getCombatTarget() == null) {
CheckForPlayerGuardAggro(mob); CheckForPlayerGuardAggro(mob);
} else { } else {
//do not need to look to change target if target is already null
AbstractWorldObject newTarget = ChangeTargetFromHateValue(mob); AbstractWorldObject newTarget = ChangeTargetFromHateValue(mob);
if (newTarget != null) { if (newTarget != null) {
@@ -1069,32 +978,17 @@ public class MobAI {
mob.setCombatTarget(newTarget); mob.setCombatTarget(newTarget);
} else } else
mob.setCombatTarget(newTarget); mob.setCombatTarget(newTarget);
}
}
if(mob.behaviourType.canRoam)
CheckMobMovement(mob);//all guards that can move check to move
if(mob.combatTarget != null)
CheckForAttack(mob); //only check to attack if combat target is not null
}
}
}else {
if (mob.npcOwner.getCombatTarget() != null)
mob.setCombatTarget(mob.npcOwner.getCombatTarget());
else
if (mob.getCombatTarget() != null)
mob.setCombatTarget(null);
}
CheckMobMovement(mob);
CheckForAttack(mob);
} catch (Exception e) { } catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: GuardMinionLogic" + " " + e.getMessage()); Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: GuardLogic" + " " + e.getMessage());
}
}
public static void GuardWallArcherLogic(Mob mob) {
try {
if (mob.getCombatTarget() == null)
CheckForPlayerGuardAggro(mob);
else
CheckForAttack(mob);
} catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: GuardWallArcherLogic" + " " + e.getMessage());
} }
} }
@@ -1102,11 +996,11 @@ public class MobAI {
try { try {
if (mob.getOwner() == null && mob.isNecroPet() == false && mob.isSiege() == false) if (mob.guardCaptain == null && mob.isNecroPet() == false && mob.isSiege() == false)
if (ZoneManager.getSeaFloor().zoneMobSet.contains(mob)) if (ZoneManager.seaFloor.zoneMobSet.contains(mob))
mob.killCharacter("no owner"); mob.killCharacter("no owner");
if (MovementUtilities.canMove(mob) && mob.BehaviourType.canRoam) if (MovementUtilities.canMove(mob) && mob.behaviourType.canRoam)
CheckMobMovement(mob); CheckMobMovement(mob);
CheckForAttack(mob); CheckForAttack(mob);
@@ -1156,7 +1050,7 @@ public class MobAI {
if (mob.getCombatTarget() != null && mob.playerAgroMap.containsKey(mob.getCombatTarget().getObjectUUID()) == false) if (mob.getCombatTarget() != null && mob.playerAgroMap.containsKey(mob.getCombatTarget().getObjectUUID()) == false)
mob.setCombatTarget(null); mob.setCombatTarget(null);
if (mob.BehaviourType.isAgressive) { if (mob.behaviourType.isAgressive) {
AbstractWorldObject newTarget = ChangeTargetFromHateValue(mob); AbstractWorldObject newTarget = ChangeTargetFromHateValue(mob);
@@ -1164,7 +1058,7 @@ public class MobAI {
mob.setCombatTarget(newTarget); mob.setCombatTarget(newTarget);
else { else {
if (mob.getCombatTarget() == null) { if (mob.getCombatTarget() == null) {
if (mob.BehaviourType == Enum.MobBehaviourType.HamletGuard) if (mob.behaviourType == Enum.MobBehaviourType.HamletGuard)
SafeGuardAggro(mob); //safehold guard SafeGuardAggro(mob); //safehold guard
else else
CheckForAggro(mob); //normal aggro CheckForAggro(mob); //normal aggro
@@ -1174,12 +1068,12 @@ public class MobAI {
//check if mob can move for patrol or moving to target //check if mob can move for patrol or moving to target
if (mob.BehaviourType.canRoam) if (mob.behaviourType.canRoam)
CheckMobMovement(mob); CheckMobMovement(mob);
//check if mob can attack if it isn't wimpy //check if mob can attack if it isn't wimpy
if (!mob.BehaviourType.isWimpy && mob.getCombatTarget() != null) if (!mob.behaviourType.isWimpy && mob.getCombatTarget() != null)
CheckForAttack(mob); CheckForAttack(mob);
} catch (Exception e) { } catch (Exception e) {
@@ -1196,12 +1090,21 @@ public class MobAI {
if (!mob.isAlive()) if (!mob.isAlive())
return; return;
ConcurrentHashMap<Integer, Boolean> loadedPlayers = mob.playerAgroMap; // Defer to captain if possible for current target
if (mob.agentType.equals(Enum.AIAgentType.GUARDMINION) &&
mob.guardCaptain.isAlive()
&& mob.guardCaptain.combatTarget != null) {
mob.setCombatTarget(mob.guardCaptain.combatTarget);
return;
}
ConcurrentHashMap<Integer, Float> loadedPlayers = mob.playerAgroMap;
for (Entry playerEntry : loadedPlayers.entrySet()) { for (Entry playerEntry : loadedPlayers.entrySet()) {
int playerID = (int) playerEntry.getKey(); int playerID = (int) playerEntry.getKey();
PlayerCharacter loadedPlayer = PlayerCharacter.getFromCache(playerID); PlayerCharacter loadedPlayer = PlayerCharacter.getPlayerCharacter(playerID);
//Player is null, let's remove them from the list. //Player is null, let's remove them from the list.
@@ -1231,27 +1134,39 @@ public class MobAI {
mob.setCombatTarget(loadedPlayer); mob.setCombatTarget(loadedPlayer);
return; return;
} }
}
if (mob.getCombatTarget() == null) {
//look for siege equipment to aggro if no players found to aggro
HashSet<AbstractWorldObject> awoList = WorldGrid.getObjectsInRangePartial(mob, MobAIThread.AI_BASE_AGGRO_RANGE, MBServerStatics.MASK_SIEGE);
for (AbstractWorldObject awoMob : awoList) {
Mob aggroMob = (Mob) awoMob;
if(GuardCanAggro(mob,aggroMob)) {
mob.setCombatTarget(aggroMob);
return;
}
}
} }
} catch (Exception e) { } catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: CheckForPlayerGuardAggro" + e.getMessage()); Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: CheckForPlayerGuardAggro" + e.getMessage());
} }
} }
public static Boolean GuardCanAggro(Mob mob, PlayerCharacter target) { public static Boolean GuardCanAggro(Mob mob, AbstractCharacter target) {
try { try {
if (mob.guardedCity.cityOutlaws.contains(target.getObjectUUID()) == true)
return true;
if (mob.getGuild().getNation().equals(target.getGuild().getNation())) if (mob.getGuild().getNation().equals(target.getGuild().getNation()))
return false; return false;
if (mob.BehaviourType.ordinal() == Enum.MobBehaviourType.GuardMinion.ordinal()) {
if (((Mob) mob.npcOwner).building.getCity().cityOutlaws.contains(target.getObjectUUID()) == true) {
return true;
}
} else if (mob.building.getCity().cityOutlaws.contains(target.getObjectUUID()) == true) {
return true;
}
//first check condemn list for aggro allowed (allies button is checked) //first check condemn list for aggro allowed (allies button is checked)
if (ZoneManager.getCityAtLocation(mob.getLoc()).getTOL().reverseKOS) { if (ZoneManager.getCityAtLocation(mob.getLoc()).getTOL().reverseKOS) {
@@ -1259,17 +1174,17 @@ public class MobAI {
//target is listed individually //target is listed individually
if (entry.getValue().getPlayerUID() == target.getObjectUUID() && entry.getValue().isActive()) if (entry.getValue().playerUID == target.getObjectUUID() && entry.getValue().active)
return false; return false;
//target's guild is listed //target's guild is listed
if (Guild.getGuild(entry.getValue().getGuildUID()) == target.getGuild()) if (Guild.getGuild(entry.getValue().guildUID) == target.getGuild())
return false; return false;
//target's nation is listed //target's nation is listed
if (Guild.getGuild(entry.getValue().getGuildUID()) == target.getGuild().getNation()) if (Guild.getGuild(entry.getValue().guildUID) == target.getGuild().getNation())
return false; return false;
} }
return true; return true;
@@ -1281,17 +1196,17 @@ public class MobAI {
//target is listed individually //target is listed individually
if (entry.getValue().getPlayerUID() == target.getObjectUUID() && entry.getValue().isActive()) if (entry.getValue().playerUID == target.getObjectUUID() && entry.getValue().active)
return true; return true;
//target's guild is listed //target's guild is listed
if (Guild.getGuild(entry.getValue().getGuildUID()) == target.getGuild()) if (Guild.getGuild(entry.getValue().guildUID) == target.getGuild())
return true; return true;
//target's nation is listed //target's nation is listed
if (Guild.getGuild(entry.getValue().getGuildUID()) == target.getGuild().getNation()) if (Guild.getGuild(entry.getValue().guildUID) == target.getGuild().getNation())
return true; return true;
} }
} }
@@ -1329,23 +1244,25 @@ public class MobAI {
MovementUtilities.aiMove(mob, mob.destination, true); MovementUtilities.aiMove(mob, mob.destination, true);
if (mob.BehaviourType.ordinal() == Enum.MobBehaviourType.GuardCaptain.ordinal()) { if (mob.agentType.equals(Enum.AIAgentType.GUARDCAPTAIN)) {
for (Entry<Mob, Integer> minion : mob.siegeMinionMap.entrySet()) { for (Integer minionUUID : mob.minions) {
Mob minion = Mob.getMob(minionUUID);
//make sure mob is out of combat stance //make sure mob is out of combat stance
if (minion.getKey().despawned == false) { if (minion.despawned == false) {
if (MovementUtilities.canMove(minion.getKey())) { if (MovementUtilities.canMove(minion)) {
Vector3f minionOffset = Formation.getOffset(2, minion.getValue() + 3); Vector3f minionOffset = Formation.getOffset(2, mob.minions.indexOf(minionUUID) + 3);
minion.getKey().updateLocation(); minion.updateLocation();
Vector3fImmutable formationPatrolPoint = new Vector3fImmutable(mob.destination.x + minionOffset.x, mob.destination.y, mob.destination.z + minionOffset.z); Vector3fImmutable formationPatrolPoint = new Vector3fImmutable(mob.destination.x + minionOffset.x, mob.destination.y, mob.destination.z + minionOffset.z);
MovementUtilities.aiMove(minion.getKey(), formationPatrolPoint, true); MovementUtilities.aiMove(minion, formationPatrolPoint, true);
} }
} }
} }
} }
} catch (Exception e) { } catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: randomGuardPatrolPoints" + " " + e.getMessage()); Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: randomGuardPatrolPoints" + " " + e);
} }
} }
@@ -1356,19 +1273,19 @@ public class MobAI {
float CurrentHateValue = 0; float CurrentHateValue = 0;
if (mob.getCombatTarget() != null && mob.getCombatTarget().getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) if (mob.getCombatTarget() != null && mob.getCombatTarget().getObjectType().equals(Enum.GameObjectType.PlayerCharacter))
CurrentHateValue = ((PlayerCharacter) mob.getCombatTarget()).getHateValue(); CurrentHateValue = mob.playerAgroMap.get(mob.combatTarget.getObjectUUID()).floatValue();
AbstractWorldObject mostHatedTarget = null; AbstractWorldObject mostHatedTarget = null;
for (Entry playerEntry : mob.playerAgroMap.entrySet()) { for (Entry playerEntry : mob.playerAgroMap.entrySet()) {
PlayerCharacter potentialTarget = PlayerCharacter.getFromCache((int) playerEntry.getKey()); PlayerCharacter potentialTarget = PlayerCharacter.getPlayerCharacter((int) playerEntry.getKey());
if (potentialTarget.equals(mob.getCombatTarget())) if (potentialTarget.equals(mob.getCombatTarget()))
continue; continue;
if (potentialTarget != null && potentialTarget.getHateValue() > CurrentHateValue && MovementUtilities.inRangeToAggro(mob, potentialTarget)) { if (potentialTarget != null && mob.playerAgroMap.get(potentialTarget.getObjectUUID()).floatValue() > CurrentHateValue && MovementUtilities.inRangeToAggro(mob, potentialTarget)) {
CurrentHateValue = potentialTarget.getHateValue(); CurrentHateValue = mob.playerAgroMap.get(potentialTarget.getObjectUUID()).floatValue();
mostHatedTarget = potentialTarget; mostHatedTarget = potentialTarget;
} }
@@ -1,66 +0,0 @@
// ·. · · · · .
// · ·
// · ·
//
// · · ·
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
package engine.mobileAI.Threads;
import engine.gameManager.ZoneManager;
import engine.objects.Mob;
import engine.objects.Zone;
import org.pmw.tinylog.Logger;
/**
* Thread blocks until MagicBane dispatch messages are
* enqueued then processes them in FIFO order. The collection
* is thread safe.
* <p>
* Any large messages not time sensitive such as load object
* sent to more than a single individual should be spawned
* individually on a DispatchMessageThread.
*/
public class MobRespawnThread implements Runnable {
public MobRespawnThread() {
Logger.info(" MobRespawnThread thread has started!");
}
@Override
public void run() {
while (true) {
try {
for (Zone zone : ZoneManager.getAllZones()) {
if (zone.respawnQue.isEmpty() == false && zone.lastRespawn + 100 < System.currentTimeMillis()) {
Mob respawner = zone.respawnQue.iterator().next();
if (respawner == null)
continue;
respawner.respawn();
zone.respawnQue.remove(respawner);
zone.lastRespawn = System.currentTimeMillis();
}
}
} catch (Exception e) {
Logger.error(e);
}
}
}
public static void startRespawnThread() {
Thread respawnThread;
respawnThread = new Thread(new MobRespawnThread());
respawnThread.setName("respawnThread");
respawnThread.start();
}
}
@@ -0,0 +1,42 @@
// ·. · · · · .
// · ·
// · ·
//
// · · ·
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
package engine.mobileAI.Threads;
import engine.objects.Mob;
import org.pmw.tinylog.Logger;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.DelayQueue;
public enum Respawner implements Runnable {
RESPAWNER;
public static BlockingQueue<Mob> respawnQueue = new DelayQueue();
@Override
public void run() {
while (true) {
try {
Mob mobile = respawnQueue.take();
mobile.respawn();
} catch (InterruptedException e) {
Logger.error(e.toString());
}
}
}
public static void start() {
Thread respawnThread;
respawnThread = new Thread(RESPAWNER);
respawnThread.setName("respawnThread");
respawnThread.start();
}
}
@@ -48,7 +48,7 @@ public class CombatUtilities {
} }
public static boolean inRange2D(AbstractWorldObject entity1, AbstractWorldObject entity2, double range) { public static boolean inRange2D(AbstractWorldObject entity1, AbstractWorldObject entity2, double range) {
return entity1.getLoc().distance2D(entity2.getLoc()) < range; return entity1.getLoc().distanceSquared2D(entity2.getLoc()) < range * range;
} }
public static void swingIsBlock(Mob agent, AbstractWorldObject target, int animation) { public static void swingIsBlock(Mob agent, AbstractWorldObject target, int animation) {
@@ -264,19 +264,9 @@ public class CombatUtilities {
swingIsBlock(agent, target, passiveAnim); swingIsBlock(agent, target, passiveAnim);
return; return;
} }
if (agent.getEquip().get(1) != null && agent.getEquip().get(2) != null && agent.getEquip().get(2).getItemBase().isShield() == false) {
//mob is duel wielding and should conduct an attack for each hand
ItemBase weapon1 = agent.getEquip().get(1).getItemBase();
double range1 = getMaxDmg(weapon1.getMinDamage(), agent, weapon1) - getMinDmg(weapon1.getMinDamage(), agent, weapon1);
double damage1 = getMinDmg(weapon1.getMinDamage(), agent, weapon1) + ((ThreadLocalRandom.current().nextFloat() * range1) + (ThreadLocalRandom.current().nextFloat() * range1)) / 2;
swingIsDamage(agent, target, (float) damage1, CombatManager.getSwingAnimation(weapon1, null, true));
ItemBase weapon2 = agent.getEquip().get(2).getItemBase();
double range2 = getMaxDmg(weapon2.getMinDamage(), agent, weapon2) - getMinDmg(weapon2.getMinDamage(), agent, weapon2);
double damage2 = getMinDmg(weapon2.getMinDamage(), agent, weapon2) + ((ThreadLocalRandom.current().nextFloat() * range2) + (ThreadLocalRandom.current().nextFloat() * range2)) / 2;
swingIsDamage(agent, target, (float) damage2, CombatManager.getSwingAnimation(weapon1, null, false));
} else {
swingIsDamage(agent, target, determineDamage(agent), anim); swingIsDamage(agent, target, determineDamage(agent), anim);
}
if (agent.getWeaponPower() != null) if (agent.getWeaponPower() != null)
agent.getWeaponPower().attack(target, MBServerStatics.ONE_MINUTE); agent.getWeaponPower().attack(target, MBServerStatics.ONE_MINUTE);
@@ -319,19 +309,10 @@ public class CombatUtilities {
if (target == null) if (target == null)
return 0; return 0;
float damage = 0; int damage = 0;
DamageType dt = getDamageType(agent); DamageType dt = getDamageType(agent);
if ((agent.agentType.equals(AIAgentType.PET)) == true || agent.isPet() == true || agent.isNecroPet() == true) { damage = ThreadLocalRandom.current().nextInt((int)getMinDmg(agent), (int)getMaxDmg(agent) + 1);
damage = calculatePetDamage(agent);
} else if (agent.isPlayerGuard() == true) {
//damage = calculateGuardDamage(agent);
damage = calculateMobDamage(agent);
} else if (agent.getLevel() > 80) {
damage = calculateEpicDamage(agent);
} else {
damage = calculateMobDamage(agent);
}
if (AbstractWorldObject.IsAbstractCharacter(target)) { if (AbstractWorldObject.IsAbstractCharacter(target)) {
if (((AbstractCharacter) target).isSit()) { if (((AbstractCharacter) target).isSit()) {
damage *= 2.5f; //increase damage if sitting damage *= 2.5f; //increase damage if sitting
@@ -357,158 +338,16 @@ public class CombatUtilities {
return dt; return dt;
} }
public static int calculatePetDamage(Mob agent) { public static double getMinDmg(Mob agent) {
//damage calc for pet if(agent.equip.get(2) != null && !agent.equip.get(2).getItemBase().isShield())
float range; return agent.minDamageHandTwo;
float damage; else return agent.minDamageHandOne;
float min = 40;
float max = 60;
float dmgMultiplier = 1 + agent.getBonuses().getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None);
double minDmg = getMinDmg(min, agent, null);
double maxDmg = getMaxDmg(max, agent, null);
dmgMultiplier += agent.getLevel() * 0.1f;
range = (float) (maxDmg - minDmg);
damage = min + ((ThreadLocalRandom.current().nextFloat() * range) + (ThreadLocalRandom.current().nextFloat() * range)) / 2;
return (int) (damage * dmgMultiplier);
} }
public static int calculateGuardDamage(Mob agent) { public static double getMaxDmg(Mob agent) {
//damage calc for guard if(agent.equip.get(2) != null && !agent.equip.get(2).getItemBase().isShield())
ItemBase weapon = agent.getEquip().get(1).getItemBase(); return agent.maxDamageHandTwo;
AbstractWorldObject target = agent.getCombatTarget(); else return agent.maxDamageHandOne;
float dmgMultiplier = 1 + agent.getBonuses().getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None);
double minDmg = weapon.getMinDamage();
double maxDmg = weapon.getMaxDamage();
double min = getMinDmg(minDmg, agent, weapon);
double max = getMaxDmg(maxDmg, agent, weapon);
DamageType dt = weapon.getDamageType();
double range = max - min;
double damage = min + ((ThreadLocalRandom.current().nextFloat() * range) + (ThreadLocalRandom.current().nextFloat() * range)) / 2;
if (AbstractWorldObject.IsAbstractCharacter(target))
if (((AbstractCharacter) target).isSit())
damage *= 2.5f; //increase damage if sitting
if (AbstractWorldObject.IsAbstractCharacter(target))
return (int) (((AbstractCharacter) target).getResists().getResistedDamage(agent, (AbstractCharacter) target, dt, (float) damage, 0) * dmgMultiplier);
return 0;
}
public static int calculateEpicDamage(Mob agent) {
//handle r8 mob damage
DamageType dt = DamageType.Crush;
AbstractWorldObject target = agent.getCombatTarget();
float dmgMultiplier = 1 + agent.getBonuses().getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None);
double min = agent.getMinDamageHandOne();
double max = agent.getMaxDamageHandOne();
if (agent.getEquip().get(1) != null) {
if (agent.getEquip().get(1).getItemBase() != null) {
dt = agent.getEquip().get(1).getItemBase().getDamageType();
min = agent.getMinDamageHandOne();
max = agent.getMaxDamageHandOne();
} else if (agent.getEquip().get(2).getItemBase() != null && agent.getEquip().get(2).getItemBase().isShield() == false) {
dt = agent.getEquip().get(2).getItemBase().getDamageType();
min = agent.getMinDamageHandTwo();
max = agent.getMaxDamageHandTwo();
}
}
double range = max - min;
double damage = min + ((ThreadLocalRandom.current().nextFloat() * range) + (ThreadLocalRandom.current().nextFloat() * range)) / 2;
return (int) (((AbstractCharacter) target).getResists().getResistedDamage(agent, (AbstractCharacter) target, dt, (float) damage, 0) * dmgMultiplier);
}
public static int calculateMobDamage(Mob agent) {
ItemBase weapon = null;
double minDmg;
double maxDmg;
DamageType dt;
//main hand or offhand damage
if (agent.getEquip().get(1) != null)
weapon = agent.getEquip().get(1).getItemBase();
else if (agent.getEquip().get(2) != null)
weapon = agent.getEquip().get(2).getItemBase();
if (weapon != null) {
minDmg = getMinDmg(weapon.getMinDamage(), agent, weapon);
maxDmg = getMaxDmg(weapon.getMaxDamage(), agent, weapon);
dt = weapon.getDamageType();
} else {
minDmg = agent.getMobBase().getDamageMin();
maxDmg = agent.getMobBase().getDamageMax();
dt = DamageType.Crush;
}
AbstractWorldObject target = agent.getCombatTarget();
float dmgMultiplier = 1 + agent.getBonuses().getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None);
double range = maxDmg - minDmg;
double damage = minDmg + ((ThreadLocalRandom.current().nextFloat() * range) + (ThreadLocalRandom.current().nextFloat() * range)) / 2;
if (AbstractWorldObject.IsAbstractCharacter(target))
if (((AbstractCharacter) target).isSit())
damage *= 2.5f; //increase damage if sitting
if (AbstractWorldObject.IsAbstractCharacter(target))
return (int) (((AbstractCharacter) target).getResists().getResistedDamage(agent, (AbstractCharacter) target, dt, (float) damage, 0) * dmgMultiplier);
return 0;
}
public static double getMinDmg(double min, Mob agent, ItemBase weapon) {
int primary = agent.getStatStrCurrent();
int secondary = agent.getStatDexCurrent();
int focusLevel = 0;
int masteryLevel = 0;
if (weapon != null) {
if (weapon.isStrBased() == true) {
primary = agent.getStatStrCurrent();
secondary = agent.getStatDexCurrent();
} else {
primary = agent.getStatDexCurrent();
secondary = agent.getStatStrCurrent();
if (agent.getSkills().containsKey(weapon.getSkillRequired())) {
focusLevel = (int) agent.getSkills().get(weapon.getSkillRequired()).getModifiedAmount();
}
if (agent.getSkills().containsKey(weapon.getMastery())) {
masteryLevel = (int) agent.getSkills().get(weapon.getMastery()).getModifiedAmount();
}
}
}
return min * (pow(0.0048 * primary + .049 * (primary - 0.75), 0.5) + pow(0.0066 * secondary + 0.064 * (secondary - 0.75), 0.5) + +0.01 * (focusLevel + masteryLevel));
}
public static double getMaxDmg(double max, Mob agent, ItemBase weapon) {
int primary = agent.getStatStrCurrent();
int secondary = agent.getStatDexCurrent();
int focusLevel = 0;
int masteryLevel = 0;
if (weapon != null) {
if (weapon.isStrBased() == true) {
primary = agent.getStatStrCurrent();
secondary = agent.getStatDexCurrent();
} else {
primary = agent.getStatDexCurrent();
secondary = agent.getStatStrCurrent();
}
if (agent.getSkills().containsKey(weapon.getSkillRequired()))
focusLevel = (int) agent.getSkills().get(weapon.getSkillRequired()).getModifiedAmount();
if (agent.getSkills().containsKey(weapon.getSkillRequired()))
masteryLevel = (int) agent.getSkills().get(weapon.getMastery()).getModifiedAmount();
}
return max * (pow(0.0124 * primary + 0.118 * (primary - 0.75), 0.5) + pow(0.0022 * secondary + 0.028 * (secondary - 0.75), 0.5) + 0.0075 * (focusLevel + masteryLevel));
} }
} }
@@ -13,10 +13,10 @@ import engine.Enum;
import engine.Enum.GameObjectType; import engine.Enum.GameObjectType;
import engine.Enum.ModType; import engine.Enum.ModType;
import engine.Enum.SourceType; import engine.Enum.SourceType;
import engine.mobileAI.Threads.MobAIThread;
import engine.exception.MsgSendException; import engine.exception.MsgSendException;
import engine.gameManager.MovementManager; import engine.gameManager.MovementManager;
import engine.math.Vector3fImmutable; import engine.math.Vector3fImmutable;
import engine.mobileAI.Threads.MobAIThread;
import engine.net.client.msg.MoveToPointMsg; import engine.net.client.msg.MoveToPointMsg;
import engine.objects.*; import engine.objects.*;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
@@ -38,7 +38,7 @@ public class MovementUtilities {
if (agent.getContract() != null) if (agent.getContract() != null)
guardCaptain = agent; guardCaptain = agent;
else else
guardCaptain = (Mob) agent.npcOwner; guardCaptain = (Mob) agent.guardCaptain;
if (guardCaptain != null) { if (guardCaptain != null) {
Building barracks = guardCaptain.building; Building barracks = guardCaptain.building;
@@ -51,7 +51,7 @@ public class MovementUtilities {
//Guards recall distance = 814. //Guards recall distance = 814.
if (tol != null) { if (tol != null) {
return !(agent.getLoc().distanceSquared2D(tol.getLoc()) > sqr(Enum.CityBoundsType.ZONE.extents)); return !(agent.getLoc().distanceSquared2D(tol.getLoc()) > sqr(Enum.CityBoundsType.ZONE.halfExtents));
} }
} }
@@ -68,8 +68,8 @@ public class MovementUtilities {
float zoneRange = 250; float zoneRange = 250;
if (agent.getParentZone() != null) { if (agent.getParentZone() != null) {
if (agent.getParentZone().getBounds() != null) if (agent.getParentZone().bounds != null)
zoneRange = agent.getParentZone().getBounds().getHalfExtents().x * 2; zoneRange = agent.getParentZone().bounds.getHalfExtents().x * 2;
} }
if (zoneRange > 300) if (zoneRange > 300)
@@ -147,7 +147,7 @@ public class MovementUtilities {
return aiAgent.getLoc().ClosestPointOnLine(aggroTarget.getLoc(), aggroTarget.getEndLoc()); return aiAgent.getLoc().ClosestPointOnLine(aggroTarget.getLoc(), aggroTarget.getEndLoc());
} }
public static void moveToLocation(Mob agent, Vector3fImmutable newLocation, float offset) { public static void moveToLocation(Mob agent, Vector3fImmutable newLocation, float offset, boolean isWalking) {
try { try {
//don't move farther than 30 units from player. //don't move farther than 30 units from player.
@@ -158,7 +158,7 @@ public class MovementUtilities {
agent.setFaceDir(newLoc.subtract2D(agent.getLoc()).normalize()); agent.setFaceDir(newLoc.subtract2D(agent.getLoc()).normalize());
aiMove(agent, newLoc, false); aiMove(agent, newLoc, isWalking);
} catch (Exception e) { } catch (Exception e) {
Logger.error(e.toString()); Logger.error(e.toString());
} }
@@ -244,10 +244,10 @@ public class MovementUtilities {
msg.setSourceID(agent.getObjectUUID()); msg.setSourceID(agent.getObjectUUID());
msg.setStartCoord(startLoc); msg.setStartCoord(startLoc);
msg.setEndCoord(endLoc); msg.setEndCoord(endLoc);
msg.setUnknown01(-1); msg.setInBuildingFloor(-1);
msg.setInBuilding(-1); msg.setInBuilding(-1);
msg.setTargetType(0); msg.setStartLocType(0);
msg.setTargetID(0); msg.setInBuildingUUID(0);
try { try {
+1 -1
View File
@@ -28,7 +28,7 @@ import static engine.net.MessageDispatcher.maxRecipients;
/* /*
* Dispatch Message is the main interface to Magicbane's threaded * Dispatch Message is the main interface to Magicbane's threaded
* asynch message delivery system. * async message delivery system.
*/ */
public class DispatchMessage { public class DispatchMessage {
+4 -7
View File
@@ -643,7 +643,7 @@ public class ClientMessagePump implements NetMsgHandler {
moveMsg.setStartCoord(sourcePlayer.getLoc()); moveMsg.setStartCoord(sourcePlayer.getLoc());
moveMsg.setEndCoord(sourcePlayer.getLoc()); moveMsg.setEndCoord(sourcePlayer.getLoc());
moveMsg.setInBuilding(-1); moveMsg.setInBuilding(-1);
moveMsg.setUnknown01(-1); moveMsg.setInBuildingFloor(-1);
dispatch = Dispatch.borrow(sourcePlayer, moveMsg); dispatch = Dispatch.borrow(sourcePlayer, moveMsg);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY); DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY);
@@ -1196,7 +1196,7 @@ public class ClientMessagePump implements NetMsgHandler {
if (npc.getCharItemManager().getInventoryCount() > 150) { if (npc.getCharItemManager().getInventoryCount() > 150) {
if (npc.getParentZone() != null && npc.getParentZone().getPlayerCityUUID() == 0) { if (npc.getParentZone() != null && npc.getParentZone().playerCityUUID == 0) {
ArrayList<Item> inv = npc.getInventory(); ArrayList<Item> inv = npc.getInventory();
for (int i = 0; i < 20; i++) { for (int i = 0; i < 20; i++) {
try { try {
@@ -1229,7 +1229,7 @@ public class ClientMessagePump implements NetMsgHandler {
if (ib == null) if (ib == null)
return; return;
if (npc.getParentZone() != null && npc.getParentZone().getPlayerCityUUID() != 0) if (npc.getParentZone() != null && npc.getParentZone().playerCityUUID != 0)
if (!npc.getCharItemManager().hasRoomInventory(ib.getWeight())) { if (!npc.getCharItemManager().hasRoomInventory(ib.getWeight())) {
ErrorPopupMsg.sendErrorPopup(player, 21); ErrorPopupMsg.sendErrorPopup(player, 21);
@@ -1280,7 +1280,7 @@ public class ClientMessagePump implements NetMsgHandler {
if (building != null && building.getProtectionState().equals(ProtectionState.NPC)) if (building != null && building.getProtectionState().equals(ProtectionState.NPC))
building = null; building = null;
if (npc.getParentZone().getPlayerCityUUID() == 0) if (npc.getParentZone().playerCityUUID == 0)
building = null; building = null;
//make sure npc can afford item //make sure npc can afford item
@@ -1892,9 +1892,6 @@ public class ClientMessagePump implements NetMsgHandler {
case POWER: case POWER:
PowersManager.usePower((PerformActionMsg) msg, origin, false); PowersManager.usePower((PerformActionMsg) msg, origin, false);
break; break;
case REQUESTMELEEATTACK:
CombatManager.setAttackTarget((AttackCmdMsg) msg, origin);
break;
case READYTOENTER: case READYTOENTER:
break; break;
case OPENVAULT: case OPENVAULT:
+1 -1
View File
@@ -173,7 +173,7 @@ public enum Protocol {
REPAIROBJECT(0x782219CE, RepairMsg.class, null), //Repair Window Req/Ack, RepairObject item Req/Ack REPAIROBJECT(0x782219CE, RepairMsg.class, null), //Repair Window Req/Ack, RepairObject item Req/Ack
REQUESTCONTENTS(0xA786B0A2, LootWindowRequestMsg.class, null), // MoveObjectToContainer Window Request REQUESTCONTENTS(0xA786B0A2, LootWindowRequestMsg.class, null), // MoveObjectToContainer Window Request
REQUESTGUILDLIST(0x85DCC6D7, ReqGuildListMsg.class, RequestGuildListHandler.class), REQUESTGUILDLIST(0x85DCC6D7, ReqGuildListMsg.class, RequestGuildListHandler.class),
REQUESTMELEEATTACK(0x98C71545, AttackCmdMsg.class, null), // Attack REQUESTMELEEATTACK(0x98C71545, AttackCmdMsg.class, AttackCmdMsgHandler.class), // Attack
REQUESTMEMBERLIST(0x3235E5EA, GuildControlMsg.class, GuildControlHandler.class), // Part of Promote/Demote, Also Player History REQUESTMEMBERLIST(0x3235E5EA, GuildControlMsg.class, GuildControlHandler.class), // Part of Promote/Demote, Also Player History
REQUESTTOOPENBANK(0xF26E453F, null, null), // RequestToOpenBankMsg REQUESTTOOPENBANK(0xF26E453F, null, null), // RequestToOpenBankMsg
REQUESTTOTRADE(0x4D84259B, TradeRequestMsg.class, null), // Trade Request REQUESTTOTRADE(0x4D84259B, TradeRequestMsg.class, null), // Trade Request
@@ -151,7 +151,7 @@ public class AbandonAssetMsgHandler extends AbstractClientMsgHandler {
cityZone = ZoneManager.findSmallestZone(targetBuilding.getLoc()); cityZone = ZoneManager.findSmallestZone(targetBuilding.getLoc());
// Can't abandon a tree not within a player city zone // Can't abandon a tree not within a player city zone
if (cityZone.isPlayerCity() == false) if (cityZone.guild_zone == false)
return; return;
if (targetBuilding.getCity() == null) if (targetBuilding.getCity() == null)
@@ -45,7 +45,7 @@ public class AssetSupportMsgHandler extends AbstractClientMsgHandler {
if (serverZone == null) if (serverZone == null)
return; return;
serverCity = City.GetCityFromCache(serverZone.getPlayerCityUUID()); serverCity = City.GetCityFromCache(serverZone.playerCityUUID);
if (serverCity == null) if (serverCity == null)
return; return;
@@ -0,0 +1,86 @@
package engine.net.client.handlers;
import engine.Enum;
import engine.exception.MsgSendException;
import engine.gameManager.BuildingManager;
import engine.gameManager.CombatManager;
import engine.net.client.ClientConnection;
import engine.net.client.msg.AttackCmdMsg;
import engine.net.client.msg.ClientNetMsg;
import engine.net.client.msg.TargetedActionMsg;
import engine.objects.*;
/*
* @Author:
* @Summary: Processes application protocol message which keeps
* client's tcp connection open.
*/
public class AttackCmdMsgHandler extends AbstractClientMsgHandler {
public AttackCmdMsgHandler() {
super(AttackCmdMsg.class);
}
@Override
protected boolean _handleNetMsg(ClientNetMsg baseMsg, ClientConnection origin) throws MsgSendException {
PlayerCharacter playerCharacter = origin.getPlayerCharacter();
// Member variable declaration
AttackCmdMsg msg;
// Member variable assignment
msg = (AttackCmdMsg) baseMsg;
if (TargetedActionMsg.un2cnt == 60 || TargetedActionMsg.un2cnt == 70)
return true;
if (playerCharacter == null)
return true;
AbstractWorldObject target = null;
Enum.GameObjectType targetType;
targetType = Enum.GameObjectType.values()[msg.getTargetType()];
switch(targetType){
case Mob:
target = Mob.getMob(msg.getTargetID());
break;
case PlayerCharacter:
target = PlayerCharacter.getPlayerCharacter(msg.getTargetID());
break;
case Building:
target = BuildingManager.getBuilding(msg.getTargetID());
break;
case NPC:
target = NPC.getNPC(msg.getTargetID());
break;
}
if(target == null) {
playerCharacter.setCombatTarget(null);
return true; // cannot attack a null target
}
//set sources target
playerCharacter.setCombatTarget(target);
//put in combat if not already
if (!playerCharacter.isCombat())
CombatManager.toggleCombat(true, origin);
//make character stand if sitting
if (playerCharacter.isSit())
CombatManager.toggleSit(false, origin);
CombatManager.AttackTarget(playerCharacter, target);
return true;
}
}
@@ -65,7 +65,7 @@ public class ChannelMuteMsgHandler extends AbstractClientMsgHandler {
cityZone = ZoneManager.findSmallestZone(targetBuilding.getLoc()); cityZone = ZoneManager.findSmallestZone(targetBuilding.getLoc());
// Can't abandon a tree not within a player city zone // Can't abandon a tree not within a player city zone
if (cityZone.isPlayerCity() == false) if (cityZone.guild_zone == false)
return; return;
if (targetBuilding.getCity().hasBeenTransfered == true) { if (targetBuilding.getCity().hasBeenTransfered == true) {
@@ -69,7 +69,7 @@ public class ClaimGuildTreeMsgHandler extends AbstractClientMsgHandler {
playerZone = building.getParentZone(); playerZone = building.getParentZone();
if (playerZone != null) if (playerZone != null)
playerCity = City.getCity(playerZone.getPlayerCityUUID()); playerCity = City.getCity(playerZone.playerCityUUID);
// Oops! *** Refactor: Log error // Oops! *** Refactor: Log error
switch (msg.getMessageType()) { switch (msg.getMessageType()) {
@@ -117,7 +117,7 @@ public class ClaimGuildTreeMsgHandler extends AbstractClientMsgHandler {
dispatch = Dispatch.borrow(sourcePlayer, gtsm); dispatch = Dispatch.borrow(sourcePlayer, gtsm);
DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.SECONDARY); DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.SECONDARY);
CityZoneMsg czm = new CityZoneMsg(2, playerZone.getLoc().x, playerZone.getLoc().y, playerZone.getLoc().z, playerCity.getCityName(), playerZone, Enum.CityBoundsType.ZONE.extents, Enum.CityBoundsType.ZONE.extents); CityZoneMsg czm = new CityZoneMsg(2, playerZone.getLoc().x, playerZone.getLoc().y, playerZone.getLoc().z, playerCity.getCityName(), playerZone, Enum.CityBoundsType.ZONE.halfExtents, Enum.CityBoundsType.ZONE.halfExtents);
DispatchMessage.dispatchMsgToAll(czm); DispatchMessage.dispatchMsgToAll(czm);
break; break;
@@ -95,7 +95,7 @@ public class DestroyBuildingHandler extends AbstractClientMsgHandler {
city.setWarehouseBuildingID(0); city.setWarehouseBuildingID(0);
} }
building.setRank(-1); BuildingManager.setRank(building, -1);
WorldGrid.RemoveWorldObject(building); WorldGrid.RemoveWorldObject(building);
WorldGrid.removeObject(building); WorldGrid.removeObject(building);
building.getParentZone().zoneBuildingSet.remove(building); building.getParentZone().zoneBuildingSet.remove(building);
@@ -75,12 +75,12 @@ public class ManageCityAssetMsgHandler extends AbstractClientMsgHandler {
Zone zone = ZoneManager.findSmallestZone(player.getLoc()); Zone zone = ZoneManager.findSmallestZone(player.getLoc());
if (!zone.isPlayerCity()) { if (!zone.guild_zone) {
ErrorPopupMsg.sendErrorMsg(player, "Unable to find city to command."); ErrorPopupMsg.sendErrorMsg(player, "Unable to find city to command.");
return true; return true;
} }
City city = City.GetCityFromCache(zone.getPlayerCityUUID()); City city = City.GetCityFromCache(zone.playerCityUUID);
if (city == null) { if (city == null) {
ErrorPopupMsg.sendErrorMsg(player, "Unable to find city to command."); ErrorPopupMsg.sendErrorMsg(player, "Unable to find city to command.");
@@ -254,7 +254,7 @@ public class ManageCityAssetMsgHandler extends AbstractClientMsgHandler {
if (baneZone == null) if (baneZone == null)
return true; return true;
City banedCity = City.getCity(baneZone.getPlayerCityUUID()); City banedCity = City.getCity(baneZone.playerCityUUID);
if (banedCity == null) if (banedCity == null)
return true; return true;
@@ -8,7 +8,6 @@ import engine.gameManager.BuildingManager;
import engine.gameManager.DbManager; import engine.gameManager.DbManager;
import engine.gameManager.NPCManager; import engine.gameManager.NPCManager;
import engine.gameManager.SessionManager; import engine.gameManager.SessionManager;
import engine.math.Vector3fImmutable;
import engine.net.Dispatch; import engine.net.Dispatch;
import engine.net.DispatchMessage; import engine.net.DispatchMessage;
import engine.net.client.ClientConnection; import engine.net.client.ClientConnection;
@@ -16,9 +15,6 @@ import engine.net.client.msg.*;
import engine.objects.*; import engine.objects.*;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
import java.util.ArrayList;
import java.util.HashMap;
/* /*
* @Author: * @Author:
* @Summary: Processes application protocol message which * @Summary: Processes application protocol message which
@@ -27,8 +23,6 @@ import java.util.HashMap;
public class MinionTrainingMsgHandler extends AbstractClientMsgHandler { public class MinionTrainingMsgHandler extends AbstractClientMsgHandler {
public static HashMap<Integer, ArrayList<Integer>> _minionsByCaptain = null;
public MinionTrainingMsgHandler() { public MinionTrainingMsgHandler() {
super(MinionTrainingMessage.class); super(MinionTrainingMessage.class);
} }
@@ -38,9 +32,9 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler {
MinionTrainingMessage minionMsg = (MinionTrainingMessage) baseMsg; MinionTrainingMessage minionMsg = (MinionTrainingMessage) baseMsg;
PlayerCharacter player = SessionManager.getPlayerCharacter(origin); PlayerCharacter playerCharacter = SessionManager.getPlayerCharacter(origin);
if (player == null) if (playerCharacter == null)
return true; return true;
if (minionMsg.getNpcType() == Enum.GameObjectType.NPC.ordinal()) { if (minionMsg.getNpcType() == Enum.GameObjectType.NPC.ordinal()) {
@@ -50,23 +44,24 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler {
if (npc == null) if (npc == null)
return true; return true;
Building b = BuildingManager.getBuildingFromCache(minionMsg.getBuildingID()); Building building = BuildingManager.getBuildingFromCache(minionMsg.getBuildingID());
if (b == null) if (building == null)
return true; return true;
//clear minion //clear minion
if (npc.minionLock.writeLock().tryLock()) { if (npc.minionLock.writeLock().tryLock()) {
try { try {
if (minionMsg.getType() == 2) { if (minionMsg.getType() == 2) {
Mob toRemove = Mob.getFromCache(minionMsg.getUUID()); Mob toRemove = Mob.getFromCache(minionMsg.getUUID());
if (!npc.getSiegeMinionMap().containsKey(toRemove)) if (!npc.minions.contains(toRemove.getObjectUUID()))
return true; return true;
npc.getSiegeMinionMap().remove(toRemove); npc.minions.remove(Integer.valueOf(toRemove.getObjectUUID()));
WorldGrid.RemoveWorldObject(toRemove); WorldGrid.RemoveWorldObject(toRemove);
@@ -74,33 +69,35 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler {
toRemove.getParentZone().zoneMobSet.remove(toRemove); toRemove.getParentZone().zoneMobSet.remove(toRemove);
DbManager.removeFromCache(toRemove); DbManager.removeFromCache(toRemove);
PlayerCharacter petOwner = toRemove.getOwner();
if(toRemove.guardCaptain.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) {
PlayerCharacter petOwner = (PlayerCharacter) toRemove.guardCaptain;
if (petOwner != null) { if (petOwner != null) {
petOwner.setPet(null); petOwner.setPet(null);
toRemove.setOwner(null);
toRemove.guardCaptain = null;
PetMsg petMsg = new PetMsg(5, null); PetMsg petMsg = new PetMsg(5, null);
Dispatch dispatch = Dispatch.borrow(petOwner, petMsg); Dispatch dispatch = Dispatch.borrow(petOwner, petMsg);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
} }
}
// we Found the move to remove, lets break the for loop so it doesnt look for more. ManageCityAssetsMsg mca1 = new ManageCityAssetsMsg(playerCharacter, building);
ManageCityAssetsMsg mca1 = new ManageCityAssetsMsg(player, b);
mca1.actionType = 3; mca1.actionType = 3;
mca1.setTargetType(b.getObjectType().ordinal()); mca1.setTargetType(building.getObjectType().ordinal());
mca1.setTargetID(b.getObjectUUID()); mca1.setTargetID(building.getObjectUUID());
mca1.setTargetType3(npc.getObjectType().ordinal()); mca1.setTargetType3(npc.getObjectType().ordinal());
mca1.setTargetID3(npc.getObjectUUID()); mca1.setTargetID3(npc.getObjectUUID());
mca1.setAssetName1(b.getName()); mca1.setAssetName1(building.getName());
mca1.setUnknown54(1); mca1.setUnknown54(1);
Dispatch dispatch = Dispatch.borrow(player, mca1); Dispatch dispatch = Dispatch.borrow(playerCharacter, mca1);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
ManageNPCMsg mnm = new ManageNPCMsg(npc); ManageNPCMsg mnm = new ManageNPCMsg(npc);
dispatch = Dispatch.borrow(player, mnm); dispatch = Dispatch.borrow(playerCharacter, mnm);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
//Add Minion //Add Minion
@@ -115,7 +112,7 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler {
if (npc.getContractID() == 842) if (npc.getContractID() == 842)
maxSlots = 1; maxSlots = 1;
if (npc.getSiegeMinionMap().size() == maxSlots) if (npc.minions.size() == maxSlots)
return true; return true;
int mobBase; int mobBase;
@@ -146,47 +143,15 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler {
if (mobBase == 0) if (mobBase == 0)
return true; return true;
Mob siegeMob = Mob.createSiegeMob(npc, mobBase, npc.getGuild(), zone, b.getLoc(), (short) 1); Mob siegeMob = Mob.createSiegeMinion(npc, mobBase);
if (siegeMob == null) if (siegeMob == null)
return true; return true;
if (siegeMob != null) {
siegeMob.setSpawnTime(60 * 15);
Building building = BuildingManager.getBuilding(((MinionTrainingMessage) baseMsg).getBuildingID());
siegeMob.building = building;
siegeMob.parentZone = zone;
// Slot siege minion
// Can be either corner tower or bulwark.
int slot;
if (building.getBlueprint().getBuildingGroup().equals(Enum.BuildingGroup.ARTYTOWER))
slot = 2;
else
slot = ((NPC) siegeMob.npcOwner).getSiegeMinionMap().get(siegeMob) + 1; // First slot is for the captain
BuildingLocation slotLocation = BuildingManager._slotLocations.get(building.meshUUID).get(slot);
siegeMob.bindLoc = building.getLoc().add(slotLocation.getLocation());
// Rotate slot position by the building rotation
siegeMob.bindLoc = Vector3fImmutable.rotateAroundPoint(building.getLoc(), siegeMob.bindLoc, building.getBounds().getQuaternion().angleY);
siegeMob.loc = new Vector3fImmutable(siegeMob.bindLoc);
siegeMob.endLoc = new Vector3fImmutable(siegeMob.bindLoc);
zone.zoneMobSet.add(siegeMob);
siegeMob.setLoc(siegeMob.bindLoc);
}
} }
ManageNPCMsg mnm = new ManageNPCMsg(npc); ManageNPCMsg mnm = new ManageNPCMsg(npc);
mnm.setMessageType(1); mnm.setMessageType(1);
Dispatch dispatch = Dispatch.borrow(player, mnm); Dispatch dispatch = Dispatch.borrow(playerCharacter, mnm);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
} finally { } finally {
@@ -214,13 +179,13 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler {
Mob toRemove = Mob.getFromCache(minionMsg.getUUID()); Mob toRemove = Mob.getFromCache(minionMsg.getUUID());
if (!npc.getSiegeMinionMap().containsKey(toRemove)) if (!npc.minions.contains(toRemove.getObjectUUID()))
return true; return true;
if (!DbManager.MobQueries.REMOVE_FROM_GUARDS(npc.getObjectUUID(), toRemove.getMobBaseID(), npc.getSiegeMinionMap().get(toRemove))) if (!DbManager.MobQueries.REMOVE_GUARD_MINION(npc.getObjectUUID(), toRemove.firstName))
return true; return true;
npc.getSiegeMinionMap().remove(toRemove); npc.minions.remove(Integer.valueOf(toRemove.getObjectUUID()));
WorldGrid.RemoveWorldObject(toRemove); WorldGrid.RemoveWorldObject(toRemove);
@@ -228,17 +193,22 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler {
toRemove.getParentZone().zoneMobSet.remove(toRemove); toRemove.getParentZone().zoneMobSet.remove(toRemove);
DbManager.removeFromCache(toRemove); DbManager.removeFromCache(toRemove);
PlayerCharacter petOwner = toRemove.getOwner();
if (petOwner != null) { if (toRemove.agentType.equals(Enum.AIAgentType.SIEGEENGINE)) {
petOwner.setPet(null);
toRemove.setOwner(null); PlayerCharacter trebOwner = (PlayerCharacter) toRemove.guardCaptain;
if (trebOwner != null) {
trebOwner.setPet(null);
toRemove.guardCaptain = null;
PetMsg petMsg = new PetMsg(5, null); PetMsg petMsg = new PetMsg(5, null);
Dispatch dispatch = Dispatch.borrow(petOwner, petMsg); Dispatch dispatch = Dispatch.borrow(trebOwner, petMsg);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
} }
}
ManageCityAssetsMsg mca1 = new ManageCityAssetsMsg(player, building); ManageCityAssetsMsg mca1 = new ManageCityAssetsMsg(playerCharacter, building);
mca1.actionType = 3; mca1.actionType = 3;
mca1.setTargetType(building.getObjectType().ordinal()); mca1.setTargetType(building.getObjectType().ordinal());
mca1.setTargetID(building.getObjectUUID()); mca1.setTargetID(building.getObjectUUID());
@@ -248,11 +218,11 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler {
mca1.setAssetName1(building.getName()); mca1.setAssetName1(building.getName());
mca1.setUnknown54(1); mca1.setUnknown54(1);
Dispatch dispatch = Dispatch.borrow(player, mca1); Dispatch dispatch = Dispatch.borrow(playerCharacter, mca1);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
ManageNPCMsg mnm = new ManageNPCMsg(npc); ManageNPCMsg mnm = new ManageNPCMsg(npc);
dispatch = Dispatch.borrow(player, mnm); dispatch = Dispatch.borrow(playerCharacter, mnm);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
//Add Minion //Add Minion
@@ -288,7 +258,7 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler {
break; break;
} }
if (npc.getSiegeMinionMap().size() == maxSlots) if (npc.minions.size() == maxSlots)
return true; return true;
int mobBase = npc.getMobBaseID(); int mobBase = npc.getMobBaseID();
@@ -298,14 +268,14 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler {
String pirateName = NPCManager.getPirateName(mobBase); String pirateName = NPCManager.getPirateName(mobBase);
if (!DbManager.MobQueries.ADD_TO_GUARDS(npc.getObjectUUID(), mobBase, pirateName, npc.getSiegeMinionMap().size() + 1)) Mob toCreate = Mob.createGuardMinion(npc, npc.getLevel(), pirateName);
return true;
Mob toCreate = Mob.createGuardMob(npc, npc.getGuild(), zone, building.getLoc(), npc.getLevel(), pirateName);
if (toCreate == null) if (toCreate == null)
return true; return true;
if (!DbManager.MobQueries.ADD_GUARD_MINION(npc.getObjectUUID(), pirateName))
return true;
if (toCreate != null) { if (toCreate != null) {
toCreate.setDeathTime(System.currentTimeMillis()); toCreate.setDeathTime(System.currentTimeMillis());
toCreate.parentZone.zoneMobSet.add(toCreate); toCreate.parentZone.zoneMobSet.add(toCreate);
@@ -314,7 +284,7 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler {
ManageNPCMsg mnm = new ManageNPCMsg(npc); ManageNPCMsg mnm = new ManageNPCMsg(npc);
mnm.setMessageType(1); mnm.setMessageType(1);
Dispatch dispatch = Dispatch.borrow(player, mnm); Dispatch dispatch = Dispatch.borrow(playerCharacter, mnm);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
} catch (Exception e) { } catch (Exception e) {
@@ -9,12 +9,22 @@
package engine.net.client.handlers; package engine.net.client.handlers;
import engine.InterestManagement.WorldGrid;
import engine.exception.MsgSendException; import engine.exception.MsgSendException;
import engine.gameManager.BuildingManager;
import engine.gameManager.ChatManager;
import engine.CollisionEngine.CollisionManager;
import engine.gameManager.MovementManager; import engine.gameManager.MovementManager;
import engine.math.Vector3fImmutable;
import engine.net.client.ClientConnection; import engine.net.client.ClientConnection;
import engine.net.client.msg.ClientNetMsg; import engine.net.client.msg.ClientNetMsg;
import engine.net.client.msg.MoveToPointMsg; import engine.net.client.msg.MoveToPointMsg;
import engine.objects.PlayerCharacter; import engine.objects.*;
import engine.server.MBServerStatics;
import java.awt.geom.Line2D;
import java.util.HashSet;
public class MoveToPointHandler extends AbstractClientMsgHandler { public class MoveToPointHandler extends AbstractClientMsgHandler {
@@ -26,13 +36,37 @@ public class MoveToPointHandler extends AbstractClientMsgHandler {
protected boolean _handleNetMsg(ClientNetMsg baseMsg, protected boolean _handleNetMsg(ClientNetMsg baseMsg,
ClientConnection origin) throws MsgSendException { ClientConnection origin) throws MsgSendException {
MoveToPointMsg msg = (MoveToPointMsg) baseMsg; MoveToPointMsg msg = (MoveToPointMsg) baseMsg;
PlayerCharacter pc = origin.getPlayerCharacter();
if(pc == null)
return true;
PlayerCharacter pc = (origin != null) ? (origin.getPlayerCharacter()) : null; //check for collisions
if (pc == null) Line2D travelLine = new Line2D.Float();
return false; Vector3fImmutable endLoc = new Vector3fImmutable(msg.getEndLat(),msg.getEndAlt(),msg.getEndLon());
travelLine.setLine(pc.loc.x,pc.loc.z,endLoc.x,endLoc.z);
if(BuildingManager.getBuildingAtLocation(pc.loc) != null){
Building current = BuildingManager.getBuildingAtLocation(pc.loc);
if (CollisionManager.CollisionDetected(current, travelLine, pc.getCharacterHeight(), pc.loc.y)) {
ChatManager.chatSystemInfo(pc, "Collision Detected With : " + current.getName() + " Rect: " + current.buildingRect);
//msg.setEndCoord();
MovementManager.movement(msg, pc);
return true;
}
}
HashSet<AbstractWorldObject> awoList = WorldGrid.getObjectsInRangePartial(pc.loc, 1000, MBServerStatics.MASK_BUILDING);
for(AbstractWorldObject awo : awoList){
Building building = (Building)awo;
if(travelLine.intersects(building.buildingRect) || building.buildingRect.contains(travelLine.getP1()) || building.buildingRect.contains(travelLine.getP2())) {
if (CollisionManager.CollisionDetected(building, travelLine, pc.getCharacterHeight(), pc.loc.y)) {
ChatManager.chatSystemInfo(pc, "Collision Detected With : " + building.getName() + " Rect: " + building.buildingRect);
//msg.setEndCoord();
MovementManager.movement(msg, pc);
return true;
}
}
}
//ChatManager.chatSystemInfo(pc, "No Collision Detected");
MovementManager.movement(msg, pc); MovementManager.movement(msg, pc);
return true; return true;
} }
} }
@@ -182,7 +182,7 @@ public class ObjectActionMsgHandler extends AbstractClientMsgHandler {
realm.claimRealmForCity(city, charterUUID); realm.claimRealmForCity(city, charterUUID);
tol.setRank(8); BuildingManager.setRank(tol, 8);
WorldGrid.updateObject(tol); WorldGrid.updateObject(tol);
for (Building building : city.getParent().zoneBuildingSet) { for (Building building : city.getParent().zoneBuildingSet) {
@@ -334,7 +334,7 @@ public class ObjectActionMsgHandler extends AbstractClientMsgHandler {
Zone zone = ZoneManager.findSmallestZone(player.getLoc()); Zone zone = ZoneManager.findSmallestZone(player.getLoc());
if (zone != null) { if (zone != null) {
if (zone.isPlayerCity()) { if (zone.guild_zone) {
loc = zone.getLoc(); loc = zone.getLoc();
} }
} }
@@ -151,7 +151,7 @@ public class OpenFriendsCondemnListMsgHandler extends AbstractClientMsgHandler {
if (removeCondemn == null) if (removeCondemn == null)
return true; return true;
if (!DbManager.BuildingQueries.REMOVE_FROM_CONDEMNED_LIST(removeCondemn.getParent(), removeCondemn.getPlayerUID(), removeCondemn.getGuildUID(), removeCondemn.getFriendType())) if (!DbManager.BuildingQueries.REMOVE_FROM_CONDEMNED_LIST(removeCondemn.buildingUUID, removeCondemn.playerUID, removeCondemn.guildUID, removeCondemn.friendType))
return true; return true;
sourceBuilding.getCondemned().remove(msg.getRemoveFriendID()); sourceBuilding.getCondemned().remove(msg.getRemoveFriendID());
@@ -175,7 +175,7 @@ public class OpenFriendsCondemnListMsgHandler extends AbstractClientMsgHandler {
return true; return true;
condemn.setActive(msg.isReverseKOS()); condemn.setActive(msg.isReverseKOS());
openFriendsCondemnListMsg.setReverseKOS(condemn.isActive()); openFriendsCondemnListMsg.setReverseKOS(condemn.active);
dispatch = Dispatch.borrow(player, msg); dispatch = Dispatch.borrow(player, msg);
DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.SECONDARY); DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.SECONDARY);
break; break;
@@ -354,7 +354,7 @@ public class OpenFriendsCondemnListMsgHandler extends AbstractClientMsgHandler {
if (friend == null) if (friend == null)
return true; return true;
if (!DbManager.BuildingQueries.REMOVE_FROM_FRIENDS_LIST(sourceBuilding.getObjectUUID(), friend.getPlayerUID(), friend.getGuildUID(), friend.getFriendType())) { if (!DbManager.BuildingQueries.REMOVE_FROM_FRIENDS_LIST(sourceBuilding.getObjectUUID(), friend.playerUID, friend.guildUID, friend.friendType)) {
Logger.debug("Failed to remove Friend: " + msg.getRemoveFriendID() + " from Building With UID " + sourceBuilding.getObjectUUID()); Logger.debug("Failed to remove Friend: " + msg.getRemoveFriendID() + " from Building With UID " + sourceBuilding.getObjectUUID());
return true; return true;
} }
@@ -7,7 +7,6 @@ import engine.Enum.ProfitType;
import engine.exception.MsgSendException; import engine.exception.MsgSendException;
import engine.gameManager.BuildingManager; import engine.gameManager.BuildingManager;
import engine.gameManager.DbManager; import engine.gameManager.DbManager;
import engine.gameManager.NPCManager;
import engine.gameManager.SessionManager; import engine.gameManager.SessionManager;
import engine.math.FastMath; import engine.math.FastMath;
import engine.math.Vector3fImmutable; import engine.math.Vector3fImmutable;
@@ -37,7 +36,7 @@ public class OrderNPCMsgHandler extends AbstractClientMsgHandler {
super(OrderNPCMsg.class); super(OrderNPCMsg.class);
} }
public static void processRedeedMob(Mob mob, Building building, ClientConnection origin) { public static void processRedeedHireling(AbstractCharacter hireling, Building building, ClientConnection origin) {
PlayerCharacter player; PlayerCharacter player;
Contract contract; Contract contract;
@@ -48,33 +47,28 @@ public class OrderNPCMsgHandler extends AbstractClientMsgHandler {
player = SessionManager.getPlayerCharacter(origin); player = SessionManager.getPlayerCharacter(origin);
itemMan = player.getCharItemManager(); itemMan = player.getCharItemManager();
contract = mob.getContract(); contract = hireling.contract;
if (!player.getCharItemManager().hasRoomInventory((short) 1)) { if (!player.getCharItemManager().hasRoomInventory((short) 1)) {
ErrorPopupMsg.sendErrorPopup(player, 21); ErrorPopupMsg.sendErrorPopup(player, 21);
return; return;
} }
if (!building.getHirelings().containsKey(mob)) if (!building.getHirelings().containsKey(hireling))
return; return;
if (!NPCManager.removeMobileFromBuilding(mob, building)) { BuildingManager.removeHireling(building, hireling);
PlaceAssetMsg.sendPlaceAssetError(player.getClientConnection(), 1, "A Serious error has occurred. Please post details for to ensure transaction integrity");
return;
}
building.getHirelings().remove(mob);
itemBase = ItemBase.getItemBase(contract.getContractID()); itemBase = ItemBase.getItemBase(contract.getContractID());
if (itemBase == null) { if (itemBase == null) {
Logger.error("Could not find Contract for npc: " + mob.getObjectUUID()); Logger.error("Could not find Contract for npc: " + hireling.getObjectUUID());
return; return;
} }
boolean itemWorked = false; boolean itemWorked = false;
item = new Item(itemBase, player.getObjectUUID(), Enum.OwnerType.PlayerCharacter, (byte) ((byte) mob.getRank() - 1), (byte) ((byte) mob.getRank() - 1), (short) 1, (short) 1, true, false, Enum.ItemContainerType.INVENTORY, (byte) 0, new ArrayList<>(), ""); item = new Item(itemBase, player.getObjectUUID(), Enum.OwnerType.PlayerCharacter, (byte) ((byte) hireling.getRank() - 1), (byte) ((byte) hireling.getRank() - 1), (short) 1, (short) 1, true, false, Enum.ItemContainerType.INVENTORY, (byte) 0, new ArrayList<>(), "");
item.setNumOfItems(1); item.setNumOfItems(1);
item.containerType = Enum.ItemContainerType.INVENTORY; item.containerType = Enum.ItemContainerType.INVENTORY;
@@ -212,10 +206,6 @@ public class OrderNPCMsgHandler extends AbstractClientMsgHandler {
return; return;
} }
for (AbstractCharacter guard : building.getHirelings().keySet()) {
if (guard.getObjectType() == GameObjectType.Mob)
((Mob) guard).setPatrolPointIndex(0);
}
} else if (building.getPatrolPoints() != null) } else if (building.getPatrolPoints() != null)
ClearPatrolPoints(building.getObjectUUID()); ClearPatrolPoints(building.getObjectUUID());
@@ -223,10 +213,6 @@ public class OrderNPCMsgHandler extends AbstractClientMsgHandler {
AddSentryPoints(building.getObjectUUID(), orderNpcMsg.getSentryPoints()); AddSentryPoints(building.getObjectUUID(), orderNpcMsg.getSentryPoints());
} else if (building.getSentryPoints() != null) } else if (building.getSentryPoints() != null)
ClearSentryPoints(building.getObjectUUID()); ClearSentryPoints(building.getObjectUUID());
// Dispatch dispatch = Dispatch.borrow(pc, msg);
// DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
} }
private static void processUpgradeNPC(PlayerCharacter player, AbstractCharacter abstractCharacter) { private static void processUpgradeNPC(PlayerCharacter player, AbstractCharacter abstractCharacter) {
@@ -290,28 +276,6 @@ public class OrderNPCMsgHandler extends AbstractClientMsgHandler {
} }
} }
private static synchronized void processRedeedNPC(AbstractCharacter abstractCharacter, Building building, ClientConnection origin) {
// Member variable declaration
switch (abstractCharacter.getObjectType()) {
case NPC:
NPC npc = (NPC) abstractCharacter;
Building cityBuilding = npc.getBuilding();
if (cityBuilding == null)
return;
BuildingManager.processRedeedNPC(npc, npc.building, origin);
break;
case Mob:
Mob mob = (Mob) abstractCharacter;
processRedeedMob(mob, mob.building, origin);
break;
}
}
private static boolean AddPatrolPoints(int buildingID, ArrayList<Vector3fImmutable> patrolPoints) { private static boolean AddPatrolPoints(int buildingID, ArrayList<Vector3fImmutable> patrolPoints) {
Building building = BuildingManager.getBuildingFromCache(buildingID); Building building = BuildingManager.getBuildingFromCache(buildingID);
@@ -324,7 +288,7 @@ public class OrderNPCMsgHandler extends AbstractClientMsgHandler {
if (zone == null) if (zone == null)
return false; return false;
if (zone.getPlayerCityUUID() == 0) if (zone.playerCityUUID == 0)
return false; return false;
City city = building.getCity(); City city = building.getCity();
@@ -502,7 +466,7 @@ public class OrderNPCMsgHandler extends AbstractClientMsgHandler {
if (BuildingManager.PlayerCanControlNotOwner(building, player) == false) if (BuildingManager.PlayerCanControlNotOwner(building, player) == false)
return true; return true;
processRedeedNPC(npc, building, origin); processRedeedHireling(npc, building, origin);
return true; return true;
//MB TODO HANDLE all profits. //MB TODO HANDLE all profits.
case 7: case 7:
@@ -541,7 +505,7 @@ public class OrderNPCMsgHandler extends AbstractClientMsgHandler {
} else if (orderNPCMsg.getObjectType() == GameObjectType.Mob.ordinal()) { } else if (orderNPCMsg.getObjectType() == GameObjectType.Mob.ordinal()) {
mob = Mob.getFromCacheDBID(orderNPCMsg.getNpcUUID()); mob = Mob.getMob(orderNPCMsg.getNpcUUID());
if (mob == null) if (mob == null)
return true; return true;
@@ -570,10 +534,7 @@ public class OrderNPCMsgHandler extends AbstractClientMsgHandler {
if (building.getHirelings().containsKey(mob) == false) if (building.getHirelings().containsKey(mob) == false)
return true; return true;
if (NPCManager.removeMobileFromBuilding(mob, building) == false) { BuildingManager.removeHireling(building, mob);
PlaceAssetMsg.sendPlaceAssetError(player.getClientConnection(), 1, "A Serious error has occurred. Please post details for to ensure transaction integrity");
return true;
}
ManageCityAssetsMsg manageCityAssetsMsg = new ManageCityAssetsMsg(); ManageCityAssetsMsg manageCityAssetsMsg = new ManageCityAssetsMsg();
manageCityAssetsMsg.actionType = SVR_CLOSE_WINDOW; manageCityAssetsMsg.actionType = SVR_CLOSE_WINDOW;
@@ -608,7 +569,7 @@ public class OrderNPCMsgHandler extends AbstractClientMsgHandler {
if (BuildingManager.PlayerCanControlNotOwner(building, player) == false) if (BuildingManager.PlayerCanControlNotOwner(building, player) == false)
return true; return true;
processRedeedNPC(mob, building, origin); processRedeedHireling(mob, building, origin);
return true; return true;
//MB TODO HANDLE all profits. //MB TODO HANDLE all profits.
case 7: case 7:
@@ -2,7 +2,6 @@ package engine.net.client.handlers;
import engine.Enum; import engine.Enum;
import engine.Enum.*; import engine.Enum.*;
import engine.InterestManagement.HeightMap;
import engine.InterestManagement.InterestManager; import engine.InterestManagement.InterestManager;
import engine.InterestManagement.RealmMap; import engine.InterestManagement.RealmMap;
import engine.InterestManagement.WorldGrid; import engine.InterestManagement.WorldGrid;
@@ -112,7 +111,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
// Cannot place a tree underwater // Cannot place a tree underwater
if (HeightMap.isLocUnderwater(placementInfo.getLoc())) { if (ZoneManager.isLocUnderwater(placementInfo.getLoc())) {
PlaceAssetMsg.sendPlaceAssetError(origin, 6, ""); // Cannot place underwater PlaceAssetMsg.sendPlaceAssetError(origin, 6, ""); // Cannot place underwater
return false; return false;
} }
@@ -138,7 +137,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
private static boolean validateBuildingPlacement(Zone serverZone, PlaceAssetMsg msg, ClientConnection origin, PlayerCharacter player, PlacementInfo placementInfo) { private static boolean validateBuildingPlacement(Zone serverZone, PlaceAssetMsg msg, ClientConnection origin, PlayerCharacter player, PlacementInfo placementInfo) {
if (serverZone.isPlayerCity() == false) { if (serverZone.guild_zone == false) {
PlaceAssetMsg.sendPlaceAssetError(origin, 52, player.getName()); PlaceAssetMsg.sendPlaceAssetError(origin, 52, player.getName());
return false; return false;
} }
@@ -157,7 +156,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
// Retrieve the building details we're placing // Retrieve the building details we're placing
if (serverZone.isNPCCity() == true) { if (serverZone.isNPCCity == true) {
PlaceAssetMsg.sendPlaceAssetError(origin, 15, ""); // Cannot place in a peace zone PlaceAssetMsg.sendPlaceAssetError(origin, 15, ""); // Cannot place in a peace zone
return false; return false;
} }
@@ -178,7 +177,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
// Cannot place a building underwater // Cannot place a building underwater
if (HeightMap.isLocUnderwater(placementInfo.getLoc())) { if (ZoneManager.isLocUnderwater(placementInfo.getLoc())) {
PlaceAssetMsg.sendPlaceAssetError(origin, 6, ""); // Cannot place underwater PlaceAssetMsg.sendPlaceAssetError(origin, 6, ""); // Cannot place underwater
return false; return false;
} }
@@ -186,7 +185,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
// Players cannot place buildings in mob zones. // Players cannot place buildings in mob zones.
if ((serverZone.isMacroZone() == true) if ((serverZone.isMacroZone() == true)
|| (serverZone.getParent().isMacroZone() == true)) { || (serverZone.parent.isMacroZone() == true)) {
PlaceAssetMsg.sendPlaceAssetError(origin, 57, player.getName()); // No building may be placed within this territory PlaceAssetMsg.sendPlaceAssetError(origin, 57, player.getName()); // No building may be placed within this territory
return false; return false;
} }
@@ -202,8 +201,8 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
// Cannot place assets on a dead tree // Cannot place assets on a dead tree
if ((serverZone.isPlayerCity()) if ((serverZone.guild_zone)
&& (City.getCity(serverZone.getPlayerCityUUID()).getTOL().getRank() == -1)) { && (City.getCity(serverZone.playerCityUUID).getTOL().getRank() == -1)) {
PlaceAssetMsg.sendPlaceAssetError(origin, 1, "Cannot place asset on dead tree until world heals"); PlaceAssetMsg.sendPlaceAssetError(origin, 1, "Cannot place asset on dead tree until world heals");
return false; return false;
} }
@@ -262,14 +261,14 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
// Must be a player city // Must be a player city
if (serverZone.isPlayerCity() == false) { if (serverZone.guild_zone == false) {
PlaceAssetMsg.sendPlaceAssetError(origin, 41, player.getName()); // Cannot place outside a guild zone PlaceAssetMsg.sendPlaceAssetError(origin, 41, player.getName()); // Cannot place outside a guild zone
return false; return false;
} }
//Test zone has a city object //Test zone has a city object
City city = City.getCity(serverZone.getPlayerCityUUID()); City city = City.getCity(serverZone.playerCityUUID);
if (city == null) { if (city == null) {
PlaceAssetMsg.sendPlaceAssetError(origin, 52, ""); //"no city to associate asset with" PlaceAssetMsg.sendPlaceAssetError(origin, 52, ""); //"no city to associate asset with"
@@ -513,7 +512,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
if (serverZone == null) if (serverZone == null)
return false; return false;
cityObject = City.getCity(serverZone.getPlayerCityUUID()); cityObject = City.getCity(serverZone.playerCityUUID);
// Early exit if something went horribly wrong // Early exit if something went horribly wrong
@@ -572,7 +571,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
// No valid player city found // No valid player city found
if (serverCity == null || serverCity.getParent().isPlayerCity() == false) { if (serverCity == null || serverCity.getParent().guild_zone == false) {
PlaceAssetMsg.sendPlaceAssetError(origin, 52, ""); // Cannot place outisde a guild zone PlaceAssetMsg.sendPlaceAssetError(origin, 52, ""); // Cannot place outisde a guild zone
return false; return false;
} }
@@ -661,7 +660,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
if (!building.getBlueprint().isSiegeEquip()) if (!building.getBlueprint().isSiegeEquip())
continue; continue;
if (!building.getLoc().isInsideCircle(serverCity.getLoc(), CityBoundsType.ZONE.extents)) if (!building.getLoc().isInsideCircle(serverCity.getLoc(), CityBoundsType.ZONE.halfExtents))
continue; continue;
if (building.getGuild() == null) if (building.getGuild() == null)
@@ -745,15 +744,16 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
} }
Vector3fImmutable plantLoc = new Vector3fImmutable(treeInfo.getLoc().x, Vector3fImmutable plantLoc = new Vector3fImmutable(treeInfo.getLoc().x,
HeightMap.getWorldHeight(treeInfo.getLoc()), 0,
treeInfo.getLoc().z); treeInfo.getLoc().z);
cityObjects = DbManager.CityQueries.CREATE_CITY(playerCharacter.getObjectUUID(), serverZone.getObjectUUID(), cityObjects = DbManager.CityQueries.CREATE_CITY(playerCharacter.getObjectUUID(), serverZone.getObjectUUID(),
serverRealm.getRealmID(), serverRealm.getRealmID(),
plantLoc.x - serverZone.getAbsX(), plantLoc.y, plantLoc.x - serverZone.absX, plantLoc.y,
plantLoc.z - serverZone.getAbsZ(), treeInfo.getRot().y, treeInfo.getW(), playerCharacter.getGuild().getName(), LocalDateTime.now()); plantLoc.z - serverZone.absZ, treeInfo.getRot().y, treeInfo.getW(), playerCharacter.getGuild().getName(), LocalDateTime.now());
// Uh oh! // Uh oh!
if (cityObjects == null || cityObjects.isEmpty()) { if (cityObjects == null || cityObjects.isEmpty()) {
PlaceAssetMsg.sendPlaceAssetError(origin, 1, "A Serious error has occurred. Please post details for to ensure transaction integrity"); PlaceAssetMsg.sendPlaceAssetError(origin, 1, "A Serious error has occurred. Please post details for to ensure transaction integrity");
return false; return false;
@@ -766,8 +766,6 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
cityObjectMap.put(gameObject.getObjectType(), gameObject); cityObjectMap.put(gameObject.getObjectType(), gameObject);
treeObject = (Building) cityObjectMap.get(GameObjectType.Building); treeObject = (Building) cityObjectMap.get(GameObjectType.Building);
treeObject.runAfterLoad();
;
cityObject = (City) cityObjectMap.get(GameObjectType.City); cityObject = (City) cityObjectMap.get(GameObjectType.City);
zoneObject = (Zone) cityObjectMap.get(GameObjectType.Zone); zoneObject = (Zone) cityObjectMap.get(GameObjectType.Zone);
@@ -780,44 +778,30 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
playerNation = playerCharacter.getGuild(); playerNation = playerCharacter.getGuild();
playerNation.setGuildState(GuildState.Sovereign); playerNation.setGuildState(GuildState.Sovereign);
// Link the zone with the city and then add
// to the appropriate hash tables and cache
zoneObject.setPlayerCity(true);
if (zoneObject.getParent() != null)
zoneObject.getParent().addNode(zoneObject); //add as child to parent
ZoneManager.addZone(zoneObject.getObjectUUID(), zoneObject);
ZoneManager.addPlayerCityZone(zoneObject);
serverZone.addNode(zoneObject);
zoneObject.generateWorldAltitude();
cityObject.setParent(zoneObject);
cityObject.setObjectTypeMask(MBServerStatics.MASK_CITY); // *** Refactor : should have it already
//Link the tree of life with the new zone
treeObject.setObjectTypeMask(MBServerStatics.MASK_BUILDING);
treeObject.setParentZone(zoneObject);
MaintenanceManager.setMaintDateTime(treeObject, LocalDateTime.now().plusDays(7));
// Update guild binds and tags // Update guild binds and tags
//load the new city on the clients
CityZoneMsg czm = new CityZoneMsg(1, treeObject.getLoc().x, treeObject.getLoc().y, treeObject.getLoc().z, cityObject.getCityName(), zoneObject, Enum.CityBoundsType.ZONE.extents, Enum.CityBoundsType.ZONE.extents);
DispatchMessage.dispatchMsgToAll(czm);
GuildManager.updateAllGuildBinds(playerNation, cityObject); GuildManager.updateAllGuildBinds(playerNation, cityObject);
GuildManager.updateAllGuildTags(playerNation); GuildManager.updateAllGuildTags(playerNation);
//load the new city on the clients
CityZoneMsg czm = new CityZoneMsg(1, treeObject.getLoc().x, treeObject.getLoc().y, treeObject.getLoc().z, cityObject.getCityName(), zoneObject, Enum.CityBoundsType.ZONE.halfExtents, Enum.CityBoundsType.ZONE.halfExtents);
DispatchMessage.dispatchMsgToAll(czm);
// Set maintenance date
MaintenanceManager.setMaintDateTime(treeObject, LocalDateTime.now().plusDays(7));
// Send all the cities to the clients? // Send all the cities to the clients?
// *** Refactor : figure out how to send like, one? // *** Refactor : figure out how to send like, one?
City.lastCityUpdate = System.currentTimeMillis(); City.lastCityUpdate = System.currentTimeMillis();
treeObject.setLoc(treeObject.getLoc()); treeObject.setLoc(treeObject.getLoc());
// As this is a new static object set it's dirtyFlag
// so players already near it will have the object loaded.
InterestManager.setObjectDirty(treeObject); InterestManager.setObjectDirty(treeObject);
// WorldGrid.addObject(treeObject, playerCharacter);
serverRealm.addCity(cityObject.getObjectUUID()); serverRealm.addCity(cityObject.getObjectUUID());
playerNation.setCityUUID(cityObject.getObjectUUID()); playerNation.setCityUUID(cityObject.getObjectUUID());
@@ -857,7 +841,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
if (serverZone == null) if (serverZone == null)
return false; return false;
cityObject = City.getCity(serverZone.getPlayerCityUUID()); cityObject = City.getCity(serverZone.playerCityUUID);
if (cityObject == null) if (cityObject == null)
return false; return false;
@@ -915,6 +899,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
// Early exit if something went horribly wrong // Early exit if something went horribly wrong
// with locating the current realm and/or zone // with locating the current realm and/or zone
if (serverZone == null) if (serverZone == null)
return false; return false;
@@ -930,7 +915,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
int shrineCount = 0; int shrineCount = 0;
cityObject = City.getCity(serverZone.getPlayerCityUUID()); cityObject = City.getCity(serverZone.playerCityUUID);
// Cannot place shrine in abandoned city. Shrines must be owned // Cannot place shrine in abandoned city. Shrines must be owned
// by the tol owner not the person placing them. // by the tol owner not the person placing them.
@@ -977,7 +962,8 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
City cityObject; City cityObject;
PlacementInfo buildingList; PlacementInfo buildingList;
// Setup working variables we'll need // Setup working variables
buildingList = msg.getFirstPlacementInfo(); buildingList = msg.getFirstPlacementInfo();
serverZone = ZoneManager.findSmallestZone(buildingList.getLoc()); serverZone = ZoneManager.findSmallestZone(buildingList.getLoc());
@@ -999,7 +985,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
int barracksCount = 0; int barracksCount = 0;
cityObject = City.getCity(serverZone.getPlayerCityUUID()); cityObject = City.getCity(serverZone.playerCityUUID);
// Cannot place barracks in abandoned city. // Cannot place barracks in abandoned city.
@@ -1059,7 +1045,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
if (validateCityBuildingPlacement(serverZone, msg, origin, player, msg.getFirstPlacementInfo()) == false) if (validateCityBuildingPlacement(serverZone, msg, origin, player, msg.getFirstPlacementInfo()) == false)
return false; return false;
cityObject = City.getCity(serverZone.getPlayerCityUUID()); cityObject = City.getCity(serverZone.playerCityUUID);
// We need to be able to access how much gold a character is carrying // We need to be able to access how much gold a character is carrying
@@ -1090,7 +1076,6 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
placementCost = 0; // reset placement cost for fix bug with wall pieces somethings not taking gold out if forced an error. placementCost = 0; // reset placement cost for fix bug with wall pieces somethings not taking gold out if forced an error.
// Overlap check and wall deed verifications // Overlap check and wall deed verifications
for (PlacementInfo wall : walls) { for (PlacementInfo wall : walls) {
@@ -1109,7 +1094,6 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
for (Building building : serverZone.zoneBuildingSet) { for (Building building : serverZone.zoneBuildingSet) {
//TODO Clean up collision with placementInfo. don't need to create the same placementinfo bounds for collision checks on each building. //TODO Clean up collision with placementInfo. don't need to create the same placementinfo bounds for collision checks on each building.
if ((building.getBlueprintUUID() != 0) && (Bounds.collide(wall, building) == true)) { if ((building.getBlueprintUUID() != 0) && (Bounds.collide(wall, building) == true)) {
@@ -1117,7 +1101,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
building.removeFromCache(); building.removeFromCache();
WorldGrid.RemoveWorldObject(building); WorldGrid.RemoveWorldObject(building);
WorldGrid.removeObject(building); WorldGrid.removeObject(building);
building.getParentZone().getParent().zoneBuildingSet.remove(building); building.getParentZone().parent.zoneBuildingSet.remove(building);
if (building.getBlueprint() != null && building.getBlueprint().getBuildingGroup().equals(BuildingGroup.BARRACK)) { if (building.getBlueprint() != null && building.getBlueprint().getBuildingGroup().equals(BuildingGroup.BARRACK)) {
building.RemoveFromBarracksList(); building.RemoveFromBarracksList();
} }
@@ -1129,12 +1113,14 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
return false; return false;
} }
} }
placementCost = PlaceAssetMsg.getWallCost(wall.getBlueprintUUID()); placementCost = PlaceAssetMsg.getWallCost(wall.getBlueprintUUID());
if (!itemMan.modifyInventoryGold(-placementCost)) { if (!itemMan.modifyInventoryGold(-placementCost)) {
ChatManager.chatSystemInfo(player, player.getFirstName() + " can't has free moneys! no for real.. Thor.. seriously... I didnt fix it because you getting laid isnt important enough for me."); ChatManager.chatSystemInfo(player, player.getFirstName() + " can't has free moneys! no for real.. Thor.. seriously... I didnt fix it because you getting laid isnt important enough for me.");
return false; return false;
} }
// Attempt to place wall piece // Attempt to place wall piece
wallPiece = createStructure(player, wall, serverZone); wallPiece = createStructure(player, wall, serverZone);
@@ -1145,14 +1131,12 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
} }
// walls are auto protected // walls are auto protected
wallPiece.setProtectionState(ProtectionState.PROTECTED); wallPiece.setProtectionState(ProtectionState.PROTECTED);
PlaceAssetMsg.sendPlaceAssetConfirmWall(origin, serverZone); PlaceAssetMsg.sendPlaceAssetConfirmWall(origin, serverZone);
} }
// Deduct gold from character's inventory
return true; return true;
} }
@@ -1172,6 +1156,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
} }
// All siege buildings build in 15 minutes // All siege buildings build in 15 minutes
if ((blueprint.getBuildingGroup().equals(BuildingGroup.SIEGETENT)) if ((blueprint.getBuildingGroup().equals(BuildingGroup.SIEGETENT))
|| (blueprint.getBuildingGroup().equals(BuildingGroup.BULWARK))) || (blueprint.getBuildingGroup().equals(BuildingGroup.BULWARK)))
completionDate = DateTime.now().plusMinutes(15); completionDate = DateTime.now().plusMinutes(15);
@@ -1191,6 +1176,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
completionDate, blueprint.getMeshForRank(0), vendorRotation, buildingRotation); completionDate, blueprint.getMeshForRank(0), vendorRotation, buildingRotation);
// Make sure we have a valid mesh // Make sure we have a valid mesh
if (newMesh == null) { if (newMesh == null) {
Logger.error("CreateStructure: DB returned null object."); Logger.error("CreateStructure: DB returned null object.");
return null; return null;
@@ -1227,7 +1213,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
shrineType = Shrine.getShrineTypeByBlueprintUUID(blueprint.getBlueprintUUID()); shrineType = Shrine.getShrineTypeByBlueprintUUID(blueprint.getBlueprintUUID());
city = City.getCity(currentZone.getPlayerCityUUID()); city = City.getCity(currentZone.playerCityUUID);
if (city == null) if (city == null)
return false; return false;
@@ -1292,7 +1278,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
return false; return false;
} }
city = City.getCity(currentZone.getPlayerCityUUID()); city = City.getCity(currentZone.playerCityUUID);
if (city == null) if (city == null)
return false; return false;
@@ -1362,15 +1348,16 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
newMesh = (Building) ago; newMesh = (Building) ago;
newMesh.setObjectTypeMask(MBServerStatics.MASK_BUILDING); newMesh.setObjectTypeMask(MBServerStatics.MASK_BUILDING);
MaintenanceManager.setMaintDateTime(newMesh, LocalDateTime.now().plusDays(7)); MaintenanceManager.setMaintDateTime(newMesh, LocalDateTime.now().plusDays(7));
// WorldGrid.addObject(newMesh, player);
newMesh.setLoc(newMesh.getLoc()); newMesh.setLoc(newMesh.getLoc());
InterestManager.setObjectDirty(newMesh); InterestManager.setObjectDirty(newMesh);
newMesh.runAfterLoad(); newMesh.runAfterLoad();
} else if (ago.getObjectType() == GameObjectType.Warehouse) { } else if (ago.getObjectType() == GameObjectType.Warehouse) {
Warehouse warehouse = (Warehouse) ago; Warehouse warehouse = (Warehouse) ago;
City city = City.getCity(currentZone.getPlayerCityUUID()); City city = City.getCity(currentZone.playerCityUUID);
if (city == null) if (city == null)
return true; return true;
city.setWarehouseBuildingID(newMesh.getObjectUUID()); city.setWarehouseBuildingID(newMesh.getObjectUUID());
Warehouse.warehouseByBuildingUUID.put(newMesh.getObjectUUID(), warehouse); Warehouse.warehouseByBuildingUUID.put(newMesh.getObjectUUID(), warehouse);
} }
@@ -44,11 +44,11 @@ public class RepairBuildingMsgHandler extends AbstractClientMsgHandler {
serverZone = ZoneManager.findSmallestZone(pc.getLoc()); serverZone = ZoneManager.findSmallestZone(pc.getLoc());
if (serverZone.getPlayerCityUUID() == 0 && targetBuilding.getBlueprint() != null && targetBuilding.getBlueprint().getBuildingGroup() != BuildingGroup.MINE) if (serverZone.playerCityUUID == 0 && targetBuilding.getBlueprint() != null && targetBuilding.getBlueprint().getBuildingGroup() != BuildingGroup.MINE)
return; return;
City city = City.GetCityFromCache(serverZone.getPlayerCityUUID()); City city = City.GetCityFromCache(serverZone.playerCityUUID);
if (city != null) { if (city != null) {
if (city.getBane() != null && city.protectionEnforced == false) if (city.getBane() != null && city.protectionEnforced == false)
@@ -110,7 +110,6 @@ public class RequestEnterWorldHandler extends AbstractClientMsgHandler {
player.stopMovement(player.getBindLoc()); player.stopMovement(player.getBindLoc());
player.setSafeMode(); player.setSafeMode();
player.updateLocation(); player.updateLocation();
player.setRegion(AbstractWorldObject.GetRegionByWorldObject(player));
} }
player.setTimeStamp("logout", 0); player.setTimeStamp("logout", 0);
+1 -1
View File
@@ -92,7 +92,7 @@ public class CityAssetMsg extends ClientNetMsg {
return; return;
} }
city = City.getCity(zone.getPlayerCityUUID()); city = City.getCity(zone.playerCityUUID);
if (city == null) { if (city == null) {
Logger.debug("Failed to load city data for Tree of life."); Logger.debug("Failed to load city data for Tree of life.");
@@ -117,8 +117,8 @@ public class GuildTreeStatusMsg extends ClientNetMsg {
city = null; city = null;
if (cityZone != null) if (cityZone != null)
if (cityZone.isPlayerCity()) if (cityZone.guild_zone)
city = City.GetCityFromCache(cityZone.getPlayerCityUUID()); city = City.GetCityFromCache(cityZone.playerCityUUID);
else if (this.treeOfLife != null && this.treeOfLife.getGuild() != null) else if (this.treeOfLife != null && this.treeOfLife.getGuild() != null)
city = this.treeOfLife.getGuild().getOwnedCity(); city = this.treeOfLife.getGuild().getOwnedCity();
@@ -299,8 +299,8 @@ public class ManageCityAssetsMsg extends ClientNetMsg {
Set<Building> buildings = ZoneManager.findSmallestZone(assetManager.getLoc()).zoneBuildingSet; Set<Building> buildings = ZoneManager.findSmallestZone(assetManager.getLoc()).zoneBuildingSet;
Building tol = null; Building tol = null;
if (playerZone.getPlayerCityUUID() != 0) if (playerZone.playerCityUUID != 0)
city = City.GetCityFromCache(playerZone.getPlayerCityUUID()); city = City.GetCityFromCache(playerZone.playerCityUUID);
if (city != null) if (city != null)
tol = city.getTOL(); tol = city.getTOL();
@@ -368,7 +368,7 @@ public class ManageCityAssetsMsg extends ClientNetMsg {
if (zone == null) if (zone == null)
return; return;
City banedCity = City.getCity(zone.getPlayerCityUUID()); City banedCity = City.getCity(zone.playerCityUUID);
if (banedCity == null) if (banedCity == null)
return; return;
@@ -479,7 +479,7 @@ public class ManageCityAssetsMsg extends ClientNetMsg {
if (zone == null) if (zone == null)
writer.putString("Forlord"); writer.putString("Forlord");
else else
writer.putString(zone.getName()); writer.putString(zone.zoneName);
writer.putString(building.getGuild().getName()); writer.putString(building.getGuild().getName());
@@ -621,9 +621,9 @@ public class ManageCityAssetsMsg extends ClientNetMsg {
} else { } else {
writer.putInt(1); //kos on/off? writer.putInt(1); //kos on/off?
writer.putInt(3); // was 3 writer.putInt(3); // was 3
if (zone.getPlayerCityUUID() != 0 && asset.assetIsProtected()) { if (zone.playerCityUUID != 0 && asset.assetIsProtected()) {
writer.putInt(GameObjectType.Building.ordinal()); writer.putInt(GameObjectType.Building.ordinal());
writer.putInt(City.getCity(zone.getPlayerCityUUID()).getTOL().getObjectUUID()); writer.putInt(City.getCity(zone.playerCityUUID).getTOL().getObjectUUID());
} else { } else {
writer.putInt(0); writer.putInt(0);
writer.putInt(0); writer.putInt(0);
@@ -727,9 +727,9 @@ public class ManageCityAssetsMsg extends ClientNetMsg {
if (!npcHire.isAlive()) { if (!npcHire.isAlive()) {
writer.put((byte) 1); // 1 SHOWs respawning writer.put((byte) 1); // 1 SHOWs respawning
int respawnRemaining = (int) (((Mob) npcHire).deathTime + ((Mob) npcHire).spawnTime * 1000 - System.currentTimeMillis()) / 1000; int respawnRemaining = (int) (((Mob) npcHire).deathTime + ((Mob) npcHire).spawnDelay * 1000 - System.currentTimeMillis()) / 1000;
writer.putInt(respawnRemaining); // Seconds in respawn remaining. writer.putInt(respawnRemaining); // Seconds in respawn remaining.
writer.putInt(((Mob) npcHire).spawnTime); // max seconds for respawn writer.putInt(((Mob) npcHire).spawnDelay); // max seconds for respawn
} else } else
writer.put((byte) 0); writer.put((byte) 0);
+24 -21
View File
@@ -27,7 +27,6 @@ import org.pmw.tinylog.Logger;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
@@ -96,7 +95,7 @@ public class ManageNPCMsg extends ClientNetMsg {
writer.putString("A weapon suited to laying siege"); writer.putString("A weapon suited to laying siege");
} }
private static void serializeGuardList(ByteBufferWriter writer, int minion) { private static void serializeGuardList(ByteBufferWriter writer, int minion, Mob captain) {
writer.putInt(1); writer.putInt(1);
@@ -106,7 +105,7 @@ public class ManageNPCMsg extends ClientNetMsg {
writer.putInt(minion); writer.putInt(minion);
writer.putInt(1); writer.putInt(1);
writer.putInt(minion); writer.putInt(minion);
writer.putInt(1); writer.putInt(captain.getRank());//minion rank
writer.put((byte) 0); writer.put((byte) 0);
writer.putInt(600); //roll time writer.putInt(600); //roll time
@@ -343,14 +342,17 @@ public class ManageNPCMsg extends ClientNetMsg {
writer.putInt(0); //runemaster list writer.putInt(0); //runemaster list
//artillery captain list //artillery captain list
ConcurrentHashMap<Mob, Integer> siegeMinions = npc.getSiegeMinionMap();
writer.putInt(1 + siegeMinions.size()); writer.putInt(1 + npc.minions.size());
serializeBulwarkList(writer, 1); //Trebuchet serializeBulwarkList(writer, 1); //Trebuchet
//serializeBulwarkList(writer, 2); //Ballista //serializeBulwarkList(writer, 2); //Ballista
if (siegeMinions != null && siegeMinions.size() > 0) if (npc.minions != null && npc.minions.size() > 0)
for (Integer minionUUID : npc.minions) {
Mob mob = Mob.getMob(minionUUID);
for (Mob mob : siegeMinions.keySet()) {
this.unknown83 = mob.getObjectUUID(); this.unknown83 = mob.getObjectUUID();
writer.putInt(2); writer.putInt(2);
writer.putInt(mob.getObjectType().ordinal()); writer.putInt(mob.getObjectType().ordinal());
@@ -362,14 +364,14 @@ public class ManageNPCMsg extends ClientNetMsg {
writer.putInt(1); writer.putInt(1);
long curTime = System.currentTimeMillis() / 1000; long curTime = System.currentTimeMillis() / 1000;
long upgradeTime = (mob.deathTime + (mob.spawnTime * 1000)) / 1000; long upgradeTime = (mob.deathTime + (mob.spawnDelay * 1000)) / 1000;
long timeLife = upgradeTime - curTime; long timeLife = upgradeTime - curTime;
if (upgradeTime * 1000 > System.currentTimeMillis()) { if (upgradeTime * 1000 > System.currentTimeMillis()) {
if (mob.npcOwner.isAlive()) { if (mob.guardCaptain.isAlive()) {
writer.put((byte) 0);//shows respawning timer writer.put((byte) 0);//shows respawning timer
writer.putInt(mob.spawnTime); writer.putInt(mob.spawnDelay);
writer.putInt(mob.spawnTime); writer.putInt(mob.spawnDelay);
writer.putInt((int) timeLife); //time remaining for mob that is dead writer.putInt((int) timeLife); //time remaining for mob that is dead
writer.putInt(0); writer.putInt(0);
writer.put((byte) 0); writer.put((byte) 0);
@@ -557,7 +559,7 @@ public class ManageNPCMsg extends ClientNetMsg {
} else if (this.targetType == GameObjectType.Mob.ordinal()) { } else if (this.targetType == GameObjectType.Mob.ordinal()) {
mobA = Mob.getFromCacheDBID(this.targetID); mobA = Mob.getMob(this.targetID);
if (mobA == null) { if (mobA == null) {
Logger.error("Missing Mob of ID " + this.targetID); Logger.error("Missing Mob of ID " + this.targetID);
@@ -666,14 +668,15 @@ public class ManageNPCMsg extends ClientNetMsg {
writer.putInt(0); //runemaster list writer.putInt(0); //runemaster list
//artillery captain list //artillery captain list
ConcurrentHashMap<Mob, Integer> siegeMinions = mobA.getSiegeMinionMap();
writer.putInt(siegeMinions.size() + 1); writer.putInt(mobA.minions.size() + 1);
serializeGuardList(writer, mobA.getContract().getContractID()); //Guard
if (siegeMinions != null && siegeMinions.size() > 0) serializeGuardList(writer, mobA.getContract().getContractID(), mobA); //Guard
for (Mob mob : siegeMinions.keySet()) { if (mobA.minions != null && mobA.minions.size() > 0)
for (Integer minionUUID : mobA.minions) {
Mob mob = Mob.getMob(minionUUID);
this.unknown83 = mob.getObjectUUID(); this.unknown83 = mob.getObjectUUID();
writer.putInt(2); writer.putInt(2);
writer.putInt(mob.getObjectType().ordinal()); writer.putInt(mob.getObjectType().ordinal());
@@ -685,14 +688,14 @@ public class ManageNPCMsg extends ClientNetMsg {
writer.putInt(1); writer.putInt(1);
long curTime = System.currentTimeMillis() / 1000; long curTime = System.currentTimeMillis() / 1000;
long upgradeTime = (mob.deathTime + (mob.spawnTime * 1000)) / 1000; long upgradeTime = (mob.deathTime + (mob.spawnDelay * 1000)) / 1000;
long timeLife = upgradeTime - curTime; long timeLife = upgradeTime - curTime;
if (upgradeTime * 1000 > System.currentTimeMillis()) { if (upgradeTime * 1000 > System.currentTimeMillis()) {
if (mob.npcOwner.isAlive()) { if (mob.guardCaptain.isAlive()) {
writer.put((byte) 0);//shows respawning timer writer.put((byte) 0);//shows respawning timer
writer.putInt(mob.spawnTime); writer.putInt(mob.spawnDelay);
writer.putInt(mob.spawnTime); writer.putInt(mob.spawnDelay);
writer.putInt((int) timeLife); //time remaining for mob that is dead writer.putInt((int) timeLife); //time remaining for mob that is dead
writer.putInt(0); writer.putInt(0);
writer.put((byte) 0); writer.put((byte) 0);
+56 -55
View File
@@ -10,6 +10,7 @@
package engine.net.client.msg; package engine.net.client.msg;
import engine.Enum.GameObjectType; import engine.Enum.GameObjectType;
import engine.gameManager.BuildingManager;
import engine.gameManager.ZoneManager; import engine.gameManager.ZoneManager;
import engine.math.Vector3fImmutable; import engine.math.Vector3fImmutable;
import engine.net.AbstractConnection; import engine.net.AbstractConnection;
@@ -21,19 +22,19 @@ import engine.objects.Building;
public class MoveToPointMsg extends ClientNetMsg { public class MoveToPointMsg extends ClientNetMsg {
private int sourceType; private int sourceType; //ordinal of the character type that sent this message 54=PlayerCharacter
private int sourceID; private int sourceID; // uuid of the source character of this message
private float startLat; private float startLat; //start loc of move message (offset if inside a building not world loc)
private float startLon; private float startLon; //start loc of move message (offset if inside a building not world loc)
private float startAlt; private float startAlt; //start loc of move message (offset if inside a building not world loc)
private float endLat; private float endLat; //end loc of move message (offset if inside a building not world loc)
private float endLon; private float endLon; //end loc of move message (offset if inside a building not world loc)
private float endAlt; private float endAlt; //end loc of move message (offset if inside a building not world loc)
private int targetType; private int startLocType; // enum ordinal of the object player is inside 0=nothing 8=building
private int targetID; private int inBuildingUUID; // uuid of the building character is currently inside
private int inBuilding; // 0=true, -1=false 0/1/2 = floor you are on private int inBuilding; // is inside a building 0=true -1=false
private int unknown01; private int inBuildingFloor; // floor of building character is currently in -1=not inside building 0/1/2/3 = floor number
private byte unknown02; private byte initiatedByAttack; // move message sent as a result of move to target to attack 0=false 1=true
private byte unknown03; private byte unknown03;
/** /**
@@ -54,11 +55,11 @@ public class MoveToPointMsg extends ClientNetMsg {
this.endLat = msg.endLat; this.endLat = msg.endLat;
this.endLon = msg.endLon; this.endLon = msg.endLon;
this.endAlt = msg.endAlt; this.endAlt = msg.endAlt;
this.targetType = msg.targetType; this.startLocType = msg.startLocType;
this.targetID = msg.targetID; this.inBuildingUUID = msg.inBuildingUUID;
this.inBuilding = msg.inBuilding; this.inBuilding = msg.inBuilding;
this.unknown01 = msg.unknown01; this.inBuildingFloor = msg.inBuildingFloor;
this.unknown02 = msg.unknown02; this.initiatedByAttack = msg.initiatedByAttack;
this.unknown03 = msg.unknown03; this.unknown03 = msg.unknown03;
} }
@@ -73,11 +74,11 @@ public class MoveToPointMsg extends ClientNetMsg {
this.endLat = building.getLoc().x; this.endLat = building.getLoc().x;
this.endLon = building.getLoc().z; this.endLon = building.getLoc().z;
this.endAlt = building.getLoc().y; this.endAlt = building.getLoc().y;
this.targetType = 0; this.startLocType = 0;
this.targetID = 0; this.inBuildingUUID = 0;
this.inBuilding = -1; this.inBuilding = -1;
this.unknown01 = -1; this.inBuildingFloor = -1;
this.unknown02 = 0; this.initiatedByAttack = 0;
this.unknown03 = 0; this.unknown03 = 0;
} }
@@ -108,11 +109,11 @@ public class MoveToPointMsg extends ClientNetMsg {
writer.putFloat(this.endAlt); writer.putFloat(this.endAlt);
writer.putFloat(this.endLon); writer.putFloat(this.endLon);
writer.putInt(this.targetType); writer.putInt(this.startLocType);
writer.putInt(this.targetID); writer.putInt(this.inBuildingUUID);
writer.putInt(this.inBuilding); writer.putInt(this.inBuilding);
writer.putInt(this.unknown01); writer.putInt(this.inBuildingFloor);
writer.put((byte) 0); writer.put((byte) 0);
writer.put((byte) 0); writer.put((byte) 0);
@@ -135,13 +136,13 @@ public class MoveToPointMsg extends ClientNetMsg {
this.endAlt = reader.getFloat(); this.endAlt = reader.getFloat();
this.endLon = reader.getFloat(); this.endLon = reader.getFloat();
this.targetType = reader.getInt(); this.startLocType = reader.getInt();
this.targetID = reader.getInt(); this.inBuildingUUID = reader.getInt();
this.inBuilding = reader.getInt(); this.inBuilding = reader.getInt();
this.unknown01 = reader.getInt(); this.inBuildingFloor = reader.getInt();
this.unknown02 = reader.get(); this.initiatedByAttack = reader.get();
this.unknown03 = reader.get(); this.unknown03 = reader.get();
} }
@@ -209,20 +210,20 @@ public class MoveToPointMsg extends ClientNetMsg {
this.endAlt = value; this.endAlt = value;
} }
public int getTargetType() { public int getStartLocType() {
return this.targetType; return this.startLocType;
} }
public void setTargetType(int value) { public void setStartLocType(int value) {
this.targetType = value; this.startLocType = value;
} }
public int getTargetID() { public int getInBuildingUUID() {
return this.targetID; return this.inBuildingUUID;
} }
public void setTargetID(int value) { public void setInBuildingUUID(int value) {
this.targetID = value; this.inBuildingUUID = value;
} }
public int getInBuilding() { public int getInBuilding() {
@@ -233,12 +234,8 @@ public class MoveToPointMsg extends ClientNetMsg {
this.inBuilding = value; this.inBuilding = value;
} }
public int getUnknown01() { public void setInBuildingFloor(int value) {
return this.unknown01; this.inBuildingFloor = value;
}
public void setUnknown01(int value) {
this.unknown01 = value;
} }
public void setStartCoord(Vector3fImmutable value) { public void setStartCoord(Vector3fImmutable value) {
@@ -254,8 +251,8 @@ public class MoveToPointMsg extends ClientNetMsg {
} }
public void clearTarget() { public void clearTarget() {
this.targetType = 0; this.startLocType = 0;
this.targetID = 0; this.inBuildingUUID = 0;
} }
public void setPlayer(AbstractCharacter ac) { public void setPlayer(AbstractCharacter ac) {
@@ -263,10 +260,10 @@ public class MoveToPointMsg extends ClientNetMsg {
this.sourceID = ac.getObjectUUID(); this.sourceID = ac.getObjectUUID();
this.setStartCoord(ac.getLoc()); this.setStartCoord(ac.getLoc());
this.setEndCoord(ac.getEndLoc()); this.setEndCoord(ac.getEndLoc());
this.targetType = 0; this.startLocType = 0;
this.targetID = 0; this.inBuildingUUID = 0;
this.inBuilding = ac.getInBuilding(); this.inBuilding = ac.getInBuilding();
this.unknown01 = ac.getInFloorID(); this.inBuildingFloor = ac.getInFloorID();
} }
@@ -274,10 +271,10 @@ public class MoveToPointMsg extends ClientNetMsg {
if (target == null) { if (target == null) {
this.setStartCoord(ac.getLoc()); this.setStartCoord(ac.getLoc());
this.setEndCoord(ac.getEndLoc()); this.setEndCoord(ac.getEndLoc());
this.targetType = 0; this.startLocType = 0;
this.targetID = 0; this.inBuildingUUID = 0;
this.inBuilding = -1; this.inBuilding = -1;
this.unknown01 = -1; this.inBuildingFloor = -1;
} else { } else {
Vector3fImmutable convertLocStart = ZoneManager.convertWorldToLocal(target, ac.getLoc()); Vector3fImmutable convertLocStart = ZoneManager.convertWorldToLocal(target, ac.getLoc());
Vector3fImmutable convertLocEnd = convertLocStart; Vector3fImmutable convertLocEnd = convertLocStart;
@@ -286,10 +283,10 @@ public class MoveToPointMsg extends ClientNetMsg {
this.setStartCoord(convertLocStart); this.setStartCoord(convertLocStart);
this.setEndCoord(convertLocEnd); this.setEndCoord(convertLocEnd);
this.targetType = GameObjectType.Building.ordinal(); this.startLocType = GameObjectType.Building.ordinal();
this.targetID = target.getObjectUUID(); this.inBuildingUUID = target.getObjectUUID();
this.inBuilding = ac.getInBuilding(); this.inBuilding = ac.getInBuilding();
this.unknown01 = ac.getInFloorID(); this.inBuildingFloor = ac.getInFloorID();
} }
} }
@@ -298,7 +295,11 @@ public class MoveToPointMsg extends ClientNetMsg {
return unknown03; return unknown03;
} }
public int getUnknown02() { public int getInitiatedFromAttack() {
return unknown02; return initiatedByAttack;
}
public int getInBuildingFloor() {
return this.inBuildingFloor;
} }
} }
@@ -513,17 +513,17 @@ public class OpenFriendsCondemnListMsg extends ClientNetMsg {
writer.put((byte) 1); writer.put((byte) 1);
switch (condemned.getFriendType()) { switch (condemned.friendType) {
case 2: case 2:
PlayerCharacter playerCharacter = (PlayerCharacter) DbManager.getObject(engine.Enum.GameObjectType.PlayerCharacter, condemned.getPlayerUID()); PlayerCharacter playerCharacter = (PlayerCharacter) DbManager.getObject(engine.Enum.GameObjectType.PlayerCharacter, condemned.playerUID);
guild = playerCharacter.getGuild(); guild = playerCharacter.getGuild();
writer.putInt(GameObjectType.PlayerCharacter.ordinal()); writer.putInt(GameObjectType.PlayerCharacter.ordinal());
writer.putInt(condemned.getPlayerUID()); writer.putInt(condemned.playerUID);
writer.putInt(condemned.getFriendType()); writer.putInt(condemned.friendType);
writer.putInt(GameObjectType.PlayerCharacter.ordinal()); writer.putInt(GameObjectType.PlayerCharacter.ordinal());
writer.putInt(condemned.getPlayerUID()); writer.putInt(condemned.playerUID);
writer.putInt(0); writer.putInt(0);
writer.putInt(0); writer.putInt(0);
writer.putInt(GameObjectType.Guild.ordinal()); writer.putInt(GameObjectType.Guild.ordinal());
@@ -531,9 +531,9 @@ public class OpenFriendsCondemnListMsg extends ClientNetMsg {
writer.putInt(guild.getObjectUUID()); writer.putInt(guild.getObjectUUID());
else else
writer.putInt(0); writer.putInt(0);
writer.put(condemned.isActive() ? (byte) 1 : (byte) 0); writer.put(condemned.active ? (byte) 1 : (byte) 0);
writer.put((byte) 0); writer.put((byte) 0);
writer.put(condemned.isActive() ? (byte) 1 : (byte) 0); writer.put(condemned.active ? (byte) 1 : (byte) 0);
if (playerCharacter != null) if (playerCharacter != null)
writer.putString(playerCharacter.getFirstName()); writer.putString(playerCharacter.getFirstName());
@@ -547,16 +547,16 @@ public class OpenFriendsCondemnListMsg extends ClientNetMsg {
} }
break; break;
case 4: case 4:
guild = Guild.getGuild(condemned.getGuildUID()); guild = Guild.getGuild(condemned.guildUID);
writer.putInt(GameObjectType.Guild.ordinal()); writer.putInt(GameObjectType.Guild.ordinal());
writer.putInt(condemned.getGuildUID()); writer.putInt(condemned.guildUID);
writer.putInt(condemned.getFriendType()); writer.putInt(condemned.friendType);
writer.putLong(0); writer.putLong(0);
writer.putInt(GameObjectType.Guild.ordinal()); writer.putInt(GameObjectType.Guild.ordinal());
writer.putInt(condemned.getGuildUID()); writer.putInt(condemned.guildUID);
writer.putLong(0); writer.putLong(0);
writer.put((byte) 0); writer.put((byte) 0);
writer.put(condemned.isActive() ? (byte) 1 : (byte) 0); writer.put(condemned.active ? (byte) 1 : (byte) 0);
writer.put((byte) 0); writer.put((byte) 0);
if (guild != null) if (guild != null)
writer.putString(guild.getName()); writer.putString(guild.getName());
@@ -570,17 +570,17 @@ public class OpenFriendsCondemnListMsg extends ClientNetMsg {
GuildTag._serializeForDisplay(GuildTag.ERRANT, writer); GuildTag._serializeForDisplay(GuildTag.ERRANT, writer);
break; break;
case 5: case 5:
guild = Guild.getGuild(condemned.getGuildUID()); guild = Guild.getGuild(condemned.guildUID);
writer.putInt(GameObjectType.Guild.ordinal()); writer.putInt(GameObjectType.Guild.ordinal());
writer.putInt(condemned.getGuildUID()); writer.putInt(condemned.guildUID);
writer.putInt(condemned.getFriendType()); writer.putInt(condemned.friendType);
writer.putLong(0); writer.putLong(0);
writer.putLong(0); writer.putLong(0);
writer.putInt(GameObjectType.Guild.ordinal()); writer.putInt(GameObjectType.Guild.ordinal());
writer.putInt(condemned.getGuildUID()); writer.putInt(condemned.guildUID);
writer.put((byte) 0); writer.put((byte) 0);
writer.put((byte) 0); writer.put((byte) 0);
writer.put(condemned.isActive() ? (byte) 1 : (byte) 0); writer.put(condemned.active ? (byte) 1 : (byte) 0);
if (guild != null) if (guild != null)
writer.putString(guild.getName()); writer.putString(guild.getName());
else else
@@ -619,22 +619,22 @@ public class OpenFriendsCondemnListMsg extends ClientNetMsg {
writer.putInt(listSize); writer.putInt(listSize);
for (BuildingFriends friend : this.friends.values()) { for (BuildingFriends friend : this.friends.values()) {
pc = PlayerCharacter.getFromCache(friend.getPlayerUID()); pc = PlayerCharacter.getFromCache(friend.playerUID);
guild = Guild.getGuild(friend.getGuildUID()); guild = Guild.getGuild(friend.guildUID);
if (friend.getFriendType() == 7) { if (friend.friendType == 7) {
if (pc != null) if (pc != null)
name = pc.getCombinedName(); name = pc.getCombinedName();
} else if (guild != null) } else if (guild != null)
name = guild.getName(); name = guild.getName();
writer.put((byte) 1); writer.put((byte) 1);
if (friend.getFriendType() == 7) { if (friend.friendType == 7) {
writer.putInt(GameObjectType.PlayerCharacter.ordinal()); writer.putInt(GameObjectType.PlayerCharacter.ordinal());
writer.putInt(friend.getPlayerUID()); writer.putInt(friend.playerUID);
} else { } else {
writer.putInt(GameObjectType.Guild.ordinal()); writer.putInt(GameObjectType.Guild.ordinal());
writer.putInt(friend.getGuildUID()); writer.putInt(friend.guildUID);
} }
writer.putInt(friend.getFriendType()); writer.putInt(friend.friendType);
writer.putInt(0); writer.putInt(0);
writer.putInt(0); writer.putInt(0);
-151
View File
@@ -1,151 +0,0 @@
// ·. · · · · .
// · ·
// · ·
//
// · · ·
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
package engine.net.client.msg;
import engine.exception.SerializationException;
import engine.gameManager.BuildingManager;
import engine.gameManager.DbManager;
import engine.gameManager.ZoneManager;
import engine.net.AbstractConnection;
import engine.net.ByteBufferReader;
import engine.net.ByteBufferWriter;
import engine.net.client.Protocol;
import engine.objects.Building;
import engine.objects.Zone;
import org.pmw.tinylog.Logger;
import java.util.ArrayList;
public class SyncMessage extends ClientNetMsg {
private int type;
private int size;
private int pad = 0;
private int objectType;
private int objectUUID;
/**
* This constructor is used by NetMsgFactory. It attempts to deserialize the
* ByteBuffer into a message. If a BufferUnderflow occurs (based on reading
* past the limit) then this constructor Throws that Exception to the
* caller.
*/
public SyncMessage(AbstractConnection origin, ByteBufferReader reader) {
super(Protocol.CITYASSET, origin, reader);
}
public SyncMessage() {
super(Protocol.CITYASSET);
}
/**
* Deserializes the subclass specific items from the supplied NetMsgReader.
*/
@Override
protected void _deserialize(ByteBufferReader reader) {
//none yet
}
/**
* Serializes the subclass specific items to the supplied NetMsgWriter.
*/
@Override
protected void _serialize(ByteBufferWriter writer) throws SerializationException {
//lets do returns before writing so we don't send improper structures to the client
Building tol = BuildingManager.getBuilding(this.objectUUID);
if (tol == null) {
Logger.debug("TOL is null");
return;
}
Zone zone = ZoneManager.findSmallestZone(tol.getLoc());
if (zone == null) {
Logger.debug("Zone is null");
return;
}
ArrayList<Building> allCityAssets = DbManager.BuildingQueries.GET_ALL_BUILDINGS_FOR_ZONE(zone);
// *** Refactor: collection created but never used?
ArrayList<Building> canProtectAssets = new ArrayList<>();
for (Building b : allCityAssets) {
if (b.getBlueprintUUID() != 0)
canProtectAssets.add(b);
}
// *** Refactor : Not sure what this synch message does
// Get the feeling it should be looping over upgradable
// assets.
writer.putInt(0);
writer.putInt(0);
writer.putInt(this.objectType);
writer.putInt(this.objectUUID);
writer.putInt(allCityAssets.size());
for (Building b : allCityAssets) {
String name = b.getName();
// if (name.equals(""))
// name = b.getBuildingSet().getName();
writer.putInt(b.getObjectType().ordinal());
writer.putInt(b.getObjectUUID());
writer.putString(b.getName()); // Blueprint name?
writer.putString(b.getGuild().getName());
writer.putInt(20);// \/ Temp \/
writer.putInt(b.getRank());
writer.putInt(1); // symbol
writer.putInt(7); //TODO identify these Guild tags??
writer.putInt(17);
writer.putInt(14);
writer.putInt(14);
writer.putInt(98);// /\ Temp /\
}
}
public int getObjectType() {
return objectType;
}
public void setObjectType(int value) {
this.objectType = value;
}
public int getUUID() {
return objectUUID;
}
public int getPad() {
return pad;
}
public void setPad(int value) {
this.pad = value;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
}
@@ -73,7 +73,7 @@ public class ViewResourcesMessage extends ClientNetMsg {
if (this.warehouseBuilding.getParentZone() == null) if (this.warehouseBuilding.getParentZone() == null)
return false; return false;
this.city = (City) DbManager.getObject(Enum.GameObjectType.City, this.warehouseBuilding.getParentZone().getPlayerCityUUID()); this.city = (City) DbManager.getObject(Enum.GameObjectType.City, this.warehouseBuilding.getParentZone().playerCityUUID);
if (this.city == null) if (this.city == null)
return false; return false;
+6 -11
View File
@@ -10,8 +10,10 @@
package engine.net.client.msg; package engine.net.client.msg;
import engine.Enum;
import engine.exception.SerializationException; import engine.exception.SerializationException;
import engine.gameManager.ConfigManager; import engine.gameManager.ConfigManager;
import engine.gameManager.DbManager;
import engine.gameManager.ZoneManager; import engine.gameManager.ZoneManager;
import engine.net.AbstractConnection; import engine.net.AbstractConnection;
import engine.net.AbstractNetMsg; import engine.net.AbstractNetMsg;
@@ -44,14 +46,9 @@ public class WorldDataMsg extends ClientNetMsg {
super(Protocol.NEWWORLD, origin, reader); super(Protocol.NEWWORLD, origin, reader);
} }
private static int getTotalMapSize(Zone root) { private static int getTotalMapSize() {
if (root.getNodes().isEmpty())
return 0;
int size = root.getNodes().size(); return DbManager.getList(Enum.GameObjectType.Zone).size();
for (Zone child : root.getNodes())
size += getTotalMapSize(child);
return size;
} }
/** /**
@@ -73,7 +70,7 @@ public class WorldDataMsg extends ClientNetMsg {
// TODO replace this return with SerializationException // TODO replace this return with SerializationException
Zone root = ZoneManager.getSeaFloor(); Zone root = ZoneManager.seaFloor;
if (root == null) { if (root == null) {
Logger.error("Failed to find Sea Floor!"); Logger.error("Failed to find Sea Floor!");
return; return;
@@ -86,11 +83,10 @@ public class WorldDataMsg extends ClientNetMsg {
writer.putInt(WorldServer.worldMapID); writer.putInt(WorldServer.worldMapID);
writer.putInt(0x00000000); writer.putInt(0x00000000);
writer.putInt(getTotalMapSize(root) + 1); writer.putInt(getTotalMapSize());
Zone.serializeForClientMsg(root, writer); Zone.serializeForClientMsg(root, writer);
Zone hotzone = ZoneManager.hotZone; Zone hotzone = ZoneManager.hotZone;
;
if (hotzone == null) if (hotzone == null)
writer.putLong(0L); writer.putLong(0L);
@@ -99,7 +95,6 @@ public class WorldDataMsg extends ClientNetMsg {
writer.putInt(hotzone.getObjectUUID()); writer.putInt(hotzone.getObjectUUID());
} }
writer.putFloat(0); writer.putFloat(0);
writer.putFloat(1); writer.putFloat(1);
writer.putFloat(0); writer.putFloat(0);
+99 -61
View File
@@ -12,12 +12,10 @@ package engine.objects;
import engine.Enum; import engine.Enum;
import engine.Enum.*; import engine.Enum.*;
import engine.InterestManagement.InterestManager; import engine.InterestManagement.InterestManager;
import engine.InterestManagement.Terrain;
import engine.InterestManagement.WorldGrid; import engine.InterestManagement.WorldGrid;
import engine.exception.SerializationException; import engine.exception.SerializationException;
import engine.gameManager.CombatManager; import engine.gameManager.*;
import engine.gameManager.ConfigManager;
import engine.gameManager.MovementManager;
import engine.gameManager.PowersManager;
import engine.job.AbstractJob; import engine.job.AbstractJob;
import engine.job.JobContainer; import engine.job.JobContainer;
import engine.job.JobScheduler; import engine.job.JobScheduler;
@@ -29,6 +27,7 @@ import engine.math.Bounds;
import engine.math.Vector3fImmutable; import engine.math.Vector3fImmutable;
import engine.net.ByteBufferWriter; import engine.net.ByteBufferWriter;
import engine.net.DispatchMessage; import engine.net.DispatchMessage;
import engine.net.client.msg.ErrorPopupMsg;
import engine.net.client.msg.UpdateStateMsg; import engine.net.client.msg.UpdateStateMsg;
import engine.powers.EffectsBase; import engine.powers.EffectsBase;
import engine.server.MBServerStatics; import engine.server.MBServerStatics;
@@ -39,6 +38,7 @@ import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock;
@@ -52,8 +52,8 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
public int contractUUID; public int contractUUID;
public Contract contract; public Contract contract;
protected String firstName; public String firstName;
protected String lastName; public String lastName;
protected short statStrCurrent; protected short statStrCurrent;
protected short statDexCurrent; protected short statDexCurrent;
protected short statConCurrent; protected short statConCurrent;
@@ -71,7 +71,7 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
public Guild guild; public Guild guild;
protected byte runningTrains; protected byte runningTrains;
protected ConcurrentHashMap<Integer, CharacterPower> powers; protected ConcurrentHashMap<Integer, CharacterPower> powers;
protected ConcurrentHashMap<String, CharacterSkill> skills; public ConcurrentHashMap<String, CharacterSkill> skills;
// Variables NOT to be stored in db // Variables NOT to be stored in db
protected boolean sit = false; protected boolean sit = false;
protected boolean walkMode; protected boolean walkMode;
@@ -88,20 +88,20 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
protected AtomicFloat mana = new AtomicFloat(); protected AtomicFloat mana = new AtomicFloat();
protected float manaMax; // Health/Mana/Stamina protected float manaMax; // Health/Mana/Stamina
protected AtomicBoolean isAlive = new AtomicBoolean(true); protected AtomicBoolean isAlive = new AtomicBoolean(true);
protected Resists resists = new Resists("Genric"); public Resists resists = new Resists("Genric");
protected ConcurrentHashMap<String, JobContainer> timers; protected ConcurrentHashMap<String, JobContainer> timers;
protected ConcurrentHashMap<String, Long> timestamps; protected ConcurrentHashMap<String, Long> timestamps;
protected int atrHandOne; public int atrHandOne;
protected int atrHandTwo; public int atrHandTwo;
protected int minDamageHandOne; public int minDamageHandOne;
protected int maxDamageHandOne; public int maxDamageHandOne;
protected int minDamageHandTwo; public int minDamageHandTwo;
protected int maxDamageHandTwo; public int maxDamageHandTwo;
protected float rangeHandOne; public float rangeHandOne;
protected float rangeHandTwo; public float rangeHandTwo;
protected float speedHandOne; public float speedHandOne;
protected float speedHandTwo; public float speedHandTwo;
protected int defenseRating; public int defenseRating;
protected boolean isActive; // <-Do not use this for deleting character! protected boolean isActive; // <-Do not use this for deleting character!
protected float altitude = 0; // 0=on terrain, 1=tier 1, 2=tier 2, etc. protected float altitude = 0; // 0=on terrain, 1=tier 1, 2=tier 2, etc.
protected ConcurrentHashMap<Integer, JobContainer> recycleTimers; protected ConcurrentHashMap<Integer, JobContainer> recycleTimers;
@@ -117,16 +117,37 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
protected boolean movingUp = false; protected boolean movingUp = false;
private float desiredAltitude = 0; private float desiredAltitude = 0;
private long takeOffTime = 0; private long takeOffTime = 0;
private float hateValue = 0;
private long lastHateUpdate = 0; private long lastHateUpdate = 0;
private boolean collided = false;
private byte aoecntr = 0; private byte aoecntr = 0;
public int hidden = 0; // current rank of hide/sneak/invis
public CopyOnWriteArrayList<Integer> minions = new CopyOnWriteArrayList();
public ArrayList<CharacterRune> runes;
public AbstractCharacter() { public AbstractCharacter() {
super(); super();
this.firstName = "";
this.lastName = "";
this.powers = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW); this.statStrCurrent = (short) 0;
this.skills = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW); this.statDexCurrent = (short) 0;
this.statConCurrent = (short) 0;
this.statIntCurrent = (short) 0;
this.statSpiCurrent = (short) 0;
this.unusedStatPoints = (short) 0;
this.level = (short) 0; // TODO get this from MobsBase later
this.exp = 1;
this.walkMode = true;
this.bindLoc = Vector3fImmutable.ZERO;
this.faceDir = Vector3fImmutable.ZERO;
this.runningTrains = (byte) 0;
this.skills = new ConcurrentHashMap<>();
this.powers = new ConcurrentHashMap<>();
this.initializeCharacter(); this.initializeCharacter();
} }
@@ -214,8 +235,6 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
this.skills = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW); this.skills = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
this.initializeCharacter(); this.initializeCharacter();
// Dangerous to use THIS in a constructor!!!
this.charItemManager = new CharacterItemManager(this);
} }
/** /**
@@ -258,8 +277,6 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
this.powers = new ConcurrentHashMap<>(); this.powers = new ConcurrentHashMap<>();
this.initializeCharacter(); this.initializeCharacter();
// Dangerous to use THIS in a constructor!!!
this.charItemManager = new CharacterItemManager(this);
} }
/** /**
@@ -291,8 +308,6 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
this.powers = new ConcurrentHashMap<>(); this.powers = new ConcurrentHashMap<>();
initializeCharacter(); initializeCharacter();
// Dangerous to use THIS in a constructor!!!
this.charItemManager = new CharacterItemManager(this);
} }
/** /**
@@ -342,9 +357,6 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
this.powers = new ConcurrentHashMap<>(); this.powers = new ConcurrentHashMap<>();
this.initializeCharacter(); this.initializeCharacter();
// Dangerous to use THIS in a constructor!!!
this.charItemManager = new CharacterItemManager(this);
} }
public static int getBankCapacity() { public static int getBankCapacity() {
@@ -504,10 +516,9 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
} }
public static void teleport(AbstractCharacter worldObject, final Vector3fImmutable targetLoc) { public static void teleport(AbstractCharacter worldObject, final Vector3fImmutable targetLoc) {
Regions targetRegion = Regions.GetRegionForTeleport(targetLoc);
worldObject.locationLock.writeLock().lock(); worldObject.locationLock.writeLock().lock();
try { try {
MovementManager.translocate(worldObject, targetLoc, targetRegion); MovementManager.translocate(worldObject, targetLoc);
if (worldObject.getObjectType().equals(GameObjectType.PlayerCharacter)) if (worldObject.getObjectType().equals(GameObjectType.PlayerCharacter))
InterestManager.INTERESTMANAGER.HandleLoadForTeleport((PlayerCharacter) worldObject); InterestManager.INTERESTMANAGER.HandleLoadForTeleport((PlayerCharacter) worldObject);
} catch (Exception e) { } catch (Exception e) {
@@ -975,8 +986,38 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
@Override @Override
public final void setLoc(final Vector3fImmutable value) { public final void setLoc(final Vector3fImmutable value) {
super.setLoc(value); // set the location in the world
Building building = BuildingManager.getBuildingAtLocation(this.loc);
Regions region = null;
if(building != null) {
//look for region in the building we are in
for (Regions regionCycle : building.getBounds().getRegions()) {
float regionHeight = regionCycle.highLerp.y - regionCycle.lowLerp.y;
if(regionHeight < 10)
regionHeight = 10;
if (regionCycle.isPointInPolygon(value) && Math.abs(regionCycle.highLerp.y - value.y) < regionHeight)
region = regionCycle;
}
}
float regionHeightOffset = 0;
if(region != null){
this.region = region;
regionHeightOffset = region.lerpY(this);
this.inBuilding = region.level; // -1 not in building 0 on ground floor, 1 on first floor etc
this.inBuildingID = region.parentBuildingID;
this.inFloorID = region.room;
} else {
this.region = null;
this.inBuilding = -1;
this.inBuildingID = 0;
this.inFloorID = -1;
}
float terrainHeight = Terrain.getWorldHeight(value);
Vector3fImmutable finalLocation = new Vector3fImmutable(value.x,terrainHeight + regionHeightOffset, value.z);
super.setLoc(finalLocation); // set the location in the world
this.resetLastSetLocUpdate(); this.resetLastSetLocUpdate();
} }
public Vector3fImmutable getMovementLoc() { public Vector3fImmutable getMovementLoc() {
@@ -1096,6 +1137,7 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
} }
public final void setCombatTarget(final AbstractWorldObject value) { public final void setCombatTarget(final AbstractWorldObject value) {
if(this.getObjectTypeMask() == 2050) {//MOB? if(this.getObjectTypeMask() == 2050) {//MOB?
if (value == null) { if (value == null) {
if (this.isCombat()) { if (this.isCombat()) {
@@ -1113,7 +1155,9 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
} }
} }
} }
this.combatTarget = value; this.combatTarget = value;
} }
public final ConcurrentHashMap<String, JobContainer> getTimers() { public final ConcurrentHashMap<String, JobContainer> getTimers() {
@@ -1230,11 +1274,29 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
CombatManager.handleRetaliate(this, attacker); CombatManager.handleRetaliate(this, attacker);
} }
if(this.getObjectType().equals(GameObjectType.Mob)){
//handle hate value addition
Mob target = (Mob)this;
if (attacker.getObjectType().equals(GameObjectType.PlayerCharacter)) {
target.playerAgroMap.put(attacker.getObjectUUID(), target.playerAgroMap.get(attacker.getObjectUUID()) + value);
if (target.isPlayerGuard()){
if(target.guardedCity != null && target.guardedCity.cityOutlaws.contains(attacker.getObjectUUID()) == false)
target.guardedCity.cityOutlaws.add(attacker.getObjectUUID());
}
}
} else if(this.getObjectType().equals(GameObjectType.PlayerCharacter)){
City playerCity = ZoneManager.getCityAtLocation(this.loc);
if(playerCity != null){
if(!attacker.getGuild().getNation().equals(playerCity.getGuild().getNation()))
if(!playerCity.getGuild().getNation().getAllyList().contains(attacker.getGuild().getNation()))
if(!playerCity.cityOutlaws.contains(attacker.getObjectUUID()))
playerCity.cityOutlaws.add(attacker.getObjectUUID());
}
}
return newHealth - oldHealth; return newHealth - oldHealth;
} finally { } finally {
this.healthLock.writeLock().unlock(); this.healthLock.writeLock().unlock();
} }
} catch (InterruptedException e) { } catch (InterruptedException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
@@ -1420,10 +1482,9 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
} }
public void teleport(final Vector3fImmutable targetLoc) { public void teleport(final Vector3fImmutable targetLoc) {
Regions targetRegion = Regions.GetRegionForTeleport(targetLoc);
locationLock.writeLock().lock(); locationLock.writeLock().lock();
try { try {
MovementManager.translocate(this, targetLoc, targetRegion); MovementManager.translocate(this, targetLoc);
MovementManager.sendRWSSMsg(this); MovementManager.sendRWSSMsg(this);
} catch (Exception e) { } catch (Exception e) {
Logger.error(e); Logger.error(e);
@@ -1758,29 +1819,6 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
this.inBuildingID = inBuildingID; this.inBuildingID = inBuildingID;
} }
public float getHateValue() {
if (this.hateValue <= 0) {
this.hateValue = 0;
return hateValue;
}
if (this.lastHateUpdate == 0) {
this.lastHateUpdate = System.currentTimeMillis();
return this.hateValue;
}
long duration = System.currentTimeMillis() - this.lastHateUpdate;
//convert duration to seconds and multiply Hate Delimiter.
float modAmount = duration / 1000 * MBServerStatics.PLAYER_HATE_DELIMITER;
this.hateValue -= modAmount;
this.lastHateUpdate = System.currentTimeMillis();
return this.hateValue;
}
public void setHateValue(float hateValue) {
this.lastHateUpdate = System.currentTimeMillis();
this.hateValue = hateValue;
}
public int getInFloorID() { public int getInFloorID() {
return inFloorID; return inFloorID;
} }
@@ -9,6 +9,7 @@
package engine.objects; package engine.objects;
import ch.claude_martin.enumbitset.EnumBitSet;
import engine.Enum; import engine.Enum;
import engine.Enum.GameObjectType; import engine.Enum.GameObjectType;
import engine.Enum.ModType; import engine.Enum.ModType;
@@ -32,6 +33,19 @@ public abstract class AbstractIntelligenceAgent extends AbstractCharacter {
public boolean assist = false; public boolean assist = false;
public Enum.AIAgentType agentType = Enum.AIAgentType.MOBILE; public Enum.AIAgentType agentType = Enum.AIAgentType.MOBILE;
public AbstractCharacter guardCaptain;
public EnumBitSet<Enum.MonsterType> notEnemy = EnumBitSet.noneOf(Enum.MonsterType.class);
public EnumBitSet<Enum.MonsterType> enemy = EnumBitSet.noneOf(Enum.MonsterType.class);
;
public Enum.MobBehaviourType behaviourType;
public ArrayList<Vector3fImmutable> patrolPoints;
public int lastPatrolPointIndex = 0;
public long stopPatrolTime = 0;
public City guardedCity;
public AbstractIntelligenceAgent() {
super();
}
public AbstractIntelligenceAgent(ResultSet rs) throws SQLException { public AbstractIntelligenceAgent(ResultSet rs) throws SQLException {
super(rs); super(rs);
@@ -87,7 +101,8 @@ public abstract class AbstractIntelligenceAgent extends AbstractCharacter {
this.agentType = Enum.AIAgentType.CHARMED; this.agentType = Enum.AIAgentType.CHARMED;
if (this.getObjectType().equals(GameObjectType.Mob)) { if (this.getObjectType().equals(GameObjectType.Mob)) {
((Mob) this).setOwner(owner);
((Mob) this).guardCaptain = owner;
} }
} }
@@ -110,20 +125,12 @@ public abstract class AbstractIntelligenceAgent extends AbstractCharacter {
return 0; return 0;
} }
public PlayerCharacter getOwner() {
if (this.getObjectType().equals(GameObjectType.Mob))
return this.getOwner();
return null;
}
public boolean getSafeZone() { public boolean getSafeZone() {
ArrayList<Zone> allIn = ZoneManager.getAllZonesIn(this.getLoc()); ArrayList<Zone> allIn = ZoneManager.getAllZonesIn(this.getLoc());
for (Zone zone : allIn) for (Zone zone : allIn)
if (zone.getSafeZone() == (byte) 1) if (zone.peace_zone == (byte) 1)
return true; return true;
return false; return false;
@@ -156,9 +163,11 @@ public abstract class AbstractIntelligenceAgent extends AbstractCharacter {
this.setCombatTarget(null); this.setCombatTarget(null);
} }
//clear owner // clear owner and set not alive
PlayerCharacter owner = this.getOwner(); this.isAlive.set(false);
PlayerCharacter owner = (PlayerCharacter) this.guardCaptain;
//close pet window //close pet window
@@ -174,7 +183,7 @@ public abstract class AbstractIntelligenceAgent extends AbstractCharacter {
owner.setPet(null); owner.setPet(null);
if (this.getObjectType().equals(GameObjectType.Mob)) if (this.getObjectType().equals(GameObjectType.Mob))
((Mob) this).setOwner(null); this.guardCaptain = null;
} }
+11 -6
View File
@@ -13,7 +13,7 @@ import engine.Enum.DispatchChannel;
import engine.Enum.EffectSourceType; import engine.Enum.EffectSourceType;
import engine.Enum.GameObjectType; import engine.Enum.GameObjectType;
import engine.Enum.GridObjectType; import engine.Enum.GridObjectType;
import engine.InterestManagement.HeightMap; import engine.InterestManagement.Terrain;
import engine.InterestManagement.WorldGrid; import engine.InterestManagement.WorldGrid;
import engine.job.AbstractScheduleJob; import engine.job.AbstractScheduleJob;
import engine.job.JobContainer; import engine.job.JobContainer;
@@ -357,7 +357,9 @@ public abstract class AbstractWorldObject extends AbstractGameObject {
Mob mob = (Mob) this; Mob mob = (Mob) this;
if (mob.isSiege()) { if (mob.isSiege()) {
if (mob.isPet()) { if (mob.isPet()) {
PlayerCharacter petOwner = mob.getOwner();
PlayerCharacter petOwner = (PlayerCharacter) mob.guardCaptain;
if (petOwner != null && source.equals(EffectSourceType.Effect)) { if (petOwner != null && source.equals(EffectSourceType.Effect)) {
petOwner.dismissPet(); petOwner.dismissPet();
return; return;
@@ -500,7 +502,13 @@ public abstract class AbstractWorldObject extends AbstractGameObject {
return; return;
this.lastLoc = new Vector3fImmutable(this.loc); this.lastLoc = new Vector3fImmutable(this.loc);
this.loc = loc; this.loc = loc;
this.loc = this.loc.setY(HeightMap.getWorldHeight(this) + this.getAltitude());
if(this instanceof AbstractCharacter && this.region != null){
this.loc = this.loc.setY(this.region.lerpY(this) + this.getAltitude());
} else{
this.loc = this.loc.setY(Terrain.getWorldHeight(this.getLoc()) + this.getAltitude());
}
//lets not add mob to world grid if he is currently despawned. //lets not add mob to world grid if he is currently despawned.
if (this.getObjectType().equals(GameObjectType.Mob) && ((Mob) this).despawned) if (this.getObjectType().equals(GameObjectType.Mob) && ((Mob) this).despawned)
@@ -608,9 +616,6 @@ public abstract class AbstractWorldObject extends AbstractGameObject {
this.movingUp = movingUp; this.movingUp = movingUp;
} }
public void setRegion(Regions region) {
this.region = region;
}
//used for interestmanager loading and unloading objects to client. //used for interestmanager loading and unloading objects to client.
// if not in grid, unload from player. // if not in grid, unload from player.
+3 -4
View File
@@ -13,7 +13,6 @@ import engine.Enum;
import engine.Enum.ProtectionState; import engine.Enum.ProtectionState;
import engine.Enum.SiegePhase; import engine.Enum.SiegePhase;
import engine.Enum.SiegeResult; import engine.Enum.SiegeResult;
import engine.InterestManagement.HeightMap;
import engine.InterestManagement.WorldGrid; import engine.InterestManagement.WorldGrid;
import engine.db.archive.BaneRecord; import engine.db.archive.BaneRecord;
import engine.db.archive.DataWarehouse; import engine.db.archive.DataWarehouse;
@@ -135,7 +134,7 @@ public final class Bane {
// Cannot place banestone underwater; // Cannot place banestone underwater;
if (HeightMap.isLocUnderwater(player.getLoc())) { if (ZoneManager.isLocUnderwater(player.getLoc())) {
PlaceAssetMsg.sendPlaceAssetError(origin, 6, ""); // Cannot place underwater PlaceAssetMsg.sendPlaceAssetError(origin, 6, ""); // Cannot place underwater
return false; return false;
} }
@@ -163,8 +162,8 @@ public final class Bane {
// Cannot place assets on a dead tree // Cannot place assets on a dead tree
if ((cityZone.isPlayerCity()) && if ((cityZone.guild_zone) &&
(City.getCity(cityZone.getPlayerCityUUID()).getTOL().getRank() == -1)) { (City.getCity(cityZone.playerCityUUID).getTOL().getRank() == -1)) {
PlaceAssetMsg.sendPlaceAssetError(origin, 1, "Cannot bane a dead tree!"); PlaceAssetMsg.sendPlaceAssetError(origin, 1, "Cannot bane a dead tree!");
return false; return false;
} }
+124 -297
View File
@@ -9,11 +9,13 @@
package engine.objects; package engine.objects;
import engine.CollisionEngine.Triangle;
import engine.Enum; import engine.Enum;
import engine.Enum.*; import engine.Enum.*;
import engine.InterestManagement.HeightMap;
import engine.InterestManagement.RealmMap; import engine.InterestManagement.RealmMap;
import engine.InterestManagement.Terrain;
import engine.InterestManagement.WorldGrid; import engine.InterestManagement.WorldGrid;
import engine.CollisionEngine.Mesh;
import engine.db.archive.CityRecord; import engine.db.archive.CityRecord;
import engine.db.archive.DataWarehouse; import engine.db.archive.DataWarehouse;
import engine.db.archive.MineRecord; import engine.db.archive.MineRecord;
@@ -34,6 +36,7 @@ import engine.net.client.msg.UpdateObjectMsg;
import engine.server.MBServerStatics; import engine.server.MBServerStatics;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
import java.awt.geom.Rectangle2D;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.time.LocalDateTime; import java.time.LocalDateTime;
@@ -55,6 +58,7 @@ public class Building extends AbstractWorldObject {
private final HashMap<Integer, DoorCloseJob> doorJobs = new HashMap<>(); private final HashMap<Integer, DoorCloseJob> doorJobs = new HashMap<>();
public int meshUUID; public int meshUUID;
public Zone parentZone; public Zone parentZone;
public int parentZoneUUID;
public boolean reverseKOS; public boolean reverseKOS;
public int reserve = 0; public int reserve = 0;
public float statLat; public float statLat;
@@ -62,7 +66,6 @@ public class Building extends AbstractWorldObject {
public float statAlt; public float statAlt;
public LocalDateTime upgradeDateTime = null; public LocalDateTime upgradeDateTime = null;
public LocalDateTime taxDateTime = null; public LocalDateTime taxDateTime = null;
public ArrayList<Vector3fImmutable> patrolPoints = new ArrayList<>();
public ArrayList<Vector3fImmutable> sentryPoints = new ArrayList<>(); public ArrayList<Vector3fImmutable> sentryPoints = new ArrayList<>();
public TaxType taxType = TaxType.NONE; public TaxType taxType = TaxType.NONE;
public int taxAmount; public int taxAmount;
@@ -75,11 +78,14 @@ public class Building extends AbstractWorldObject {
public int level; public int level;
public AtomicBoolean isDeranking = new AtomicBoolean(false); public AtomicBoolean isDeranking = new AtomicBoolean(false);
public LocalDateTime maintDateTime; public LocalDateTime maintDateTime;
protected Resists resists;
/* The Blueprint class has methods able to derive /* The Blueprint class has methods able to derive
* all defining characteristics of this building, * all defining characteristics of this building,
*/ */
private int blueprintUUID = 0; public int blueprintUUID = 0;
public int rank;
public ArrayList<Vector3fImmutable> patrolPoints;
public ProtectionState protectionState = ProtectionState.NONE;
protected Resists resists;
private float w = 1.0f; private float w = 1.0f;
private Vector3f meshScale = new Vector3f(1.0f, 1.0f, 1.0f); private Vector3f meshScale = new Vector3f(1.0f, 1.0f, 1.0f);
private int doorState = 0; private int doorState = 0;
@@ -88,16 +94,17 @@ public class Building extends AbstractWorldObject {
private int maxGold; private int maxGold;
private int effectFlags = 0; private int effectFlags = 0;
private String name = ""; private String name = "";
private int rank;
private boolean ownerIsNPC = true; private boolean ownerIsNPC = true;
private boolean spireIsActive = false; private boolean spireIsActive = false;
private ConcurrentHashMap<String, JobContainer> timers = null; private ConcurrentHashMap<String, JobContainer> timers = null;
private ConcurrentHashMap<String, Long> timestamps = null; private ConcurrentHashMap<String, Long> timestamps = null;
private ConcurrentHashMap<Integer, BuildingFriends> friends = new ConcurrentHashMap<>(); private ConcurrentHashMap<Integer, BuildingFriends> friends;
private ConcurrentHashMap<Integer, Condemned> condemned = new ConcurrentHashMap<>(); private ConcurrentHashMap<Integer, Condemned> condemned;
private ProtectionState protectionState = ProtectionState.NONE;
private ArrayList<Building> children = null; private ArrayList<Building> children = null;
public ArrayList<Mesh> buildingMeshes;
public Rectangle2D.Float buildingRect;
/** /**
* ResultSet Constructor * ResultSet Constructor
*/ */
@@ -106,27 +113,23 @@ public class Building extends AbstractWorldObject {
super(rs); super(rs);
float scale; float scale;
Blueprint blueprint = null;
try { try {
this.meshUUID = rs.getInt("meshUUID"); this.meshUUID = rs.getInt("meshUUID");
this.setObjectTypeMask(MBServerStatics.MASK_BUILDING); this.setObjectTypeMask(MBServerStatics.MASK_BUILDING);
this.blueprintUUID = rs.getInt("blueprintUUID"); this.blueprintUUID = rs.getInt("blueprintUUID");
this.gridObjectType = GridObjectType.STATIC; this.gridObjectType = GridObjectType.STATIC;
this.parentZone = DbManager.ZoneQueries.GET_BY_UID(rs.getLong("parent")); this.parentZoneUUID = rs.getInt("parent");
this.name = rs.getString("name"); this.name = rs.getString("name");
this.ownerUUID = rs.getInt("ownerUUID"); this.ownerUUID = rs.getInt("ownerUUID");
// Orphaned Object Sanity Check
//This was causing ABANDONED Tols.
// if (objectType == DbObjectType.INVALID)
// this.ownerUUID = 0;
this.doorState = rs.getInt("doorState"); this.doorState = rs.getInt("doorState");
this.setHealth(rs.getInt("currentHP")); this.setHealth(rs.getInt("currentHP"));
this.w = rs.getFloat("w"); this.w = rs.getFloat("w");
this.setRot(new Vector3f(0f, rs.getFloat("rotY"), 0f)); this.setRot(new Vector3f(0f, rs.getFloat("rotY"), 0f));
this.reverseKOS = rs.getByte("reverseKOS") == 1 ? true : false; this.reverseKOS = rs.getByte("reverseKOS") == 1;
this.statLat = rs.getFloat("locationX");
this.statAlt = rs.getFloat("locationY");
this.statLon = rs.getFloat("locationZ");
scale = rs.getFloat("scale"); scale = rs.getFloat("scale");
this.meshScale = new Vector3f(scale, scale, scale); this.meshScale = new Vector3f(scale, scale, scale);
@@ -143,79 +146,10 @@ public class Building extends AbstractWorldObject {
this.level = rs.getInt("level"); this.level = rs.getInt("level");
this.isFurniture = (rs.getBoolean("isFurniture")); this.isFurniture = (rs.getBoolean("isFurniture"));
// Lookup building blueprint
if (this.blueprintUUID == 0)
blueprint = Blueprint._meshLookup.get(meshUUID);
else
blueprint = this.getBlueprint();
// Log error if something went horrible wrong
if ((this.blueprintUUID != 0) && (blueprint == null))
Logger.error("Invalid blueprint for object: " + this.getObjectUUID());
// Note: We handle R8 tree edge case for mesh and health
// after city is loaded to avoid recursive result set call
// in City resulting in a stack ovreflow.
if (blueprint != null) {
// Only switch mesh for player dropped structures
if (this.blueprintUUID != 0)
this.meshUUID = blueprint.getMeshForRank(rank);
this.healthMax = blueprint.getMaxHealth(this.rank);
// If this object has no blueprint but is a blueprint
// mesh then set it's current health to max health
if (this.blueprintUUID == 0)
this.setHealth(healthMax);
if (blueprint.getBuildingGroup().equals(BuildingGroup.BARRACK))
this.patrolPoints = DbManager.BuildingQueries.LOAD_PATROL_POINTS(this);
} else {
this.healthMax = 100000; // Structures with no blueprint mesh
this.setHealth(healthMax);
}
// Null out blueprint if not needed (npc building)
if (blueprintUUID == 0)
blueprint = null;
resists = new Resists("Building");
this.statLat = rs.getFloat("locationX");
this.statAlt = rs.getFloat("locationY");
this.statLon = rs.getFloat("locationZ");
if (this.parentZone != null) {
if (this.parentBuildingID != 0) {
Building parentBuilding = BuildingManager.getBuilding(this.parentBuildingID);
if (parentBuilding != null) {
this.setLoc(new Vector3fImmutable(this.statLat + this.parentZone.absX + parentBuilding.statLat, this.statAlt + this.parentZone.absY + parentBuilding.statAlt, this.statLon + this.parentZone.absZ + parentBuilding.statLon));
} else {
this.setLoc(new Vector3fImmutable(this.statLat + this.parentZone.absX, this.statAlt + this.parentZone.absY, this.statLon + this.parentZone.absZ));
}
} else {
// Altitude of this building is derived from the heightmap engine.
Vector3fImmutable tempLoc = new Vector3fImmutable(this.statLat + this.parentZone.absX, 0, this.statLon + this.parentZone.absZ);
tempLoc = new Vector3fImmutable(tempLoc.x, HeightMap.getWorldHeight(tempLoc), tempLoc.z);
this.setLoc(tempLoc);
}
}
this._strongboxValue = rs.getInt("currentGold"); this._strongboxValue = rs.getInt("currentGold");
this.maxGold = 15000000; // *** Refactor to blueprint method this.maxGold = 15000000; // *** Refactor to blueprint method
this.reserve = rs.getInt("reserve"); this.reserve = rs.getInt("reserve");
// Does building have a protection contract?
this.taxType = TaxType.valueOf(rs.getString("taxType")); this.taxType = TaxType.valueOf(rs.getString("taxType"));
this.taxAmount = rs.getInt("taxAmount"); this.taxAmount = rs.getInt("taxAmount");
this.protectionState = ProtectionState.valueOf(rs.getString("protectionState")); this.protectionState = ProtectionState.valueOf(rs.getString("protectionState"));
@@ -236,8 +170,7 @@ public class Building extends AbstractWorldObject {
this.upgradeDateTime = LocalDateTime.ofInstant(upgradeTimeStamp.toInstant(), ZoneId.systemDefault()); this.upgradeDateTime = LocalDateTime.ofInstant(upgradeTimeStamp.toInstant(), ZoneId.systemDefault());
} catch (Exception e) { } catch (Exception e) {
Logger.error("Failed for object " + this.blueprintUUID + ' ' + this.getObjectUUID() + e);
Logger.error("Failed for object " + this.blueprintUUID + ' ' + this.getObjectUUID() + e.toString());
} }
} }
@@ -350,86 +283,6 @@ public class Building extends AbstractWorldObject {
return rank; return rank;
} }
public final void setRank(int newRank) {
int newMeshUUID;
boolean success;
// If this building has no blueprint then set rank and exit immediatly.
if (this.blueprintUUID == 0 || this.getBlueprint() != null && this.getBlueprint().getBuildingGroup().equals(BuildingGroup.MINE)) {
this.rank = newRank;
DbManager.BuildingQueries.CHANGE_RANK(this.getObjectUUID(), newRank);
return;
}
// Delete any upgrade jobs before doing anything else. It won't quite work
// if in a few lines we happen to delete this building.
JobContainer jc = this.getTimers().get("UPGRADE");
if (jc != null) {
if (!JobScheduler.getInstance().cancelScheduledJob(jc))
Logger.error("failed to cancel existing upgrade job.");
}
// Attempt write to database, or delete the building
// if we are destroying it.
if (newRank == -1)
success = DbManager.BuildingQueries.DELETE_FROM_DATABASE(this);
else
success = DbManager.BuildingQueries.updateBuildingRank(this, newRank);
if (success == false) {
Logger.error("Error writing to database UUID: " + this.getObjectUUID());
return;
}
this.isDeranking.compareAndSet(false, true);
// Change the building's rank
this.rank = newRank;
// New rank means new mesh
newMeshUUID = this.getBlueprint().getMeshForRank(this.rank);
this.meshUUID = newMeshUUID;
// New rank mean new max hitpoints.
this.healthMax = this.getBlueprint().getMaxHealth(this.rank);
this.setCurrentHitPoints(this.healthMax);
if (this.getUpgradeDateTime() != null)
BuildingManager.setUpgradeDateTime(this, null, 0);
// If we destroyed this building make sure to turn off
// protection
if (this.rank == -1)
this.protectionState = ProtectionState.NONE;
if ((this.getBlueprint().getBuildingGroup() == BuildingGroup.TOL)
&& (this.rank == 8))
this.meshUUID = Realm.getRealmMesh(this.getCity());
;
// update object to clients
this.refresh(true);
if (this.getBounds() != null)
this.getBounds().setBounds(this);
// Cleanup hirelings resulting from rank change
BuildingManager.cleanupHirelings(this);
this.isDeranking.compareAndSet(true, false);
}
public final int getOwnerUUID() { public final int getOwnerUUID() {
return ownerUUID; return ownerUUID;
} }
@@ -446,24 +299,24 @@ public class Building extends AbstractWorldObject {
if (this.getBlueprint() != null && this.getBlueprint().isSiegeEquip() && this.protectionState.equals(ProtectionState.PROTECTED)) { if (this.getBlueprint() != null && this.getBlueprint().isSiegeEquip() && this.protectionState.equals(ProtectionState.PROTECTED)) {
if (this.getGuild() != null) { if (this.getGuild() != null) {
if (this.getGuild().getOwnedCity() != null) { if (this.getGuild().getOwnedCity() != null) {
if (this.getLoc().isInsideCircle(this.getGuild().getOwnedCity().getLoc(), CityBoundsType.ZONE.extents)) if (this.getLoc().isInsideCircle(this.getGuild().getOwnedCity().getLoc(), CityBoundsType.ZONE.halfExtents))
return this.getGuild().getOwnedCity(); return this.getGuild().getOwnedCity();
} else { } else {
Bane bane = Bane.getBaneByAttackerGuild(this.getGuild()); Bane bane = Bane.getBaneByAttackerGuild(this.getGuild());
if (bane != null) { if (bane != null) {
if (bane.getCity() != null) { if (bane.getCity() != null) {
if (this.getLoc().isInsideCircle(bane.getCity().getLoc(), CityBoundsType.ZONE.extents)) if (this.getLoc().isInsideCircle(bane.getCity().getLoc(), CityBoundsType.ZONE.halfExtents))
return bane.getCity(); return bane.getCity();
} }
} }
} }
} }
} }
if (this.parentZone.isPlayerCity() == false) if (this.parentZone.guild_zone == false)
return null; return null;
return City.getCity(this.parentZone.getPlayerCityUUID()); return City.getCity(this.parentZone.playerCityUUID);
} }
@@ -537,6 +390,18 @@ public class Building extends AbstractWorldObject {
if (value < 0) if (value < 0)
Mine.SendMineAttackMessage(this); Mine.SendMineAttackMessage(this);
City playerCity = ZoneManager.getCityAtLocation(this.loc);
if (playerCity != null) {
if (this.getGuild().getNation().equals(playerCity.getTOL().getGuild().getNation())) {
//friendly building has been attacked, add attacker to city outlaw list
if (!playerCity.cityOutlaws.contains(attacker.getObjectUUID()) && attacker.getObjectType().equals(GameObjectType.PlayerCharacter))
playerCity.cityOutlaws.add(attacker.getObjectUUID());
for (Mob guard : playerCity.getParent().zoneMobSet)
if (guard.combatTarget == null)
guard.setCombatTarget(attacker);
}
}
return newHealth - oldHealth; return newHealth - oldHealth;
@@ -589,7 +454,7 @@ public class Building extends AbstractWorldObject {
MineRecord mineRecord = MineRecord.borrow(mine, attacker, RecordEventType.DESTROY); MineRecord mineRecord = MineRecord.borrow(mine, attacker, RecordEventType.DESTROY);
DataWarehouse.pushToWarehouse(mineRecord); DataWarehouse.pushToWarehouse(mineRecord);
this.setRank(-1); BuildingManager.setRank(this, -1);
this.setCurrentHitPoints((float) 1); this.setCurrentHitPoints((float) 1);
this.healthMax = (float) 1; this.healthMax = (float) 1;
this.meshUUID = this.getBlueprint().getMeshForRank(this.rank); this.meshUUID = this.getBlueprint().getMeshForRank(this.rank);
@@ -612,9 +477,9 @@ public class Building extends AbstractWorldObject {
// Time to either derank or destroy the building. // Time to either derank or destroy the building.
if ((this.rank - 1) < 1) if ((this.rank - 1) < 1)
this.setRank(-1); BuildingManager.setRank(this, -1);
else else
this.setRank(this.rank - 1); BuildingManager.setRank(this, this.rank - 1);
} }
@@ -672,7 +537,7 @@ public class Building extends AbstractWorldObject {
if (spireBuilding != null) { if (spireBuilding != null) {
spireBuilding.disableSpire(true); spireBuilding.disableSpire(true);
spireBuilding.setRank(-1); BuildingManager.setRank(spireBuilding, -1);
} }
} }
@@ -683,7 +548,7 @@ public class Building extends AbstractWorldObject {
// Delete a random shrine // Delete a random shrine
if (shrineBuilding != null) if (shrineBuilding != null)
shrineBuilding.setRank(-1); BuildingManager.setRank(shrineBuilding, -1);
} }
if (barracksBuildings.size() > this.rank - 1) { if (barracksBuildings.size() > this.rank - 1) {
@@ -693,7 +558,7 @@ public class Building extends AbstractWorldObject {
// Delete a random barrack // Delete a random barrack
if (barracksBuilding != null) if (barracksBuilding != null)
barracksBuilding.setRank(-1); BuildingManager.setRank(barracksBuilding, -1);
} }
// If the tree is R8 and deranking, we need to update it's // If the tree is R8 and deranking, we need to update it's
@@ -722,7 +587,7 @@ public class Building extends AbstractWorldObject {
// Let's do so and early exit // Let's do so and early exit
if (this.rank > 1) { if (this.rank > 1) {
this.setRank(rank - 1); BuildingManager.setRank(this, rank - 1);
City.lastCityUpdate = System.currentTimeMillis(); City.lastCityUpdate = System.currentTimeMillis();
return; return;
} }
@@ -840,10 +705,6 @@ public class Building extends AbstractWorldObject {
return this.meshUUID; return this.meshUUID;
} }
public final void setMeshUUID(int value) {
this.meshUUID = value;
}
public final Resists getResists() { public final Resists getResists() {
return this.resists; return this.resists;
} }
@@ -930,13 +791,8 @@ public class Building extends AbstractWorldObject {
DispatchMessage.sendToAllInRange(this, applyBuildingEffectMsg); DispatchMessage.sendToAllInRange(this, applyBuildingEffectMsg);
} }
/*
* Utils
*/
public void removeEffectBit(int bit) { public void removeEffectBit(int bit) {
this.effectFlags &= (~bit); this.effectFlags &= (~bit);
} }
@Override @Override
@@ -953,26 +809,18 @@ public class Building extends AbstractWorldObject {
this.updateName(); this.updateName();
} }
/*
* Serializing
*/
public final AbstractCharacter getOwner() { public final AbstractCharacter getOwner() {
if (this.ownerUUID == 0) if (this.ownerUUID == 0)
return null; return null;
if (this.ownerIsNPC)
return NPC.getFromCache(this.ownerUUID);
return PlayerCharacter.getFromCache(this.ownerUUID); if (this.ownerIsNPC)
return NPC.getNPC(this.ownerUUID);
return PlayerCharacter.getPlayerCharacter(this.ownerUUID);
} }
/*
* Database
*/
public final String getOwnerName() { public final String getOwnerName() {
AbstractCharacter owner = this.getOwner(); AbstractCharacter owner = this.getOwner();
if (owner != null) if (owner != null)
@@ -1033,19 +881,6 @@ public class Building extends AbstractWorldObject {
} }
// *** Refactor: Can't we just use setRank() for this?
public final void rebuildMine() {
this.setRank(1);
this.meshUUID = this.getBlueprint().getMeshForRank(this.rank);
// New rank mean new max hitpoints.
this.healthMax = this.getBlueprint().getMaxHealth(this.rank);
this.setCurrentHitPoints(this.healthMax);
this.getBounds().setBounds(this);
}
public final void refreshGuild() { public final void refreshGuild() {
UpdateObjectMsg uom = new UpdateObjectMsg(this, 5); UpdateObjectMsg uom = new UpdateObjectMsg(this, 5);
@@ -1057,15 +892,78 @@ public class Building extends AbstractWorldObject {
return maxGold; return maxGold;
} }
//This returns if a player is allowed access to control the building
@Override @Override
public void runAfterLoad() { public void runAfterLoad() {
try { // Set Parent Zone
this.parentZone = ZoneManager.getZoneByUUID(this.parentZoneUUID);
this.parentZone.zoneBuildingSet.add(this); this.parentZone.zoneBuildingSet.add(this);
// Lookup building blueprint
Blueprint blueprint;
if (this.blueprintUUID == 0)
blueprint = Blueprint._meshLookup.get(meshUUID);
else
blueprint = this.getBlueprint();
// Log error if something went horrible wrong
if ((this.blueprintUUID != 0) && (blueprint == null))
Logger.error("Invalid blueprint for object: " + this.getObjectUUID());
// Note: We handle R8 tree edge case for mesh and health
// after city is loaded to avoid recursive result set call
// in City resulting in a stack ovreflow.
if (blueprint != null) {
// Only switch mesh for player dropped structures
if (this.blueprintUUID != 0)
this.meshUUID = blueprint.getMeshForRank(rank);
this.healthMax = blueprint.getMaxHealth(this.rank);
// If this object has no blueprint but is a blueprint
// mesh then set it's current health to max health
if (this.blueprintUUID == 0)
this.setHealth(healthMax);
this.patrolPoints = BuildingManager._buildingPatrolPoints.computeIfAbsent(this.getObjectUUID(), k -> new ArrayList<>());
if (this.patrolPoints == null)
Logger.error("Null patrol points");
} else {
this.healthMax = 100000; // Structures with no blueprint mesh
this.setHealth(healthMax);
}
resists = new Resists("Building");
if (this.parentZone != null) {
if (this.parentBuildingID != 0) {
Building parentBuilding = BuildingManager.getBuilding(this.parentBuildingID);
if (parentBuilding != null) {
this.setLoc(new Vector3fImmutable(this.statLat + this.parentZone.absX + parentBuilding.statLat, this.statAlt + this.parentZone.absY + parentBuilding.statAlt, this.statLon + this.parentZone.absZ + parentBuilding.statLon));
} else {
this.setLoc(new Vector3fImmutable(this.statLat + this.parentZone.absX, this.statAlt + this.parentZone.absY, this.statLon + this.parentZone.absZ));
}
} else {
// Altitude of this building is derived from the heightmap engine.
Vector3fImmutable tempLoc = new Vector3fImmutable(this.statLat + this.parentZone.absX, 0, this.statLon + this.parentZone.absZ);
tempLoc = new Vector3fImmutable(tempLoc.x, Terrain.getWorldHeight(tempLoc), tempLoc.z);
this.setLoc(tempLoc);
}
}
// Submit upgrade job if building is currently set to rank. // Submit upgrade job if building is currently set to rank.
try { try {
@@ -1076,52 +974,10 @@ public class Building extends AbstractWorldObject {
Logger.error("Failed to find Object Type for owner " + this.ownerUUID + " Location " + this.getLoc().toString()); Logger.error("Failed to find Object Type for owner " + this.ownerUUID + " Location " + this.getLoc().toString());
} }
try { // Reference friend and condemn lists from BuildingManager
DbManager.BuildingQueries.LOAD_ALL_FRIENDS_FOR_BUILDING(this);
DbManager.BuildingQueries.LOAD_ALL_CONDEMNED_FOR_BUILDING(this);
} catch (Exception e) {
Logger.error(this.getObjectUUID() + " failed to load friends/condemned." + e.getMessage());
}
//LOad Owners in Cache so we do not have to continuely look in the db for owner. this.friends = BuildingManager._buildingFriends.computeIfAbsent(this.getObjectUUID(), k -> new ConcurrentHashMap<>());
this.condemned = BuildingManager._buildingCondemned.computeIfAbsent(this.getObjectUUID(), k -> new ConcurrentHashMap<>());
if (this.ownerIsNPC) {
if (NPC.getNPC(this.ownerUUID) == null)
Logger.info("Building UID " + this.getObjectUUID() + " Failed to Load NPC Owner with ID " + this.ownerUUID + " Location " + this.getLoc().toString());
} else if (this.ownerUUID != 0) {
if (PlayerCharacter.getPlayerCharacter(this.ownerUUID) == null) {
Logger.info("Building UID " + this.getObjectUUID() + " Failed to Load Player Owner with ID " + this.ownerUUID + " Location " + this.getLoc().toString());
}
}
// Apply health bonus and special mesh for realm if applicable
if ((this.getCity() != null) && this.getCity().getTOL() != null && (this.getCity().getTOL().rank == 8)) {
// Update mesh accordingly
if (this.getBlueprint() != null && this.getBlueprint().getBuildingGroup() == BuildingGroup.TOL)
this.meshUUID = Realm.getRealmMesh(this.getCity());
// Apply realm capital health bonus.
// Do not apply bonus to banestones or TOL's. *** Refactor:
// Possibly only protected buildings? Needs some thought.
float missingHealth = 0;
if (this.health.get() != 0)
missingHealth = this.healthMax - this.health.get();
if ((this.getBlueprint() != null && this.getBlueprint().getBuildingGroup() != BuildingGroup.TOL)
&& (this.getBlueprint().getBuildingGroup() != BuildingGroup.BANESTONE)) {
this.healthMax += (this.healthMax * Realm.getRealmHealthMod(this.getCity()));
if (this.health.get() != 0)
this.health.set(this.healthMax - missingHealth);
if (this.health.get() > this.healthMax)
this.health.set(this.healthMax);
}
}
// Set bounds for this building // Set bounds for this building
@@ -1136,7 +992,7 @@ public class Building extends AbstractWorldObject {
this.children = new ArrayList<>(); this.children = new ArrayList<>();
if (this.parentBuildingID != 0) { if (this.parentBuildingID != 0) {
Building parent = BuildingManager.getBuildingFromCache(this.parentBuildingID); Building parent = BuildingManager.getBuilding(this.parentBuildingID);
if (parent != null) { if (parent != null) {
parent.children.add(this); parent.children.add(this);
@@ -1144,6 +1000,7 @@ public class Building extends AbstractWorldObject {
//add furniture to region cache. floor and level are reversed in database, //TODO Fix //add furniture to region cache. floor and level are reversed in database, //TODO Fix
Regions region = BuildingManager.GetRegion(parent, this.level, this.floor, this.getLoc().x, this.getLoc().z); Regions region = BuildingManager.GetRegion(parent, this.level, this.floor, this.getLoc().x, this.getLoc().z);
if (region != null) if (region != null)
Regions.FurnitureRegionMap.put(this.getObjectUUID(), region); Regions.FurnitureRegionMap.put(this.getObjectUUID(), region);
} }
@@ -1153,9 +1010,8 @@ public class Building extends AbstractWorldObject {
if (this.upgradeDateTime != null) if (this.upgradeDateTime != null)
BuildingManager.submitUpgradeJob(this); BuildingManager.submitUpgradeJob(this);
} catch (Exception e) { //BuildingManager.BakeBuildingMeshes(this);
e.printStackTrace(); BuildingManager.BakeBuildingColliders(this);
}
} }
public synchronized boolean setOwner(AbstractCharacter newOwner) { public synchronized boolean setOwner(AbstractCharacter newOwner) {
@@ -1181,7 +1037,6 @@ public class Building extends AbstractWorldObject {
this.ownerIsNPC = (newOwner.getObjectType() == GameObjectType.NPC); this.ownerIsNPC = (newOwner.getObjectType() == GameObjectType.NPC);
} }
// Set new guild for hirelings and refresh all clients // Set new guild for hirelings and refresh all clients
this.refreshGuild(); this.refreshGuild();
@@ -1301,7 +1156,7 @@ public class Building extends AbstractWorldObject {
} }
// Save to database ? // Save to database ?
if (updateRecord == true) if (updateRecord)
return DbManager.BuildingQueries.UPDATE_DOOR_LOCK(this.getObjectUUID(), this.doorState); return DbManager.BuildingQueries.UPDATE_DOOR_LOCK(this.getObjectUUID(), this.doorState);
else else
return true; return true;
@@ -1337,7 +1192,6 @@ public class Building extends AbstractWorldObject {
this.spireIsActive = true; this.spireIsActive = true;
this.updateEffects(); this.updateEffects();
} }
public final void disableSpire(boolean refreshEffect) { public final void disableSpire(boolean refreshEffect) {
@@ -1390,7 +1244,7 @@ public class Building extends AbstractWorldObject {
// Buildings on an npc citygrid are never vulnerable // Buildings on an npc citygrid are never vulnerable
if (this.getCity() != null) { if (this.getCity() != null) {
if (this.getCity().getParent().isNPCCity() == true) if (this.getCity().getParent().isNPCCity == true)
return false; return false;
} }
@@ -1546,10 +1400,7 @@ public class Building extends AbstractWorldObject {
public boolean assetIsProtected() { public boolean assetIsProtected() {
boolean outValue = false; boolean outValue = protectionState.equals(ProtectionState.PROTECTED);
if (protectionState.equals(ProtectionState.PROTECTED))
outValue = true;
if (protectionState.equals(ProtectionState.CONTRACT)) if (protectionState.equals(ProtectionState.CONTRACT))
outValue = true; outValue = true;
@@ -1626,18 +1477,10 @@ public class Building extends AbstractWorldObject {
return patrolPoints; return patrolPoints;
} }
public void setPatrolPoints(ArrayList<Vector3fImmutable> patrolPoints) {
this.patrolPoints = patrolPoints;
}
public ArrayList<Vector3fImmutable> getSentryPoints() { public ArrayList<Vector3fImmutable> getSentryPoints() {
return sentryPoints; return sentryPoints;
} }
public void setSentryPoints(ArrayList<Vector3fImmutable> sentryPoints) {
this.sentryPoints = sentryPoints;
}
public synchronized boolean addProtectionTax(Building building, PlayerCharacter pc, final TaxType taxType, int amount, boolean enforceKOS) { public synchronized boolean addProtectionTax(Building building, PlayerCharacter pc, final TaxType taxType, int amount, boolean enforceKOS) {
if (building == null) if (building == null)
return false; return false;
@@ -1662,14 +1505,6 @@ public class Building extends AbstractWorldObject {
} }
public synchronized boolean declineTaxOffer() {
return true;
}
public synchronized boolean acceptTaxOffer() {
return true;
}
public synchronized boolean acceptTaxes() { public synchronized boolean acceptTaxes() {
if (!DbManager.BuildingQueries.acceptTaxes(this)) if (!DbManager.BuildingQueries.acceptTaxes(this))
@@ -1694,14 +1529,6 @@ public class Building extends AbstractWorldObject {
return true; return true;
} }
public boolean isTaxed() {
if (this.taxType == TaxType.NONE)
return false;
if (this.taxAmount == 0)
return false;
return this.taxDateTime != null;
}
public void AddToBarracksList() { public void AddToBarracksList() {
City playerCity = ZoneManager.getCityAtLocation(this.loc); City playerCity = ZoneManager.getCityAtLocation(this.loc);
if (playerCity != null) { if (playerCity != null) {
+4 -16
View File
@@ -14,10 +14,10 @@ import java.sql.SQLException;
public class BuildingFriends { public class BuildingFriends {
private int playerUID; public int playerUID;
private int buildingUID; public int buildingUID;
private int guildUID; public int guildUID;
private int friendType; public int friendType;
/** /**
* ResultSet Constructor * ResultSet Constructor
@@ -38,16 +38,4 @@ public class BuildingFriends {
this.friendType = friendType; this.friendType = friendType;
} }
public int getPlayerUID() {
return playerUID;
}
public int getGuildUID() {
return guildUID;
}
public int getFriendType() {
return friendType;
}
} }
+33 -27
View File
@@ -223,7 +223,7 @@ public class CharacterSkill extends AbstractGameObject {
this.numTrains.set(0); this.numTrains.set(0);
this.ownerUID = pc.getObjectUUID(); this.ownerUID = pc.getObjectUUID();
calculateBaseAmount(); calculateBaseAmount();
calculateModifiedAmount(); calculateModifiedAmount(false);
this.skillType = CharacterSkills.GetCharacterSkillByToken(this.skillsBase.getToken()); this.skillType = CharacterSkills.GetCharacterSkillByToken(this.skillsBase.getToken());
} }
@@ -238,7 +238,7 @@ public class CharacterSkill extends AbstractGameObject {
this.ownerUID = pc.getObjectUUID(); this.ownerUID = pc.getObjectUUID();
this.trained = true; this.trained = true;
calculateBaseAmount(); calculateBaseAmount();
calculateModifiedAmount(); calculateModifiedAmount(false);
this.skillType = CharacterSkills.GetCharacterSkillByToken(this.skillsBase.getToken()); this.skillType = CharacterSkills.GetCharacterSkillByToken(this.skillsBase.getToken());
} }
@@ -254,7 +254,7 @@ public class CharacterSkill extends AbstractGameObject {
this.numTrains.set(rs.getShort("trains")); this.numTrains.set(rs.getShort("trains"));
this.ownerUID = pc.getObjectUUID(); this.ownerUID = pc.getObjectUUID();
calculateBaseAmount(); calculateBaseAmount();
calculateModifiedAmount(); calculateModifiedAmount(false);
this.skillType = CharacterSkills.GetCharacterSkillByToken(this.skillsBase.getToken()); this.skillType = CharacterSkills.GetCharacterSkillByToken(this.skillsBase.getToken());
} }
@@ -264,8 +264,9 @@ public class CharacterSkill extends AbstractGameObject {
this.numTrains.set(trains); this.numTrains.set(trains);
this.ownerUID = mob.getObjectUUID(); this.ownerUID = mob.getObjectUUID();
this.isMobOwner = true; this.isMobOwner = true;
calculateMobBaseAmount(); boolean isGuard = mob.agentType.equals(Enum.AIAgentType.GUARDCAPTAIN) || mob.agentType.equals(Enum.AIAgentType.GUARDMINION);
calculateModifiedAmount(); calculateMobBaseAmount(isGuard);
calculateModifiedAmount(isGuard);
this.skillType = CharacterSkills.GetCharacterSkillByToken(this.skillsBase.getToken()); this.skillType = CharacterSkills.GetCharacterSkillByToken(this.skillsBase.getToken());
} }
@@ -277,7 +278,7 @@ public class CharacterSkill extends AbstractGameObject {
this.ownerUID = rs.getInt("CharacterID"); this.ownerUID = rs.getInt("CharacterID");
// this.owner = DbManager.PlayerCharacterQueries.GET_PLAYER_CHARACTER(rs.getInt("CharacterID")); // this.owner = DbManager.PlayerCharacterQueries.GET_PLAYER_CHARACTER(rs.getInt("CharacterID"));
calculateBaseAmount(); calculateBaseAmount();
calculateModifiedAmount(); calculateModifiedAmount(false);
this.skillType = CharacterSkills.GetCharacterSkillByToken(this.skillsBase.getToken()); this.skillType = CharacterSkills.GetCharacterSkillByToken(this.skillsBase.getToken());
} }
@@ -370,7 +371,7 @@ public class CharacterSkill extends AbstractGameObject {
String name = it.next(); String name = it.next();
CharacterSkill cs = skills.get(name); CharacterSkill cs = skills.get(name);
if (cs != null) if (cs != null)
cs.calculateModifiedAmount(); cs.calculateModifiedAmount(false);
} }
@@ -756,7 +757,7 @@ public class CharacterSkill extends AbstractGameObject {
//recalculate this skill //recalculate this skill
calculateBaseAmount(); calculateBaseAmount();
calculateModifiedAmount(); calculateModifiedAmount(false);
//see if any new skills or powers granted //see if any new skills or powers granted
pc.calculateSkills(); pc.calculateSkills();
@@ -848,7 +849,7 @@ public class CharacterSkill extends AbstractGameObject {
if (recalculate) { if (recalculate) {
//recalculate this skill //recalculate this skill
calculateBaseAmount(); calculateBaseAmount();
calculateModifiedAmount(); calculateModifiedAmount(false);
//see if any skills or powers removed //see if any skills or powers removed
pc.calculateSkills(); pc.calculateSkills();
@@ -887,7 +888,7 @@ public class CharacterSkill extends AbstractGameObject {
if (recalculate) { if (recalculate) {
//recalculate this skill //recalculate this skill
calculateBaseAmount(); calculateBaseAmount();
calculateModifiedAmount(); calculateModifiedAmount(false);
//see if any skills or powers removed //see if any skills or powers removed
pc.calculateSkills(); pc.calculateSkills();
@@ -1016,7 +1017,8 @@ public class CharacterSkill extends AbstractGameObject {
this.modifiedAmountBeforeMods = Math.round(this.baseAmountBeforeMods + calculateAmountAfterTrains()); this.modifiedAmountBeforeMods = Math.round(this.baseAmountBeforeMods + calculateAmountAfterTrains());
} }
public void calculateMobBaseAmount() { public void calculateMobBaseAmount(boolean isGuard) {
if(!isGuard) {
if (CharacterSkill.GetOwner(this) == null) { if (CharacterSkill.GetOwner(this) == null) {
Logger.error("owner not found for owner uuid : " + this.ownerUID); Logger.error("owner not found for owner uuid : " + this.ownerUID);
this.baseAmount = 1; this.baseAmount = 1;
@@ -1030,19 +1032,19 @@ public class CharacterSkill extends AbstractGameObject {
this.modifiedAmount = 1; this.modifiedAmount = 1;
return; return;
} }
}
//Get any rune bonus //Get any rune bonus
float bonus = 0f; float bonus = 0f;
//TODO SKILLS RUNES //TODO SKILLS RUNES
if (CharacterSkill.GetOwner(this).getBonuses() != null) {
//Get bonuses from runes
bonus = CharacterSkill.GetOwner(this).getBonuses().getSkillBonus(this.skillsBase.sourceType);
}
//Get Base skill for unmodified stats
float base = 7f; float base = 7f;
float statMod = 0.5f; float statMod = 0.5f;
if (CharacterSkill.GetOwner(this) != null && CharacterSkill.GetOwner(this).getBonuses() != null) {
//Get bonuses from runes
bonus = CharacterSkill.GetOwner(this).getBonuses().getSkillBonus(this.skillsBase.sourceType);
//Get Base skill for unmodified stats
if (this.skillsBase.getStrMod() > 0) if (this.skillsBase.getStrMod() > 0)
statMod += (float) this.skillsBase.getStrMod() * (float) ((Mob) CharacterSkill.GetOwner(this)).getMobBase().getMobBaseStats().getBaseStr() / 100f; statMod += (float) this.skillsBase.getStrMod() * (float) ((Mob) CharacterSkill.GetOwner(this)).getMobBase().getMobBaseStats().getBaseStr() / 100f;
if (this.skillsBase.getDexMod() > 0) if (this.skillsBase.getDexMod() > 0)
@@ -1057,6 +1059,7 @@ public class CharacterSkill extends AbstractGameObject {
statMod = 1f; statMod = 1f;
else if (statMod > 600) else if (statMod > 600)
statMod = 600f; statMod = 600f;
}
base += CharacterSkill.baseSkillValues[(int) statMod]; base += CharacterSkill.baseSkillValues[(int) statMod];
if (base + bonus < 1f) if (base + bonus < 1f)
@@ -1066,25 +1069,27 @@ public class CharacterSkill extends AbstractGameObject {
this.modifiedAmountBeforeMods = (int) (this.baseAmountBeforeMods + calculateAmountAfterTrains()); this.modifiedAmountBeforeMods = (int) (this.baseAmountBeforeMods + calculateAmountAfterTrains());
} }
public void calculateModifiedAmount() { public void calculateModifiedAmount(boolean isGuard) {
if(!isGuard) {
if (CharacterSkill.GetOwner(this) == null || this.skillsBase == null) { if (CharacterSkill.GetOwner(this) == null || this.skillsBase == null) {
Logger.error("owner or SkillsBase not found for skill " + this.getObjectUUID()); Logger.error("owner or SkillsBase not found for skill " + this.getObjectUUID());
this.baseAmount = 1; this.baseAmount = 1;
this.modifiedAmount = 1; this.modifiedAmount = 1;
return; return;
} }
}
//Get any rune bonus //Get any rune bonus
float bonus = 0f; float bonus = 0f;
if (CharacterSkill.GetOwner(this).getBonuses() != null) { float base = 7f;
float statMod = 0.5f;
if (CharacterSkill.GetOwner(this) != null && CharacterSkill.GetOwner(this).getBonuses() != null) {
//Get bonuses from runes //Get bonuses from runes
bonus = CharacterSkill.GetOwner(this).getBonuses().getSkillBonus(this.skillsBase.sourceType); bonus = CharacterSkill.GetOwner(this).getBonuses().getSkillBonus(this.skillsBase.sourceType);
}
//Get Base skill for modified stats //Get Base skill for modified stats
//TODO this fomula needs verified //TODO this fomula needs verified
float base = 7f;
float statMod = 0.5f;
if (this.skillsBase.getStrMod() > 0) if (this.skillsBase.getStrMod() > 0)
statMod += (float) this.skillsBase.getStrMod() * (float) CharacterSkill.GetOwner(this).getStatStrCurrent() / 100f; statMod += (float) this.skillsBase.getStrMod() * (float) CharacterSkill.GetOwner(this).getStatStrCurrent() / 100f;
if (this.skillsBase.getDexMod() > 0) if (this.skillsBase.getDexMod() > 0)
@@ -1099,12 +1104,13 @@ public class CharacterSkill extends AbstractGameObject {
statMod = 1f; statMod = 1f;
else if (statMod > 600) else if (statMod > 600)
statMod = 600f; statMod = 600f;
}
base += CharacterSkill.baseSkillValues[(int) statMod]; base += CharacterSkill.baseSkillValues[(int) statMod];
SourceType sourceType = SourceType.GetSourceType(this.skillsBase.getNameNoSpace()); SourceType sourceType = SourceType.GetSourceType(this.skillsBase.getNameNoSpace());
//Get any rune, effect and item bonus //Get any rune, effect and item bonus
if (CharacterSkill.GetOwner(this).getBonuses() != null) { if (CharacterSkill.GetOwner(this) != null && CharacterSkill.GetOwner(this).getBonuses() != null) {
//add bonuses from effects/items and runes //add bonuses from effects/items and runes
base += bonus + CharacterSkill.GetOwner(this).getBonuses().getFloat(ModType.Skill, sourceType); base += bonus + CharacterSkill.GetOwner(this).getBonuses().getFloat(ModType.Skill, sourceType);
} }
@@ -1116,7 +1122,7 @@ public class CharacterSkill extends AbstractGameObject {
float modAmount = this.baseAmount + calculateAmountAfterTrains(); float modAmount = this.baseAmount + calculateAmountAfterTrains();
if (CharacterSkill.GetOwner(this).getBonuses() != null) { if (CharacterSkill.GetOwner(this) != null && CharacterSkill.GetOwner(this).getBonuses() != null) {
//Multiply any percent bonuses //Multiply any percent bonuses
modAmount *= (1 + CharacterSkill.GetOwner(this).getBonuses().getFloatPercentAll(ModType.Skill, sourceType)); modAmount *= (1 + CharacterSkill.GetOwner(this).getBonuses().getFloatPercentAll(ModType.Skill, sourceType));
} }

Some files were not shown because too many files have changed in this diff Show More