Compare commits

...

582 Commits

Author SHA1 Message Date
MagicBot a10c8c9aa5 Update sourcetype 2024-07-21 22:04:21 -04:00
MagicBot cdf3e4db8a Update sourcetype 2024-07-21 22:00:09 -04:00
MagicBot b53133655c Update sourcetype 2024-07-21 21:55:08 -04:00
FatBoy f07974f673 dual wield spam attack issue resolved 2024-07-21 19:46:06 -05:00
FatBoy 0d5cef1652 guilds that have sub guilds can no longer be invited to join nations 2024-07-21 19:36:17 -05:00
FatBoy 04203c092a Lowering stats below item requirement unequips and removes item from map correctly 2024-07-21 19:32:16 -05:00
FatBoy 78feee482b items can now be equipped when skill level exactly meets item requirement 2024-07-21 19:23:34 -05:00
FatBoy 8c35844e08 Huntress pet cannot attack players resolved 2024-07-21 19:16:57 -05:00
FatBoy 0fbb43e021 proc fix 2024-07-12 13:43:28 -04:00
MagicBot 145449f26d Bronzewood mine_production updated. 2024-06-29 14:33:19 -04:00
FatBoy feef6263b4 cleanup 2024-06-27 20:41:43 -05:00
FatBoy 6c622c377f blocked power type structuring 2024-06-27 20:19:11 -05:00
FatBoy 8943121336 blocked power type structuring 2024-06-27 19:54:29 -05:00
FatBoy 70cb469190 final cleanup 2024-06-26 20:44:46 -05:00
FatBoy a42f307a70 immunitiy check compiled to single location 2024-06-26 20:37:28 -05:00
FatBoy 2a3ae6eaec Immunities refresh 2024-06-26 20:24:05 -05:00
FatBoy 9e4b596aa1 enforce KOS for building works 2024-06-26 20:07:37 -05:00
FatBoy aa1fe792a3 Load enforceKOS for buildings 2024-06-26 19:57:50 -05:00
FatBoy 79919121a8 claiming an errant ToL gives ownership to the leader of the guild, not individual player 2024-06-26 19:44:23 -05:00
FatBoy 80ccfff635 Building Management compiled to a single method check 2024-06-26 19:27:32 -05:00
MagicBot 381139af35 Collection of resourceHash 2024-06-26 12:31:08 -04:00
MagicBot e79da63556 Method cleanup. 2024-06-24 03:18:59 -04:00
MagicBot 533565e37e UUID is in keyset 2024-06-24 03:09:38 -04:00
FatBoy da0510d2bc proccing system 2024-06-22 19:50:53 -05:00
FatBoy 1f732a8ca9 failed rune sno longer get consumed 2024-06-22 19:31:13 -05:00
FatBoy 0d24789a93 reverse KOS function completed 2024-06-22 19:22:13 -05:00
FatBoy 35427cfb4a reverse KOS function 2024-06-22 19:04:04 -05:00
MagicBot 695a78b1e2 Noob island filter at 20 2024-06-19 17:57:28 -04:00
MagicBot 9f6710ccb9 More logic work 2024-06-19 17:51:42 -04:00
MagicBot fff1e80f61 More logic work 2024-06-19 17:49:46 -04:00
MagicBot 141af19daa More logic work 2024-06-19 17:38:44 -04:00
MagicBot 630748541f More logic work 2024-06-19 17:36:09 -04:00
MagicBot d32818f351 Rearrange logic 2024-06-19 17:27:04 -04:00
MagicBot d6f94bd0e7 Merged methods 2024-06-19 17:10:49 -04:00
MagicBot db6a4e471d Lore rules added to method 2024-06-19 17:08:56 -04:00
MagicBot a24c611bac Lore rules added to method 2024-06-19 17:01:02 -04:00
MagicBot 3926160ab1 Unused method removed 2024-06-19 16:56:57 -04:00
MagicBot 4a7013de61 Signature update 2024-06-19 16:56:06 -04:00
MagicBot 56564f1c3b Cleanup of teleport list 2024-06-19 16:53:55 -04:00
MagicBot 8a3e39e97d Cleanup of cityChoice handler 2024-06-19 15:05:01 -04:00
MagicBot 5224c79441 Condemned uuid is key not value in map 2024-06-19 14:53:57 -04:00
MagicBot ede016a93d Never null 2024-06-19 14:43:31 -04:00
MagicBot cc1825dec9 Increase to handle larger banks. 2024-06-18 12:43:59 -04:00
MagicBot d257ce50cf Sanity check for null city. 2024-06-18 11:56:19 -04:00
MagicBot 5b246211e1 Warehouse record removed in destruction banes. 2024-06-18 11:51:11 -04:00
FatBoy 33c923b0de fixed immunities in powers manager 2024-06-13 20:47:28 -05:00
FatBoy 02d524663a fixed a lore issue in powers manager 2024-06-13 20:14:43 -05:00
MagicBot 5bd85addb7 Removed count when validating stack withdraw weight. 2024-06-13 15:42:54 -04:00
FatBoy 40bae67443 fixed mob damage defense and ATR 2024-06-12 19:35:20 -05:00
FatBoy 1cf1d731c4 added = to range checks and converted speed to float 2024-06-12 19:23:34 -05:00
MagicBot 24215e21c9 Sanity check for deleted vendors 2024-06-12 14:15:19 -04:00
MagicBot 3accd779b9 Sanity check for deleted vendors 2024-06-12 14:06:18 -04:00
MagicBot 1d673ca2e5 Sanity check for deleted vendors 2024-06-12 14:04:19 -04:00
MagicBot c935ea1986 Project reformat. 2024-06-11 13:40:42 -04:00
MagicBot 678ccafd3c Unused variable removed. 2024-06-11 13:23:49 -04:00
MagicBot 31292785a5 templateHash used in this context. 2024-06-11 13:09:40 -04:00
MagicBot cdc4717033 Update to resources message 2024-06-11 12:54:57 -04:00
MagicBot 35c8ac0289 Update to resources message 2024-06-11 12:53:07 -04:00
MagicBot f5cc4a3290 Update to resource type 2024-06-10 15:19:57 -04:00
FatBoy 74bd7ddb8b attack speed calculation handled correctly 2024-05-31 19:02:59 -05:00
FatBoy 4feb95131c early exit for pets attacking a null target 2024-05-31 18:34:27 -05:00
FatBoy d22ba7b89d early exit for pets attacking a null target 2024-05-31 18:32:53 -05:00
FatBoy 722fd14be5 character should now play swing animation everytime he tried to swing regardless of early exits 2024-05-31 18:29:59 -05:00
FatBoy 12e73d59c7 apply weapon powers before early exit for defense of passives 2024-05-31 18:26:36 -05:00
FatBoy 5c70f15064 check player agro map for key before tryign to assign to it 2024-05-31 18:23:34 -05:00
MagicBot 8ca641f353 Return 0 for null table entry. 2024-05-31 07:41:25 -04:00
FatBoy 0f9500a0d7 swing animation for miss 2024-05-29 18:39:24 -05:00
FatBoy 0d51afb737 pet damage adjustment 2024-05-28 19:28:41 -05:00
FatBoy 60e331de1a animation work 2024-05-28 19:12:00 -05:00
FatBoy 4a554b0d61 animation work 2024-05-28 19:09:46 -05:00
FatBoy 3f3d85fb36 animation work 2024-05-28 18:55:54 -05:00
MagicBot d2d655a839 Null check for vendor workorder lookup. 2024-05-28 18:31:16 -04:00
FatBoy 0096b8051c updated range chack and hitbox calculations 2024-05-27 19:59:35 -05:00
FatBoy 86102c8933 updated range chack and hitbox calculations 2024-05-27 19:50:52 -05:00
FatBoy f06e2c2e5c traveller open gate fix 2024-05-26 22:36:12 -05:00
FatBoy 74b425e567 casting fix for lore rulesets 2024-05-26 22:20:30 -05:00
FatBoy 22c8cdcf65 fixed pet attack and null weapon combat issue 2024-05-26 22:00:52 -05:00
FatBoy 7ed026f088 machine gun combat fixed 2024-05-26 21:49:36 -05:00
FatBoy 232c381e96 early exit for attack timer 2024-05-26 21:41:59 -05:00
FatBoy 69ea460d5e early exit for attack timer 2024-05-26 20:31:22 -05:00
FatBoy cbe9a30590 corrected convention for naming auto attack job 2024-05-26 20:17:15 -05:00
FatBoy 1bbbc396bd handle destory or derank for buildings 2024-05-22 20:49:33 -05:00
FatBoy 8601f9fcd5 special animation case for Siege Bow 2024-05-22 19:52:21 -05:00
FatBoy 7f029fd0e2 invalid range check for ranged characters attacking a building 2024-05-22 19:45:16 -05:00
FatBoy cc7188b404 invalid range check for ranged characters attacking a building 2024-05-22 19:40:25 -05:00
FatBoy aa0621bb02 bane live processing with vulnerable buildings 2024-05-22 19:27:44 -05:00
FatBoy b4ff1a3f7f swing animation lookup 2024-05-17 20:34:26 -05:00
FatBoy 9d6b1dcf60 swing animation lookup 2024-05-17 20:22:56 -05:00
FatBoy 6e123ecb86 swing animation lookup 2024-05-17 20:17:17 -05:00
FatBoy 2b8b9464af swing animation lookup 2024-05-17 20:09:46 -05:00
FatBoy cd8099b42f noob island guard aggro 2024-05-17 20:01:39 -05:00
FatBoy 2cdcba47a5 noob island guard aggro 2024-05-17 19:57:18 -05:00
FatBoy b7b4623c75 noob island guard aggro 2024-05-17 19:53:39 -05:00
FatBoy 2d958b929d noob island guard aggro 2024-05-17 19:50:44 -05:00
FatBoy e8f0e9f5de noob island guard aggro 2024-05-17 19:50:09 -05:00
FatBoy 03f0f3fcf0 noob island guard aggro 2024-05-17 19:41:26 -05:00
FatBoy 65db64d3df null spam fix for hamlet guards 2024-05-16 19:41:06 -05:00
FatBoy 5a25958aa5 cannot teleport od repledge to perdition or bastion 2024-05-14 19:35:37 -05:00
FatBoy 1f8c5495ab repledge work 2024-05-14 19:28:19 -05:00
FatBoy a54aa03ade can always teleport and repledge to your own nation 2024-05-14 19:22:31 -05:00
FatBoy e82445fcd2 teleport and repledge inside your own nation 2024-05-14 19:14:40 -05:00
FatBoy 9e9716fc88 Lore Teleport list and repledge list construction 2024-05-14 19:10:01 -05:00
FatBoy 4f01da368c Lore Guard AI Aggro 2024-05-14 18:49:30 -05:00
FatBoy 93c4103f61 Lore Mob AI Aggro 2024-05-14 18:42:38 -05:00
MagicBot f8180a7000 Removed custom exception candy 2024-05-12 13:42:11 -04:00
MagicBot 634f1478ce Removed custom exception candy 2024-05-12 13:36:47 -04:00
MagicBot 7335946c10 Removed 4 squigglies 2024-05-12 13:31:05 -04:00
MagicBot fb4eea67ed Comment cleanup 2024-05-12 13:18:51 -04:00
MagicBot 96ba17f67a DispatchManager is now an official manager singleton. 2024-05-12 13:14:42 -04:00
MagicBot ff17cacda7 magicvalue update 2024-05-12 12:54:11 -04:00
MagicBot 4d6ce2b155 Update to value in item rs constructor 2024-05-12 12:06:30 -04:00
MagicBot b2c9331899 Unused variables removed 2024-05-12 11:57:26 -04:00
MagicBot 1cb01b1cce Unused field removed 2024-05-12 11:55:12 -04:00
MagicBot e79fd0c3b4 Unused method removed 2024-05-12 11:46:28 -04:00
MagicBot 6dd1d97be5 Comment cleanup 2024-05-12 11:34:22 -04:00
MagicBot 805034e30b Comment cleanup 2024-05-12 11:32:00 -04:00
MagicBot 9646964698 TODO touchup 2024-05-12 11:31:25 -04:00
MagicBot 9ffaf96017 recalc magic value 2024-05-12 11:24:01 -04:00
MagicBot ce98f80b85 recalc magic value 2024-05-12 11:22:12 -04:00
MagicBot f683201086 recalc magic value 2024-05-12 11:18:22 -04:00
MagicBot 4796f7042d Bugfix in update_value 2024-05-12 11:09:45 -04:00
MagicBot 94ff3cf222 New rolling duration method moved to manager singleton. 2024-05-12 08:14:06 -04:00
MagicBot 174be35cac Comment cleanup 2024-05-12 07:17:31 -04:00
MagicBot ba266e506a Comment cleanup 2024-05-12 07:15:55 -04:00
MagicBot 4123157b92 Comment cleanup 2024-05-11 13:12:10 -04:00
MagicBot 7bb9aeacf7 Comment cleanup 2024-05-11 11:06:07 -04:00
MagicBot 1eda55a3f1 Serialization update 2024-05-11 11:01:49 -04:00
MagicBot f670e3143c Serialization update 2024-05-11 10:52:31 -04:00
MagicBot d55b57f7d0 Flag testing 2024-05-11 10:46:34 -04:00
MagicBot ea2f6f4593 Remove from dbManager cache 2024-05-11 09:37:23 -04:00
MagicBot b592f050c2 convention is == false 2024-05-11 09:33:54 -04:00
MagicBot 25f522c539 Make sure no memory leaks 2024-05-11 09:25:57 -04:00
MagicBot e89404abda json and string methods updated 2024-05-11 09:19:29 -04:00
MagicBot ad2cde9d85 Atomic instead of volatile to match counter 2024-05-11 09:16:48 -04:00
MagicBot ba94fabfb8 Atomic instead of volatile to match counter 2024-05-11 09:15:11 -04:00
MagicBot f7ab38e9a8 Comment updated 2024-05-11 09:02:54 -04:00
MagicBot 0d97fa614b Equals and hash overrides for workObject 2024-05-11 08:57:26 -04:00
MagicBot 6878916874 Update to workOrder cleanup 2024-05-11 08:51:41 -04:00
MagicBot c545468f26 Update to workOrder cleanup 2024-05-11 08:49:44 -04:00
MagicBot 7993fb22d2 Thread consistency for these 2024-05-11 08:33:34 -04:00
MagicBot 19bdb89c0f Unused variable removed 2024-05-11 08:30:32 -04:00
MagicBot 6b0b0cc357 Workorder set to completed when redeeding. 2024-05-11 08:07:04 -04:00
MagicBot bc1ae9a2c9 Minor cleanup 2024-05-11 08:02:19 -04:00
MagicBot 408e3a45ca Workorders cleared with hireling removal. 2024-05-11 07:51:56 -04:00
MagicBot 52e0b5be4d Minor cleanup 2024-05-11 07:31:09 -04:00
MagicBot 161335da26 Comment cleanup 2024-05-10 10:12:45 -04:00
MagicBot 7f1bc2a4b7 Update to workOrder loading. 2024-05-10 09:50:14 -04:00
MagicBot e37a4fab38 Update to workOrder loading. 2024-05-10 09:44:11 -04:00
MagicBot 2760a45d2f Early exit moved to run() 2024-05-10 09:39:43 -04:00
MagicBot 77673fde5f completed workOrders handling update 2024-05-10 09:34:58 -04:00
MagicBot 5fd4e5a088 Early exit for no avail slots 2024-05-09 14:50:47 -04:00
MagicBot b01b62ac3d Withdraw logic cleanup 2024-05-09 14:40:40 -04:00
MagicBot 7193ff7698 Withdraw logic cleanup 2024-05-09 14:12:55 -04:00
MagicBot dd72e20ff9 Withdraw logic cleanup 2024-05-09 14:04:19 -04:00
MagicBot f465ea4045 Withdraw logic cleanup 2024-05-09 11:32:26 -04:00
MagicBot 973dfc94f7 Withdraw logic cleanup 2024-05-09 11:31:12 -04:00
MagicBot a5255bcf11 Simplify total cost calc 2024-05-08 15:40:35 -04:00
MagicBot ec35228de9 Beardstyle bugfix 2024-05-08 13:31:47 -04:00
MagicBot 47a93f6545 sql parm count fix 2024-05-06 13:56:18 -04:00
MagicBot 0cff40070b Realm derived not stored 2024-05-06 13:33:28 -04:00
FatBoy 3f3fb53675 hamlet guard aggro 2024-05-05 19:45:46 -05:00
FatBoy b198dbcc09 Added ./setrace command 2024-05-04 21:39:35 -05:00
FatBoy 60b8843563 Added ./setrace command 2024-05-04 21:38:06 -05:00
MagicBot eff8be91d6 Comment cleanup 2024-05-04 13:38:38 -04:00
MagicBot 55e2d3fb5e Class cleanup 2024-05-04 13:33:33 -04:00
MagicBot a6f417d9cc Comment cleanup 2024-05-04 13:23:33 -04:00
MagicBot 7b1b09dc40 Comment cleanup 2024-05-04 13:20:26 -04:00
MagicBot 5724608005 Class cleanup 2024-05-04 13:18:34 -04:00
MagicBot f5d410f868 typo fixed contextually 2024-05-04 12:58:46 -04:00
MagicBot a5c1422534 unused variable removed 2024-05-04 12:55:51 -04:00
MagicBot 6df0e5625c Class cleanup. 2024-05-04 12:53:06 -04:00
MagicBot 5de932b095 Comment updated. 2024-05-04 12:41:45 -04:00
MagicBot db7d606b36 Devcmd removed. 2024-05-04 12:31:25 -04:00
FatBoy 30d302c43e Lore Guards use charter restrictions when aggroing 2024-04-30 21:45:28 -05:00
FatBoy 95cfc43956 debug option added in canJoin for charter type 2024-04-28 13:49:14 -05:00
FatBoy 7c8d78581e debug option added in canJoin for charter type 2024-04-28 13:46:35 -05:00
FatBoy 6f4a9f7d1a debug option added in canJoin for charter type 2024-04-28 13:44:35 -05:00
FatBoy 7a5569ab89 return guild charter type 2024-04-28 13:39:24 -05:00
FatBoy 042f7c675f cleanup dbEffectsResourceCostHandler 2024-04-28 13:28:53 -05:00
MagicBot 3c4d8239db Charter template id is stored not ordinal 2024-04-28 14:18:13 -04:00
MagicBot 4f20cc9aba Comment update. 2024-04-28 13:56:03 -04:00
MagicBot 34812694b7 Comparison fix 2024-04-28 13:49:21 -04:00
MagicBot 0bbbcbaa81 Removed squiggles 2024-04-28 13:44:35 -04:00
FatBoy 72172b9f05 GuildType lookup work 2024-04-28 12:40:53 -05:00
MagicBot 1876e09b48 method for populating lookup table 2024-04-28 13:34:45 -04:00
MagicBot 31c83f2bb5 upgraded protection for variables 2024-04-28 13:26:07 -04:00
MagicBot 065aa34652 Update to type constructor 2024-04-28 13:23:52 -04:00
FatBoy 8bbaae418d fix for player guild checks 2024-04-28 12:05:56 -05:00
FatBoy 10db850de4 replace == "LORE" with .equals("LORE") 2024-04-28 11:58:55 -05:00
FatBoy 753c3686ea Added MB Dev Notes 2024-04-28 11:44:28 -05:00
FatBoy f4bd928796 Lore check for telport and repledge 2024-04-28 11:34:03 -05:00
MagicBot 916a12a434 City realm id lookup not db load 2024-04-27 11:32:05 -04:00
MagicBot 3a8521683b Bootstrap logging info update 2024-04-27 09:32:25 -04:00
MagicBot df4d5a654f Comment cleanup 2024-04-27 08:58:28 -04:00
MagicBot 7fb5d7d23d Comment cleanup 2024-04-27 08:53:50 -04:00
MagicBot a7c9a15405 Comment cleanup 2024-04-27 08:47:04 -04:00
MagicBot b3b115e9ba Comment cleanup 2024-04-27 08:37:20 -04:00
MagicBot 1b5a64d8fc Minor cleanup 2024-04-27 08:17:43 -04:00
MagicBot 01f0e25e08 Minor cleanup 2024-04-27 08:17:17 -04:00
MagicBot 0782814c8e Update to junk handling 2024-04-27 08:14:31 -04:00
MagicBot 111ba02289 Merge remote-tracking branch 'refs/remotes/origin/feature-workorder2.8' into magicbox-1.5.2.1 2024-04-27 07:28:55 -04:00
MagicBot f09a7d4d12 Unused method removed 2024-04-27 07:27:03 -04:00
MagicBot e1e72b71bd Better name for context 2024-04-27 07:24:57 -04:00
MagicBot 4dce2e2aa2 Comment cleanup 2024-04-27 07:22:20 -04:00
MagicBot 743c897254 total_to_produce updated when slot removed from workOrder 2024-04-27 07:18:24 -04:00
MagicBot f134f71695 Squiggly removal 2024-04-27 07:07:59 -04:00
MagicBot 91016dd53c Cleanup in bane handling 2024-04-27 07:06:39 -04:00
FatBoy 39d04188b4 cleanup old rune handler in ObjectActionMsgHandler 2024-04-26 19:10:56 -05:00
FatBoy c99433c9bd missing case for type RUNE in ObjectActionMsgHandler 2024-04-26 19:07:33 -05:00
FatBoy 6cc94e076d promoting was attempting to use players promotion class (which is null) 2024-04-26 19:00:12 -05:00
MagicBot f294e48140 Null check added for city 2024-04-26 16:15:16 -04:00
MagicBot c25f325f87 Null check added for city 2024-04-26 16:15:07 -04:00
MagicBot ac0c11cb46 Comment cleanup 2024-04-26 15:56:04 -04:00
MagicBot 79e86e0a6f Comment cleanup 2024-04-26 15:43:45 -04:00
MagicBot 46f35f0b10 Minor update to keyset() usages 2024-04-26 15:37:37 -04:00
MagicBot 1b20201f8d MB Dev note added 2024-04-26 15:32:17 -04:00
MagicBot 0d744d900c MB Dev note added 2024-04-26 15:12:53 -04:00
MagicBot 9a8e0bd5c9 Comment cleanup 2024-04-26 15:10:49 -04:00
MagicBot 6b6be80fa8 Comment cleanup 2024-04-26 15:02:19 -04:00
MagicBot c2152432ce Comment cleanup 2024-04-26 15:00:03 -04:00
MagicBot 9348852e2c Comment cleanup 2024-04-26 14:57:02 -04:00
MagicBot 4b67f97ded MB Dev Notes added 2024-04-26 08:21:15 -04:00
MagicBot 2a9463be4e camelCase 2024-04-26 08:14:16 -04:00
MagicBot 67bc13dcde MB Dev Notes added to critical classes. 2024-04-26 08:09:07 -04:00
MagicBot 7d6407fbf5 comment cleanup 2024-04-25 20:26:13 -04:00
MagicBot 7b6f5f752b comment cleanup 2024-04-25 20:25:16 -04:00
MagicBot ef43211103 comment cleanup 2024-04-25 20:24:15 -04:00
MagicBot b312904548 comment cleanup 2024-04-25 20:22:55 -04:00
MagicBot 3b1db51a5e comment cleanup 2024-04-25 20:22:29 -04:00
MagicBot 17011de201 comment cleanup 2024-04-25 19:59:15 -04:00
MagicBot f03edf5c5d comment cleanup 2024-04-25 19:57:56 -04:00
MagicBot 320f06e1db comment cleanup 2024-04-25 10:08:27 -04:00
MagicBot 78480ca3dd comment cleanup 2024-04-25 10:06:55 -04:00
MagicBot 2e5f8701df comment cleanup 2024-04-25 10:04:58 -04:00
MagicBot 3a514dc771 comment cleanup 2024-04-25 10:03:37 -04:00
MagicBot c0b93ff809 comment cleanup 2024-04-25 09:51:34 -04:00
MagicBot 31037c9324 comment cleanup 2024-04-25 09:47:58 -04:00
MagicBot 2464deb3f3 comment cleanup 2024-04-25 09:41:02 -04:00
MagicBot dbf42bfbef json fix in constructor 2024-04-25 09:39:03 -04:00
MagicBot e80cdc192d Update to withdraw calc 2024-04-25 09:33:47 -04:00
MagicBot 9850b54981 Comment cleanup 2024-04-25 09:22:50 -04:00
MagicBot a3a30f3f8a Comment cleanup 2024-04-25 09:02:52 -04:00
MagicBot 4d0018b176 Comment cleanup 2024-04-25 08:51:33 -04:00
MagicBot a9dcac0ad7 Comment cleanup 2024-04-25 08:49:59 -04:00
MagicBot adaa521bf5 Comment cleanup 2024-04-25 08:49:13 -04:00
MagicBot 0fe04041f6 Workorder method moved to workorder 2024-04-25 08:42:20 -04:00
MagicBot 9dd2e1d5e5 Comment cleanup 2024-04-25 08:41:23 -04:00
MagicBot 81d6054982 Debit building first then warehouse 2024-04-25 07:44:19 -04:00
MagicBot ff2e381999 Update to validation order. 2024-04-24 13:47:25 -04:00
MagicBot e1d43ce0d0 Expand scope of try block. 2024-04-24 13:44:22 -04:00
MagicBot a906e30931 Setting containertype. 2024-04-24 13:36:32 -04:00
MagicBot 6a17f93e41 Setting containertype. 2024-04-24 13:13:48 -04:00
MagicBot 1edd4d681b Update to protection check. 2024-04-23 15:14:43 -04:00
MagicBot 911698a7e3 Method moved to WorkOrder 2024-04-23 15:11:56 -04:00
MagicBot 4fa646ce94 New costmap data implemented 2024-04-23 15:05:03 -04:00
MagicBot bcb40fecbb Loading effect costmap data at bootsrap 2024-04-23 14:56:30 -04:00
MagicBot 147b9a42c4 Costmap data generated; removed from bootstrap 2024-04-23 14:41:34 -04:00
MagicBot 81f86ceca9 Code written to refactor db call out of effect costs. 2024-04-23 14:36:01 -04:00
MagicBot e2dbc19adc Code written to refactor db call out of effect costs. 2024-04-23 14:31:08 -04:00
MagicBot d590511035 Code written to refactor db call out of effect costs. 2024-04-23 14:27:12 -04:00
MagicBot f48b9f10e1 Code written to refactor db call out of effect costs. 2024-04-23 14:25:19 -04:00
MagicBot 2607962038 Minor cleanup 2024-04-23 13:40:51 -04:00
MagicBot 4e05c2ab74 Warehouse debit work 2024-04-23 13:38:35 -04:00
MagicBot 6cbcef00aa Serialization update 2024-04-23 13:27:01 -04:00
MagicBot a76fd9f319 Update to identify assignment 2024-04-23 13:20:34 -04:00
MagicBot 8d7d3227cb Update to submit logging 2024-04-23 13:15:15 -04:00
MagicBot 9102fe1f6c Update to single item rolling config 2024-04-23 13:12:49 -04:00
MagicBot d999d00755 Rebuild of ./createitem 2024-04-23 12:42:12 -04:00
MagicBot a7e953ac20 Rebuild of ./createitem 2024-04-23 12:41:10 -04:00
MagicBot 46b4c110e5 Rebuild of ./createitem 2024-04-23 12:38:49 -04:00
MagicBot 30787f7ae2 Remnants of old garbage system removed 2024-04-23 12:25:26 -04:00
MagicBot 9de1afa0fd Comment update 2024-04-23 12:15:26 -04:00
MagicBot 9efba13b03 Simplified lambda function 2024-04-23 12:14:31 -04:00
MagicBot d7ac838b6d Simplified lambda function 2024-04-23 12:11:04 -04:00
MagicBot 50a169149f Resubmit unfinished workorders 2024-04-22 16:33:29 -04:00
MagicBot de65f6bcef Bugfix in pre/suf parsing 2024-04-22 16:28:02 -04:00
MagicBot 2adaff8f66 workOrderID added to output 2024-04-22 16:21:00 -04:00
MagicBot e8032f65d1 Loading workorders at bootstrap 2024-04-22 16:14:10 -04:00
MagicBot e710cf0930 Loading workorders at bootstrap 2024-04-22 16:12:26 -04:00
MagicBot 286a76b1de More workorder loading work 2024-04-22 16:07:25 -04:00
MagicBot 73e30062ea Method to load workorders on bootstrap 2024-04-22 16:02:22 -04:00
MagicBot 7300af9073 Method to load workorders on bootstrap 2024-04-22 15:49:57 -04:00
MagicBot 2a2b61bc0f Method to load workorders on bootstrap 2024-04-22 15:43:13 -04:00
MagicBot 89c3eb4d47 New workorder constructor 2024-04-22 15:34:57 -04:00
MagicBot c03f464043 More workorder db work 2024-04-22 15:12:46 -04:00
MagicBot 7b7492b5cc Workokrders updates as they cycle 2024-04-22 15:09:43 -04:00
MagicBot 684a5459b3 Worker saved upon submit 2024-04-22 15:02:15 -04:00
MagicBot bb5904552a Worker saved upon submit 2024-04-22 14:57:00 -04:00
MagicBot fb9d65b54d Method to save workorders to disk created 2024-04-22 14:55:46 -04:00
MagicBot a53848334f id is key not saved in json 2024-04-22 14:47:42 -04:00
MagicBot 19c6cd76a9 Warehouse updated for org.json 2024-04-22 13:43:22 -04:00
MagicBot d92b1c7473 Helpee and groupee parsing 2024-04-22 13:38:04 -04:00
MagicBot 07a5de2c57 Helpee and groupee parsing 2024-04-22 13:33:03 -04:00
MagicBot d0a837783e Update to sparsetype parsing 2024-04-22 13:23:18 -04:00
MagicBot 576f4af433 Update to sparsetype parsing 2024-04-22 13:18:41 -04:00
MagicBot 8ce81b144a Update to sparsetype parsing 2024-04-22 13:01:25 -04:00
MagicBot fcbb9b0cf1 Update to sparsetype parsing 2024-04-22 12:56:01 -04:00
MagicBot 4f115291eb No some are longs 2024-04-22 12:50:45 -04:00
MagicBot 79079e200a Bitvectors use int not long for mb 2024-04-22 12:48:03 -04:00
MagicBot dbab8f66da Migration to org.json 2024-04-22 12:42:52 -04:00
MagicBot 1d847d781b Migration to org.json 2024-04-22 12:34:57 -04:00
MagicBot 7604b7b07f Migration to org.json 2024-04-22 12:20:53 -04:00
MagicBot 8818282341 Migration to org.json 2024-04-22 11:49:41 -04:00
MagicBot 475ccaff0c Migration to org.json 2024-04-22 09:32:20 -04:00
MagicBot ba47b30673 Migration to org.json 2024-04-22 09:21:46 -04:00
MagicBot d557e30716 Workorder to json work 2024-04-22 08:57:02 -04:00
MagicBot 6499a16cc2 Workorder to json work 2024-04-22 08:53:33 -04:00
MagicBot a851d9a6ec Workorder to json work 2024-04-22 08:40:20 -04:00
MagicBot c09ae5d32f Workorder to json work 2024-04-22 08:35:58 -04:00
MagicBot 27d140f703 Junk or completion removes slot from workOrder 2024-04-22 08:28:43 -04:00
MagicBot 41aefa4a48 Comment cleanup 2024-04-22 08:20:02 -04:00
MagicBot 4723eb4bf2 Serialization update. 2024-04-22 07:56:25 -04:00
MagicBot 28c6953c3d Serialization update. 2024-04-22 07:54:03 -04:00
MagicBot 746a95e7d5 Overflow calc updated 2024-04-22 07:44:47 -04:00
MagicBot 0e7336b8c6 Concurrency update 2024-04-22 07:35:59 -04:00
MagicBot 11013bcd07 Reformat for easier debugging 2024-04-22 01:13:26 -04:00
MagicBot 63c7fb08e0 Concurrency update 2024-04-22 00:46:59 -04:00
MagicBot 6f39767fb4 Concurrency update 2024-04-22 00:37:49 -04:00
MagicBot 2de1f78f22 Slot tracking update 2024-04-22 00:25:16 -04:00
MagicBot 98b73d978a Slot tracking update 2024-04-22 00:19:29 -04:00
MagicBot 5a62361edd Slot tracking update 2024-04-22 00:10:32 -04:00
MagicBot 127f80054f Slot tracking update 2024-04-22 00:03:03 -04:00
FatBoy 41b1718df1 use delay for attacks for players 2024-04-21 13:19:50 -05:00
MagicBot d3b1cf9928 Comment update 2024-04-21 14:10:35 -04:00
MagicBot 7f8c297ae2 City check moved outside of validation 2024-04-21 14:08:27 -04:00
FatBoy 979cd70d65 update class type when promoting 2024-04-21 13:04:47 -05:00
FatBoy 35945f7542 equipping bug 2024-04-21 12:53:38 -05:00
FatBoy 84233ecdd6 use of proper animations 2024-04-21 12:43:23 -05:00
FatBoy 4d601f13a0 Merge remote-tracking branch 'origin/feature-workorder2.7' into feature-workorder2.7 2024-04-21 12:22:02 -05:00
FatBoy 1911de0757 random animation for weapon powers 2024-04-21 12:21:34 -05:00
MagicBot e00871324e Float fix 2024-04-21 13:21:00 -04:00
MagicBot 0286b63a8e Class reformat 2024-04-21 12:56:41 -04:00
FatBoy a84c712110 random animation for weapon powers 2024-04-21 11:52:47 -05:00
FatBoy 8e93e82526 random animation for weapon powers 2024-04-21 11:50:04 -05:00
FatBoy 67bf8c2b11 animation combat cleanup 2024-04-21 11:46:45 -05:00
FatBoy b8dbcb62db early exit for combat cycle 2024-04-21 11:21:40 -05:00
FatBoy bb5d257ae8 early exit for out of stam when attacking 2024-04-21 11:14:10 -05:00
MagicBot 2391bd6606 Unused method removed 2024-04-21 11:54:17 -04:00
MagicBot dc83bee227 File reformat 2024-04-21 11:40:27 -04:00
MagicBot 3ff7414fb4 Rework of item forge method collection usage 2024-04-21 11:39:59 -04:00
MagicBot 1e5790e6b9 Rework of item forge method collection usage 2024-04-21 08:23:58 -04:00
MagicBot 364fb40e0b junk, complete and produce wrapped with same lock as warehouse. 2024-04-20 16:52:24 -04:00
MagicBot 6a72a83076 Must be in a building and in city 2024-04-20 16:22:22 -04:00
MagicBot a83008ea4f Removed bypass in prep for db load. 2024-04-20 16:00:58 -04:00
MagicBot 89f672e0b0 json constructor for workOrders 2024-04-20 15:58:01 -04:00
MagicBot cc324777d1 Warehouse withdraws are persisted 2024-04-20 15:54:31 -04:00
MagicBot 692e7ec416 Comment cleanup 2024-04-20 13:35:04 -04:00
MagicBot 6cba850af5 Class cleanup and comment fixes 2024-04-20 13:26:44 -04:00
MagicBot f3e266cf46 Class cleanup 2024-04-20 13:21:53 -04:00
MagicBot ac347db0c8 debitWorkOrderCost method created 2024-04-20 13:05:19 -04:00
MagicBot 70e6756651 debitWorkOrderCost method created 2024-04-20 13:01:21 -04:00
MagicBot a46205b67b Uses mainline cache for virtual items 2024-04-20 12:45:05 -04:00
MagicBot 80aa413ea8 Methods moved to itemmanger 2024-04-20 12:37:55 -04:00
MagicBot 98d03620bc Persisting effects in complete item 2024-04-20 12:33:55 -04:00
MagicBot cca4521c93 Item prefix and suffix applied 2024-04-20 12:28:30 -04:00
MagicBot a859150a20 Item prefix and suffix applied 2024-04-20 12:17:37 -04:00
MagicBot d64bd193d8 Item prefix and suffix applied 2024-04-20 12:13:33 -04:00
MagicBot d0df406236 Item prefix and suffix applied 2024-04-20 11:53:53 -04:00
MagicBot 92c8430031 Item prefix and suffix applied 2024-04-20 11:13:31 -04:00
MagicBot 99671697ba Item prefix and suffix applied 2024-04-20 11:05:30 -04:00
MagicBot 171c79dcf6 Item prefix and suffix applied 2024-04-20 11:02:35 -04:00
MagicBot 726d471e95 Item prefix and suffix applied 2024-04-20 10:57:51 -04:00
MagicBot c0ed59f14f Item prefix and suffix applied 2024-04-20 10:43:39 -04:00
MagicBot c19c516669 Item prefix and suffix applied 2024-04-20 10:39:45 -04:00
MagicBot 589ea1bce8 Item prefix and suffix applied 2024-04-20 10:26:21 -04:00
MagicBot c133b2da5c Item prefix and suffix applied 2024-04-20 10:20:02 -04:00
MagicBot 24a05543c8 Item prefix and suffix applied 2024-04-20 10:11:56 -04:00
MagicBot 90271890d7 Item prefix and suffix applied 2024-04-20 09:59:04 -04:00
MagicBot 225dc2af18 Item prefix and suffix applied 2024-04-20 09:42:48 -04:00
MagicBot 501c68b1e3 Item prefix and suffix applied 2024-04-20 09:34:49 -04:00
MagicBot 13a75fcd5d Item prefix and suffix applied 2024-04-20 09:10:31 -04:00
MagicBot 2c87e48178 Work on adding modifiers 2024-04-20 08:55:04 -04:00
MagicBot ac10b78d68 Work on adding modifiers 2024-04-20 08:54:28 -04:00
MagicBot 4549688ad7 Update to modifier returned 2024-04-20 08:43:12 -04:00
MagicBot 0a6e40eb74 removed for testing 2024-04-19 10:55:07 -04:00
MagicBot b1b635380a Completed items are identified 2024-04-19 10:49:19 -04:00
MagicBot 7309fdc62f Method moved to Warehouse 2024-04-19 10:46:31 -04:00
MagicBot 412ef0f642 Do not remove until complete pressed 2024-04-19 10:45:28 -04:00
MagicBot 3071cb5847 Apply effects to item 2024-04-19 10:40:03 -04:00
MagicBot 1a7f63ce05 lastNegativeId moved to ItemManager 2024-04-19 10:32:36 -04:00
MagicBot c03c1f4057 Update to item effect serialization 2024-04-19 10:11:27 -04:00
MagicBot 264094924b Proper accounting for workOrder removal post completion 2024-04-19 09:50:29 -04:00
MagicBot 0ec2b436de Window refresh update 2024-04-19 09:38:01 -04:00
MagicBot f36239a67e Window refresh update 2024-04-19 09:30:59 -04:00
MagicBot b673ca9636 Window refresh update 2024-04-19 09:27:50 -04:00
MagicBot cba7ee4066 Window refresh update 2024-04-19 09:23:34 -04:00
MagicBot 0f2b46b898 Window refresh update 2024-04-19 09:20:01 -04:00
MagicBot d76b670b75 Window refresh update 2024-04-19 09:18:30 -04:00
MagicBot ca71079106 Window refresh update 2024-04-19 09:16:38 -04:00
MagicBot adf686974d Window refresh update 2024-04-19 09:16:01 -04:00
MagicBot 6ecaa4dc0c Window refresh update 2024-04-19 09:07:49 -04:00
MagicBot c1939075cd Window refresh update 2024-04-19 09:07:23 -04:00
MagicBot 18587e281f refactored out collection 2024-04-19 09:03:35 -04:00
MagicBot dbd4c5d246 Method added to replace collection 2024-04-19 08:59:10 -04:00
MagicBot 919b29c38f Deduct cost from warehouse 2024-04-19 08:15:17 -04:00
MagicBot 01113fc3a6 Configure before setting cost 2024-04-17 14:24:05 -04:00
MagicBot b9627e1643 Class cleanup 2024-04-17 14:15:12 -04:00
MagicBot e6d83ca36c Mobloot vestiges removed 2024-04-17 14:07:42 -04:00
MagicBot a522eeb823 Update to completion 2024-04-17 13:59:34 -04:00
MagicBot 8d1561cd29 Update to completion 2024-04-17 13:58:25 -04:00
MagicBot d7ba42f4da Update to batch completion 2024-04-17 13:48:39 -04:00
MagicBot 689fc142d0 Persisted items belong in vendor inventory not virtual ones. 2024-04-17 13:46:10 -04:00
MagicBot 8df0c838cc More completion work 2024-04-17 12:47:28 -04:00
MagicBot f9825900cc More completion work 2024-04-17 12:36:23 -04:00
MagicBot 1a27a54926 Not right place for this perhaps 2024-04-17 12:24:17 -04:00
MagicBot 1e003c28ab Completion work 2024-04-17 12:20:45 -04:00
MagicBot 8cada05424 Completion time reset before new batch 2024-04-17 12:04:41 -04:00
MagicBot dda98318eb Work on virtual item handling 2024-04-17 11:56:23 -04:00
MagicBot 6e95ae5245 Variable naming update 2024-04-16 16:01:17 -04:00
MagicBot a4a9a26ac4 Complete is complete 2024-04-16 15:53:13 -04:00
MagicBot 93aec63f78 File reformat 2024-04-16 15:40:10 -04:00
MagicBot 9804a0fc89 Debug strings were removed 2024-04-16 15:35:55 -04:00
MagicBot 3484802a24 Comment cleanup 2024-04-16 15:34:39 -04:00
MagicBot 946a150db1 Comment cleanup 2024-04-16 15:34:14 -04:00
MagicBot 197df90a21 Comment cleanup 2024-04-16 15:33:39 -04:00
MagicBot a944f7342a All rolls treated equally 2024-04-16 15:17:15 -04:00
MagicBot 7c855afbe7 All runs set to complete 2024-04-16 15:11:03 -04:00
MagicBot d42bc3520d Single runs are set to complete. Multiple item runs are dumped to inventory. 2024-04-16 15:03:59 -04:00
MagicBot a86d90ef41 serialization work 2024-04-16 14:55:03 -04:00
MagicBot c5dfb3ad81 Serialization work 2024-04-16 14:47:35 -04:00
MagicBot e879c588dc More window work. 2024-04-16 14:21:29 -04:00
MagicBot 862e75cd4c Serialization updated. Collection adds slot. 2024-04-16 14:01:46 -04:00
MagicBot d47643e730 Error logging added 2024-04-15 15:48:15 -04:00
MagicBot 0727361933 More window work 2024-04-15 15:29:13 -04:00
MagicBot c1b0bcedf4 Remove workorder when completed 2024-04-15 15:22:11 -04:00
MagicBot 315c2abfb9 Remove workorder when completed 2024-04-15 15:15:08 -04:00
MagicBot b0c0c507e5 More window work 2024-04-15 14:59:07 -04:00
MagicBot 12b6e41432 Fixing Junk functionality 2024-04-15 14:45:34 -04:00
MagicBot a2484f94eb Bugfix in forge contains 2024-04-15 14:33:33 -04:00
MagicBot b4824c69b8 Window work 2024-04-15 14:24:50 -04:00
MagicBot 03fb180f02 Set variable on submit 2024-04-15 12:49:37 -04:00
MagicBot 250afe3bba Serialization update 2024-04-15 12:41:05 -04:00
MagicBot b80b3a81b5 Message sent early 2024-04-15 12:34:35 -04:00
MagicBot cd8b910262 Clear collections last 2024-04-15 12:31:16 -04:00
MagicBot d007850afe Clear collections last 2024-04-15 12:23:46 -04:00
MagicBot 7f3873b63f fail fast on null 2024-04-15 12:23:01 -04:00
MagicBot 963df074a4 More persist work 2024-04-15 12:17:57 -04:00
MagicBot 5505d7bc61 Items are persisted and moved to vendor inventory 2024-04-15 12:12:40 -04:00
MagicBot 0c9ec31fa3 Window serialization work 2024-04-15 11:53:24 -04:00
MagicBot d71c65702d Window serialization work 2024-04-15 11:49:42 -04:00
MagicBot a4af39cab7 Window serialization work 2024-04-15 11:45:38 -04:00
MagicBot 9ba697c310 Persist item work 2024-04-15 11:30:56 -04:00
MagicBot 2b670ea53a Persist item work 2024-04-15 11:17:10 -04:00
MagicBot 5ade37f7a4 Persist item work 2024-04-15 11:15:34 -04:00
MagicBot 1be657d3ef Persist item work 2024-04-15 11:07:26 -04:00
MagicBot 9dbefcd830 Unused variable removed 2024-04-15 11:01:53 -04:00
MagicBot e1a9ddae89 forged items are persisted 2024-04-14 17:30:35 -04:00
MagicBot 2690c3212b forged items are persisted 2024-04-14 17:18:58 -04:00
MagicBot aac7e46ae8 forged items are persisted 2024-04-14 17:04:59 -04:00
MagicBot a16bef418b forged items are persisted 2024-04-14 17:02:36 -04:00
MagicBot 8b4b3b971a forged items are persisted 2024-04-14 16:46:31 -04:00
MagicBot 692ee51608 forged items are persisted 2024-04-14 16:31:05 -04:00
MagicBot d5bd500f39 forged items are persisted 2024-04-14 16:29:17 -04:00
MagicBot e195d86fb6 Serialization update 2024-04-14 15:49:08 -04:00
MagicBot 114aeb9f64 Update NPC window 2024-04-14 15:38:24 -04:00
MagicBot d95bc5c261 Initialize all collections for npc 2024-04-14 15:30:10 -04:00
MagicBot 73fa5b5c7e Support for non-random rolling 2024-04-14 15:19:55 -04:00
MagicBot 85e5e2a7e3 Init forge support only for valid contracts 2024-04-14 15:17:32 -04:00
MagicBot 48f88ec819 Serialization update 2024-04-14 15:11:10 -04:00
MagicBot 139998eaa1 Moved declaration outside of loop 2024-04-14 15:02:52 -04:00
MagicBot 673f606de8 Cleanup of cache usage 2024-04-14 15:00:25 -04:00
MagicBot 9464500e95 More integration work 2024-04-14 14:48:59 -04:00
MagicBot 5e5b9884ef Begin integration 2024-04-14 14:13:10 -04:00
MagicBot 94ab64d629 reformat class 2024-04-14 14:11:22 -04:00
MagicBot 2c89509fa2 Moved logging message up 2024-04-14 14:07:06 -04:00
MagicBot fae81a0263 Removed cast in validation 2024-04-14 13:58:25 -04:00
MagicBot a8d5521dd8 Mobtype work related to ForgeManager 2024-04-14 13:51:37 -04:00
MagicBot ea555be08e Mobtype work related to ForgeManager 2024-04-14 13:13:28 -04:00
MagicBot 74e97fb435 Minor cleanup 2024-04-14 12:41:16 -04:00
MagicBot eed25d8c16 Minor cleanup 2024-04-14 12:24:53 -04:00
MagicBot bc195c27db Rework of error handling. 2024-04-14 12:14:17 -04:00
MagicBot 0653828fe3 Rework of error handling. 2024-04-14 12:13:51 -04:00
MagicBot 2feba8ac50 Rework of error handling. 2024-04-14 12:08:51 -04:00
MagicBot 5e7515a9ad Merge remote-tracking branch 'refs/remotes/origin/bugfix-combat-range' into feature-workorder2.4 2024-04-14 11:55:19 -04:00
FatBoy 2aaca661e2 new combat finalized 2024-04-13 19:44:03 -05:00
FatBoy 3f27bae099 mobs dont double tap when unarmed 2024-04-13 19:12:09 -05:00
FatBoy 79f4a33b6e add half player character height to attack range in lieu of hitbox 2024-04-13 19:10:10 -05:00
MagicBot ec47e24549 Not yet set when validating. 2024-04-13 12:26:39 -04:00
MagicBot 8fe7a6e896 Class cleanup 2024-04-13 11:28:48 -04:00
MagicBot f068e6891e Collection declaration cleanup 2024-04-13 10:10:17 -04:00
MagicBot cabbf8bf44 Java 8 TimeUnit 2024-04-13 10:06:44 -04:00
MagicBot 9c146fff4d Only random rolled items are unidentified. 2024-04-13 10:01:35 -04:00
MagicBot 333fcc9d14 Multiple item workOrder work 2024-04-13 09:53:20 -04:00
MagicBot 4aca075da6 Multiple item workOrder work 2024-04-13 09:38:58 -04:00
MagicBot a5bcdff216 Multiple item workOrder work 2024-04-13 09:31:18 -04:00
MagicBot 3c704d6b85 Multiple item workOrder work 2024-04-13 09:22:23 -04:00
MagicBot d26214d032 Multiple item workOrder work 2024-04-13 09:20:25 -04:00
MagicBot 09c96c772e Multiple item workOrder work 2024-04-13 09:10:56 -04:00
MagicBot f6e1c78b0b Debug string update 2024-04-13 08:57:53 -04:00
MagicBot ec80146117 forge items each cycle 2024-04-13 08:51:02 -04:00
MagicBot 980dee2e14 Work on multiple slot support 2024-04-13 08:31:36 -04:00
MagicBot 832b994757 Begin work on forgeItem() 2024-04-13 08:19:09 -04:00
MagicBot a18785fb3d Begin work on forgeItem() 2024-04-13 08:10:59 -04:00
MagicBot f076b38044 Contextual variable name updates 2024-04-13 07:54:26 -04:00
MagicBot 68f2af5306 Bugfix in delay override 2024-04-13 07:44:16 -04:00
MagicBot 052867893c Bugfix in delay override 2024-04-13 07:31:17 -04:00
MagicBot 13ba31285e Logging on each cycle 2024-04-13 07:26:39 -04:00
MagicBot 61a418fd8e Debug comment update 2024-04-13 07:18:55 -04:00
MagicBot 3fa4185b7f Debug comment update 2024-04-13 06:55:49 -04:00
MagicBot 5cb08c1dc0 Forge must be protected 2024-04-13 06:53:36 -04:00
MagicBot fc3a0eaf0c Forge must be protected 2024-04-13 06:48:58 -04:00
MagicBot 2e83b8c693 Better context in name 2024-04-13 06:42:21 -04:00
MagicBot 44eafc3345 Validation work 2024-04-12 17:41:08 -04:00
MagicBot 29ce3537f7 Work on cost overflow calculations 2024-04-12 17:29:52 -04:00
MagicBot 058887ff4d Locked resources are always unavailable. 2024-04-12 17:16:12 -04:00
MagicBot dc18e71ee4 Locked resources are always unavailable. 2024-04-12 17:15:04 -04:00
MagicBot 479e38e3f6 Validation work 2024-04-12 17:06:42 -04:00
MagicBot dd764281e8 Rolling duration updated 2024-04-12 16:52:43 -04:00
MagicBot f7959a51bd Rolling duration updated 2024-04-12 16:43:22 -04:00
MagicBot 97e0ada1a9 workerOrder cost updating 2024-04-12 16:16:34 -04:00
MagicBot cc3d5fe076 workerOrder cost updating 2024-04-12 15:48:25 -04:00
MagicBot 2200cb9bef workerOrder cost updating 2024-04-12 15:41:15 -04:00
MagicBot a16cda8a4a workerOrder cost updating 2024-04-12 15:31:12 -04:00
MagicBot af53859ba9 Comment added 2024-04-11 13:46:24 -04:00
MagicBot a7a1230f1b Work on wordOrder iteration 2024-04-10 18:01:27 -04:00
MagicBot df037a51f0 More info on template bootstrap 2024-04-10 17:40:00 -04:00
MagicBot 4d18e71aa1 More info on template bootstrap 2024-04-10 17:33:59 -04:00
MagicBot 7f579e5268 Bane rank loaded from template 2024-04-10 17:22:45 -04:00
MagicBot f6c53e51ed Calculate cost of workOrder 2024-04-10 16:47:02 -04:00
MagicBot 1429a3a4d5 Configure upon submit() 2024-04-10 16:06:09 -04:00
FatBoy dc81ddaba7 handle retaliate when being attacked 2024-04-09 21:23:29 -05:00
FatBoy 4a001179b5 add hitbox to abs vs abs range checks 2024-04-08 20:37:27 -05:00
FatBoy 1bff06cde0 using building bounds and hitBox for mele range 2024-04-08 20:20:16 -05:00
MagicBot ba4648f812 Minor class cleanup 2024-04-08 17:56:51 -04:00
MagicBot 1d0ab95b88 Minor class cleanup 2024-04-08 17:52:35 -04:00
MagicBot 275644ec83 Minor class cleanup 2024-04-08 17:42:47 -04:00
MagicBot 69416528b3 Minor class cleanup 2024-04-08 17:40:38 -04:00
MagicBot d3e0146d86 Minor class cleanup 2024-04-08 17:16:05 -04:00
MagicBot 35fab88949 Minor class cleanup 2024-04-08 17:15:56 -04:00
MagicBot 27a37eba79 Minor class cleanup 2024-04-08 17:06:42 -04:00
MagicBot deb5b36309 Minor class cleanup 2024-04-08 17:02:20 -04:00
MagicBot b84de95865 Minor class cleanup 2024-04-08 16:58:07 -04:00
MagicBot 5650c0f05a Minor class cleanup 2024-04-08 16:54:33 -04:00
MagicBot afa1b8478a Minor class cleanup 2024-04-08 16:53:53 -04:00
MagicBot cafe0a0fe1 Minor class cleanup 2024-04-08 16:49:19 -04:00
MagicBot bfa43823f6 Minor class cleanup 2024-04-08 16:42:44 -04:00
MagicBot 533ed87321 Minor class cleanup 2024-04-08 16:26:56 -04:00
MagicBot 129bd4aaa6 Minor class cleanup 2024-04-08 16:26:29 -04:00
MagicBot eb93481fda Merge branch 'feature-workorder2.4' of http://repo.magicbane.com/MagicBane/Server into feature-workorder2.4 2024-04-08 16:23:41 -04:00
MagicBot a160fe1b00 Time recycle update 2024-04-08 16:23:08 -04:00
MagicBot c2f70c0f26 Unused method removed 2024-04-08 15:58:48 -04:00
MagicBot 98c0712dea Method to calculate warehosue overflow. 2024-04-08 15:55:57 -04:00
MagicBot 7c4f7f391b Method to calculate warehosue overflow. 2024-04-08 15:54:25 -04:00
MagicBot e01dc9b09c More fleshing out of workorder usage 2024-04-08 13:15:40 -04:00
MagicBot 178bb3718a Slot count calculated 2024-04-08 13:10:23 -04:00
MagicBot f088d2aa72 More WorkOrder work 2024-04-08 13:06:22 -04:00
MagicBot 0645a93b9c Track items and their workorders. 2024-04-08 04:46:54 -04:00
MagicBot 8b38f1a695 Track items and their workorders. 2024-04-08 04:42:44 -04:00
MagicBot 652476fde8 Track items and their workorders. 2024-04-08 04:37:27 -04:00
MagicBot 74a7a255be Track items and their workorders. 2024-04-08 04:32:04 -04:00
MagicBot abd112035a Track items and their workorders. 2024-04-08 04:17:31 -04:00
MagicBot f5f92a1d88 rollingDuration fleshed out 2024-04-07 23:21:35 -04:00
MagicBot 75d520831f More workorder logic work 2024-04-07 23:00:37 -04:00
MagicBot 92402097d4 ForgeManager started at boot 2024-04-07 22:53:41 -04:00
MagicBot 5e92bab977 submit workorder to forgemanager 2024-04-07 22:40:14 -04:00
MagicBot a5df674fbe Update to debug strings 2024-04-07 22:34:06 -04:00
MagicBot 4462f74f8c More workorder work. 2024-04-07 22:31:58 -04:00
MagicBot 781053ab22 Debug string added 2024-04-07 22:28:07 -04:00
MagicBot 053c105c26 Method to validate workorder 2024-04-07 22:21:47 -04:00
MagicBot 46bf67672a workorder fields assigned 2024-04-07 22:18:12 -04:00
MagicBot d539e419fe Begin adding workOrder logic 2024-04-07 22:15:06 -04:00
MagicBot ec5a8f5281 Logic cleanup. 2024-04-07 13:25:42 -04:00
MagicBot 97558b51c8 Method moved to top of handler. 2024-04-07 13:23:22 -04:00
MagicBot 4a3a8d4b65 Minor class cleanup 2024-04-07 13:10:58 -04:00
MagicBot 85a66339e2 inline accessors 2024-04-07 13:08:00 -04:00
MagicBot b785d35231 Removed unused method 2024-04-07 13:03:24 -04:00
MagicBot 21b1dba84d Switch directly on actiontype 2024-04-07 13:01:43 -04:00
MagicBot fc71b8cb61 Inline setter 2024-04-07 12:53:55 -04:00
MagicBot 31129493e5 ActionType Take 2024-04-07 12:51:58 -04:00
MagicBot 8b4eafebf3 Elevate access. It's a message... 2024-04-07 12:48:56 -04:00
MagicBot cf38362d84 Handler uses enumeration 2024-04-07 12:45:13 -04:00
MagicBot 30800478f2 Message now uses enum 2024-04-07 12:04:15 -04:00
MagicBot 9bbe9b399e Better name for map 2024-04-06 16:08:06 -04:00
MagicBot 16d17798be Mirror field in client 2024-04-06 16:06:55 -04:00
MagicBot 679c7afe0e field is templateID not item uuid. 2024-04-06 16:05:52 -04:00
MagicBot f10141eddb Variable removed from city 2024-04-06 15:45:45 -04:00
MagicBot 10805a7d37 Class moved up in package 2024-04-06 15:30:35 -04:00
MagicBot b979fbb1bc Begin message rewrite 2024-04-06 14:01:23 -04:00
MagicBot b86ca33087 Unused variables removed 2024-04-06 10:56:31 -04:00
MagicBot 993abfbf6f variable renamed 2024-04-06 07:26:17 -04:00
MagicBot ffd41101c3 variable renamed 2024-04-05 20:14:29 -04:00
MagicBot 39e06994d9 Workorder and Forgemanger classes created 2024-04-05 20:13:16 -04:00
536 changed files with 4867 additions and 6598 deletions
@@ -8,6 +8,7 @@
package engine.InterestManagement; package engine.InterestManagement;
import engine.gameManager.DispatchManager;
import engine.gameManager.GroupManager; import engine.gameManager.GroupManager;
import engine.gameManager.SessionManager; import engine.gameManager.SessionManager;
import engine.job.JobScheduler; import engine.job.JobScheduler;
@@ -17,7 +18,6 @@ import engine.mbEnums.DispatchChannel;
import engine.mbEnums.GameObjectType; import engine.mbEnums.GameObjectType;
import engine.net.AbstractNetMsg; import engine.net.AbstractNetMsg;
import engine.net.Dispatch; import engine.net.Dispatch;
import engine.net.DispatchMessage;
import engine.net.client.ClientConnection; import engine.net.client.ClientConnection;
import engine.net.client.msg.LoadCharacterMsg; import engine.net.client.msg.LoadCharacterMsg;
import engine.net.client.msg.LoadStructureMsg; import engine.net.client.msg.LoadStructureMsg;
@@ -88,7 +88,7 @@ public enum InterestManager implements Runnable {
if (send) { if (send) {
Dispatch dispatch = Dispatch.borrow(player, msg); Dispatch dispatch = Dispatch.borrow(player, msg);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY); DispatchManager.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY);
} }
} }
} }
@@ -270,7 +270,7 @@ public enum InterestManager implements Runnable {
} }
Dispatch dispatch = Dispatch.borrow(player, uom); Dispatch dispatch = Dispatch.borrow(player, uom);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY); DispatchManager.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY);
} }
loadedStaticObjects.removeAll(toRemove); loadedStaticObjects.removeAll(toRemove);
@@ -292,7 +292,7 @@ public enum InterestManager implements Runnable {
lcm = new LoadCharacterMsg(corpse, PlayerCharacter.hideNonAscii()); lcm = new LoadCharacterMsg(corpse, PlayerCharacter.hideNonAscii());
Dispatch dispatch = Dispatch.borrow(player, lcm); Dispatch dispatch = Dispatch.borrow(player, lcm);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY); DispatchManager.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY);
} else if (awo.getObjectType().equals(GameObjectType.NPC)) { } else if (awo.getObjectType().equals(GameObjectType.NPC)) {
NPC npc = (NPC) awo; NPC npc = (NPC) awo;
@@ -304,13 +304,13 @@ public enum InterestManager implements Runnable {
if (lsm.getStructureList().size() > 0) { if (lsm.getStructureList().size() > 0) {
Dispatch dispatch = Dispatch.borrow(player, lsm); Dispatch dispatch = Dispatch.borrow(player, lsm);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY); DispatchManager.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY);
} }
for (LoadCharacterMsg lc : lcmList) { for (LoadCharacterMsg lc : lcmList) {
Dispatch dispatch = Dispatch.borrow(player, lc); Dispatch dispatch = Dispatch.borrow(player, lc);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY); DispatchManager.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY);
} }
loadedStaticObjects.addAll(toLoad); loadedStaticObjects.addAll(toLoad);
@@ -414,7 +414,7 @@ public enum InterestManager implements Runnable {
if (!uom.getObjectList().isEmpty()) { if (!uom.getObjectList().isEmpty()) {
Dispatch dispatch = Dispatch.borrow(player, uom); Dispatch dispatch = Dispatch.borrow(player, uom);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY); DispatchManager.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY);
} }
} }
@@ -492,7 +492,7 @@ public enum InterestManager implements Runnable {
if (lcm != null) { if (lcm != null) {
Dispatch dispatch = Dispatch.borrow(player, lcm); Dispatch dispatch = Dispatch.borrow(player, lcm);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY); DispatchManager.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY);
} }
+15 -12
View File
@@ -8,14 +8,10 @@
package engine.InterestManagement; package engine.InterestManagement;
/* This class is the main interface for Magicbane's import engine.gameManager.DispatchManager;
* Interest management facilities.
*/
import engine.math.Vector3fImmutable; import engine.math.Vector3fImmutable;
import engine.mbEnums; import engine.mbEnums;
import engine.net.Dispatch; import engine.net.Dispatch;
import engine.net.DispatchMessage;
import engine.net.client.msg.TerritoryChangeMessage; import engine.net.client.msg.TerritoryChangeMessage;
import engine.objects.City; import engine.objects.City;
import engine.objects.PlayerCharacter; import engine.objects.PlayerCharacter;
@@ -31,10 +27,17 @@ import static engine.objects.Realm.getRealm;
public enum RealmMap { public enum RealmMap {
REALM_MAP; // MB Dev Notes:
// This class loads and caches realm maps used by each
// map set for its realm overlay. The RealmMap loaded is
// controlled by config entry MB_WORLD_REALMMAP
//
// Unlike a Heightmap this is a just color lookup; identical to
// the old image maps used in 90s web technology.
//
// Realm Map images are stored on disk in /mb.data/realmmaps/
// Spatial hashmap. Used for determining which Realm REALM_MAP;
// a player is currently located within.
private static final HashMap<Color, Integer> _rgbToIDMap = new HashMap<>(); private static final HashMap<Color, Integer> _rgbToIDMap = new HashMap<>();
public static int[][] _realmImageMap; public static int[][] _realmImageMap;
@@ -65,7 +68,7 @@ public enum RealmMap {
public static Realm getRealmForCity(City city) { public static Realm getRealmForCity(City city) {
Realm outRealm = null; Realm outRealm = null;
outRealm = city.getRealm(); outRealm = city.realm;
return outRealm; return outRealm;
} }
@@ -88,17 +91,17 @@ public enum RealmMap {
if (city != null) { if (city != null) {
TerritoryChangeMessage tcm = new TerritoryChangeMessage((PlayerCharacter) realm.getRulingCity().getOwner(), realm); TerritoryChangeMessage tcm = new TerritoryChangeMessage((PlayerCharacter) realm.getRulingCity().getOwner(), realm);
Dispatch dispatch = Dispatch.borrow(player, tcm); Dispatch dispatch = Dispatch.borrow(player, tcm);
DispatchMessage.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.PRIMARY); DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.PRIMARY);
} else { } else {
TerritoryChangeMessage tcm = new TerritoryChangeMessage(null, realm); TerritoryChangeMessage tcm = new TerritoryChangeMessage(null, realm);
Dispatch dispatch = Dispatch.borrow(player, tcm); Dispatch dispatch = Dispatch.borrow(player, tcm);
DispatchMessage.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.PRIMARY); DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.PRIMARY);
} }
} else { } else {
TerritoryChangeMessage tcm = new TerritoryChangeMessage(null, realm); TerritoryChangeMessage tcm = new TerritoryChangeMessage(null, realm);
Dispatch dispatch = Dispatch.borrow(player, tcm); Dispatch dispatch = Dispatch.borrow(player, tcm);
DispatchMessage.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.PRIMARY); DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.PRIMARY);
} }
} }
+9 -1
View File
@@ -18,6 +18,14 @@ import java.util.HashMap;
import static java.lang.Math.PI; import static java.lang.Math.PI;
// MB Dev Notes:
// The Terrain class handles lookups into the Heightmap data.
// It supports all current maps along with the differences in
// their parenting configuration.
//
// Heightmap images are stored on disk in /mb.data/heightmaps/
public class Terrain { public class Terrain {
public static final HashMap<Integer, short[][]> _heightmap_pixel_cache = new HashMap<>(); public static final HashMap<Integer, short[][]> _heightmap_pixel_cache = new HashMap<>();
public short[][] terrain_pixel_data; public short[][] terrain_pixel_data;
@@ -112,7 +120,7 @@ public class Terrain {
public static float getWorldHeight(Zone zone, Vector3fImmutable world_loc) { public static float getWorldHeight(Zone zone, Vector3fImmutable world_loc) {
// Retrieve the next zone with a terrain defined. // Retrieve the next zone up in the tree with a terrain defined.
Zone terrainZone = getNextZoneWithTerrain(zone); Zone terrainZone = getNextZoneWithTerrain(zone);
Zone parentZone = getNextZoneWithTerrain(zone.parent); Zone parentZone = getNextZoneWithTerrain(zone.parent);
+11 -11
View File
@@ -8,11 +8,11 @@
package engine.InterestManagement; package engine.InterestManagement;
import engine.mbEnums.GridObjectType; import engine.gameManager.DispatchManager;
import engine.math.FastMath; import engine.math.FastMath;
import engine.math.Vector3f; import engine.math.Vector3f;
import engine.math.Vector3fImmutable; import engine.math.Vector3fImmutable;
import engine.net.DispatchMessage; import engine.mbEnums.GridObjectType;
import engine.net.client.ClientConnection; import engine.net.client.ClientConnection;
import engine.net.client.msg.LoadCharacterMsg; import engine.net.client.msg.LoadCharacterMsg;
import engine.net.client.msg.LoadStructureMsg; import engine.net.client.msg.LoadStructureMsg;
@@ -201,7 +201,7 @@ public class WorldGrid {
UnloadObjectsMsg uom = new UnloadObjectsMsg(); UnloadObjectsMsg uom = new UnloadObjectsMsg();
uom.addObject(awo); uom.addObject(awo);
DispatchMessage.sendToAllInRange(awo, uom); DispatchManager.sendToAllInRange(awo, uom);
} }
public static void loadObject(AbstractWorldObject awo) { public static void loadObject(AbstractWorldObject awo) {
@@ -213,15 +213,15 @@ public class WorldGrid {
case Building: case Building:
lsm = new LoadStructureMsg(); lsm = new LoadStructureMsg();
lsm.addObject((Building) awo); lsm.addObject((Building) awo);
DispatchMessage.sendToAllInRange(awo, lsm); DispatchManager.sendToAllInRange(awo, lsm);
break; break;
case NPC: case NPC:
lcm = new LoadCharacterMsg((NPC) awo, false); lcm = new LoadCharacterMsg((NPC) awo, false);
DispatchMessage.sendToAllInRange(awo, lcm); DispatchManager.sendToAllInRange(awo, lcm);
break; break;
case Mob: case Mob:
lcm = new LoadCharacterMsg((Mob) awo, false); lcm = new LoadCharacterMsg((Mob) awo, false);
DispatchMessage.sendToAllInRange(awo, lcm); DispatchManager.sendToAllInRange(awo, lcm);
break; break;
default: default:
// *** Refactor: Log error? // *** Refactor: Log error?
@@ -239,19 +239,19 @@ public class WorldGrid {
case Building: case Building:
lsm = new LoadStructureMsg(); lsm = new LoadStructureMsg();
lsm.addObject((Building) awo); lsm.addObject((Building) awo);
DispatchMessage.sendToAllInRange(awo, lsm); DispatchManager.sendToAllInRange(awo, lsm);
break; break;
case NPC: case NPC:
lcm = new LoadCharacterMsg((NPC) awo, false); lcm = new LoadCharacterMsg((NPC) awo, false);
DispatchMessage.sendToAllInRange(awo, lcm); DispatchManager.sendToAllInRange(awo, lcm);
break; break;
case Mob: case Mob:
lcm = new LoadCharacterMsg((Mob) awo, false); lcm = new LoadCharacterMsg((Mob) awo, false);
DispatchMessage.sendToAllInRange(awo, lcm); DispatchManager.sendToAllInRange(awo, lcm);
break; break;
case PlayerCharacter: case PlayerCharacter:
lcm = new LoadCharacterMsg((PlayerCharacter) awo, false); lcm = new LoadCharacterMsg((PlayerCharacter) awo, false);
DispatchMessage.sendToAllInRange(awo, lcm); DispatchManager.sendToAllInRange(awo, lcm);
break; break;
default: default:
// *** Refactor: Log error? // *** Refactor: Log error?
@@ -263,7 +263,7 @@ public class WorldGrid {
ClientConnection origin) { ClientConnection origin) {
UnloadObjectsMsg uom = new UnloadObjectsMsg(); UnloadObjectsMsg uom = new UnloadObjectsMsg();
uom.addObject(awo); uom.addObject(awo);
DispatchMessage.sendToAllInRange(awo, uom); DispatchManager.sendToAllInRange(awo, uom);
} }
public static void addObject(AbstractWorldObject awo, PlayerCharacter pc) { public static void addObject(AbstractWorldObject awo, PlayerCharacter pc) {
+2 -1
View File
@@ -89,7 +89,8 @@ public class GuildRecord extends DataRecord {
guildRecord.guildHash = guildRecord.guild.getHash(); guildRecord.guildHash = guildRecord.guild.getHash();
guildRecord.guildID = guildRecord.guild.getObjectUUID(); guildRecord.guildID = guildRecord.guild.getObjectUUID();
guildRecord.guildName = guildRecord.guild.getName(); guildRecord.guildName = guildRecord.guild.getName();
guildRecord.charterName = mbEnums.GuildCharterType.getGuildTypeFromInt(guildRecord.guild.getCharter()).getCharterName(); mbEnums.GuildCharterType guildCharterType = guild.charter;
guildRecord.charterName = guildCharterType.name;
guildRecord.GLHash = DataWarehouse.hasher.encrypt(guildRecord.guild.getGuildLeaderUUID()); guildRecord.GLHash = DataWarehouse.hasher.encrypt(guildRecord.guild.getGuildLeaderUUID());
+10 -11
View File
@@ -52,25 +52,24 @@ public class dbCityHandler extends dbHandlerBase {
} }
} }
public ArrayList<AbstractGameObject> CREATE_CITY(int ownerID, int parentZoneID, int realmID, float xCoord, float yCoord, float zCoord, float rotation, float W, String name, LocalDateTime established) { public ArrayList<AbstractGameObject> CREATE_CITY(int ownerID, int parentZoneID, float xCoord, float yCoord, float zCoord, float rotation, float W, String name, LocalDateTime established) {
LocalDateTime upgradeTime = LocalDateTime.now().plusHours(2); LocalDateTime upgradeTime = LocalDateTime.now().plusHours(2);
ArrayList<AbstractGameObject> objectList = new ArrayList<>(); ArrayList<AbstractGameObject> objectList = new ArrayList<>();
try (Connection connection = DbManager.getConnection(); try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("CALL `city_CREATE`(?, ?, ?, ?, ?, ?, ?, ?, ?,?,?)")) { PreparedStatement preparedStatement = connection.prepareStatement("CALL `city_CREATE`(?, ?, ?, ?, ?, ?, ?, ?,?,?)")) {
preparedStatement.setLong(1, ownerID); //objectUUID of owning player preparedStatement.setLong(1, ownerID); //objectUUID of owning player
preparedStatement.setLong(2, parentZoneID); //objectUUID of parent (continent) zone preparedStatement.setLong(2, parentZoneID); //objectUUID of parent (continent) zone
preparedStatement.setLong(3, realmID); //objectUUID of realm city belongs in preparedStatement.setFloat(3, xCoord); //xOffset from parentZone center
preparedStatement.setFloat(4, xCoord); //xOffset from parentZone center preparedStatement.setFloat(4, yCoord); //yOffset from parentZone center
preparedStatement.setFloat(5, yCoord); //yOffset from parentZone center preparedStatement.setFloat(5, zCoord); //zOffset from parentZone center
preparedStatement.setFloat(6, zCoord); //zOffset from parentZone center preparedStatement.setString(6, name); //city name
preparedStatement.setString(7, name); //city name preparedStatement.setTimestamp(7, Timestamp.valueOf(established));
preparedStatement.setTimestamp(8, Timestamp.valueOf(established)); preparedStatement.setFloat(8, rotation);
preparedStatement.setFloat(9, rotation); preparedStatement.setFloat(9, W);
preparedStatement.setFloat(10, W); preparedStatement.setTimestamp(10, Timestamp.valueOf(upgradeTime));
preparedStatement.setTimestamp(11, Timestamp.valueOf(upgradeTime));
boolean work = preparedStatement.execute(); boolean work = preparedStatement.execute();
@@ -10,10 +10,10 @@
package engine.db.handlers; package engine.db.handlers;
import engine.gameManager.DbManager; import engine.gameManager.DbManager;
import engine.gameManager.ItemManager;
import engine.mbEnums; import engine.mbEnums;
import engine.objects.Contract; import engine.objects.Contract;
import engine.objects.Item; import engine.objects.Item;
import engine.objects.MobLoot;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
import java.sql.Connection; import java.sql.Connection;
@@ -66,7 +66,7 @@ public class dbContractHandler extends dbHandlerBase {
int templateID = rs.getInt("templateID"); int templateID = rs.getInt("templateID");
Item item = new Item(templateID); Item item = new Item(templateID);
item.objectUUID = MobLoot.lastNegativeID.decrementAndGet(); item.objectUUID = ItemManager.lastNegativeID.decrementAndGet();
contract.getSellInventory().add(item); contract.getSellInventory().add(item);
} }
@@ -10,15 +10,17 @@
package engine.db.handlers; package engine.db.handlers;
import engine.gameManager.DbManager; import engine.gameManager.DbManager;
import engine.gameManager.PowersManager;
import engine.mbEnums; import engine.mbEnums;
import engine.objects.EffectsResourceCosts; import engine.objects.EffectsResourceCosts;
import org.json.JSONObject;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
import java.sql.Connection; import java.sql.Connection;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList; import java.util.HashMap;
public class dbEffectsResourceCostHandler extends dbHandlerBase { public class dbEffectsResourceCostHandler extends dbHandlerBase {
@@ -27,22 +29,30 @@ public class dbEffectsResourceCostHandler extends dbHandlerBase {
this.localObjectType = mbEnums.GameObjectType.valueOf(this.localClass.getSimpleName()); this.localObjectType = mbEnums.GameObjectType.valueOf(this.localClass.getSimpleName());
} }
public ArrayList<EffectsResourceCosts> GET_ALL_EFFECT_RESOURCES(String idString) { public void LOAD_ALL_COSTMAPS() {
ArrayList<EffectsResourceCosts> effectsResourceCosts = new ArrayList<>();
try (Connection connection = DbManager.getConnection(); try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_power_effectcost` WHERE `IDString` = ?")) { PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_effect_costmaps`")) {
preparedStatement.setString(1, idString);
ResultSet rs = preparedStatement.executeQuery(); ResultSet rs = preparedStatement.executeQuery();
effectsResourceCosts = getObjectsFromRs(rs, 1000);
while (rs.next()) {
String effectID = rs.getString("effectID");
String costString = rs.getString("costmap");
JSONObject costJSON = new JSONObject(costString);
HashMap<mbEnums.ResourceType, Integer> costmap = new HashMap<>();
for (String key : costJSON.keySet()) {
int value = costJSON.getInt(key);
costmap.put(mbEnums.ResourceType.valueOf(key), value);
}
PowersManager._effect_costMaps.put(effectID, costmap);
}
} catch (SQLException e) { } catch (SQLException e) {
Logger.error(e); Logger.error(e);
} }
return effectsResourceCosts;
} }
} }
+2 -2
View File
@@ -427,7 +427,7 @@ public class dbGuildHandler extends dbHandlerBase {
preparedStatement.setInt(6, guildTag.symbolColor); preparedStatement.setInt(6, guildTag.symbolColor);
preparedStatement.setInt(7, guildTag.backgroundDesign); preparedStatement.setInt(7, guildTag.backgroundDesign);
preparedStatement.setInt(8, guildTag.symbol); preparedStatement.setInt(8, guildTag.symbol);
preparedStatement.setInt(9, g.getCharter()); preparedStatement.setInt(9, g.charter.templateID);
preparedStatement.setString(10, g.getLeadershipType()); preparedStatement.setString(10, g.getLeadershipType());
preparedStatement.setString(11, g.getMotto()); preparedStatement.setString(11, g.getMotto());
@@ -573,7 +573,7 @@ public class dbGuildHandler extends dbHandlerBase {
preparedStatement.setInt(4, g.getGuildTag().symbolColor); preparedStatement.setInt(4, g.getGuildTag().symbolColor);
preparedStatement.setInt(5, g.getGuildTag().backgroundDesign); preparedStatement.setInt(5, g.getGuildTag().backgroundDesign);
preparedStatement.setInt(6, g.getGuildTag().symbol); preparedStatement.setInt(6, g.getGuildTag().symbol);
preparedStatement.setInt(7, g.getCharter()); preparedStatement.setInt(7, g.charter.templateID);
preparedStatement.setString(8, g.getMOTD()); preparedStatement.setString(8, g.getMOTD());
preparedStatement.setString(9, g.getICMOTD()); preparedStatement.setString(9, g.getICMOTD());
preparedStatement.setString(10, ""); preparedStatement.setString(10, "");
+8 -5
View File
@@ -17,8 +17,7 @@ import engine.objects.AbstractCharacter;
import engine.objects.CharacterItemManager; import engine.objects.CharacterItemManager;
import engine.objects.Item; import engine.objects.Item;
import engine.objects.ItemTemplate; import engine.objects.ItemTemplate;
import org.json.simple.JSONObject; import org.json.JSONObject;
import org.json.simple.parser.JSONParser;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
import java.sql.Connection; import java.sql.Connection;
@@ -26,6 +25,7 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
@@ -179,7 +179,7 @@ public class dbItemHandler extends dbHandlerBase {
public void LOAD_ITEM_TEMPLATES() { public void LOAD_ITEM_TEMPLATES() {
JSONParser jsonParser = new JSONParser(); HashMap<ItemType, Integer> templateTCountMap = new HashMap<>();
try (Connection connection = DbManager.getConnection(); try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_item_templates`;"); PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_item_templates`;");
@@ -187,12 +187,15 @@ public class dbItemHandler extends dbHandlerBase {
while (rs.next()) { while (rs.next()) {
int templateID = rs.getInt("id"); int templateID = rs.getInt("id");
JSONObject jsonObject = (JSONObject) jsonParser.parse(rs.getString("template")); JSONObject jsonObject = new JSONObject(rs.getString("template"));
ItemTemplate itemTemplate = new ItemTemplate(jsonObject); ItemTemplate itemTemplate = new ItemTemplate(jsonObject);
itemTemplate.template_id = templateID; itemTemplate.template_id = templateID;
ItemTemplate.templates.put(templateID, itemTemplate); ItemTemplate.templates.put(templateID, itemTemplate);
templateTCountMap.merge(itemTemplate.item_type, 1, Integer::sum);
} }
Logger.info(templateTCountMap.toString());
} catch (Exception e) { } catch (Exception e) {
Logger.error(e); Logger.error(e);
} }
@@ -551,7 +554,7 @@ public class dbItemHandler extends dbHandlerBase {
// Write 0 if we will not modify the value from template // Write 0 if we will not modify the value from template
if (item.value == item.template.item_value) if (value == item.template.item_value)
value = 0; value = 0;
try (Connection connection = DbManager.getConnection(); try (Connection connection = DbManager.getConnection();
+1 -1
View File
@@ -8,8 +8,8 @@
package engine.db.handlers; package engine.db.handlers;
import engine.mbEnums;
import engine.gameManager.DbManager; import engine.gameManager.DbManager;
import engine.mbEnums;
import engine.objects.Mine; import engine.objects.Mine;
import engine.objects.MineProduction; import engine.objects.MineProduction;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
+1 -1
View File
@@ -9,9 +9,9 @@
package engine.db.handlers; package engine.db.handlers;
import engine.gameManager.DbManager;
import engine.mbEnums; import engine.mbEnums;
import engine.mbEnums.GameObjectType; import engine.mbEnums.GameObjectType;
import engine.gameManager.DbManager;
import engine.objects.MobBase; import engine.objects.MobBase;
import engine.objects.MobBaseEffects; import engine.objects.MobBaseEffects;
import engine.objects.MobBaseStats; import engine.objects.MobBaseStats;
+18 -114
View File
@@ -9,13 +9,12 @@
package engine.db.handlers; package engine.db.handlers;
import engine.mbEnums;
import engine.mbEnums.ProfitType;
import engine.gameManager.DbManager; import engine.gameManager.DbManager;
import engine.math.Vector3fImmutable; import engine.math.Vector3fImmutable;
import engine.mbEnums;
import engine.mbEnums.ProfitType;
import engine.objects.NPC; import engine.objects.NPC;
import engine.objects.NPCProfits; import engine.objects.NPCProfits;
import engine.objects.ProducedItem;
import org.joda.time.DateTime; import org.joda.time.DateTime;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
@@ -311,6 +310,22 @@ public class dbNPCHandler extends dbHandlerBase {
} }
} }
public boolean UPDATE_RACE(NPC npc, int value) {
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE `obj_npc` SET `npc_raceID`=? WHERE `UID`=?")) {
preparedStatement.setInt(1, value);
preparedStatement.setLong(2, npc.getObjectUUID());
return (preparedStatement.executeUpdate() > 0);
} catch (SQLException e) {
Logger.error(e);
return false;
}
}
public void LOAD_PIRATE_NAMES() { public void LOAD_PIRATE_NAMES() {
String pirateName; String pirateName;
@@ -346,117 +361,6 @@ public class dbNPCHandler extends dbHandlerBase {
+ NPC._pirateNames.size() + " mobBases"); + NPC._pirateNames.size() + " mobBases");
} }
public boolean ADD_TO_PRODUCTION_LIST(final long ID, final long npcUID, final long templateID, DateTime dateTime, String prefix, String suffix, String name, boolean isRandom, int playerID) {
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("INSERT INTO `dyn_npc_production` (`ID`,`npcUID`, `templateID`,`dateToUpgrade`, `isRandom`, `prefix`, `suffix`, `name`,`playerID`) VALUES (?,?,?,?,?,?,?,?,?)")) {
preparedStatement.setLong(1, ID);
preparedStatement.setLong(2, npcUID);
preparedStatement.setLong(3, templateID);
preparedStatement.setTimestamp(4, new java.sql.Timestamp(dateTime.getMillis()));
preparedStatement.setBoolean(5, isRandom);
preparedStatement.setString(6, prefix);
preparedStatement.setString(7, suffix);
preparedStatement.setString(8, name);
preparedStatement.setInt(9, playerID);
return (preparedStatement.executeUpdate() > 0);
} catch (SQLException e) {
Logger.error(e);
return false;
}
}
public boolean REMOVE_FROM_PRODUCTION_LIST(final long ID, final long npcUID) {
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("DELETE FROM `dyn_npc_production` WHERE `ID`=? AND `npcUID`=?;")) {
preparedStatement.setLong(1, ID);
preparedStatement.setLong(2, npcUID);
return (preparedStatement.executeUpdate() > 0);
} catch (SQLException e) {
Logger.error(e);
return false;
}
}
public boolean UPDATE_ITEM_TO_INVENTORY(final long ID, final long npcUID) {
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE `dyn_npc_production` SET `inForge`=? WHERE `ID`=? AND `npcUID`=?;")) {
preparedStatement.setByte(1, (byte) 0);
preparedStatement.setLong(2, ID);
preparedStatement.setLong(3, npcUID);
return (preparedStatement.executeUpdate() > 0);
} catch (SQLException e) {
Logger.error(e);
return false;
}
}
public boolean UPDATE_ITEM_PRICE(final long ID, final long npcUID, int value) {
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE `dyn_npc_production` SET `value`=? WHERE `ID`=? AND `npcUID`=?;")) {
preparedStatement.setInt(1, value);
preparedStatement.setLong(2, ID);
preparedStatement.setLong(3, npcUID);
return (preparedStatement.executeUpdate() > 0);
} catch (SQLException e) {
Logger.error(e);
return false;
}
}
public boolean UPDATE_ITEM_ID(final long ID, final long npcUID, final long value) {
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE `dyn_npc_production` SET `ID`=? WHERE `ID`=? AND `npcUID`=? LIMIT 1;")) {
preparedStatement.setLong(1, value);
preparedStatement.setLong(2, ID);
preparedStatement.setLong(3, npcUID);
return (preparedStatement.executeUpdate() > 0);
} catch (SQLException e) {
Logger.error(e);
return false;
}
}
public void LOAD_ALL_ITEMS_TO_PRODUCE(NPC npc) {
if (npc == null)
return;
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `dyn_npc_production` WHERE `npcUID` = ?")) {
preparedStatement.setInt(1, npc.getObjectUUID());
ResultSet rs = preparedStatement.executeQuery();
while (rs.next()) {
ProducedItem producedItem = new ProducedItem(rs);
npc.forgedItems.add(producedItem);
}
} catch (SQLException e) {
Logger.error(e);
}
}
public boolean UPDATE_PROFITS(NPC npc, ProfitType profitType, float value) { public boolean UPDATE_PROFITS(NPC npc, ProfitType profitType, float value) {
try (Connection connection = DbManager.getConnection(); try (Connection connection = DbManager.getConnection();
@@ -9,8 +9,8 @@
package engine.db.handlers; package engine.db.handlers;
import engine.mbEnums;
import engine.gameManager.DbManager; import engine.gameManager.DbManager;
import engine.mbEnums;
import engine.objects.Petition; import engine.objects.Petition;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
@@ -9,8 +9,8 @@
package engine.db.handlers; package engine.db.handlers;
import engine.mbEnums;
import engine.gameManager.DbManager; import engine.gameManager.DbManager;
import engine.mbEnums;
import engine.objects.AbstractWorldObject; import engine.objects.AbstractWorldObject;
import engine.objects.Heraldry; import engine.objects.Heraldry;
import engine.objects.PlayerCharacter; import engine.objects.PlayerCharacter;
+2 -2
View File
@@ -9,9 +9,9 @@
package engine.db.handlers; package engine.db.handlers;
import engine.mbEnums;
import engine.gameManager.DbManager; import engine.gameManager.DbManager;
import engine.gameManager.PowersManager; import engine.gameManager.PowersManager;
import engine.mbEnums;
import engine.objects.Mob; import engine.objects.Mob;
import engine.powers.EffectsBase; import engine.powers.EffectsBase;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
@@ -41,7 +41,7 @@ public class dbPowerHandler extends dbHandlerBase {
int token = DbManager.hasher.SBStringHash(IDString); int token = DbManager.hasher.SBStringHash(IDString);
source = rs.getString("source").replace("-", "").trim(); source = rs.getString("source").replace("-", "").trim();
mbEnums.EffectSourceType effectSourceType = mbEnums.EffectSourceType.GetEffectSourceType(source); mbEnums.EffectSourceType effectSourceType = mbEnums.EffectSourceType.getEffectSourceType(source);
if (EffectsBase.effectSourceTypeMap.containsKey(token) == false) if (EffectsBase.effectSourceTypeMap.containsKey(token) == false)
EffectsBase.effectSourceTypeMap.put(token, new HashSet<>()); EffectsBase.effectSourceTypeMap.put(token, new HashSet<>());
@@ -9,9 +9,9 @@
package engine.db.handlers; package engine.db.handlers;
import engine.gameManager.DbManager;
import engine.mbEnums; import engine.mbEnums;
import engine.mbEnums.GameObjectType; import engine.mbEnums.GameObjectType;
import engine.gameManager.DbManager;
import engine.objects.AbstractGameObject; import engine.objects.AbstractGameObject;
import engine.objects.RuneBaseEffect; import engine.objects.RuneBaseEffect;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
@@ -9,8 +9,8 @@
package engine.db.handlers; package engine.db.handlers;
import engine.mbEnums;
import engine.gameManager.DbManager; import engine.gameManager.DbManager;
import engine.mbEnums;
import engine.objects.Building; import engine.objects.Building;
import engine.objects.Portal; import engine.objects.Portal;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
+2 -2
View File
@@ -9,10 +9,10 @@
package engine.db.handlers; package engine.db.handlers;
import engine.mbEnums;
import engine.mbEnums.ProtectionState;
import engine.gameManager.DbManager; import engine.gameManager.DbManager;
import engine.math.Vector3fImmutable; import engine.math.Vector3fImmutable;
import engine.mbEnums;
import engine.mbEnums.ProtectionState;
import engine.objects.AbstractGameObject; import engine.objects.AbstractGameObject;
import engine.objects.Building; import engine.objects.Building;
import engine.objects.Shrine; import engine.objects.Shrine;
@@ -9,9 +9,9 @@
package engine.db.handlers; package engine.db.handlers;
import engine.gameManager.DbManager;
import engine.mbEnums; import engine.mbEnums;
import engine.mbEnums.GameObjectType; import engine.mbEnums.GameObjectType;
import engine.gameManager.DbManager;
import engine.objects.MaxSkills; import engine.objects.MaxSkills;
import engine.objects.SkillsBase; import engine.objects.SkillsBase;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
@@ -9,8 +9,8 @@
package engine.db.handlers; package engine.db.handlers;
import engine.mbEnums;
import engine.gameManager.DbManager; import engine.gameManager.DbManager;
import engine.mbEnums;
import engine.objects.VendorDialog; import engine.objects.VendorDialog;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
+85 -8
View File
@@ -9,19 +9,20 @@
package engine.db.handlers; package engine.db.handlers;
import engine.gameManager.DbManager;
import engine.gameManager.ForgeManager;
import engine.loot.WorkOrder;
import engine.mbEnums; import engine.mbEnums;
import engine.mbEnums.GameObjectType; import engine.mbEnums.GameObjectType;
import engine.mbEnums.TransactionType; import engine.mbEnums.TransactionType;
import engine.gameManager.DbManager;
import engine.objects.Building; import engine.objects.Building;
import engine.objects.City; import engine.objects.City;
import engine.objects.Transaction; import engine.objects.Transaction;
import engine.objects.Warehouse; import engine.objects.Warehouse;
import engine.server.MBServerStatics; import engine.server.MBServerStatics;
import org.joda.time.DateTime; import org.joda.time.DateTime;
import org.json.simple.JSONArray; import org.json.JSONArray;
import org.json.simple.JSONObject; import org.json.JSONObject;
import org.json.simple.parser.JSONParser;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
import java.sql.Connection; import java.sql.Connection;
@@ -106,7 +107,7 @@ public class dbWarehouseHandler extends dbHandlerBase {
JSONArray locks = new JSONArray(); JSONArray locks = new JSONArray();
for (mbEnums.ResourceType resource : warehouse.locked) for (mbEnums.ResourceType resource : warehouse.locked)
locks.add(resource.name()); locks.put(resource.name());
warehouseJSON.put("locked", locks); warehouseJSON.put("locked", locks);
@@ -127,16 +128,20 @@ public class dbWarehouseHandler extends dbHandlerBase {
public void LOAD_WAREHOUSES() { public void LOAD_WAREHOUSES() {
JSONParser jsonParser = new JSONParser();
try (Connection connection = DbManager.getConnection(); try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `dyn_warehouse`;"); PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `dyn_warehouse`;");
ResultSet rs = preparedStatement.executeQuery()) { ResultSet rs = preparedStatement.executeQuery()) {
while (rs.next()) { while (rs.next()) {
int cityUID = rs.getInt("cityUUID"); int cityUID = rs.getInt("cityUUID");
JSONObject jsonObject = (JSONObject) jsonParser.parse(rs.getString("warehouse")); JSONObject jsonObject = new JSONObject(rs.getString("warehouse"));
City city = City.getCity(cityUID); City city = City.getCity(cityUID);
if (city == null) {
Logger.error("No city " + cityUID + " for warehouse");
continue;
}
city.warehouse = new Warehouse(jsonObject); city.warehouse = new Warehouse(jsonObject);
city.warehouse.city = city; city.warehouse.city = city;
@@ -154,4 +159,76 @@ public class dbWarehouseHandler extends dbHandlerBase {
Logger.error(e); Logger.error(e);
} }
} }
public boolean WRITE_WORKORDER(WorkOrder workOrder) {
JSONObject warehouseJSON = WorkOrder.toJson(workOrder);
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("INSERT INTO `dyn_workorders` (`workorderID`, `workorder`) VALUES (?, ?) " +
"ON DUPLICATE KEY UPDATE `workorder` = VALUES(`workorder`)")) {
preparedStatement.setInt(1, workOrder.workOrderID);
preparedStatement.setString(2, warehouseJSON.toString());
return (preparedStatement.executeUpdate() > 0);
} catch (SQLException e) {
Logger.error(e);
}
return false;
}
public void DELETE_WORKORDER(WorkOrder workOrder) {
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("DELETE FROM `dyn_workorders` WHERE `workorderID` = ?;")) {
preparedStatement.setInt(1, workOrder.workOrderID);
preparedStatement.executeUpdate();
} catch (SQLException e) {
Logger.error(e);
}
}
public void LOAD_WORKORDERS() {
// Method loads NPC workOrders from disk at bootstrap.
// A workOrder will persist until completed or junked
// via the client interface.
ArrayList<WorkOrder> submitList = new ArrayList<>();
ArrayList<WorkOrder> orphanList = new ArrayList<>();
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `dyn_workorders`;");
ResultSet rs = preparedStatement.executeQuery()) {
while (rs.next()) {
JSONObject jsonObject = new JSONObject(rs.getString("workorder"));
WorkOrder workOrder = new WorkOrder(jsonObject);
submitList.add(workOrder);
}
} catch (Exception e) {
Logger.error(e);
}
// Submit new workOrders to the ForgeManager
for (WorkOrder workOrder : submitList) {
DbManager.WarehouseQueries.DELETE_WORKORDER(workOrder);
// Delete but do not reconstitute orphan workOrders
if (workOrder.vendor == null)
continue;
workOrder.workOrderID = ForgeManager.workOrderCounter.incrementAndGet();
DbManager.WarehouseQueries.WRITE_WORKORDER(workOrder);
ForgeManager.vendorWorkOrderLookup.get(workOrder.vendor).add(workOrder);
ForgeManager.forge.add(workOrder);
}
}
} }
+1 -1
View File
@@ -9,9 +9,9 @@
package engine.db.handlers; package engine.db.handlers;
import engine.mbEnums;
import engine.gameManager.DbManager; import engine.gameManager.DbManager;
import engine.gameManager.ZoneManager; import engine.gameManager.ZoneManager;
import engine.mbEnums;
import engine.objects.Zone; import engine.objects.Zone;
import engine.objects.ZoneTemplate; import engine.objects.ZoneTemplate;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
+33 -4
View File
@@ -10,9 +10,14 @@
package engine.devcmd.cmds; package engine.devcmd.cmds;
import engine.devcmd.AbstractDevCmd; import engine.devcmd.AbstractDevCmd;
import engine.gameManager.ChatManager;
import engine.gameManager.DbManager;
import engine.mbEnums;
import engine.objects.AbstractGameObject; import engine.objects.AbstractGameObject;
import engine.objects.ItemFactory; import engine.objects.Item;
import engine.objects.ItemTemplate;
import engine.objects.PlayerCharacter; import engine.objects.PlayerCharacter;
import org.pmw.tinylog.Logger;
/** /**
* @author Eighty * @author Eighty
@@ -24,22 +29,46 @@ public class CreateItemCmd extends AbstractDevCmd {
} }
@Override @Override
protected void _doCmd(PlayerCharacter pc, String[] words, protected void _doCmd(PlayerCharacter playerCharacter, String[] words,
AbstractGameObject target) { AbstractGameObject target) {
if (words.length < 2) { if (words.length < 2) {
this.sendUsage(pc); this.sendUsage(playerCharacter);
return; return;
} }
int templateID = Integer.parseInt(words[0]); int templateID = Integer.parseInt(words[0]);
ItemTemplate template = ItemTemplate.templates.get(templateID);
if (template == null) {
ChatManager.chatSystemInfo(playerCharacter, "No such template found.");
return;
}
int size = 1; int size = 1;
if (words.length == 2) if (words.length == 2)
size = Integer.parseInt(words[1]); size = Integer.parseInt(words[1]);
ItemFactory.fillInventory(pc, templateID, size); for (int i = 0; i < size; i++) {
if (!playerCharacter.charItemManager.hasRoomInventory(template.item_wt)) {
ChatManager.chatSystemInfo(playerCharacter, "You are encumbered!.");
break;
}
Item item = new Item(templateID);
item.ownerID = playerCharacter.getObjectUUID();
item.ownerType = mbEnums.OwnerType.PlayerCharacter;
item.containerType = mbEnums.ItemContainerType.INVENTORY;
try {
item = DbManager.ItemQueries.PERSIST(item);
playerCharacter.charItemManager.addItemToInventory(item);
} catch (Exception e) {
Logger.error(e);
}
}
playerCharacter.charItemManager.updateInventory();
} }
@Override @Override
+1 -1
View File
@@ -9,11 +9,11 @@
package engine.devcmd.cmds; package engine.devcmd.cmds;
import engine.mbEnums.GameObjectType;
import engine.devcmd.AbstractDevCmd; import engine.devcmd.AbstractDevCmd;
import engine.gameManager.DbManager; import engine.gameManager.DbManager;
import engine.gameManager.SessionManager; import engine.gameManager.SessionManager;
import engine.math.Vector3fImmutable; import engine.math.Vector3fImmutable;
import engine.mbEnums.GameObjectType;
import engine.objects.*; import engine.objects.*;
import engine.server.MBServerStatics; import engine.server.MBServerStatics;
+1 -1
View File
@@ -9,10 +9,10 @@
package engine.devcmd.cmds; package engine.devcmd.cmds;
import engine.mbEnums;
import engine.devcmd.AbstractDevCmd; import engine.devcmd.AbstractDevCmd;
import engine.gameManager.DbManager; import engine.gameManager.DbManager;
import engine.math.Vector3fImmutable; import engine.math.Vector3fImmutable;
import engine.mbEnums;
import engine.objects.*; import engine.objects.*;
public class GotoObj extends AbstractDevCmd { public class GotoObj extends AbstractDevCmd {
+1 -1
View File
@@ -475,7 +475,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().templateID; output += "Parent Zone LoadNum : " + targetMob.parentZone.templateID;
} catch (Exception ex) { } catch (Exception ex) {
//who cares //who cares
} }
-212
View File
@@ -1,212 +0,0 @@
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
package engine.devcmd.cmds;
import engine.InterestManagement.WorldGrid;
import engine.devcmd.AbstractDevCmd;
import engine.gameManager.BuildingManager;
import engine.gameManager.ChatManager;
import engine.gameManager.DbManager;
import engine.gameManager.ZoneManager;
import engine.math.Vector3f;
import engine.math.Vector3fImmutable;
import engine.mbEnums.ProtectionState;
import engine.objects.*;
import org.pmw.tinylog.Logger;
/**
* @author Eighty
*/
public class MakeBaneCmd extends AbstractDevCmd {
public MakeBaneCmd() {
super("makebane");
}
@Override
protected void _doCmd(PlayerCharacter pc, String[] words,
AbstractGameObject target) {
if (words.length < 1 || words.length > 2) {
this.sendUsage(pc);
return;
}
int attackerID = 0;
int rank = 8;
if (words.length == 2) {
try {
attackerID = Integer.parseInt(words[0]);
rank = Integer.parseInt(words[1]);
} catch (NumberFormatException e) {
throwbackError(pc, "AttackerGuildID must be a number, " + words[0] + " is invalid");
return;
}
} else if (words.length == 1) {
if (target == null) {
throwbackError(pc, "No target specified");
return;
}
if (!(target instanceof PlayerCharacter)) {
throwbackError(pc, "Target is not a player");
return;
}
attackerID = target.getObjectUUID();
try {
rank = Integer.parseInt(words[0]);
} catch (NumberFormatException e) {
throwbackError(pc, "Rank must be specified, 1 through 8");
return;
}
}
if (rank < 1 || rank > 8) {
throwbackError(pc, "Rank must be 1 through 8");
return;
}
PlayerCharacter player = PlayerCharacter.getPlayerCharacter(attackerID);
if (player.getGuild().isEmptyGuild()) {
throwbackError(pc, "Errant's can not place banes");
return;
}
AbstractCharacter attackerAGL = Guild.GetGL(player.getGuild());
if (attackerAGL == null) {
throwbackError(pc, "No guild leader found for attacking guild.");
return;
}
if (!(attackerAGL instanceof PlayerCharacter)) {
throwbackError(pc, "Attacking guild leader is an NPC.");
return;
}
if (player.getGuild().isNPCGuild()) {
throwbackError(pc, "The guild used is an npc guild. They can not bane.");
return;
}
// if (player.getGuild().getOwnedCity() != null) {
// throwbackError(pc, "The attacking guild already has a city.");
// return;
// }
Zone zone = ZoneManager.findSmallestZone(pc.getLoc());
if (zone == null) {
throwbackError(pc, "Unable to find the zone you're in.");
return;
}
if (!zone.guild_zone) {
throwbackError(pc, "This is not a player city.");
return;
}
City city = City.getCity(zone.playerCityUUID);
if (city == null) {
throwbackError(pc, "Unable to find the city associated with this zone.");
return;
}
if (city.getTOL() == null) {
throwbackError(pc, "Unable to find the tree of life for this city.");
return;
}
if (city.getBane() != null) {
throwbackError(pc, "This city is already baned.");
return;
}
if (Bane.getBaneByAttackerGuild(player.getGuild()) != null) {
throwbackError(pc, "This guild is already baning someone.");
return;
}
Blueprint blueprint = Blueprint.getBlueprint(24300);
if (blueprint == null) {
throwbackError(pc, "Unable to find building set for banestone.");
return;
}
Vector3f rot = new Vector3f(0, 0, 0);
// *** Refactor : Overlap test goes here
//Let's drop a banestone!
Vector3fImmutable localLocation = ZoneManager.worldToLocal(pc.getLoc(), zone);
if (localLocation == null) {
ChatManager.chatSystemError(pc, "Failed to convert world location to zone location. Contact a CCR.");
Logger.info("Failed to Convert World coordinates to local zone coordinates");
return;
}
Building stone = DbManager.BuildingQueries.CREATE_BUILDING(
zone.getObjectUUID(), pc.getObjectUUID(), blueprint.getName(), blueprint.getBlueprintUUID(),
localLocation, 1.0f, blueprint.getMaxHealth(rank), ProtectionState.PROTECTED, 0, rank,
null, blueprint.getBlueprintUUID(), 1, 0.0f);
if (stone == null) {
ChatManager.chatSystemError(pc, "Failed to create banestone.");
return;
}
stone.addEffectBit((1 << 19));
BuildingManager.setRank(stone, (byte) rank);
stone.setMaxHitPoints(blueprint.getMaxHealth(stone.getRank()));
stone.setCurrentHitPoints(stone.getMaxHitPoints());
BuildingManager.setUpgradeDateTime(stone, null, 0);
//Make the bane
Bane bane = Bane.makeBane(player, city, stone);
if (bane == null) {
//delete bane stone, failed to make bane object
DbManager.BuildingQueries.DELETE_FROM_DATABASE(stone);
throwbackError(pc, "Failed to create bane.");
return;
}
WorldGrid.addObject(stone, pc);
//Add baned effect to TOL
city.getTOL().addEffectBit((1 << 16));
city.getTOL().updateEffects();
Vector3fImmutable movePlayerOutsideStone = player.getLoc();
movePlayerOutsideStone = movePlayerOutsideStone.setX(movePlayerOutsideStone.x + 10);
movePlayerOutsideStone = movePlayerOutsideStone.setZ(movePlayerOutsideStone.z + 10);
player.teleport(movePlayerOutsideStone);
throwbackInfo(pc, "The city has been succesfully baned.");
}
@Override
protected String _getHelpString() {
return "Creates an bane.";
}
@Override
protected String _getUsageString() {
return "'./makebane playerUUID baneRank'";
}
}
+8 -4
View File
@@ -64,8 +64,9 @@ public class PurgeObjectsCmd extends AbstractDevCmd {
WorldGrid.RemoveWorldObject(mob); WorldGrid.RemoveWorldObject(mob);
WorldGrid.removeObject(mob, pc); WorldGrid.removeObject(mob, pc);
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);
@@ -78,8 +79,9 @@ public class PurgeObjectsCmd extends AbstractDevCmd {
WorldGrid.RemoveWorldObject(mob); WorldGrid.RemoveWorldObject(mob);
WorldGrid.removeObject(mob, pc); WorldGrid.removeObject(mob, pc);
if (mob.getParentZone() != null) if (mob.getParentZone() != null) {
mob.getParentZone().zoneMobSet.remove(mob); mob.getParentZone().zoneMobSet.remove(mob);
}
} }
DbManager.MobQueries.DELETE_MOB(mobA); DbManager.MobQueries.DELETE_MOB(mobA);
DbManager.removeFromCache(GameObjectType.Mob, DbManager.removeFromCache(GameObjectType.Mob,
@@ -159,8 +161,9 @@ public class PurgeObjectsCmd extends AbstractDevCmd {
WorldGrid.RemoveWorldObject(mob); WorldGrid.RemoveWorldObject(mob);
WorldGrid.removeObject(mob, pc); WorldGrid.removeObject(mob, pc);
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(mbEnums.GameObjectType.NPC, DbManager.removeFromCache(mbEnums.GameObjectType.NPC,
@@ -172,8 +175,9 @@ public class PurgeObjectsCmd extends AbstractDevCmd {
WorldGrid.RemoveWorldObject(mob); WorldGrid.RemoveWorldObject(mob);
WorldGrid.removeObject(mob, pc); WorldGrid.removeObject(mob, pc);
if (mob.getParentZone() != null) if (mob.getParentZone() != null) {
mob.getParentZone().zoneMobSet.remove(mob); mob.getParentZone().zoneMobSet.remove(mob);
}
} }
DbManager.MobQueries.DELETE_MOB(mobA); DbManager.MobQueries.DELETE_MOB(mobA);
DbManager.removeFromCache(mbEnums.GameObjectType.Mob, DbManager.removeFromCache(mbEnums.GameObjectType.Mob,
+10 -6
View File
@@ -180,8 +180,9 @@ public class RemoveObjectCmd extends AbstractDevCmd {
WorldGrid.RemoveWorldObject(minionMob); WorldGrid.RemoveWorldObject(minionMob);
WorldGrid.removeObject(minionMob, pc); WorldGrid.removeObject(minionMob, pc);
if (minionMob.getParentZone() != null) if (minionMob.getParentZone() != null) {
minionMob.getParentZone().zoneMobSet.remove(minionMob); minionMob.getParentZone().zoneMobSet.remove(minionMob);
}
} }
DbManager.NPCQueries.DELETE_NPC(npc); DbManager.NPCQueries.DELETE_NPC(npc);
@@ -202,9 +203,11 @@ public class RemoveObjectCmd extends AbstractDevCmd {
return; return;
} }
if (mob.getParentZone() != null && mob.getParentZone() != currentZone && !mob.isPet() && !mob.isNecroPet()) { if (mob.getParentZone() != null) {
this.throwbackError(pc, "Error 376954: Could not Remove Mob.Mob is not in the same zone as player."); if (mob.parentZone != currentZone && !mob.isPet() && !mob.isNecroPet()) {
return; this.throwbackError(pc, "Error 376954: Could not Remove Mob.Mob is not in the same zone as player.");
return;
}
} }
// Remove npc from hirelings list. // Remove npc from hirelings list.
@@ -222,8 +225,9 @@ public class RemoveObjectCmd extends AbstractDevCmd {
WorldGrid.RemoveWorldObject(mob); WorldGrid.RemoveWorldObject(mob);
WorldGrid.removeObject(mob, pc); WorldGrid.removeObject(mob, pc);
if (mob.getParentZone() != null) if (mob.parentZone != null) {
mob.getParentZone().zoneMobSet.remove(mob); mob.parentZone.zoneMobSet.remove(mob);
}
ChatManager.chatSayInfo(pc, ChatManager.chatSayInfo(pc,
"Mob with ID " + mob.getDBID() + " removed"); "Mob with ID " + mob.getDBID() + " removed");
@@ -9,12 +9,12 @@
package engine.devcmd.cmds; package engine.devcmd.cmds;
import engine.mbEnums.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;
import engine.gameManager.DbManager; import engine.gameManager.DbManager;
import engine.math.Vector3fImmutable; import engine.math.Vector3fImmutable;
import engine.mbEnums.GameObjectType;
import engine.objects.AbstractGameObject; import engine.objects.AbstractGameObject;
import engine.objects.Building; import engine.objects.Building;
import engine.objects.PlayerCharacter; import engine.objects.PlayerCharacter;
+1 -1
View File
@@ -1,9 +1,9 @@
package engine.devcmd.cmds; package engine.devcmd.cmds;
import engine.mbEnums.GameObjectType;
import engine.InterestManagement.WorldGrid; import engine.InterestManagement.WorldGrid;
import engine.devcmd.AbstractDevCmd; import engine.devcmd.AbstractDevCmd;
import engine.gameManager.DbManager; import engine.gameManager.DbManager;
import engine.mbEnums.GameObjectType;
import engine.objects.AbstractGameObject; import engine.objects.AbstractGameObject;
import engine.objects.Guild; import engine.objects.Guild;
import engine.objects.NPC; import engine.objects.NPC;
+3 -3
View File
@@ -9,9 +9,9 @@
package engine.devcmd.cmds; package engine.devcmd.cmds;
import engine.mbEnums.DispatchChannel;
import engine.devcmd.AbstractDevCmd; import engine.devcmd.AbstractDevCmd;
import engine.net.DispatchMessage; import engine.gameManager.DispatchManager;
import engine.mbEnums.DispatchChannel;
import engine.net.client.msg.TargetedActionMsg; import engine.net.client.msg.TargetedActionMsg;
import engine.objects.AbstractGameObject; import engine.objects.AbstractGameObject;
import engine.objects.PlayerCharacter; import engine.objects.PlayerCharacter;
@@ -41,7 +41,7 @@ public class SetHealthCmd extends AbstractDevCmd {
// Update all surrounding clients. // Update all surrounding clients.
TargetedActionMsg cmm = new TargetedActionMsg(pc); TargetedActionMsg cmm = new TargetedActionMsg(pc);
DispatchMessage.dispatchMsgToInterestArea(pc, cmm, DispatchChannel.SECONDARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false); DispatchManager.dispatchMsgToInterestArea(pc, cmm, DispatchChannel.SECONDARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false);
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
this.throwbackError(pc, "Supplied data: " + words[0] this.throwbackError(pc, "Supplied data: " + words[0]
+1 -1
View File
@@ -10,9 +10,9 @@
package engine.devcmd.cmds; package engine.devcmd.cmds;
import engine.devcmd.AbstractDevCmd;
import engine.mbEnums; import engine.mbEnums;
import engine.mbEnums.ProtectionState; import engine.mbEnums.ProtectionState;
import engine.devcmd.AbstractDevCmd;
import engine.objects.AbstractGameObject; import engine.objects.AbstractGameObject;
import engine.objects.Building; import engine.objects.Building;
import engine.objects.City; import engine.objects.City;
+2 -2
View File
@@ -1,8 +1,8 @@
package engine.devcmd.cmds; package engine.devcmd.cmds;
import engine.devcmd.AbstractDevCmd; import engine.devcmd.AbstractDevCmd;
import engine.gameManager.DispatchManager;
import engine.mbEnums; import engine.mbEnums;
import engine.net.DispatchMessage;
import engine.net.client.msg.TargetedActionMsg; import engine.net.client.msg.TargetedActionMsg;
import engine.objects.AbstractGameObject; import engine.objects.AbstractGameObject;
import engine.objects.PlayerCharacter; import engine.objects.PlayerCharacter;
@@ -32,7 +32,7 @@ public class SetManaCmd extends AbstractDevCmd {
//Update all surrounding clients. - NOT for Mana? //Update all surrounding clients. - NOT for Mana?
TargetedActionMsg cmm = new TargetedActionMsg(pc); TargetedActionMsg cmm = new TargetedActionMsg(pc);
DispatchMessage.dispatchMsgToInterestArea(pc, cmm, mbEnums.DispatchChannel.SECONDARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false); DispatchManager.dispatchMsgToInterestArea(pc, cmm, mbEnums.DispatchChannel.SECONDARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false);
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
this.throwbackError(pc, "Supplied data: " + words[0] this.throwbackError(pc, "Supplied data: " + words[0]
+1 -1
View File
@@ -9,9 +9,9 @@
package engine.devcmd.cmds; package engine.devcmd.cmds;
import engine.mbEnums.GameObjectType;
import engine.InterestManagement.WorldGrid; import engine.InterestManagement.WorldGrid;
import engine.devcmd.AbstractDevCmd; import engine.devcmd.AbstractDevCmd;
import engine.mbEnums.GameObjectType;
import engine.objects.AbstractGameObject; import engine.objects.AbstractGameObject;
import engine.objects.NPC; import engine.objects.NPC;
import engine.objects.PlayerCharacter; import engine.objects.PlayerCharacter;
+2 -2
View File
@@ -1,10 +1,10 @@
package engine.devcmd.cmds; package engine.devcmd.cmds;
import engine.devcmd.AbstractDevCmd;
import engine.gameManager.DbManager;
import engine.mbEnums; import engine.mbEnums;
import engine.mbEnums.DbObjectType; import engine.mbEnums.DbObjectType;
import engine.mbEnums.GameObjectType; import engine.mbEnums.GameObjectType;
import engine.devcmd.AbstractDevCmd;
import engine.gameManager.DbManager;
import engine.objects.*; import engine.objects.*;
@@ -1,10 +1,10 @@
package engine.devcmd.cmds; package engine.devcmd.cmds;
import engine.mbEnums.DispatchChannel;
import engine.InterestManagement.InterestManager; import engine.InterestManagement.InterestManager;
import engine.devcmd.AbstractDevCmd; import engine.devcmd.AbstractDevCmd;
import engine.gameManager.ChatManager; import engine.gameManager.ChatManager;
import engine.net.DispatchMessage; import engine.gameManager.DispatchManager;
import engine.mbEnums.DispatchChannel;
import engine.net.client.msg.ApplyRuneMsg; import engine.net.client.msg.ApplyRuneMsg;
import engine.objects.AbstractGameObject; import engine.objects.AbstractGameObject;
import engine.objects.PlayerCharacter; import engine.objects.PlayerCharacter;
@@ -54,7 +54,7 @@ public class SetPromotionClassCmd extends AbstractDevCmd {
PromotionClass promo = pc.getPromotionClass(); PromotionClass promo = pc.getPromotionClass();
if (promo != null) { if (promo != null) {
ApplyRuneMsg arm = new ApplyRuneMsg(pc.getObjectType().ordinal(), pc.getObjectUUID(), promo.getObjectUUID(), promo.getObjectType().ordinal(), promo.getObjectUUID(), true); ApplyRuneMsg arm = new ApplyRuneMsg(pc.getObjectType().ordinal(), pc.getObjectUUID(), promo.getObjectUUID(), promo.getObjectType().ordinal(), promo.getObjectUUID(), true);
DispatchMessage.dispatchMsgToInterestArea(pc, arm, DispatchChannel.SECONDARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false); DispatchManager.dispatchMsgToInterestArea(pc, arm, DispatchChannel.SECONDARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false);
} }
} }
+52
View File
@@ -0,0 +1,52 @@
// ·. · · · · .
// · ·
// · ·
//
// · · ·
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
package engine.devcmd.cmds;
import engine.InterestManagement.InterestManager;
import engine.devcmd.AbstractDevCmd;
import engine.gameManager.DbManager;
import engine.mbEnums;
import engine.objects.AbstractGameObject;
import engine.objects.NPC;
import engine.objects.PlayerCharacter;
public class SetRaceCmd extends AbstractDevCmd {
public SetRaceCmd() {
super("setRace");
}
@Override
protected void _doCmd(PlayerCharacter player, String[] words,
AbstractGameObject target) {
int newRace = Integer.parseInt(words[0]);
if (target.getObjectType().equals(mbEnums.GameObjectType.NPC) == false) {
throwbackError(player, "You Must Target An NPC");
}
NPC npc = (NPC) target;
npc.loadID = newRace;
DbManager.NPCQueries.UPDATE_RACE(npc, newRace);
InterestManager.reloadCharacter(npc);
}
@Override
protected String _getHelpString() {
return "Sets NPC race";
}
@Override
protected String _getUsageString() {
return "' /setrace ID'";
}
}
+3 -3
View File
@@ -9,9 +9,9 @@
package engine.devcmd.cmds; package engine.devcmd.cmds;
import engine.mbEnums.DispatchChannel;
import engine.devcmd.AbstractDevCmd; import engine.devcmd.AbstractDevCmd;
import engine.net.DispatchMessage; import engine.gameManager.DispatchManager;
import engine.mbEnums.DispatchChannel;
import engine.net.client.msg.TargetedActionMsg; import engine.net.client.msg.TargetedActionMsg;
import engine.objects.AbstractGameObject; import engine.objects.AbstractGameObject;
import engine.objects.PlayerCharacter; import engine.objects.PlayerCharacter;
@@ -42,7 +42,7 @@ public class SetStaminaCmd extends AbstractDevCmd {
// Update all surrounding clients. // Update all surrounding clients.
TargetedActionMsg cmm = new TargetedActionMsg(pc); TargetedActionMsg cmm = new TargetedActionMsg(pc);
DispatchMessage.dispatchMsgToInterestArea(pc, cmm, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false); DispatchManager.dispatchMsgToInterestArea(pc, cmm, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false);
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
this.throwbackError(pc, "Supplied data: " + words[0] this.throwbackError(pc, "Supplied data: " + words[0]
+5 -5
View File
@@ -10,9 +10,9 @@
package engine.devcmd.cmds; package engine.devcmd.cmds;
import engine.mbEnums.GameObjectType;
import engine.devcmd.AbstractDevCmd; import engine.devcmd.AbstractDevCmd;
import engine.net.DispatchMessage; import engine.gameManager.DispatchManager;
import engine.mbEnums.GameObjectType;
import engine.net.client.msg.ApplyBuildingEffectMsg; import engine.net.client.msg.ApplyBuildingEffectMsg;
import engine.net.client.msg.UpdateCharOrMobMessage; import engine.net.client.msg.UpdateCharOrMobMessage;
import engine.objects.*; import engine.objects.*;
@@ -39,13 +39,13 @@ public class SetSubRaceCmd extends AbstractDevCmd {
if (raceID == 0) if (raceID == 0)
raceID = player.getRaceID(); raceID = player.getRaceID();
UpdateCharOrMobMessage ucm = new UpdateCharOrMobMessage(player, 1, raceID); UpdateCharOrMobMessage ucm = new UpdateCharOrMobMessage(player, 1, raceID);
DispatchMessage.sendToAllInRange(player, ucm); DispatchManager.sendToAllInRange(player, ucm);
return; return;
} }
if (words[0].equals("all")) { if (words[0].equals("all")) {
for (int i = 15999; i < 16337; i++) { for (int i = 15999; i < 16337; i++) {
ApplyBuildingEffectMsg applyBuildingEffectMsg = new ApplyBuildingEffectMsg(4, 0, target.getObjectType().ordinal(), target.getObjectUUID(), i); ApplyBuildingEffectMsg applyBuildingEffectMsg = new ApplyBuildingEffectMsg(4, 0, target.getObjectType().ordinal(), target.getObjectUUID(), i);
DispatchMessage.sendToAllInRange((AbstractWorldObject) target, applyBuildingEffectMsg); DispatchManager.sendToAllInRange((AbstractWorldObject) target, applyBuildingEffectMsg);
try { try {
Thread.sleep(500); Thread.sleep(500);
} catch (InterruptedException e) { } catch (InterruptedException e) {
@@ -56,7 +56,7 @@ public class SetSubRaceCmd extends AbstractDevCmd {
} else { } else {
ApplyBuildingEffectMsg applyBuildingEffectMsg = new ApplyBuildingEffectMsg(4, 0, target.getObjectType().ordinal(), target.getObjectUUID(), Integer.parseInt(words[0])); ApplyBuildingEffectMsg applyBuildingEffectMsg = new ApplyBuildingEffectMsg(4, 0, target.getObjectType().ordinal(), target.getObjectUUID(), Integer.parseInt(words[0]));
DispatchMessage.sendToAllInRange((AbstractWorldObject) target, applyBuildingEffectMsg); DispatchManager.sendToAllInRange((AbstractWorldObject) target, applyBuildingEffectMsg);
} }
return; return;
+1 -1
View File
@@ -1,8 +1,8 @@
package engine.devcmd.cmds; package engine.devcmd.cmds;
import engine.mbEnums.GameObjectType;
import engine.devcmd.AbstractDevCmd; import engine.devcmd.AbstractDevCmd;
import engine.math.Vector3fImmutable; import engine.math.Vector3fImmutable;
import engine.mbEnums.GameObjectType;
import engine.objects.AbstractGameObject; import engine.objects.AbstractGameObject;
import engine.objects.Building; import engine.objects.Building;
import engine.objects.PlayerCharacter; import engine.objects.PlayerCharacter;
+1 -1
View File
@@ -9,11 +9,11 @@
package engine.devcmd.cmds; package engine.devcmd.cmds;
import engine.mbEnums.GameObjectType;
import engine.devcmd.AbstractDevCmd; import engine.devcmd.AbstractDevCmd;
import engine.gameManager.BuildingManager; import engine.gameManager.BuildingManager;
import engine.gameManager.ChatManager; import engine.gameManager.ChatManager;
import engine.math.Vector3fImmutable; import engine.math.Vector3fImmutable;
import engine.mbEnums.GameObjectType;
import engine.objects.*; import engine.objects.*;
import java.util.ArrayList; import java.util.ArrayList;
+1 -1
View File
@@ -1,9 +1,9 @@
package engine.devcmd.cmds; package engine.devcmd.cmds;
import engine.mbEnums;
import engine.devcmd.AbstractDevCmd; import engine.devcmd.AbstractDevCmd;
import engine.gameManager.ZoneManager; import engine.gameManager.ZoneManager;
import engine.math.Vector3fImmutable; import engine.math.Vector3fImmutable;
import engine.mbEnums;
import engine.objects.AbstractGameObject; import engine.objects.AbstractGameObject;
import engine.objects.Mob; import engine.objects.Mob;
import engine.objects.PlayerCharacter; import engine.objects.PlayerCharacter;
@@ -9,8 +9,8 @@
package engine.devcmd.cmds; package engine.devcmd.cmds;
import engine.mbEnums.GameObjectType;
import engine.devcmd.AbstractDevCmd; import engine.devcmd.AbstractDevCmd;
import engine.mbEnums.GameObjectType;
import engine.net.client.msg.LoadStructureMsg; import engine.net.client.msg.LoadStructureMsg;
import engine.net.client.msg.MoveToPointMsg; import engine.net.client.msg.MoveToPointMsg;
import engine.net.client.msg.UnloadObjectsMsg; import engine.net.client.msg.UnloadObjectsMsg;
@@ -1,31 +0,0 @@
// ·. · · · · .
// · ·
// · ·
//
// · · ·
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
package engine.exception;
public class MsgSendException extends MBServerException {
private static final long serialVersionUID = 6927044139998382254L;
public MsgSendException() {
super();
}
public MsgSendException(String arg0, Throwable arg1) {
super(arg0, arg1);
}
public MsgSendException(String arg0) {
super(arg0);
}
public MsgSendException(Throwable arg0) {
super(arg0);
}
}
@@ -1,31 +0,0 @@
// ·. · · · · .
// · ·
// · ·
//
// · · ·
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
package engine.exception;
public class SerializationException extends MBServerException {
private static final long serialVersionUID = 6927044139998382254L;
public SerializationException() {
super();
}
public SerializationException(String arg0, Throwable arg1) {
super(arg0, arg1);
}
public SerializationException(String arg0) {
super(arg0);
}
public SerializationException(Throwable arg0) {
super(arg0);
}
}
+115 -138
View File
@@ -14,6 +14,7 @@ import engine.InterestManagement.WorldGrid;
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.loot.WorkOrder;
import engine.math.Bounds; import engine.math.Bounds;
import engine.math.Vector3fImmutable; import engine.math.Vector3fImmutable;
import engine.mbEnums; import engine.mbEnums;
@@ -49,8 +50,7 @@ public enum BuildingManager {
// Some meshes might not have slot locations assigned. // Some meshes might not have slot locations assigned.
if (slotLocations == null || if (slotLocations == null || slotLocations.isEmpty())
slotLocations.isEmpty())
return -1; return -1;
int numOfSlots = _slotLocations.get(building.meshUUID).size(); int numOfSlots = _slotLocations.get(building.meshUUID).size();
@@ -69,17 +69,15 @@ public enum BuildingManager {
// Some meshes might not have slot locations assigned. // Some meshes might not have slot locations assigned.
if (slotLocations == null || if (slotLocations == null || slotLocations.isEmpty())
slotLocations.isEmpty())
return -1; return -1;
int numOfSlots = _slotLocations.get(building.meshUUID).size(); int numOfSlots = _slotLocations.get(building.meshUUID).size();
for (int i = numOfSlots; i > 0; i--) { for (int i = numOfSlots; i > 0; i--)
if (!building.getHirelings().containsValue(i)) if (!building.getHirelings().containsValue(i))
return i; return i;
}
return -1; return -1;
} }
@@ -92,9 +90,8 @@ public enum BuildingManager {
buildingLocation = _slotLocations.get(building.meshUUID).get(slot - 1); // array index buildingLocation = _slotLocations.get(building.meshUUID).get(slot - 1); // array index
if (buildingLocation == null) { if (buildingLocation == null)
Logger.error("Invalid slot for building: " + building.getObjectUUID()); Logger.error("Invalid slot for building: " + building.getObjectUUID());
}
return buildingLocation; return buildingLocation;
} }
@@ -107,73 +104,67 @@ public enum BuildingManager {
if (building == null) if (building == null)
return false; return false;
//cannot access destroyed buildings
if (building.getRank() == -1) if (building.getRank() == -1)
return false; return false;
if (IsOwner(building, player)) //admin characters can always access buildings
return true;
//individual friend.
if (building.getFriends() != null && building.getFriends().get(player.getObjectUUID()) != null)
return true;
//Admins can access stuff
if (player.isCSR()) if (player.isCSR())
return true; return true;
//Guild stuff //owner can always access their own building
if (building.getGuild().isGuildLeader(player.getObjectUUID()))
return true;
if (building.getFriends().get(player.getGuild().getObjectUUID()) != null
&& building.getFriends().get(player.getGuild().getObjectUUID()).friendType == 8)
return true;
if (building.getFriends().get(player.getGuild().getObjectUUID()) != null
&& building.getFriends().get(player.getGuild().getObjectUUID()).friendType == 9
&& GuildStatusController.isInnerCouncil(player.getGuildStatus()))
return true;
if (Guild.sameGuild(building.getGuild(), player.getGuild()) && GuildStatusController.isInnerCouncil(player.getGuildStatus()))
return true;
if (Guild.sameGuild(building.getGuild(), player.getGuild()) && GuildStatusController.isGuildLeader(player.getGuildStatus()))
return true;
return false;
//TODO test friends list once added
//does not meet above criteria. Cannot access.
}
public static boolean playerCanManageNotFriends(PlayerCharacter player, Building building) {
//Player Can only Control Building if player is in Same Guild as Building and is higher rank than IC.
if (player == null)
return false;
if (building == null)
return false;
if (building.getRank() == -1)
return false;
if (IsOwner(building, player)) if (IsOwner(building, player))
return true; return true;
//Somehow guild leader check fails? lets check if Player is true Guild GL. //check for default IC access if building belongs to same guild
if (building.getGuild() != null && building.getGuild().isGuildLeader(player.getObjectUUID())) if(player.guild.equals(building.getGuild())) {
return true; if (building.getBlueprint() != null && building.getBlueprint().getBuildingGroup() != null) {
if (GuildStatusController.isGuildLeader(player.getGuildStatus()) == false && GuildStatusController.isInnerCouncil(player.getGuildStatus()) == false) switch (building.getBlueprint().getBuildingGroup()) {
return false; case TOL:
case BARRACK:
case SPIRE:
case SHRINE:
case BANESTONE:
case MINE:
case WAREHOUSE:
case BULWARK:
case SIEGETENT:
if (GuildStatusController.isInnerCouncil(player.getGuildStatus()))
return true;
if (GuildStatusController.isGuildLeader(player.getGuildStatus()))
return true;
break;
}
}
}
//check against friends list entries if any present
if (building.getFriends() != null) {
//check individuals
if (building.getFriends().get(player.getObjectUUID()) != null)
return true;
if (building.getFriends().get(player.guild.objectUUID) != null) {
//check friend type for guild related access
switch (building.getFriends().get(player.guild.objectUUID).friendType) {
case 8: //full member
if (GuildStatusController.isFullMember(player.getGuildStatus()))
return true;
break;
case 9: //Inner Council
if (GuildStatusController.isInnerCouncil(player.getGuildStatus()))
return true;
if (GuildStatusController.isGuildLeader(player.getGuildStatus()))
return true;
break;
}
}
}
//did not meet access grant criteria, deny access
return false; return false;
} }
public static synchronized boolean lootBuilding(PlayerCharacter player, Building building) { public static synchronized boolean lootBuilding(PlayerCharacter player, Building building) {
@@ -274,9 +265,7 @@ public enum BuildingManager {
// Submit upgrade job for future date or current instant // Submit upgrade job for future date or current instant
if (building.getUpgradeDateTime().isAfter(LocalDateTime.now())) { if (building.getUpgradeDateTime().isAfter(LocalDateTime.now())) {
JobContainer jc = JobScheduler.getInstance().scheduleJob(new UpgradeBuildingJob(building), JobContainer jc = JobScheduler.getInstance().scheduleJob(new UpgradeBuildingJob(building), building.getUpgradeDateTime().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
building.getUpgradeDateTime().atZone(ZoneId.systemDefault())
.toInstant().toEpochMilli());
} else } else
JobScheduler.getInstance().scheduleJob(new UpgradeBuildingJob(building), 0); JobScheduler.getInstance().scheduleJob(new UpgradeBuildingJob(building), 0);
} }
@@ -335,8 +324,35 @@ public enum BuildingManager {
WorldGrid.RemoveWorldObject(minionMob); WorldGrid.RemoveWorldObject(minionMob);
WorldGrid.unloadObject(minionMob); WorldGrid.unloadObject(minionMob);
if (minionMob.getParentZone() != null) if (minionMob.parentZone != null)
minionMob.getParentZone().zoneMobSet.remove(minionMob); minionMob.parentZone.zoneMobSet.remove(minionMob);
}
// Clear all workorders for this hireling
if (hireling.getObjectType().equals(GameObjectType.NPC)) {
NPC hirelingNPC = (NPC) hireling;
if (ForgeManager.vendorWorkOrderLookup.get(hirelingNPC) != null)
for (WorkOrder workOrder : ForgeManager.vendorWorkOrderLookup.get(hirelingNPC)) {
workOrder.runCompleted.set(true);
workOrder.vendor = null;
// Remove any cooking items from collections
// to ensure we don't leak memory.
for (Item item : workOrder.cooking) {
DbManager.removeFromCache(item);
ForgeManager.itemWorkOrderLookup.remove(item);
}
DbManager.WarehouseQueries.DELETE_WORKORDER(workOrder);
}
// Finally remove the NPC from ForgeManager
ForgeManager.vendorWorkOrderLookup.remove(hirelingNPC);
} }
// Remove hireling from building // Remove hireling from building
@@ -349,10 +365,9 @@ public enum BuildingManager {
Mob hirelingMob = (Mob) hireling; Mob hirelingMob = (Mob) hireling;
if (hirelingMob.getParentZone() != null) if (hirelingMob.parentZone != null)
if (hirelingMob.getParentZone().zoneMobSet.contains(hirelingMob)) if (hirelingMob.parentZone.zoneMobSet.contains(hirelingMob))
hirelingMob.getParentZone().zoneMobSet.remove(hireling); hirelingMob.parentZone.zoneMobSet.remove(hireling);
} }
if (hireling.getObjectType().equals(GameObjectType.NPC)) { if (hireling.getObjectType().equals(GameObjectType.NPC)) {
@@ -377,10 +392,8 @@ public enum BuildingManager {
DbManager.MobQueries.DELETE_MOB((Mob) hireling); DbManager.MobQueries.DELETE_MOB((Mob) hireling);
else else
DbManager.NPCQueries.DELETE_NPC((NPC) hireling); 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
@@ -392,22 +405,17 @@ public enum BuildingManager {
// Remove all hirelings for destroyed buildings // Remove all hirelings for destroyed buildings
if (building.getRank() < 1) { if (building.getRank() < 1) {
for (AbstractCharacter slottedNPC : building.getHirelings().keySet()) for (AbstractCharacter slottedNPC : building.getHirelings().keySet())
BuildingManager.removeHireling(building, slottedNPC); BuildingManager.removeHireling(building, slottedNPC);
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())
if (building.getHirelings().get(hireling) > building.getBlueprint().getSlotsForRank(building.getRank())) if (building.getHirelings().get(hireling) > building.getBlueprint().getSlotsForRank(building.getRank()))
BuildingManager.removeHireling(building, hireling); BuildingManager.removeHireling(building, hireling);
}
refreshHirelings(building); refreshHirelings(building);
} }
@@ -439,6 +447,7 @@ public enum BuildingManager {
return false; return false;
//lets pass true if player is owner anyway. //lets pass true if player is owner anyway.
if (building.getOwner().equals(player)) if (building.getOwner().equals(player))
return true; return true;
@@ -451,52 +460,22 @@ public enum BuildingManager {
if (!Guild.sameGuild(building.getGuild(), player.getGuild())) if (!Guild.sameGuild(building.getGuild(), player.getGuild()))
return false; return false;
return GuildStatusController.isGuildLeader(player.getGuildStatus()) != false || GuildStatusController.isInnerCouncil(player.getGuildStatus()) != false; return GuildStatusController.isGuildLeader(player.getGuildStatus()) || GuildStatusController.isInnerCouncil(player.getGuildStatus());
}
//This is mainly used for Rolling and gold sharing between building and warehouse.
public static int GetWithdrawAmountForRolling(Building building, int cost) {
//all funds are available to roll.
if (cost <= GetAvailableGold(building))
return cost;
// cost is more than available gold, return available gold
return GetAvailableGold(building);
}
public static int GetAvailableGold(Building building) {
if (building.getStrongboxValue() == 0)
return 0;
if (building.getStrongboxValue() < building.reserve)
return 0;
return building.getStrongboxValue() - building.reserve;
}
public static int GetOverdraft(Building building, int cost) {
int availableGold = GetWithdrawAmountForRolling(building, cost);
return cost - availableGold;
} }
public static boolean IsPlayerHostile(Building building, PlayerCharacter player) { public static boolean IsPlayerHostile(Building building, PlayerCharacter player) {
//Nation Members and Guild members are not hostile.
// if (building.getGuild() != null){
// if (pc.getGuild() != null)
// if (building.getGuild().getObjectUUID() == pc.getGuildUUID()
// || pc.getGuild().getNation().getObjectUUID() == building.getGuild().getNation().getObjectUUID())
// return false;
// }
if (Guild.sameNationExcludeErrant(building.getGuild(), player.getGuild())) if (Guild.sameNationExcludeErrant(building.getGuild(), player.getGuild()))
return false; return false;
if(building.enforceKOS) {
if (building.getCity() != null) {
Building TOL = building.getCity().getTOL();
if (TOL != null) {
building = TOL;
}
}
}
if (!building.reverseKOS) { if (!building.reverseKOS) {
Condemned condemn = building.getCondemned().get(player.getObjectUUID()); Condemned condemn = building.getCondemned().get(player.getObjectUUID());
@@ -548,7 +527,7 @@ public enum BuildingManager {
String pirateName = NPCManager.getPirateName(NpcID.getMobbaseID()); String pirateName = NPCManager.getPirateName(NpcID.getMobbaseID());
NPC npc = null; NPC npc;
npc = NPC.createNPC(pirateName, NpcID.getObjectUUID(), NpcLoc, building.getGuild(), zone, (short) rank, building); npc = NPC.createNPC(pirateName, NpcID.getObjectUUID(), NpcLoc, building.getGuild(), zone, (short) rank, building);
@@ -564,7 +543,7 @@ public enum BuildingManager {
public static synchronized boolean addHireling(Building building, PlayerCharacter contractOwner, Zone zone, Contract contract, Item item) { public static synchronized boolean addHireling(Building building, PlayerCharacter contractOwner, Zone zone, Contract contract, Item item) {
int rank = 1; int rank;
if (building.getBlueprintUUID() == 0) if (building.getBlueprintUUID() == 0)
return false; return false;
@@ -623,6 +602,7 @@ public enum BuildingManager {
if (contract.getContractID() == 910) { if (contract.getContractID() == 910) {
//guard dog //guard dog
mobile = Mob.createMob(contract.getMobbaseID(), Vector3fImmutable.ZERO, contractOwner.getGuild(), zone, building, contract, pirateName, rank, mbEnums.AIAgentType.GUARDCAPTAIN); mobile = Mob.createMob(contract.getMobbaseID(), Vector3fImmutable.ZERO, contractOwner.getGuild(), zone, building, contract, pirateName, rank, mbEnums.AIAgentType.GUARDCAPTAIN);
if (mobile == null) if (mobile == null)
@@ -682,9 +662,7 @@ public enum BuildingManager {
if (building.getOwner() == null) if (building.getOwner() == null)
return false; return false;
return building.getOwner().getObjectUUID() == player.getObjectUUID(); return building.getOwner().getObjectUUID() == player.getObjectUUID();
} }
public static float GetMissingHealth(Building building) { public static float GetMissingHealth(Building building) {
@@ -696,6 +674,7 @@ public enum BuildingManager {
} }
public static Regions GetRegion(Building building, float x, float y, float z) { public static Regions GetRegion(Building building, float x, float y, float z) {
if (building.getBounds() == null) if (building.getBounds() == null)
return null; return null;
@@ -703,17 +682,18 @@ public enum BuildingManager {
return null; return null;
Regions currentRegion = null; Regions currentRegion = null;
for (Regions region : building.getBounds().getRegions()) {
if (region.isPointInPolygon(new Vector3fImmutable(x, y, z))) { for (Regions region : building.getBounds().getRegions()) {
if (region.isPointInPolygon(new Vector3fImmutable(x, y, z)))
if (y > (region.highLerp.y - 5)) if (y > (region.highLerp.y - 5))
currentRegion = region; currentRegion = region;
}
} }
return currentRegion; return currentRegion;
} }
public static Regions GetRegion(Building building, int room, int level, float x, float z) { public static Regions GetRegion(Building building, int room, int level, float x, float z) {
if (building.getBounds() == null) if (building.getBounds() == null)
return null; return null;
@@ -724,12 +704,12 @@ public enum BuildingManager {
if (region.getLevel() != level) if (region.getLevel() != level)
continue; continue;
if (region.getRoom() != room) if (region.getRoom() != room)
continue; continue;
if (region.isPointInPolygon(new Vector3fImmutable(x, 0, z))) { if (region.isPointInPolygon(new Vector3fImmutable(x, 0, z)))
return region; return region;
}
} }
return null; return null;
} }
@@ -741,11 +721,10 @@ public enum BuildingManager {
if (building == null) if (building == null)
return mbEnums.Ruins.getRandomRuin().getLocation(); return mbEnums.Ruins.getRandomRuin().getLocation();
bindLoc = building.getLoc(); bindLoc = building.getLoc();
float radius = Bounds.meshBoundsCache.get(building.getMeshUUID()).radius; float radius = Bounds.meshBoundsCache.get(building.getMeshUUID()).radius;
if (building.getRank() == 8) { if (building.getRank() == 8) {
bindLoc = building.getStuckLocation(); bindLoc = building.getStuckLocation();
if (bindLoc != null) if (bindLoc != null)
@@ -798,7 +777,6 @@ public enum BuildingManager {
int newMeshUUID; int newMeshUUID;
boolean success; boolean success;
// If this building has no blueprint then set rank and exit immediatly. // 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)) { if (building.blueprintUUID == 0 || building.getBlueprint() != null && building.getBlueprint().getBuildingGroup().equals(BuildingGroup.MINE)) {
@@ -810,14 +788,14 @@ public enum BuildingManager {
// Delete any upgrade jobs before doing anything else. It won't quite work // Delete any upgrade jobs before doing anything else. It won't quite work
// if in a few lines we happen to delete this building. // if in a few lines we happen to delete this building.
JobContainer jc = building.getTimers().get("UPGRADE"); JobContainer jobContainer = building.getTimers().get("UPGRADE");
if (jc != null) { if (jobContainer != null) {
if (!JobScheduler.getInstance().cancelScheduledJob(jc)) if (!JobScheduler.getInstance().cancelScheduledJob(jobContainer))
Logger.error("failed to cancel existing upgrade job."); Logger.error("failed to cancel existing upgrade job.");
} }
// Attempt write to database, or delete the building // Attempt to write to database or delete the building
// if we are destroying it. // if we are destroying it.
if (rank == -1) if (rank == -1)
@@ -825,7 +803,7 @@ public enum BuildingManager {
else else
success = DbManager.BuildingQueries.updateBuildingRank(building, rank); success = DbManager.BuildingQueries.updateBuildingRank(building, rank);
if (success == false) { if (!success) {
Logger.error("Error writing to database UUID: " + building.getObjectUUID()); Logger.error("Error writing to database UUID: " + building.getObjectUUID());
return; return;
} }
@@ -882,7 +860,6 @@ public enum BuildingManager {
if (Bounds.collide(loc, building.getBounds())) if (Bounds.collide(loc, building.getBounds()))
return building; return building;
} }
return null; return null;
} }
+19 -20
View File
@@ -13,11 +13,10 @@ import engine.InterestManagement.WorldGrid;
import engine.db.archive.BaneRecord; import engine.db.archive.BaneRecord;
import engine.db.archive.PvpRecord; import engine.db.archive.PvpRecord;
import engine.mbEnums; import engine.mbEnums;
import engine.mbEnums.EffectSourceType;
import engine.mbEnums.GameObjectType; import engine.mbEnums.GameObjectType;
import engine.mbEnums.ModType; import engine.mbEnums.ModType;
import engine.mbEnums.SourceType;
import engine.net.Dispatch; import engine.net.Dispatch;
import engine.net.DispatchMessage;
import engine.net.MessageDispatcher; import engine.net.MessageDispatcher;
import engine.net.client.ClientConnection; import engine.net.client.ClientConnection;
import engine.net.client.handlers.ClientAdminCommandMsgHandler; import engine.net.client.handlers.ClientAdminCommandMsgHandler;
@@ -87,7 +86,7 @@ public enum ChatManager {
for (AbstractWorldObject abstractWorldObject : distroList) { for (AbstractWorldObject abstractWorldObject : distroList) {
PlayerCharacter playerCharacter = (PlayerCharacter) abstractWorldObject; PlayerCharacter playerCharacter = (PlayerCharacter) abstractWorldObject;
Dispatch dispatch = Dispatch.borrow(playerCharacter, msg); Dispatch dispatch = Dispatch.borrow(playerCharacter, msg);
DispatchMessage.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY); DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY);
} }
} }
@@ -95,7 +94,7 @@ public enum ChatManager {
PlayerBonuses bonus = pc.getBonuses(); PlayerBonuses bonus = pc.getBonuses();
if (bonus != null && bonus.getBool(ModType.Silenced, SourceType.None)) { if (bonus != null && bonus.getBool(ModType.Silenced, EffectSourceType.None)) {
ChatManager.chatSayError(pc, SILENCED); ChatManager.chatSayError(pc, SILENCED);
return true; return true;
} }
@@ -161,7 +160,7 @@ public enum ChatManager {
// Make the Message // Make the Message
ChatSayMsg chatSayMsg = new ChatSayMsg(player, text); ChatSayMsg chatSayMsg = new ChatSayMsg(player, text);
DispatchMessage.dispatchMsgToInterestArea(pcSender, chatSayMsg, mbEnums.DispatchChannel.SECONDARY, MBServerStatics.SAY_RANGE, true, true); DispatchManager.dispatchMsgToInterestArea(pcSender, chatSayMsg, mbEnums.DispatchChannel.SECONDARY, MBServerStatics.SAY_RANGE, true, true);
} }
@@ -171,7 +170,7 @@ public enum ChatManager {
msg.setMessageType(4); msg.setMessageType(4);
msg.setChannel(mbEnums.ChatChannelType.SYSTEM.getChannelID()); msg.setChannel(mbEnums.ChatChannelType.SYSTEM.getChannelID());
Dispatch dispatch = Dispatch.borrow(targetPlayer, msg); Dispatch dispatch = Dispatch.borrow(targetPlayer, msg);
DispatchMessage.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY); DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY);
} }
/* /*
@@ -195,7 +194,7 @@ public enum ChatManager {
// Make the Message // Make the Message
ChatShoutMsg msg = new ChatShoutMsg(sender, text); ChatShoutMsg msg = new ChatShoutMsg(sender, text);
DispatchMessage.dispatchMsgToInterestArea(pcSender, msg, mbEnums.DispatchChannel.SECONDARY, MBServerStatics.SHOUT_RANGE, true, true); DispatchManager.dispatchMsgToInterestArea(pcSender, msg, mbEnums.DispatchChannel.SECONDARY, MBServerStatics.SHOUT_RANGE, true, true);
} }
@@ -217,7 +216,7 @@ public enum ChatManager {
// Make the Message // Make the Message
ChatGlobalMsg msg = new ChatGlobalMsg(sender, text); ChatGlobalMsg msg = new ChatGlobalMsg(sender, text);
DispatchMessage.dispatchMsgToAll(sender, msg, true); DispatchManager.dispatchMsgToAll(sender, msg, true);
} }
@@ -284,13 +283,13 @@ public enum ChatManager {
// Send dispatch to each player // Send dispatch to each player
Dispatch dispatch = Dispatch.borrow(pcRecip, chatTellMsg); Dispatch dispatch = Dispatch.borrow(pcRecip, chatTellMsg);
DispatchMessage.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY); DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY);
} }
// Also send /tell to sender // Also send /tell to sender
if (pcSender != null) { if (pcSender != null) {
Dispatch dispatch = Dispatch.borrow(pcSender, chatTellMsg); Dispatch dispatch = Dispatch.borrow(pcSender, chatTellMsg);
DispatchMessage.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY); DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY);
} }
} else } else
@@ -339,8 +338,8 @@ public enum ChatManager {
chatGuildMsg.setSourceID(sender.getObjectUUID()); chatGuildMsg.setSourceID(sender.getObjectUUID());
chatGuildMsg.setSourceName(sender.getFirstName()); chatGuildMsg.setSourceName(sender.getFirstName());
chatGuildMsg.setUnknown03(WorldServer.worldMapID); // Server ID chatGuildMsg.setUnknown03(WorldServer.worldMapID); // Server ID
chatGuildMsg.setUnknown04(sender.getGuild() != null ? sender.getGuild() Guild guild1 = sender.getGuild();
.getCharter() : 0); // Charter? chatGuildMsg.setUnknown04(sender.getGuild() != null ? guild1.charter.ordinal() : 0); // Charter?
chatGuildMsg.setUnknown05(GuildStatusController.getTitle(sender.getGuildStatus())); // Title? chatGuildMsg.setUnknown05(GuildStatusController.getTitle(sender.getGuildStatus())); // Title?
chatGuildMsg.setUnknown06(sender.race.getRaceType().getCharacterSex().equals(mbEnums.CharacterSex.MALE) ? 1 : 2); // isMale?, seen 1 and 2 chatGuildMsg.setUnknown06(sender.race.getRaceType().getCharacterSex().equals(mbEnums.CharacterSex.MALE) ? 1 : 2); // isMale?, seen 1 and 2
@@ -349,7 +348,7 @@ public enum ChatManager {
for (AbstractWorldObject abstractWorldObject : distroList) { for (AbstractWorldObject abstractWorldObject : distroList) {
PlayerCharacter playerCharacter = (PlayerCharacter) abstractWorldObject; PlayerCharacter playerCharacter = (PlayerCharacter) abstractWorldObject;
Dispatch dispatch = Dispatch.borrow(playerCharacter, chatGuildMsg); Dispatch dispatch = Dispatch.borrow(playerCharacter, chatGuildMsg);
DispatchMessage.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY); DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY);
} }
} }
@@ -404,7 +403,7 @@ public enum ChatManager {
for (AbstractWorldObject abstractWorldObject : distroList) { for (AbstractWorldObject abstractWorldObject : distroList) {
PlayerCharacter playerCharacter = (PlayerCharacter) abstractWorldObject; PlayerCharacter playerCharacter = (PlayerCharacter) abstractWorldObject;
Dispatch dispatch = Dispatch.borrow(playerCharacter, chatICMsg); Dispatch dispatch = Dispatch.borrow(playerCharacter, chatICMsg);
DispatchMessage.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY); DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY);
} }
} }
@@ -463,7 +462,7 @@ public enum ChatManager {
for (AbstractWorldObject abstractWorldObject : distroList) { for (AbstractWorldObject abstractWorldObject : distroList) {
PlayerCharacter playerCharacter = (PlayerCharacter) abstractWorldObject; PlayerCharacter playerCharacter = (PlayerCharacter) abstractWorldObject;
Dispatch dispatch = Dispatch.borrow(playerCharacter, chatGroupMsg); Dispatch dispatch = Dispatch.borrow(playerCharacter, chatGroupMsg);
DispatchMessage.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY); DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY);
} }
} }
@@ -490,14 +489,14 @@ public enum ChatManager {
msg.setName(sender.getFirstName()); msg.setName(sender.getFirstName());
msg.setGuildTitle(GuildStatusController.getTitle(sender.getGuildStatus())); msg.setGuildTitle(GuildStatusController.getTitle(sender.getGuildStatus()));
msg.setGuildUUID(guild.getObjectUUID()); msg.setGuildUUID(guild.getObjectUUID());
msg.setCharter(guild.getCharter()); msg.setCharter(guild.charter.ordinal());
// Send dispatch to each player // Send dispatch to each player
for (AbstractWorldObject abstractWorldObject : distroList) { for (AbstractWorldObject abstractWorldObject : distroList) {
PlayerCharacter playerCharacter = (PlayerCharacter) abstractWorldObject; PlayerCharacter playerCharacter = (PlayerCharacter) abstractWorldObject;
Dispatch dispatch = Dispatch.borrow(playerCharacter, msg); Dispatch dispatch = Dispatch.borrow(playerCharacter, msg);
DispatchMessage.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY); DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY);
} }
} }
@@ -733,7 +732,7 @@ public enum ChatManager {
public static void chatPVP(String text) { public static void chatPVP(String text) {
// Create message // Create message
ChatPvPMsg msg = new ChatPvPMsg(null, text); ChatPvPMsg msg = new ChatPvPMsg(null, text);
DispatchMessage.dispatchMsgToAll(msg); DispatchManager.dispatchMsgToAll(msg);
} }
public static ChatSystemMsg CombatInfo(AbstractWorldObject source, AbstractWorldObject target) { public static ChatSystemMsg CombatInfo(AbstractWorldObject source, AbstractWorldObject target) {
@@ -844,7 +843,7 @@ public enum ChatManager {
for (AbstractWorldObject abstractWorldObject : distroList) { for (AbstractWorldObject abstractWorldObject : distroList) {
PlayerCharacter playerCharacter = (PlayerCharacter) abstractWorldObject; PlayerCharacter playerCharacter = (PlayerCharacter) abstractWorldObject;
Dispatch dispatch = Dispatch.borrow(playerCharacter, chatSystemMsg); Dispatch dispatch = Dispatch.borrow(playerCharacter, chatSystemMsg);
DispatchMessage.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY); DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY);
} }
} }
@@ -993,7 +992,7 @@ public enum ChatManager {
chatSystemMsg.setChannel(channel); chatSystemMsg.setChannel(channel);
Dispatch dispatch = Dispatch.borrow(playerCharacter, chatSystemMsg); Dispatch dispatch = Dispatch.borrow(playerCharacter, chatSystemMsg);
DispatchMessage.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY); DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY);
} }
+496 -338
View File
@@ -13,23 +13,40 @@ import engine.job.JobScheduler;
import engine.jobs.AttackJob; import engine.jobs.AttackJob;
import engine.jobs.DeferredPowerJob; import engine.jobs.DeferredPowerJob;
import engine.mbEnums; import engine.mbEnums;
import engine.net.DispatchMessage;
import engine.net.client.ClientConnection; import engine.net.client.ClientConnection;
import engine.net.client.msg.TargetedActionMsg; import engine.net.client.msg.TargetedActionMsg;
import engine.net.client.msg.UpdateStateMsg; import engine.net.client.msg.UpdateStateMsg;
import engine.objects.*; import engine.objects.*;
import engine.powers.DamageShield; import engine.powers.DamageShield;
import engine.powers.effectmodifiers.AbstractEffectModifier; import engine.powers.effectmodifiers.AbstractEffectModifier;
import engine.powers.effectmodifiers.WeaponProcEffectModifier;
import engine.server.MBServerStatics; import engine.server.MBServerStatics;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
import static java.lang.Math.pow;
public enum CombatManager { public enum CombatManager {
// MB Dev notes:
// Class implements all combat mechanics for Magicbane.
//
// Combat initiates in "combatCycle" to determine which hands will be swung, and attack is processed based on that.
// Handles all combat for AbstractCharacter including player characters and mobiles.
// Controls toggling of combat and sit/stand for all AbstractCharacters
//
//
COMBAT_MANAGER; COMBAT_MANAGER;
public static final int COMBAT_BLOCK_ANIMATION = 298;
public static final int COMBAT_PARRY_ANIMATION = 299;
public static final int COMBAT_DODGE_ANIMATION = 300;
public static void combatCycle(AbstractCharacter attacker, AbstractWorldObject target) { public static void combatCycle(AbstractCharacter attacker, AbstractWorldObject target) {
@@ -38,15 +55,19 @@ public enum CombatManager {
if (attacker == null || target == null || !attacker.isAlive() || !target.isAlive()) if (attacker == null || target == null || !attacker.isAlive() || !target.isAlive())
return; return;
if (attacker.getObjectType().equals(mbEnums.GameObjectType.Mob))
if (((Mob) attacker).nextAttackTime > System.currentTimeMillis())
return;
switch (target.getObjectType()) { switch (target.getObjectType()) {
case Building: case Building:
if (((Building) target).isVulnerable() == false) if (!((Building) target).isVulnerable())
return; return;
break; break;
case PlayerCharacter: case PlayerCharacter:
case Mob: case Mob:
PlayerBonuses bonuses = ((AbstractCharacter) target).getBonuses(); PlayerBonuses bonuses = ((AbstractCharacter) target).getBonuses();
if (bonuses != null && bonuses.getBool(mbEnums.ModType.ImmuneToAttack, mbEnums.SourceType.None)) if (bonuses != null && bonuses.getBool(mbEnums.ModType.ImmuneToAttack, mbEnums.EffectSourceType.None))
return; return;
break; break;
case NPC: case NPC:
@@ -59,34 +80,58 @@ public enum CombatManager {
if (mainWeapon == null && offWeapon == null) { if (mainWeapon == null && offWeapon == null) {
//no weapons equipped, punch with both fists //no weapons equipped, punch with both fists
processAttack(attacker, target, mbEnums.EquipSlotType.RHELD); processAttack(attacker, target, mbEnums.EquipSlotType.RHELD);
if (attacker.getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter))
processAttack(attacker, target, mbEnums.EquipSlotType.LHELD);
return;
}
if (mainWeapon != null && offWeapon == null) {
//swing right hand only
processAttack(attacker, target, mbEnums.EquipSlotType.RHELD);
return;
}
if (mainWeapon == null && offWeapon != null && !offWeapon.template.item_skill_used.equals("Block")) {
//swing left hand only
processAttack(attacker, target, mbEnums.EquipSlotType.LHELD); processAttack(attacker, target, mbEnums.EquipSlotType.LHELD);
} else if (mainWeapon == null && offWeapon != null && offWeapon.template.item_skill_required.containsKey("Block")) { return;
}
if (mainWeapon == null && offWeapon != null && offWeapon.template.item_skill_used.equals("Block")) {
//no weapon equipped with a shield, punch with one hand //no weapon equipped with a shield, punch with one hand
processAttack(attacker, target, mbEnums.EquipSlotType.RHELD); processAttack(attacker, target, mbEnums.EquipSlotType.RHELD);
} else if (mainWeapon != null && offWeapon != null && offWeapon.template.item_skill_required.containsKey("Block")) { return;
}
if (mainWeapon != null && offWeapon != null && offWeapon.template.item_skill_used.equals("Block")) {
//one weapon equipped with a shield, swing with one hand //one weapon equipped with a shield, swing with one hand
processAttack(attacker, target, mbEnums.EquipSlotType.RHELD); processAttack(attacker, target, mbEnums.EquipSlotType.RHELD);
} else if (mainWeapon != null && offWeapon != null && offWeapon.template.item_skill_required.containsKey("Block") == false) { return;
}
if (mainWeapon != null && offWeapon != null && !offWeapon.template.item_skill_used.equals("Block")) {
//two weapons equipped, swing both hands //two weapons equipped, swing both hands
processAttack(attacker, target, mbEnums.EquipSlotType.RHELD); processAttack(attacker, target, mbEnums.EquipSlotType.RHELD);
processAttack(attacker, target, mbEnums.EquipSlotType.LHELD); if (attacker.getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter))
} else if (mainWeapon == null && offWeapon != null && offWeapon.template.item_skill_required.containsKey("Block") == false) { processAttack(attacker, target, mbEnums.EquipSlotType.LHELD);
//swing left hand only
processAttack(attacker, target, mbEnums.EquipSlotType.LHELD);
} else if (mainWeapon != null && offWeapon == null) {
//swing left hand only
processAttack(attacker, target, mbEnums.EquipSlotType.RHELD);
} }
} }
public static void processAttack(AbstractCharacter attacker, AbstractWorldObject target, mbEnums.EquipSlotType slot) { public static void processAttack(AbstractCharacter attacker, AbstractWorldObject target, mbEnums.EquipSlotType slot) {
// heck if character can even attack yet if (attacker.getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter)) {
if (!attacker.isCombat())
if (attacker.getTimestamps().containsKey("Attack" + slot.name()))
if (System.currentTimeMillis() < attacker.getTimestamps().get("Attack" + slot.name()))
return; return;
//check if this slot is on attack timer, if timer has passed clear it, else early exit
if (attacker.getTimers() != null && attacker.getTimers().containsKey("Attack" + slot.name()))
if (attacker.getTimers().get("Attack" + slot.name()).timeToExecutionLeft() <= 0)
attacker.getTimers().remove("Attack" + slot.name());
else
return;
}
// check if character is in range to attack target // check if character is in range to attack target
PlayerBonuses bonus = attacker.getBonuses(); PlayerBonuses bonus = attacker.getBonuses();
@@ -98,9 +143,9 @@ public enum CombatManager {
if (weapon != null) { if (weapon != null) {
if (bonus != null) if (bonus != null)
rangeMod += bonus.getFloatPercentAll(mbEnums.ModType.WeaponRange, mbEnums.SourceType.None); rangeMod += bonus.getFloatPercentAll(mbEnums.ModType.WeaponRange, mbEnums.EffectSourceType.None);
attackRange = weapon.template.item_weapon_max_range * rangeMod; attackRange += weapon.template.item_weapon_max_range * rangeMod;
} }
if (attacker.getObjectType().equals(mbEnums.GameObjectType.Mob)) if (attacker.getObjectType().equals(mbEnums.GameObjectType.Mob))
@@ -109,248 +154,335 @@ public enum CombatManager {
float distanceSquared = attacker.loc.distanceSquared(target.loc); float distanceSquared = attacker.loc.distanceSquared(target.loc);
if (distanceSquared > attackRange * attackRange) boolean inRange = false;
return;
// take stamina away from attacker
if (weapon != null) {
float stam = weapon.template.item_wt / 3f;
stam = (stam < 1) ? 1 : stam;
attacker.modifyStamina(-(stam), attacker, true);
} else
attacker.modifyStamina(-0.5f, attacker, true);
//cancel things that are cancelled by an attack
attacker.cancelOnAttackSwing();
//declare relevant variables
int min = attacker.minDamageHandOne;
int max = attacker.maxDamageHandOne;
int atr = attacker.atrHandOne;
//get the proper stats based on which slot is attacking
if (slot == mbEnums.EquipSlotType.LHELD) {
min = attacker.minDamageHandTwo;
max = attacker.maxDamageHandTwo;
atr = attacker.atrHandTwo;
}
int def = 0;
if (AbstractCharacter.IsAbstractCharacter(target))
def = ((AbstractCharacter) target).defenseRating;
//calculate hit chance based off ATR and DEF
int hitChance;
if (def == 0)
def = 1;
float dif = atr / def;
if (dif <= 0.8f)
hitChance = 4;
else
hitChance = ((int) (450 * (dif - 0.8f)) + 4);
if (target.getObjectType() == mbEnums.GameObjectType.Building)
hitChance = 100;
int passiveAnim = getSwingAnimation(null, null, slot.equals(mbEnums.EquipSlotType.RHELD));
if (attacker.charItemManager.getEquipped().get(slot) != null) {
passiveAnim = getSwingAnimation(attacker.charItemManager.getEquipped().get(slot).template, null, true);
}
if (ThreadLocalRandom.current().nextInt(100) > hitChance) {
TargetedActionMsg msg = new TargetedActionMsg(attacker, target, 0f, passiveAnim);
if (target.getObjectType() == mbEnums.GameObjectType.PlayerCharacter)
DispatchMessage.dispatchMsgToInterestArea(target, msg, mbEnums.DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false);
else
DispatchMessage.sendToAllInRange(attacker, msg);
return;
}
//calculate passive chances only if target is AbstractCharacter
if (EnumSet.of(mbEnums.GameObjectType.PlayerCharacter, mbEnums.GameObjectType.NPC, mbEnums.GameObjectType.Mob).contains(target.getObjectType())) {
mbEnums.PassiveType passiveType = mbEnums.PassiveType.None;
int hitRoll = ThreadLocalRandom.current().nextInt(100);
float dodgeChance = ((AbstractCharacter) target).getPassiveChance("Dodge", attacker.getLevel(), true);
float blockChance = ((AbstractCharacter) target).getPassiveChance("Block", attacker.getLevel(), true);
float parryChance = ((AbstractCharacter) target).getPassiveChance("Parry", attacker.getLevel(), true);
// Passive chance clamped at 75
dodgeChance = Math.max(0, Math.min(75, dodgeChance));
blockChance = Math.max(0, Math.min(75, blockChance));
parryChance = Math.max(0, Math.min(75, parryChance));
if (hitRoll < dodgeChance)
passiveType = mbEnums.PassiveType.Dodge;
else if (hitRoll < blockChance)
passiveType = mbEnums.PassiveType.Block;
else if (hitRoll < parryChance)
passiveType = mbEnums.PassiveType.Parry;
if (passiveType.equals(mbEnums.PassiveType.None) == false) {
TargetedActionMsg msg = new TargetedActionMsg(attacker, passiveAnim, target, passiveType.value);
if (target.getObjectType() == mbEnums.GameObjectType.PlayerCharacter)
DispatchMessage.dispatchMsgToInterestArea(target, msg, mbEnums.DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false);
else
DispatchMessage.sendToAllInRange(attacker, msg);
return;
}
}
//calculate the base damage
int damage = ThreadLocalRandom.current().nextInt(min, max + 1);
if (damage == 0)
return;
//get the damage type
mbEnums.DamageType damageType;
if (attacker.charItemManager.getEquipped().get(slot) == null) {
damageType = mbEnums.DamageType.CRUSHING;
if (attacker.getObjectType().equals(mbEnums.GameObjectType.Mob))
if (((Mob) attacker).isSiege())
damageType = mbEnums.DamageType.SIEGE;
} else {
damageType = (mbEnums.DamageType) attacker.charItemManager.getEquipped().get(slot).template.item_weapon_damage.keySet().toArray()[0];
}
//get resists
Resists resists;
if (AbstractCharacter.IsAbstractCharacter(target) == false)
resists = ((Building) target).getResists(); //this is a building
else
resists = ((AbstractCharacter) target).getResists(); //this is a character
if (AbstractCharacter.IsAbstractCharacter(target)) { if (AbstractCharacter.IsAbstractCharacter(target)) {
AbstractCharacter absTarget = (AbstractCharacter) target; attackRange += ((AbstractCharacter) target).calcHitBox();
} else {
//check damage shields }
PlayerBonuses bonuses = absTarget.getBonuses(); if (attackRange > 15 && attacker.isMoving()) {
//cannot shoot bow while moving;
return;
}
if (bonuses != null) { switch (target.getObjectType()) {
case PlayerCharacter:
ConcurrentHashMap<AbstractEffectModifier, DamageShield> damageShields = bonuses.getDamageShields(); attackRange += ((PlayerCharacter) target).getCharacterHeight() * 0.5f;
float total = 0; if (distanceSquared <= attackRange * attackRange)
inRange = true;
for (DamageShield ds : damageShields.values()) { break;
case Mob:
//get amount to damage back attackRange += ((AbstractCharacter) target).calcHitBox();
if (distanceSquared <= attackRange * attackRange)
float amount; inRange = true;
break;
if (ds.usePercent()) case Building:
amount = damage * ds.getAmount() / 100; if (attackRange > 15) {
else float rangeSquared = (attackRange + target.getBounds().getHalfExtents().x) * (attackRange + target.getBounds().getHalfExtents().x);
amount = ds.getAmount(); //float distanceSquared = attacker.loc.distanceSquared(target.loc);
if (distanceSquared < rangeSquared) {
//get resisted damage for damagetype inRange = true;
break;
if (resists != null) }
amount = resists.getResistedDamage(absTarget, attacker, ds.getDamageType(), amount, 0); } else {
total += amount; float locX = target.loc.x - target.getBounds().getHalfExtents().x;
float locZ = target.loc.z - target.getBounds().getHalfExtents().y;
float sizeX = (target.getBounds().getHalfExtents().x + attackRange) * 2;
float sizeZ = (target.getBounds().getHalfExtents().y + attackRange) * 2;
Rectangle2D.Float rect = new Rectangle2D.Float(locX, locZ, sizeX, sizeZ);
if (rect.contains(new Point2D.Float(attacker.loc.x, attacker.loc.z)))
inRange = true;
break;
} }
if (total > 0) {
//apply Damage back
attacker.modifyHealth(-total, absTarget, true);
TargetedActionMsg cmm = new TargetedActionMsg(attacker, attacker, total, 0);
DispatchMessage.sendToAllInRange(target, cmm);
}
}
if (resists != null) {
//check for damage type immunities
if (resists.immuneTo(damageType))
return;
//calculate resisted damage including fortitude
damage = (int) resists.getResistedDamage(attacker, (AbstractCharacter) target, damageType, damage, 0);
}
} }
//remove damage from target health //get delay for the auto attack job
long delay = 5000;
if (damage > 0) {
if (AbstractCharacter.IsAbstractCharacter(target))
((AbstractCharacter) target).modifyHealth(-damage, attacker, true);
else
((Building) target).setCurrentHitPoints(target.getCurrentHitpoints() - damage);
int attackAnim = getSwingAnimation(null, null, slot.equals(mbEnums.EquipSlotType.RHELD));
if (attacker.charItemManager.getEquipped().get(slot) != null) {
attackAnim = getSwingAnimation(attacker.charItemManager.getEquipped().get(slot).template, null, slot.equals(mbEnums.EquipSlotType.RHELD));
}
TargetedActionMsg cmm = new TargetedActionMsg(attacker, target, (float) damage, attackAnim);
DispatchMessage.sendToAllInRange(target, cmm);
}
DeferredPowerJob dpj = null;
if (attacker.getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter)) {
dpj = ((PlayerCharacter) attacker).getWeaponPower();
if (dpj != null) {
dpj.attack(target, attackRange);
if (dpj.getPower() != null && (dpj.getPowerToken() == -1851459567 || dpj.getPowerToken() == -1851489518))
((PlayerCharacter) attacker).setWeaponPower(dpj);
}
}
//calculate next allowed attack and update the timestamp
long delay = 20 * 100;
if (weapon != null) { if (weapon != null) {
int wepSpeed = (int) (weapon.template.item_weapon_wepspeed); float wepSpeed = (int) (weapon.template.item_weapon_wepspeed);
if (weapon.getBonusPercent(mbEnums.ModType.WeaponSpeed, mbEnums.SourceType.None) != 0f) //add weapon speed bonus if (weapon.getBonusPercent(mbEnums.ModType.WeaponSpeed, mbEnums.EffectSourceType.None) != 0f) //add weapon speed bonus
wepSpeed *= (1 + weapon.getBonus(mbEnums.ModType.WeaponSpeed, mbEnums.SourceType.None)); wepSpeed *= (1 + weapon.getBonus(mbEnums.ModType.WeaponSpeed, mbEnums.EffectSourceType.None));
if (attacker.getBonuses() != null && attacker.getBonuses().getFloatPercentAll(mbEnums.ModType.AttackDelay, mbEnums.SourceType.None) != 0f) //add effects speed bonus if (attacker.getBonuses() != null && attacker.getBonuses().getFloatPercentAll(mbEnums.ModType.AttackDelay, mbEnums.EffectSourceType.None) != 0f) //add effects speed bonus
wepSpeed *= (1 + attacker.getBonuses().getFloatPercentAll(mbEnums.ModType.AttackDelay, mbEnums.SourceType.None)); wepSpeed *= (1 + attacker.getBonuses().getFloatPercentAll(mbEnums.ModType.AttackDelay, mbEnums.EffectSourceType.None));
if (wepSpeed < 10) if (wepSpeed < 10)
wepSpeed = 10; //Old was 10, but it can be reached lower with legit buffs,effects. wepSpeed = 10; //Old was 10, but it can be reached lower with legit buffs,effects.
delay = wepSpeed * 100; delay = (long)wepSpeed * 100L;
} }
attacker.getTimestamps().put("Attack" + slot.name(), System.currentTimeMillis() + delay); if (attacker.getObjectType().equals(mbEnums.GameObjectType.Mob))
((Mob) attacker).nextAttackTime = System.currentTimeMillis() + delay;
//handle auto attack job creation if (inRange) {
ConcurrentHashMap<String, JobContainer> timers = attacker.getTimers(); if(attacker.getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter)){
if(!attacker.getTimestamps().contains(slot.name()+"Attack")){
attacker.getTimestamps().put(slot.name()+"Attack", System.currentTimeMillis() - 1000);
} else if(System.currentTimeMillis() < attacker.getTimestamps().get(slot.name()+"Attack") + delay){
setAutoAttackJob(attacker,slot,delay);
return;
}
}
if (timers != null) {
AttackJob aj = new AttackJob(attacker, slot.ordinal(), true); //handle retaliate
JobContainer job; if (AbstractCharacter.IsAbstractCharacter(target)) {
job = JobScheduler.getInstance().scheduleJob(aj, (System.currentTimeMillis() + delay)); // offset 1 millisecond so no overlap issue if (((AbstractCharacter) target).combatTarget == null || !((AbstractCharacter) target).combatTarget.isAlive()) {
timers.put("Attack" + slot, job); ((AbstractCharacter) target).combatTarget = attacker;
} else if (target.getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter) && ((AbstractCharacter) target).isCombat())
Logger.error("Unable to find Timers for Character " + attacker.getObjectUUID()); combatCycle((AbstractCharacter) target, attacker);
}
}
// take stamina away from attacker if its not a mob
if (weapon != null && !attacker.getObjectType().equals(mbEnums.GameObjectType.Mob)) {
//check if Out of Stamina
if (attacker.getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter)) {
if (attacker.getStamina() < (weapon.template.item_wt / 3f)) {
//set auto attack job
setAutoAttackJob(attacker, slot, delay);
return;
}
}
float stam = weapon.template.item_wt / 3f;
stam = (stam < 1) ? 1 : stam;
attacker.modifyStamina(-(stam), attacker, true);
} else
attacker.modifyStamina(1, attacker, true);
//cancel things that are cancelled by an attack
attacker.cancelOnAttackSwing();
//declare relevant variables
int min = attacker.minDamageHandOne;
int max = attacker.maxDamageHandOne;
int atr = attacker.atrHandOne;
//get the proper stats based on which slot is attacking
if (slot == mbEnums.EquipSlotType.LHELD) {
min = attacker.minDamageHandTwo;
max = attacker.maxDamageHandTwo;
atr = attacker.atrHandTwo;
}
//apply weapon powers before early exit for miss or passives
DeferredPowerJob dpj = null;
if (attacker.getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter)) {
dpj = ((PlayerCharacter) attacker).getWeaponPower();
if (dpj != null) {
dpj.attack(target, attackRange);
if (dpj.getPower() != null && (dpj.getPowerToken() == -1851459567 || dpj.getPowerToken() == -1851489518))
((PlayerCharacter) attacker).setWeaponPower(dpj);
}
}
int def = 0;
if (AbstractCharacter.IsAbstractCharacter(target))
def = ((AbstractCharacter) target).defenseRating;
//calculate hit chance based off ATR and DEF
int hitChance;
if (def == 0)
def = 1;
float dif = atr * 1f / def;
if (dif <= 0.8f)
hitChance = 4;
else
hitChance = ((int) (450 * (dif - 0.8f)) + 4);
if (target.getObjectType() == mbEnums.GameObjectType.Building)
hitChance = 100;
int passiveAnim = getPassiveAnimation(mbEnums.PassiveType.None); // checking for a miss due to ATR vs Def
if (ThreadLocalRandom.current().nextInt(100) > hitChance) {
TargetedActionMsg msg = new TargetedActionMsg(attacker, target, 0f, passiveAnim);
if (target.getObjectType() == mbEnums.GameObjectType.PlayerCharacter)
DispatchManager.dispatchMsgToInterestArea(target, msg, mbEnums.DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false);
else
DispatchManager.sendToAllInRange(attacker, msg);
//we need to send the animation even if the attacker misses
TargetedActionMsg cmm = new TargetedActionMsg(attacker, target, (float) 0, getSwingAnimation(weapon.template, null, slot));
DispatchManager.sendToAllInRange(target, cmm);
//set auto attack job
setAutoAttackJob(attacker, slot, delay);
return;
}
//calculate passive chances only if target is AbstractCharacter
if (EnumSet.of(mbEnums.GameObjectType.PlayerCharacter, mbEnums.GameObjectType.NPC, mbEnums.GameObjectType.Mob).contains(target.getObjectType())) {
mbEnums.PassiveType passiveType = mbEnums.PassiveType.None;
int hitRoll = ThreadLocalRandom.current().nextInt(100);
float dodgeChance = ((AbstractCharacter) target).getPassiveChance("Dodge", attacker.getLevel(), true);
float blockChance = ((AbstractCharacter) target).getPassiveChance("Block", attacker.getLevel(), true);
float parryChance = ((AbstractCharacter) target).getPassiveChance("Parry", attacker.getLevel(), true);
// Passive chance clamped at 75
dodgeChance = Math.max(0, Math.min(75, dodgeChance));
blockChance = Math.max(0, Math.min(75, blockChance));
parryChance = Math.max(0, Math.min(75, parryChance));
if (hitRoll < dodgeChance)
passiveType = mbEnums.PassiveType.Dodge;
else if (hitRoll < blockChance)
passiveType = mbEnums.PassiveType.Block;
else if (hitRoll < parryChance)
passiveType = mbEnums.PassiveType.Parry;
if (!passiveType.equals(mbEnums.PassiveType.None)) {
passiveAnim = getPassiveAnimation(passiveType);
TargetedActionMsg msg = new TargetedActionMsg(attacker, passiveAnim, target, passiveType.value);
if (target.getObjectType() == mbEnums.GameObjectType.PlayerCharacter)
DispatchManager.dispatchMsgToInterestArea(target, msg, mbEnums.DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false);
//we need to send the animation even if the attacker misses
TargetedActionMsg cmm = new TargetedActionMsg(attacker, target, (float) 0, getSwingAnimation(weapon.template, null, slot));
DispatchManager.sendToAllInRange(target, cmm);
//set auto attack job
setAutoAttackJob(attacker, slot, delay);
return;
}
}
//check for proccing
checkForProc(attacker,target,weapon);
//calculate the base damage
int damage = ThreadLocalRandom.current().nextInt(min, max + 1);
if (damage == 0) {
//set auto attack job
setAutoAttackJob(attacker, slot, delay);
return;
}
if (attacker.getObjectType().equals(mbEnums.GameObjectType.Mob) && ((Mob) attacker).isPet())
calculatePetDamage(attacker);
//get the damage type
mbEnums.DamageType damageType;
if (attacker.charItemManager.getEquipped().get(slot) == null) {
damageType = mbEnums.DamageType.CRUSHING;
if (attacker.getObjectType().equals(mbEnums.GameObjectType.Mob))
if (((Mob) attacker).isSiege())
damageType = mbEnums.DamageType.SIEGE;
} else {
damageType = (mbEnums.DamageType) attacker.charItemManager.getEquipped().get(slot).template.item_weapon_damage.keySet().toArray()[0];
}
//get resists
Resists resists;
if (!AbstractCharacter.IsAbstractCharacter(target))
resists = ((Building) target).getResists(); //this is a building
else
resists = ((AbstractCharacter) target).getResists(); //this is a character
if (AbstractCharacter.IsAbstractCharacter(target)) {
AbstractCharacter absTarget = (AbstractCharacter) target;
//check damage shields
PlayerBonuses bonuses = absTarget.getBonuses();
if (bonuses != null) {
ConcurrentHashMap<AbstractEffectModifier, DamageShield> damageShields = bonuses.getDamageShields();
float total = 0;
for (DamageShield ds : damageShields.values()) {
//get amount to damage back
float amount;
if (ds.usePercent())
amount = damage * ds.getAmount() / 100;
else
amount = ds.getAmount();
//get resisted damage for damagetype
if (resists != null)
amount = resists.getResistedDamage(absTarget, attacker, ds.getDamageType(), amount, 0);
total += amount;
}
if (total > 0) {
//apply Damage back
attacker.modifyHealth(-total, absTarget, true);
TargetedActionMsg cmm = new TargetedActionMsg(attacker, attacker, total, 0);
DispatchManager.sendToAllInRange(target, cmm);
}
}
if (resists != null) {
//check for damage type immunities
if (resists.immuneTo(damageType)) {
//set auto attack job
//we need to send the animation even if the attacker misses
TargetedActionMsg cmm = new TargetedActionMsg(attacker, target, (float) 0, getSwingAnimation(weapon.template, null, slot));
DispatchManager.sendToAllInRange(target, cmm);
setAutoAttackJob(attacker, slot, delay);
return;
}
//calculate resisted damage including fortitude
damage = (int) resists.getResistedDamage(attacker, (AbstractCharacter) target, damageType, damage, 0);
}
}
//remove damage from target health
if (damage > 0) {
if (AbstractCharacter.IsAbstractCharacter(target))
((AbstractCharacter) target).modifyHealth(-damage, attacker, true);
else
((Building) target).modifyHealth(-damage, attacker);
int attackAnim = getSwingAnimation(null, null, slot);
if (attacker.charItemManager.getEquipped().get(slot) != null) {
if (attacker.getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter)) {
DeferredPowerJob weaponPower = ((PlayerCharacter) attacker).getWeaponPower();
attackAnim = getSwingAnimation(weapon.template, weaponPower, slot);
} else {
attackAnim = getSwingAnimation(weapon.template, null, slot);
}
}
TargetedActionMsg cmm = new TargetedActionMsg(attacker, target, (float) damage, attackAnim);
DispatchManager.sendToAllInRange(target, cmm);
}
}
//set auto attack job
setAutoAttackJob(attacker, slot, delay);
} }
@@ -368,7 +500,7 @@ public enum CombatManager {
UpdateStateMsg rwss = new UpdateStateMsg(); UpdateStateMsg rwss = new UpdateStateMsg();
rwss.setPlayer(playerCharacter); rwss.setPlayer(playerCharacter);
DispatchMessage.dispatchMsgToInterestArea(playerCharacter, rwss, mbEnums.DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, false, false); DispatchManager.dispatchMsgToInterestArea(playerCharacter, rwss, mbEnums.DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, false, false);
} }
public static void toggleSit(boolean toggle, ClientConnection origin) { public static void toggleSit(boolean toggle, ClientConnection origin) {
@@ -381,7 +513,7 @@ public enum CombatManager {
playerCharacter.setSit(toggle); playerCharacter.setSit(toggle);
UpdateStateMsg rwss = new UpdateStateMsg(); UpdateStateMsg rwss = new UpdateStateMsg();
rwss.setPlayer(playerCharacter); rwss.setPlayer(playerCharacter);
DispatchMessage.dispatchMsgToInterestArea(playerCharacter, rwss, mbEnums.DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false); DispatchManager.dispatchMsgToInterestArea(playerCharacter, rwss, mbEnums.DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false);
} }
@@ -409,118 +541,144 @@ public enum CombatManager {
target.setCombatTarget(attacker); target.setCombatTarget(attacker);
} }
public static int getSwingAnimation(ItemTemplate wb, DeferredPowerJob dpj, boolean mainHand) { public static int getSwingAnimation(ItemTemplate wb, DeferredPowerJob dpj, mbEnums.EquipSlotType slot) {
int token = 0;
if (dpj != null)
token = (dpj.getPower() != null) ? dpj.getPower().getToken() : 0;
if (token == 563721004) //kick animation
return 79;
//No weapon, return default animation
if (wb == null) if (wb == null)
return 75; return 75;
ItemTemplate template = wb; int token;
if (mainHand) { if (dpj != null) {
if (template.weapon_attack_anim_right.size() > 0) {
int animation; token = (dpj.getPower() != null) ? dpj.getPower().getToken() : 0;
int random = ThreadLocalRandom.current().nextInt(template.weapon_attack_anim_right.size()); if (token == 563721004) //kick animation
return 79;
try {
animation = template.weapon_attack_anim_right.get(random)[0];
return animation;
} catch (Exception e) {
Logger.error(e.getMessage());
return template.weapon_attack_anim_right.get(0)[0];
}
} else if (template.weapon_attack_anim_left.size() > 0) {
int animation;
int random = ThreadLocalRandom.current().nextInt(template.weapon_attack_anim_left.size());
try {
animation = template.weapon_attack_anim_left.get(random)[0];
return animation;
} catch (Exception e) {
Logger.error(e.getMessage());
return template.weapon_attack_anim_right.get(0)[0];
}
}
} else {
if (template.weapon_attack_anim_left.size() > 0) {
int animation;
int random = ThreadLocalRandom.current().nextInt(template.weapon_attack_anim_left.size());
try {
animation = template.weapon_attack_anim_left.get(random)[0];
return animation;
} catch (Exception e) {
Logger.error(e.getMessage());
return template.weapon_attack_anim_right.get(0)[0];
}
} else if (template.weapon_attack_anim_left.size() > 0) {
int animation;
int random = ThreadLocalRandom.current().nextInt(template.weapon_attack_anim_left.size());
try {
animation = template.weapon_attack_anim_left.get(random)[0];
return animation;
} catch (Exception e) {
Logger.error(e.getMessage());
return template.weapon_attack_anim_right.get(0)[0];
}
}
} }
String required = template.item_skill_used; //Item has no equipment slots and should not try to return an animation, return default instead
String mastery = wb.item_skill_mastery_used; if (wb.item_eq_slots_or == null || wb.item_eq_slots_or.isEmpty()) {
if (required.equals("Unarmed Combat"))
return 75; return 75;
else if (required.equals("Sword")) { }
if (ItemManager.isTwoHanded(template)) //declare variables
return 105; int anim;
else int random;
return 98;
} else if (required.equals("Staff") || required.equals("Pole Arm")) { //Item can only be equipped in one slot, return animation for that slot
return 85; if (wb.item_eq_slots_or.size() == 1) {
} else if (required.equals("Spear")) { if (wb.item_eq_slots_or.iterator().next().equals(mbEnums.EquipSlotType.RHELD)) {
return 92; anim = wb.weapon_attack_anim_right.get(0)[0];
} else if (required.equals("Hammer") || required.equals("Axe")) { if (dpj != null) {
if (ItemManager.isTwoHanded(template)) { random = ThreadLocalRandom.current().nextInt(wb.weapon_attack_anim_right.size());
return 105; anim = wb.weapon_attack_anim_right.get(random)[0];
} else if (mastery.equals("Throwing")) { }
return 115;
} else { } else {
return 100; anim = wb.weapon_attack_anim_left.get(0)[0];
if (dpj != null) {
random = ThreadLocalRandom.current().nextInt(wb.weapon_attack_anim_left.size());
anim = wb.weapon_attack_anim_left.get(random)[0];
}
} }
} else if (required.equals("Dagger")) { return anim;
if (mastery.equals("Throwing")) { }
return 117;
} else { //Item can be equipped in either hand, and should have animation sets for each hand
return 81; if (slot.equals(mbEnums.EquipSlotType.RHELD)) {
anim = wb.weapon_attack_anim_right.get(0)[0];
if (dpj != null) {
random = ThreadLocalRandom.current().nextInt(wb.weapon_attack_anim_right.size());
anim = wb.weapon_attack_anim_right.get(random)[0];
} }
} else if (required.equals("Crossbow")) {
return 110;
} else if (required.equals("Bow")) {
return 109;
} else if (ItemManager.isTwoHanded(template)) {
return 105;
} else { } else {
return 100; anim = wb.weapon_attack_anim_left.get(0)[0];
if (dpj != null) {
random = ThreadLocalRandom.current().nextInt(wb.weapon_attack_anim_left.size());
anim = wb.weapon_attack_anim_left.get(random)[0];
}
}
return anim;
}
public static int getPassiveAnimation(mbEnums.PassiveType passiveType) {
switch (passiveType) {
case Block:
return COMBAT_BLOCK_ANIMATION;
case Parry:
return COMBAT_PARRY_ANIMATION;
case Dodge:
return COMBAT_DODGE_ANIMATION;
default:
return 0;
} }
} }
public static void setAutoAttackJob(AbstractCharacter attacker, mbEnums.EquipSlotType slot, long delay) {
//calculate next allowed attack and update the timestamp
if (attacker.getTimestamps().containsKey("Attack" + slot.name()) && attacker.getTimestamps().get("Attack" + slot.name()) > System.currentTimeMillis())
return;
attacker.getTimestamps().put("Attack" + slot.name(), System.currentTimeMillis() + delay);
//handle auto attack job creation
ConcurrentHashMap<String, JobContainer> timers = attacker.getTimers();
if (timers != null) {
AttackJob aj = new AttackJob(attacker, slot.ordinal(), true);
JobContainer job;
job = JobScheduler.getInstance().scheduleJob(aj, (System.currentTimeMillis() + delay)); // offset 1 millisecond so no overlap issue
timers.put("Attack" + slot.name(), job);
} else
Logger.error("Unable to find Timers for Character " + attacker.getObjectUUID());
}
public static int calculatePetDamage(AbstractCharacter agent) {
//damage calc for pet
float range;
float damage;
float min = 40;
float max = 60;
float dmgMultiplier = 1 + agent.getBonuses().getFloatPercentAll(mbEnums.ModType.MeleeDamageModifier, mbEnums.EffectSourceType.None);
double minDmg = getMinDmg(min, agent);
double maxDmg = getMaxDmg(max, agent);
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 double getMinDmg(double min, AbstractCharacter agent) {
int primary = agent.getStatStrCurrent();
int secondary = agent.getStatDexCurrent();
int focusLevel = 0;
int masteryLevel = 0;
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, AbstractCharacter agent) {
int primary = agent.getStatStrCurrent();
int secondary = agent.getStatDexCurrent();
int focusLevel = 0;
int masteryLevel = 0;
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));
}
public static void checkForProc(AbstractCharacter attacker, AbstractWorldObject target, Item weapon){
if(weapon == null) // cant proc without a weapon
return;
for(Effect eff : weapon.effects.values()){
for(AbstractEffectModifier mod : eff.getEffectsBase().getModifiers()){
if(mod.modType.equals(mbEnums.ModType.WeaponProc))
if(ThreadLocalRandom.current().nextInt(0,101) < 6)
((WeaponProcEffectModifier)mod).applyProc(attacker,target);
}
}
}
} }
+11 -7
View File
@@ -8,10 +8,6 @@
package engine.gameManager; package engine.gameManager;
/* This enumeration implements Magicbane's configuration data which
is loaded from environment variables.
*/
import engine.mbEnums; import engine.mbEnums;
import engine.server.login.LoginServer; import engine.server.login.LoginServer;
import engine.server.world.WorldServer; import engine.server.world.WorldServer;
@@ -27,6 +23,14 @@ import java.util.regex.Pattern;
public enum ConfigManager { public enum ConfigManager {
// MB Dev notes:
// Magicbane configuration is loaded from environment variables
//
// On boot the game first looks in /mb.conf for the file magicbane.conf.
//
// If not found, a default config is loaded from /mb.data to enable bootstrap.
// This version should never be modified.
MB_BIND_ADDR, MB_BIND_ADDR,
MB_EXTERNAL_ADDR, MB_EXTERNAL_ADDR,
@@ -105,11 +109,11 @@ public enum ConfigManager {
// and determine the server type at runtime. // and determine the server type at runtime.
public static final String DEFAULT_DATA_DIR = "mb.data/"; public static final String DEFAULT_DATA_DIR = "mb.data/";
public static Map<String, String> configMap = new HashMap(System.getenv()); public static final Map<String, String> configMap = new HashMap(System.getenv());
public static mbEnums.ServerType serverType = mbEnums.ServerType.NONE; public static mbEnums.ServerType serverType = mbEnums.ServerType.NONE;
public static WorldServer worldServer; public static WorldServer worldServer;
public static LoginServer loginServer; public static LoginServer loginServer;
public static Map<ConfigManager, Pattern> regex = new HashMap<>(); public static final Map<ConfigManager, Pattern> regex = new HashMap<>();
public static String currentRepoBranch = ""; public static String currentRepoBranch = "";
@@ -124,7 +128,7 @@ public enum ConfigManager {
Logger.info(configSetting.name() + ":" + configSetting.getValue()); Logger.info(configSetting.name() + ":" + configSetting.getValue());
else { else {
Logger.error("Missing Config: " + configSetting.name()); Logger.error("Missing Config: " + configSetting.name());
Logger.error("This codebase requires >= MagicBox v1.5.1"); Logger.error("This codebase requires >= MagicBox v1.5.2");
Logger.error("docker pull magicbane/magicbox:latest"); Logger.error("docker pull magicbane/magicbox:latest");
return false; return false;
} }
+1 -1
View File
@@ -10,9 +10,9 @@ package engine.gameManager;
import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource; import com.zaxxer.hikari.HikariDataSource;
import engine.db.handlers.*;
import engine.mbEnums; import engine.mbEnums;
import engine.mbEnums.GameObjectType; import engine.mbEnums.GameObjectType;
import engine.db.handlers.*;
import engine.objects.*; import engine.objects.*;
import engine.server.MBServerStatics; import engine.server.MBServerStatics;
import engine.util.Hasher; import engine.util.Hasher;
+9 -5
View File
@@ -8,9 +8,9 @@
package engine.gameManager; package engine.gameManager;
import engine.mbEnums;
import engine.devcmd.AbstractDevCmd; import engine.devcmd.AbstractDevCmd;
import engine.devcmd.cmds.*; import engine.devcmd.cmds.*;
import engine.mbEnums;
import engine.objects.AbstractGameObject; import engine.objects.AbstractGameObject;
import engine.objects.Account; import engine.objects.Account;
import engine.objects.PlayerCharacter; import engine.objects.PlayerCharacter;
@@ -22,6 +22,13 @@ import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
public enum DevCmdManager { public enum DevCmdManager {
// MB Dev Notes:
// Class registers "Dev Commands" where access requires
// Status = "ADMIN" be set in the obj_account table
//
// Use these at your own risk.
DEV_CMD_MANAGER; DEV_CMD_MANAGER;
public static ConcurrentHashMap<String, AbstractDevCmd> devCmds; public static ConcurrentHashMap<String, AbstractDevCmd> devCmds;
@@ -35,9 +42,6 @@ public enum DevCmdManager {
DevCmdManager.registerCommands(); DevCmdManager.registerCommands();
} }
/**
*
*/
private static void registerCommands() { private static void registerCommands() {
// Player // Player
@@ -72,6 +76,7 @@ public enum DevCmdManager {
DevCmdManager.registerDevCmd(new SetLevelCmd()); DevCmdManager.registerDevCmd(new SetLevelCmd());
DevCmdManager.registerDevCmd(new SetBaseClassCmd()); DevCmdManager.registerDevCmd(new SetBaseClassCmd());
DevCmdManager.registerDevCmd(new SetPromotionClassCmd()); DevCmdManager.registerDevCmd(new SetPromotionClassCmd());
DevCmdManager.registerDevCmd(new SetRaceCmd());
DevCmdManager.registerDevCmd(new SetRuneCmd()); DevCmdManager.registerDevCmd(new SetRuneCmd());
DevCmdManager.registerDevCmd(new GetOffsetCmd()); DevCmdManager.registerDevCmd(new GetOffsetCmd());
DevCmdManager.registerDevCmd(new AddGoldCmd()); DevCmdManager.registerDevCmd(new AddGoldCmd());
@@ -91,7 +96,6 @@ public enum DevCmdManager {
DevCmdManager.registerDevCmd(new RenameCmd()); DevCmdManager.registerDevCmd(new RenameCmd());
DevCmdManager.registerDevCmd(new CreateItemCmd()); DevCmdManager.registerDevCmd(new CreateItemCmd());
DevCmdManager.registerDevCmd(new SetRankCmd()); DevCmdManager.registerDevCmd(new SetRankCmd());
DevCmdManager.registerDevCmd(new MakeBaneCmd());
DevCmdManager.registerDevCmd(new RemoveBaneCmd()); DevCmdManager.registerDevCmd(new RemoveBaneCmd());
DevCmdManager.registerDevCmd(new SetBaneActiveCmd()); DevCmdManager.registerDevCmd(new SetBaneActiveCmd());
DevCmdManager.registerDevCmd(new SetAdminRuneCmd()); DevCmdManager.registerDevCmd(new SetAdminRuneCmd());
@@ -7,13 +7,15 @@
// www.magicbane.com // www.magicbane.com
package engine.net; package engine.gameManager;
import engine.InterestManagement.WorldGrid;
import engine.math.Vector3fImmutable;
import engine.mbEnums.DispatchChannel; import engine.mbEnums.DispatchChannel;
import engine.mbEnums.GameObjectType; import engine.mbEnums.GameObjectType;
import engine.InterestManagement.WorldGrid; import engine.net.AbstractNetMsg;
import engine.gameManager.SessionManager; import engine.net.Dispatch;
import engine.math.Vector3fImmutable; import engine.net.MessageDispatcher;
import engine.net.client.ClientConnection; import engine.net.client.ClientConnection;
import engine.objects.AbstractWorldObject; import engine.objects.AbstractWorldObject;
import engine.objects.Item; import engine.objects.Item;
@@ -26,12 +28,17 @@ import java.util.HashSet;
import static engine.net.MessageDispatcher.dispatchCount; import static engine.net.MessageDispatcher.dispatchCount;
import static engine.net.MessageDispatcher.maxRecipients; import static engine.net.MessageDispatcher.maxRecipients;
/* // MB Dev Notes:
* Dispatch Message is the main interface to Magicbane's threaded // Dispatch Manager is the main interface to the threaded async message
* async message delivery system. // delivery system used by Magicbane.
*/ //
// A Dispatch is .borrowed() and used to wrap an outgoing protocol message.
// A distribution list is created and passed to the MessageDispatcher for
// delivery.
public class DispatchMessage { public enum DispatchManager {
DISPATCH_MANAGER;
public static void startMessagePump() { public static void startMessagePump() {
@@ -83,7 +90,7 @@ public class DispatchMessage {
sourcePlayer = (PlayerCharacter) sourceObject; sourcePlayer = (PlayerCharacter) sourceObject;
if (sourcePlayer.getClientConnection() != null && sendToSelf) { if (sourcePlayer.getClientConnection() != null && sendToSelf) {
Dispatch dispatch = Dispatch.borrow(sourcePlayer, msg); Dispatch dispatch = Dispatch.borrow(sourcePlayer, msg);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY); DispatchManager.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY);
} }
@@ -151,7 +158,7 @@ public class DispatchMessage {
if (sourcePlayer.getClientConnection() != null && sendToSelf) { if (sourcePlayer.getClientConnection() != null && sendToSelf) {
Dispatch dispatch = Dispatch.borrow(sourcePlayer, msg); Dispatch dispatch = Dispatch.borrow(sourcePlayer, msg);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY); DispatchManager.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY);
} }
@@ -280,7 +287,7 @@ public class DispatchMessage {
} }
protected static void serializeDispatch(Dispatch messageDispatch) { public static void serializeDispatch(Dispatch messageDispatch) {
ClientConnection connection; ClientConnection connection;
if (messageDispatch.player == null) { if (messageDispatch.player == null) {
+409
View File
@@ -0,0 +1,409 @@
// ·. · · · · .
// · ·
// · ·
//
// · · ·
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
package engine.gameManager;
import engine.loot.ModTableEntry;
import engine.loot.ModTypeTableEntry;
import engine.loot.WorkOrder;
import engine.mbEnums;
import engine.net.client.msg.ItemProductionMsg;
import engine.objects.City;
import engine.objects.Item;
import engine.objects.ItemTemplate;
import engine.objects.NPC;
import engine.powers.EffectsBase;
import org.pmw.tinylog.Logger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.atomic.AtomicInteger;
public enum ForgeManager implements Runnable {
// MB Dev notes:
// Class implements forge rolling mechanics for Magicbane.
//
// .submit(workOrder) may be called from any thread: (ItemProductionMsgHandler).
// Concurrency is managed by same lock used for warehouse (city.cityTransactionLock).
// WorkOrders are persisted then reconstituted at bootstrap using table dyn.workorders.
// Forge window (ManageNPCMsg) uses item.upgradeDate to serialize completion time.
//
// Replaces garbage code that looked as if written by a mental patient.
//
// @TODO Reuse same set of virtual items for the life of a workOrder.
FORGE_MANAGER;
public static final BlockingQueue<WorkOrder> forge = new DelayQueue<>();
public static final AtomicInteger workOrderCounter = new AtomicInteger(0);
public static final ConcurrentHashMap<NPC, ConcurrentHashMap.KeySetView<WorkOrder, Boolean>> vendorWorkOrderLookup = new ConcurrentHashMap<>();
public static final ConcurrentHashMap<Item, WorkOrder> itemWorkOrderLookup = new ConcurrentHashMap<>();
@Override
public void run() {
WorkOrder workOrder;
while (true) {
// The forge is a blocking priority queue using an epoc sort.
// workOrders are popped once the workOrder.completionTime has
// passed.
try {
workOrder = forge.take();
// Early exit for completed workOrders loaded from disk
// or vendors who were re-deeded with items still cooking.
if (workOrder.vendor == null || workOrder.runCompleted.get())
continue;
// This workOrder has completed production.
if (workOrder.total_produced >= workOrder.total_to_produce) {
// CONFIRM_PRODUCE to refresh the interface after we add
// the Identified flag to the item.
for (Item workOrderItem : workOrder.cooking) {
workOrderItem.flags.add(mbEnums.ItemFlags.Identified);
ItemProductionMsg outMsg = new ItemProductionMsg(workOrder.vendor.building, workOrder.vendor, workOrderItem, mbEnums.ProductionActionType.CONFIRM_PRODUCE, true);
DispatchManager.dispatchMsgToInterestArea(workOrder.vendor, outMsg, mbEnums.DispatchChannel.SECONDARY, 700, false, false);
}
// Set this workOrder to completed and update on disk
workOrder.runCompleted.set(true);
DbManager.WarehouseQueries.WRITE_WORKORDER(workOrder);
continue;
}
// PERSIST our current cooking batch of virtual
// items then add to the vendor inventory
completeWorkOrderBatch(workOrder);
// Create new set of in-memory only virtual items
forgeWorkOrderBatch(workOrder);
// enQueue this workOrder again; back into the oven
// until all items for this workOrder are completed.
forge.add(workOrder);
// Debugging: Logger.info(workOrder.toString());
} catch (Exception e) {
Logger.error(e);
}
}
}
public static void start() {
Thread forgeManager;
forgeManager = new Thread(FORGE_MANAGER);
forgeManager.setName("Forge Manager");
forgeManager.start();
}
public static int submit(WorkOrder workOrder) {
// Must have a city to roll anything
City city = workOrder.vendor.building.getCity();
if (city == null)
return 58; //58: The formula is beyond the means of this facility
// Concurrency is rightly managed by same lock as warehouse
city.transactionLock.writeLock().lock();
// Make sure vendor can roll the formulae, warehouse can
// afford this wordOrder and other related checks.
int validation_result = WorkOrder.validate(workOrder);
// The return code is used by the caller (ItemProductionMsgHandler)
// for display of a popup error message to the player.
if (validation_result != 0)
return validation_result;
// Configure this production run.
try {
workOrder.workOrderID = workOrderCounter.incrementAndGet();
workOrder.rollingDuration = NPCManager.calcRollingDuration(workOrder.vendor, workOrder.templateID);
workOrder.completionTime = System.currentTimeMillis() + workOrder.rollingDuration;
workOrder.slots_used.set(calcAvailableSlots(workOrder));
if (workOrder.slots_used.get() == 0)
return 58;
workOrder.total_produced = 0;
// Single item configuration from protocol message (ItemProductionMsg)
if (workOrder.multiple_slot_request == false && workOrder.total_to_produce == 0)
workOrder.total_to_produce = 1;
// Calculate total cost for this production run
workOrder.total_to_produce *= workOrder.slots_used.get();
workOrder.production_cost = calcProductionCost(workOrder);
workOrder.production_cost.forEach((key, value) -> workOrder.production_cost_total.put(key, value * workOrder.total_to_produce));
// Withdraw gold and resources. Availability has previously been validated.
if (!WorkOrder.withdrawWorkOrderCost(workOrder))
return 58; //58: The formula is beyond the means of this facility
// Create new batch of virtual items
forgeWorkOrderBatch(workOrder);
// Assign the new workOrder to the vendor
vendorWorkOrderLookup.get(workOrder.vendor).add(workOrder);
// Enqueue the new workOrder
forge.add(workOrder);
// PERSIST workOrder (dyn_workorders)
DbManager.WarehouseQueries.WRITE_WORKORDER(workOrder);
} catch (Exception e) {
Logger.error(e);
} finally {
city.transactionLock.writeLock().unlock();
}
Logger.info(workOrder.toString());
return validation_result;
}
public static int calcAvailableSlots(WorkOrder workOrder) {
// Slots available in a forge are based on the npc rank
int availableSlots = workOrder.vendor.getRank();
// Subtract the slots currently assigned to other workOrders for this vendor
for (WorkOrder npcWorkOrder : ForgeManager.vendorWorkOrderLookup.get(workOrder.vendor))
availableSlots = availableSlots - npcWorkOrder.cooking.size();
// Single item rolls are always a single slot
if (availableSlots > 0 && workOrder.multiple_slot_request == false)
availableSlots = 1;
return availableSlots;
}
public static HashMap<mbEnums.ResourceType, Integer> calcProductionCost(WorkOrder workOrder) {
// Calculate production cost for a single run of the workOrder
HashMap<mbEnums.ResourceType, Integer> production_cost = new HashMap<>();
ItemTemplate template = ItemTemplate.templates.get(workOrder.templateID);
// Add gold and resource costs from template
production_cost.put(mbEnums.ResourceType.GOLD, template.item_value);
production_cost.putAll(template.item_resource_cost);
// Calculate cost of prefix and suffix
if (workOrder.prefixToken != 0) {
EffectsBase prefix = PowersManager.getEffectByToken(workOrder.prefixToken);
production_cost.putAll(PowersManager._effect_costMaps.get(prefix.getIDString()));
}
if (workOrder.suffixToken != 0) {
EffectsBase suffix = PowersManager.getEffectByToken(workOrder.suffixToken);
production_cost.putAll(PowersManager._effect_costMaps.get(suffix.getIDString()));
}
return production_cost;
}
public static Item forgeItem(WorkOrder workOrder) {
// Create new virtual item from specified template
ItemTemplate template = ItemTemplate.templates.get(workOrder.templateID);
Item forgedItem = new Item(workOrder.templateID);
// forgedItem gets a negative id; a virtual item which is not persisted
forgedItem.objectUUID = ItemManager.lastNegativeID.getAndDecrement();
forgedItem.containerType = mbEnums.ItemContainerType.FORGE;
forgedItem.ownerID = workOrder.vendor.getObjectUUID();
// item.upgradeDate is serialized (ItemProductionMsg)
// for vendor forge window completion time.
forgedItem.setDateToUpgrade(workOrder.completionTime);
// Assign a prefix and suffix to this item if random rolled
if (workOrder.prefixToken == 0)
forgedItem.prefixToken = calcRandomMod(workOrder.vendor, mbEnums.ItemModType.PREFIX, template.modTable);
else
forgedItem.prefixToken = workOrder.prefixToken;
if (workOrder.suffixToken == 0)
forgedItem.suffixToken = calcRandomMod(workOrder.vendor, mbEnums.ItemModType.SUFFIX, template.modTable);
else
forgedItem.suffixToken = workOrder.suffixToken;
// Random rolled items are unidentified until completed
if (workOrder.prefixToken == 0 && workOrder.suffixToken == 0)
forgedItem.flags.remove(mbEnums.ItemFlags.Identified);
else
forgedItem.flags.add(mbEnums.ItemFlags.Identified);
// Add virtual item to in-memory caches
workOrder.cooking.add(forgedItem);
DbManager.addToCache(forgedItem);
itemWorkOrderLookup.put(forgedItem, workOrder);
return forgedItem;
}
public static void completeWorkOrderBatch(WorkOrder workOrder) {
ArrayList<Item> toRemove = new ArrayList<>();
for (Item virutalItem : workOrder.cooking) {
// Identify completed items
virutalItem.flags.add(mbEnums.ItemFlags.Identified);
virutalItem.containerType = mbEnums.ItemContainerType.INVENTORY;
// Persist item
Item completedItem = DbManager.ItemQueries.PERSIST(virutalItem);
// Copy Prefix and Suffix tokens from virtual item.
completedItem.prefixToken = virutalItem.prefixToken;
completedItem.suffixToken = virutalItem.suffixToken;
// Add effects for the tokens. Writes to disk using
// table dyn_item_enchantment
ItemManager.applyItemEffects(completedItem);
// Add to the vendor inventory
workOrder.vendor.charItemManager.addItemToInventory(completedItem);
ItemProductionMsg outMsg1 = new ItemProductionMsg(workOrder.vendor.building, workOrder.vendor, completedItem, mbEnums.ProductionActionType.DEPOSIT, true);
DispatchManager.dispatchMsgToInterestArea(workOrder.vendor, outMsg1, mbEnums.DispatchChannel.SECONDARY, 700, false, false);
ItemProductionMsg outMsg2 = new ItemProductionMsg(workOrder.vendor.building, workOrder.vendor, completedItem, mbEnums.ProductionActionType.CONFIRM_DEPOSIT, true);
DispatchManager.dispatchMsgToInterestArea(workOrder.vendor, outMsg2, mbEnums.DispatchChannel.SECONDARY, 700, false, false);
toRemove.add(virutalItem);
}
for (Item virtualItem : toRemove) {
// Remove virtual items from the forge window
ItemProductionMsg outMsg = new ItemProductionMsg(workOrder.vendor.building, workOrder.vendor, virtualItem, mbEnums.ProductionActionType.CONFIRM_SETPRICE, true);
DispatchManager.dispatchMsgToInterestArea(workOrder.vendor, outMsg, mbEnums.DispatchChannel.SECONDARY, 700, false, false);
// Remove virtual item from all collections
workOrder.cooking.remove(virtualItem);
itemWorkOrderLookup.remove(virtualItem);
DbManager.removeFromCache(virtualItem);
}
}
public static void forgeWorkOrderBatch(WorkOrder workOrder) {
// Completion time for this batch is in the future
workOrder.completionTime = System.currentTimeMillis() + workOrder.rollingDuration;
for (int i = 0; i < workOrder.slots_used.get(); ++i) {
Item forged_item = forgeItem(workOrder);
// Update NPC window
ItemProductionMsg outMsg = new ItemProductionMsg(workOrder.vendor.building, workOrder.vendor, forged_item, mbEnums.ProductionActionType.CONFIRM_PRODUCE, true);
DispatchManager.dispatchMsgToInterestArea(workOrder.vendor, outMsg, mbEnums.DispatchChannel.SECONDARY, 700, false, false);
workOrder.total_produced = workOrder.total_produced + 1;
}
// Write updated workOrder to disk
DbManager.WarehouseQueries.WRITE_WORKORDER(workOrder);
}
public static int calcRandomMod(NPC vendor, mbEnums.ItemModType itemModType, int modTable) {
// Random prefix or suffix token based on item.template.modtable
int modifier = 0;
ModTypeTableEntry modTypeTableEntry = null;
ModTableEntry modTableEntry;
int rollForModifier;
switch (itemModType) {
case PREFIX:
int randomPrefix = vendor.getModTypeTable().get(vendor.getItemModTable().indexOf(modTable));
modTypeTableEntry = ModTypeTableEntry.rollTable(randomPrefix, ThreadLocalRandom.current().nextInt(1, 100 + 1));
break;
case SUFFIX:
int randomSuffix = vendor.getModSuffixTable().get(vendor.getItemModTable().indexOf(modTable));
modTypeTableEntry = ModTypeTableEntry.rollTable(randomSuffix, ThreadLocalRandom.current().nextInt(1, 100 + 1));
break;
}
if (modTypeTableEntry == null)
return 0;
rollForModifier = ThreadLocalRandom.current().nextInt(1, 100 + 1);
if (rollForModifier < 80) {
int randomModifier = LootManager.TableRoll(vendor.getLevel(), false);
modTableEntry = ModTableEntry.rollTable(modTypeTableEntry.modTableID, randomModifier);
// @TODO : Figure out how a null can be returned from a defined set.
if (modTableEntry == null)
return 0;
EffectsBase effectsBase = PowersManager.getEffectByIDString(modTableEntry.action);
modifier = effectsBase.getToken();
}
return modifier;
}
}
+8 -10
View File
@@ -9,9 +9,7 @@
package engine.gameManager; package engine.gameManager;
import engine.mbEnums; import engine.mbEnums;
import engine.exception.MsgSendException;
import engine.net.Dispatch; import engine.net.Dispatch;
import engine.net.DispatchMessage;
import engine.net.client.ClientConnection; import engine.net.client.ClientConnection;
import engine.net.client.msg.UpdateGoldMsg; import engine.net.client.msg.UpdateGoldMsg;
import engine.net.client.msg.group.GroupUpdateMsg; import engine.net.client.msg.group.GroupUpdateMsg;
@@ -46,12 +44,12 @@ public enum GroupManager {
} }
public static void LeaveGroup(ClientConnection origin) throws MsgSendException { public static void LeaveGroup(ClientConnection origin) {
PlayerCharacter source = SessionManager.getPlayerCharacter(origin); PlayerCharacter source = SessionManager.getPlayerCharacter(origin);
LeaveGroup(source); LeaveGroup(source);
} }
public static void LeaveGroup(PlayerCharacter source) throws MsgSendException { public static void LeaveGroup(PlayerCharacter source) {
if (source == null) if (source == null)
return; return;
@@ -80,7 +78,7 @@ public enum GroupManager {
groupUpdateMsg.setMessageType(3); groupUpdateMsg.setMessageType(3);
groupUpdateMsg.setPlayer(groupMember); groupUpdateMsg.setPlayer(groupMember);
Dispatch dispatch = Dispatch.borrow(source, groupUpdateMsg); Dispatch dispatch = Dispatch.borrow(source, groupUpdateMsg);
DispatchMessage.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY); DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY);
} }
@@ -160,7 +158,7 @@ public enum GroupManager {
gum.setPlayerUUID(groupMember.getObjectUUID()); gum.setPlayerUUID(groupMember.getObjectUUID());
Dispatch dispatch = Dispatch.borrow(groupMember, gum); Dispatch dispatch = Dispatch.borrow(groupMember, gum);
DispatchMessage.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY); DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY);
} }
} }
@@ -189,7 +187,7 @@ public enum GroupManager {
gum.setMessageType(1); gum.setMessageType(1);
gum.setPlayer(groupMember); gum.setPlayer(groupMember);
Dispatch dispatch = Dispatch.borrow(groupMember, gum); Dispatch dispatch = Dispatch.borrow(groupMember, gum);
DispatchMessage.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY); DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY);
} }
} }
@@ -217,7 +215,7 @@ public enum GroupManager {
gum.setPlayer(playerToRefresh); gum.setPlayer(playerToRefresh);
Dispatch dispatch = Dispatch.borrow(source, gum); Dispatch dispatch = Dispatch.borrow(source, gum);
DispatchMessage.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY); DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY);
} }
public static void RefreshOthersGroupList(PlayerCharacter source) { public static void RefreshOthersGroupList(PlayerCharacter source) {
@@ -372,12 +370,12 @@ public enum GroupManager {
ugm.configure(); ugm.configure();
Dispatch dispatch = Dispatch.borrow(splitPlayer, ugm); Dispatch dispatch = Dispatch.borrow(splitPlayer, ugm);
DispatchMessage.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY); DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY);
} }
UpdateGoldMsg updateTargetGold = new UpdateGoldMsg(tar); UpdateGoldMsg updateTargetGold = new UpdateGoldMsg(tar);
updateTargetGold.configure(); updateTargetGold.configure();
DispatchMessage.dispatchMsgToInterestArea(tar, updateTargetGold, mbEnums.DispatchChannel.SECONDARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false); DispatchManager.dispatchMsgToInterestArea(tar, updateTargetGold, mbEnums.DispatchChannel.SECONDARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false);
// //TODO send group split message // //TODO send group split message
String text = "Group Split: " + amount; String text = "Group Split: " + amount;
+21 -30
View File
@@ -12,7 +12,6 @@ import engine.mbEnums;
import engine.mbEnums.BuildingGroup; import engine.mbEnums.BuildingGroup;
import engine.mbEnums.GuildHistoryType; import engine.mbEnums.GuildHistoryType;
import engine.net.Dispatch; import engine.net.Dispatch;
import engine.net.DispatchMessage;
import engine.net.client.ClientConnection; import engine.net.client.ClientConnection;
import engine.net.client.msg.guild.AcceptInviteToGuildMsg; import engine.net.client.msg.guild.AcceptInviteToGuildMsg;
import engine.net.client.msg.guild.GuildInfoMsg; import engine.net.client.msg.guild.GuildInfoMsg;
@@ -89,16 +88,17 @@ public enum GuildManager {
if (fromTeleportScreen) { if (fromTeleportScreen) {
dispatch = Dispatch.borrow(playerCharacter, msg); dispatch = Dispatch.borrow(playerCharacter, msg);
DispatchMessage.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY); DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY);
} }
if (DbManager.GuildQueries.ADD_TO_GUILDHISTORY(guild.getObjectUUID(), playerCharacter, DateTime.now(), historyType)) { if (DbManager.GuildQueries.ADD_TO_GUILDHISTORY(guild.getObjectUUID(), playerCharacter, DateTime.now(), historyType)) {
GuildHistory guildHistory = new GuildHistory(guild.getObjectUUID(), guild.getName(), DateTime.now(), historyType); GuildHistory guildHistory = new GuildHistory(guild.getObjectUUID(), guild.getName(), DateTime.now(), historyType);
playerCharacter.getGuildHistory().add(guildHistory); playerCharacter.getGuildHistory().add(guildHistory);
} }
DispatchMessage.sendToAllInRange(playerCharacter, new GuildInfoMsg(playerCharacter, guild, 2)); DispatchManager.sendToAllInRange(playerCharacter, new GuildInfoMsg(playerCharacter, guild, 2));
// Send guild join message // Send guild join message
ChatManager.chatGuildInfo(playerCharacter, ChatManager.chatGuildInfo(playerCharacter,
playerCharacter.getFirstName() + " has joined the guild"); playerCharacter.getFirstName() + " has joined the guild");
@@ -108,44 +108,44 @@ public enum GuildManager {
// TODO update player to world // TODO update player to world
} }
public static void enterWorldMOTD(PlayerCharacter pc) { public static void enterWorldMOTD(PlayerCharacter playerCharacter) {
Guild guild; Guild guild;
Guild nation; Guild nation;
if (pc == null) { if (playerCharacter == null)
return; return;
}
guild = pc.getGuild(); guild = playerCharacter.getGuild();
if (guild == null || guild.getObjectUUID() == 0) // Don't send to errant if (guild == null || guild.getObjectUUID() == 0) // Don't send to errant
return; return;
// Send Guild MOTD // Send Guild MOTD
String motd = guild.getMOTD(); String motd = guild.getMOTD();
if (motd.length() > 0) {
ChatManager.chatGuildMOTD(pc, motd); if (!motd.isEmpty())
} ChatManager.chatGuildMOTD(playerCharacter, motd);
// Send Nation MOTD // Send Nation MOTD
nation = guild.getNation(); nation = guild.getNation();
if (nation != null) { if (nation != null)
if (nation.getObjectUUID() != 0) { // Don't send to errant nation if (nation.getObjectUUID() != 0) { // Don't send to errant nation
motd = nation.getMOTD(); motd = nation.getMOTD();
if (motd.length() > 0) {
ChatManager.chatNationMOTD(pc, motd); if (!motd.isEmpty())
} ChatManager.chatNationMOTD(playerCharacter, motd);
} }
}
// Send IC MOTD if player is IC // Send IC MOTD if player is IC
if (GuildStatusController.isInnerCouncil(pc.getGuildStatus())) { if (GuildStatusController.isInnerCouncil(playerCharacter.getGuildStatus())) {
motd = guild.getICMOTD(); motd = guild.getICMOTD();
if (motd.length() > 0) {
ChatManager.chatICMOTD(pc, motd); if (!motd.isEmpty())
} ChatManager.chatICMOTD(playerCharacter, motd);
} }
} }
@@ -156,12 +156,8 @@ public enum GuildManager {
if (guild == null) if (guild == null)
return; return;
int cityID = (city != null) ? city.getObjectUUID() : 0;
//update binds ingame //update binds ingame
for (PlayerCharacter playerCharacter : Guild.GuildRoster(guild)) { for (PlayerCharacter playerCharacter : Guild.GuildRoster(guild)) {
boolean updateBindBuilding = false; boolean updateBindBuilding = false;
@@ -170,7 +166,6 @@ public enum GuildManager {
if (oldBoundBuilding == null || oldBoundBuilding.getBlueprint() == null || oldBoundBuilding.getBlueprint().getBuildingGroup().equals(BuildingGroup.TOL)) if (oldBoundBuilding == null || oldBoundBuilding.getBlueprint() == null || oldBoundBuilding.getBlueprint().getBuildingGroup().equals(BuildingGroup.TOL))
updateBindBuilding = true; updateBindBuilding = true;
if (updateBindBuilding) { if (updateBindBuilding) {
Building bindBuilding = null; Building bindBuilding = null;
if (city != null) if (city != null)
@@ -183,7 +178,6 @@ public enum GuildManager {
playerCharacter.setBindBuildingID(bindBuilding != null ? bindBuilding.getObjectUUID() : 0); playerCharacter.setBindBuildingID(bindBuilding != null ? bindBuilding.getObjectUUID() : 0);
} }
} }
} }
@@ -193,12 +187,9 @@ public enum GuildManager {
if (guild == null) if (guild == null)
return; return;
for (PlayerCharacter player : SessionManager.getAllActivePlayerCharacters()) { for (PlayerCharacter player : SessionManager.getAllActivePlayerCharacters())
if (player.getGuild().equals(guild)) if (player.getGuild().equals(guild))
DispatchMessage.sendToAllInRange(player, new GuildInfoMsg(player, guild, 2)); DispatchManager.sendToAllInRange(player, new GuildInfoMsg(player, guild, 2));
}
} }
public static Boolean meetsLoreRequirements(Guild guild, PlayerCharacter player) { public static Boolean meetsLoreRequirements(Guild guild, PlayerCharacter player) {
+24 -3
View File
@@ -2,10 +2,12 @@ package engine.gameManager;
import engine.mbEnums; import engine.mbEnums;
import engine.objects.*; import engine.objects.*;
import engine.powers.EffectsBase;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
import java.util.EnumSet; import java.util.EnumSet;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
// ·. · · · · . // ·. · · · · .
// · · // · ·
// · · // · ·
@@ -17,6 +19,8 @@ import java.util.concurrent.ConcurrentHashMap;
public enum ItemManager { public enum ItemManager {
ITEMMANAGER; ITEMMANAGER;
public static final AtomicInteger lastNegativeID = new AtomicInteger(0);
public static Boolean ValidRace(Item item, mbEnums.MonsterType race) { public static Boolean ValidRace(Item item, mbEnums.MonsterType race) {
if (item.template.item_race_req.isEmpty() && item.template.item_race_res.isEmpty()) if (item.template.item_race_req.isEmpty() && item.template.item_race_res.isEmpty())
@@ -27,7 +31,7 @@ public enum ItemManager {
return true; return true;
if (item.template.item_race_res.isEmpty() == false) if (item.template.item_race_res.isEmpty() == false)
if (item.template.item_class_res.contains(race) == false) if (item.template.item_race_res.contains(race) == false)
return true; return true;
return false; return false;
@@ -98,7 +102,7 @@ public enum ItemManager {
if (characterSkill == null) if (characterSkill == null)
return false; return false;
if (characterSkill.getModifiedAmountBeforeMods() > required_value) if (characterSkill.getModifiedAmountBeforeMods() >= required_value)
return true; return true;
} }
@@ -185,7 +189,10 @@ public enum ItemManager {
if (!validForSkills(item, abstractCharacter.getSkills())) if (!validForSkills(item, abstractCharacter.getSkills()))
return false; return false;
if (canCharacterEquip(item, abstractCharacter) == false) if (!ValidRace(item, abstractCharacter.absRace))
return false;
if (!ValidClass(item, abstractCharacter.absBaseClass, abstractCharacter.absPromotionClass))
return false; return false;
//players can't wear 0 value items. //players can't wear 0 value items.
@@ -220,4 +227,18 @@ public enum ItemManager {
return true; return true;
} }
public static void applyItemEffects(Item forgedItem) {
if (forgedItem.prefixToken != 0) {
EffectsBase prefix = PowersManager.getEffectByToken(forgedItem.prefixToken);
forgedItem.addPermanentEnchantment(prefix.getIDString(), 0);
}
if (forgedItem.suffixToken != 0) {
EffectsBase suffix = PowersManager.getEffectByToken(forgedItem.suffixToken);
forgedItem.addPermanentEnchantment(suffix.getIDString(), 0);
}
}
} }
+20 -22
View File
@@ -10,7 +10,6 @@ package engine.gameManager;
import engine.loot.*; import engine.loot.*;
import engine.mbEnums; import engine.mbEnums;
import engine.net.DispatchMessage;
import engine.net.client.msg.ErrorPopupMsg; import engine.net.client.msg.ErrorPopupMsg;
import engine.net.client.msg.chat.ChatSystemMsg; import engine.net.client.msg.chat.ChatSystemMsg;
import engine.objects.*; import engine.objects.*;
@@ -25,6 +24,16 @@ import java.util.concurrent.ThreadLocalRandom;
*/ */
public enum LootManager { public enum LootManager {
// MB Dev notes:
// Class implements all loot generation mechanics for Magicbane.
// Class handles variables like drop rates
// Generation initiates in GenerateMobLoot and is passed a mobile
// Utilized database tables:
// - static_loot_bootySet - static_loot_gen - static_loot_item - static_loot_mod - static_loot_modtype
// Class also handles mechanic for Fate Peddler
//
LOOTMANAGER; LOOTMANAGER;
// Newer tables // Newer tables
@@ -80,20 +89,13 @@ public enum LootManager {
RunBootySet(_bootySetMap.get(mob.bootySet), mob, inHotzone); RunBootySet(_bootySetMap.get(mob.bootySet), mob, inHotzone);
//lastly, check mobs inventory for godly or disc runes to send a server announcement //lastly, check mobs inventory for godly or disc runes to send a server announcement
for (Item it : mob.getInventory()) { for (Item item : mob.getInventory()) {
ItemTemplate ib = it.template; if ((item.templateID > 2499 && item.templateID <= 3050) || item.template.item_base_name.toLowerCase().contains("of the gods")) {
ChatSystemMsg chatMsg = new ChatSystemMsg(null, mob.getName() + " in " + mob.getParentZone().zoneName + " has found the " + item.template.item_base_name + ". Are you tough enough to take it?");
if (ib == null)
break;
ItemTemplate template = ItemTemplate.templates.get(it.templateID);
if ((it.templateID > 2499 && it.templateID <= 3050) || template.item_base_name.toLowerCase().contains("of the gods")) {
ChatSystemMsg chatMsg = new ChatSystemMsg(null, mob.getName() + " in " + mob.getParentZone().zoneName + " has found the " + template.item_base_name + ". Are you tough enough to take it?");
chatMsg.setMessageType(10); chatMsg.setMessageType(10);
chatMsg.setChannel(mbEnums.ChatChannelType.SYSTEM.getChannelID()); chatMsg.setChannel(mbEnums.ChatChannelType.SYSTEM.getChannelID());
DispatchMessage.dispatchMsgToAll(chatMsg); DispatchManager.dispatchMsgToAll(chatMsg);
} }
} }
@@ -219,7 +221,7 @@ public enum LootManager {
int prefixTableRoll = 0; int prefixTableRoll = 0;
if (mob.getObjectType().ordinal() == 52) if (mob.getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter))
prefixTableRoll = ThreadLocalRandom.current().nextInt(1, 320 + 1); prefixTableRoll = ThreadLocalRandom.current().nextInt(1, 320 + 1);
else else
prefixTableRoll = TableRoll(mob.level, inHotzone); prefixTableRoll = TableRoll(mob.level, inHotzone);
@@ -229,7 +231,7 @@ public enum LootManager {
if (prefixMod == null) if (prefixMod == null)
return inItem; return inItem;
if (prefixMod.action.length() > 0) { if (prefixMod.action.isEmpty() == false) {
inItem.setPrefix(prefixMod.action); inItem.setPrefix(prefixMod.action);
inItem.addPermanentEnchantment(prefixMod.action, 0, prefixMod.level, true); inItem.addPermanentEnchantment(prefixMod.action, 0, prefixMod.level, true);
} }
@@ -253,7 +255,7 @@ public enum LootManager {
int suffixTableRoll; int suffixTableRoll;
if (mob.getObjectType().ordinal() == 52) if (mob.getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter))
suffixTableRoll = ThreadLocalRandom.current().nextInt(1, 320 + 1); suffixTableRoll = ThreadLocalRandom.current().nextInt(1, 320 + 1);
else else
suffixTableRoll = TableRoll(mob.level, inHotzone); suffixTableRoll = TableRoll(mob.level, inHotzone);
@@ -263,7 +265,7 @@ public enum LootManager {
if (suffixMod == null) if (suffixMod == null)
return inItem; return inItem;
if (suffixMod.action.length() > 0) { if (suffixMod.action.isEmpty() == false) {
inItem.setSuffix(suffixMod.action); inItem.setSuffix(suffixMod.action);
inItem.addPermanentEnchantment(suffixMod.action, 0, suffixMod.level, false); inItem.addPermanentEnchantment(suffixMod.action, 0, suffixMod.level, false);
} }
@@ -277,14 +279,10 @@ public enum LootManager {
mobLevel = 65; mobLevel = 65;
int max = (int) (4.882 * mobLevel + 127.0); int max = (int) (4.882 * mobLevel + 127.0);
if (max > 319)
max = 319;
int min = (int) (4.469 * mobLevel - 3.469); int min = (int) (4.469 * mobLevel - 3.469);
if (min < 70) min = Math.max(min, 70);
min = 70; max = Math.min(max, 319);
if (inHotzone) if (inHotzone)
min += mobLevel; min += mobLevel;
+12 -14
View File
@@ -9,16 +9,14 @@
package engine.gameManager; package engine.gameManager;
import engine.InterestManagement.InterestManager; import engine.InterestManagement.InterestManager;
import engine.exception.MsgSendException;
import engine.math.Bounds; import engine.math.Bounds;
import engine.math.Vector3f; import engine.math.Vector3f;
import engine.math.Vector3fImmutable; import engine.math.Vector3fImmutable;
import engine.mbEnums; import engine.mbEnums;
import engine.mbEnums.DispatchChannel; import engine.mbEnums.DispatchChannel;
import engine.mbEnums.EffectSourceType;
import engine.mbEnums.GameObjectType; import engine.mbEnums.GameObjectType;
import engine.mbEnums.ModType; import engine.mbEnums.ModType;
import engine.mbEnums.SourceType;
import engine.net.DispatchMessage;
import engine.net.client.ClientConnection; import engine.net.client.ClientConnection;
import engine.net.client.msg.MoveToPointMsg; import engine.net.client.msg.MoveToPointMsg;
import engine.net.client.msg.TeleportToPointMsg; import engine.net.client.msg.TeleportToPointMsg;
@@ -50,9 +48,9 @@ public enum MovementManager {
UpdateStateMsg rssm = new UpdateStateMsg(); UpdateStateMsg rssm = new UpdateStateMsg();
rssm.setPlayer(ac); rssm.setPlayer(ac);
if (ac.getObjectType() == GameObjectType.PlayerCharacter) if (ac.getObjectType() == GameObjectType.PlayerCharacter)
DispatchMessage.dispatchMsgToInterestArea(ac, rssm, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false); DispatchManager.dispatchMsgToInterestArea(ac, rssm, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false);
else else
DispatchMessage.sendToAllInRange(ac, rssm); DispatchManager.sendToAllInRange(ac, rssm);
} }
/* /*
@@ -61,7 +59,7 @@ public enum MovementManager {
* target upon each move, unless something has set the firstHitCombatTarget * target upon each move, unless something has set the firstHitCombatTarget
* Also used to determine the size of a monster's hitbox * Also used to determine the size of a monster's hitbox
*/ */
public static void movement(MoveToPointMsg msg, AbstractCharacter toMove) throws MsgSendException { public static void movement(MoveToPointMsg msg, AbstractCharacter toMove) {
// check for stun/root // check for stun/root
if (!toMove.isAlive()) if (!toMove.isAlive())
@@ -76,7 +74,7 @@ public enum MovementManager {
toMove.setIsCasting(false); toMove.setIsCasting(false);
toMove.setItemCasting(false); toMove.setItemCasting(false);
if (toMove.getBonuses().getBool(ModType.Stunned, SourceType.None) || toMove.getBonuses().getBool(ModType.CannotMove, SourceType.None)) { if (toMove.getBonuses().getBool(ModType.Stunned, EffectSourceType.None) || toMove.getBonuses().getBool(ModType.CannotMove, EffectSourceType.None)) {
return; return;
} }
@@ -241,7 +239,7 @@ public enum MovementManager {
// If it's not a player moving just send the message // If it's not a player moving just send the message
if ((toMove.getObjectType() == GameObjectType.PlayerCharacter) == false) { if ((toMove.getObjectType() == GameObjectType.PlayerCharacter) == false) {
DispatchMessage.sendToAllInRange(toMove, msg); DispatchManager.sendToAllInRange(toMove, msg);
return; return;
} }
@@ -253,9 +251,9 @@ public enum MovementManager {
player.setTimeStamp("lastMoveGate", System.currentTimeMillis()); player.setTimeStamp("lastMoveGate", System.currentTimeMillis());
if (collide) if (collide)
DispatchMessage.dispatchMsgToInterestArea(player, msg, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false); DispatchManager.dispatchMsgToInterestArea(player, msg, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false);
else else
DispatchMessage.dispatchMsgToInterestArea(player, msg, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, false, false); DispatchManager.dispatchMsgToInterestArea(player, msg, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, false, false);
// Handle formation movement if needed // Handle formation movement if needed
@@ -349,7 +347,7 @@ public enum MovementManager {
// Handle formation movement in group // Handle formation movement in group
public static void moveGroup(PlayerCharacter pc, ClientConnection origin, MoveToPointMsg msg) throws MsgSendException { public static void moveGroup(PlayerCharacter pc, ClientConnection origin, MoveToPointMsg msg) {
// get forward vector // get forward vector
Vector3f faceDir = new Vector3f(pc.getFaceDir().x, 0, pc.getFaceDir().z).normalize(); Vector3f faceDir = new Vector3f(pc.getFaceDir().x, 0, pc.getFaceDir().z).normalize();
// get perpendicular vector // get perpendicular vector
@@ -392,7 +390,7 @@ public enum MovementManager {
//don't move if player is stunned or rooted //don't move if player is stunned or rooted
PlayerBonuses bonus = member.getBonuses(); PlayerBonuses bonus = member.getBonuses();
if (bonus.getBool(ModType.Stunned, SourceType.None) || bonus.getBool(ModType.CannotMove, SourceType.None)) if (bonus.getBool(ModType.Stunned, EffectSourceType.None) || bonus.getBool(ModType.CannotMove, EffectSourceType.None))
continue; continue;
member.update(); member.update();
@@ -443,7 +441,7 @@ public enum MovementManager {
groupMsg.setStartCoord(member.getLoc()); groupMsg.setStartCoord(member.getLoc());
groupMsg.setEndCoord(destination); groupMsg.setEndCoord(destination);
groupMsg.clearTarget(); groupMsg.clearTarget();
DispatchMessage.sendToAllInRange(member, groupMsg); DispatchManager.sendToAllInRange(member, groupMsg);
// update group member // update group member
member.setFaceDir(destination.subtract2D(member.getLoc()).normalize()); member.setFaceDir(destination.subtract2D(member.getLoc()).normalize());
@@ -463,7 +461,7 @@ public enum MovementManager {
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); 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); DispatchManager.dispatchMsgToInterestArea(oldLoc, teleporter, msg, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false);
} }
+40 -2
View File
@@ -9,12 +9,12 @@
package engine.gameManager; package engine.gameManager;
import engine.InterestManagement.WorldGrid; import engine.InterestManagement.WorldGrid;
import engine.loot.WorkOrder;
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.mbEnums; import engine.mbEnums;
import engine.net.Dispatch; import engine.net.Dispatch;
import engine.net.DispatchMessage;
import engine.net.client.ClientConnection; import engine.net.client.ClientConnection;
import engine.net.client.msg.ErrorPopupMsg; import engine.net.client.msg.ErrorPopupMsg;
import engine.net.client.msg.PetMsg; import engine.net.client.msg.PetMsg;
@@ -26,7 +26,9 @@ import org.pmw.tinylog.Logger;
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;
import java.util.concurrent.TimeUnit;
import static engine.math.FastMath.acos; import static engine.math.FastMath.acos;
@@ -66,7 +68,7 @@ public enum NPCManager {
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, mbEnums.DispatchChannel.PRIMARY); DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.PRIMARY);
} }
} }
@@ -516,4 +518,40 @@ public enum NPCManager {
return true; return true;
} }
public static ArrayList<Item> getAllCookingForVendor(NPC npc) {
ArrayList<Item> itemList = new ArrayList<>();
ConcurrentHashMap.KeySetView<WorkOrder, Boolean> vendorWorkOrders = ForgeManager.vendorWorkOrderLookup.get(npc);
if (vendorWorkOrders == null)
return itemList;
for (WorkOrder workOrder : vendorWorkOrders)
itemList.addAll(workOrder.cooking);
return itemList;
}
public static long calcRollingDuration(NPC vendor, int templateID) {
ItemTemplate template = ItemTemplate.templates.get(templateID);
float rollingDuration;
if (template == null)
return 0;
if (template.item_bane_rank > 0)
return (long) (template.item_bane_rank * 60 * 60 * 3 * 1000 * Float.parseFloat(ConfigManager.MB_PRODUCTION_RATE.getValue()));
if (vendor.building == null)
return 600;
rollingDuration = vendor.getBuilding().getRank() * -5L + 40;
rollingDuration = TimeUnit.MINUTES.toMillis((long) rollingDuration);
rollingDuration *= Float.parseFloat(ConfigManager.MB_PRODUCTION_RATE.getValue());
return (long) rollingDuration;
}
} }
+61 -49
View File
@@ -25,7 +25,6 @@ import engine.math.Vector3fImmutable;
import engine.mbEnums.*; import engine.mbEnums.*;
import engine.net.ByteBufferWriter; import engine.net.ByteBufferWriter;
import engine.net.Dispatch; import engine.net.Dispatch;
import engine.net.DispatchMessage;
import engine.net.client.ClientConnection; import engine.net.client.ClientConnection;
import engine.net.client.msg.*; import engine.net.client.msg.*;
import engine.objects.*; import engine.objects.*;
@@ -57,6 +56,7 @@ public enum PowersManager {
public static HashMap<String, Integer> AnimationOverrides = new HashMap<>(); public static HashMap<String, Integer> AnimationOverrides = new HashMap<>();
public static HashMap<Integer, ArrayList<RunePowerEntry>> _allRunePowers; public static HashMap<Integer, ArrayList<RunePowerEntry>> _allRunePowers;
public static HashMap<Integer, ArrayList<RuneSkillAdjustEntry>> _allRuneSkillAdjusts; public static HashMap<Integer, ArrayList<RuneSkillAdjustEntry>> _allRuneSkillAdjusts;
public static HashMap<String, HashMap<ResourceType, Integer>> _effect_costMaps = new HashMap<>();
private static JobScheduler js; private static JobScheduler js;
public static void initPowersManager(boolean fullPowersLoad) { public static void initPowersManager(boolean fullPowersLoad) {
@@ -172,16 +172,33 @@ public enum PowersManager {
public static void usePower(final PerformActionMsg msg, ClientConnection origin, public static void usePower(final PerformActionMsg msg, ClientConnection origin,
boolean sendCastToSelf) { boolean sendCastToSelf) {
if (ConfigManager.MB_RULESET.getValue() == "LORE") { if (ConfigManager.MB_RULESET.getValue().equals("LORE")) {
PowersBase pb = PowersManager.powersBaseByToken.get(msg.getPowerUsedID()); PowersBase pb = PowersManager.powersBaseByToken.get(msg.getPowerUsedID());
PlayerCharacter caster = origin.getPlayerCharacter(); PlayerCharacter caster = origin.getPlayerCharacter();
PlayerCharacter target = PlayerCharacter.getFromCache(msg.getTargetID()); PlayerCharacter target = PlayerCharacter.getFromCache(msg.getTargetID());
if (pb != null && pb.isHarmful == false) { if (pb != null && pb.enforceLore()) {
if (caster.guild.equals(Guild.getErrantGuild())) //if (caster.guild.equals(Guild.getErrantGuild()))
return; // return;
if (target != null && caster.guild.getGuildType().equals(target.guild.getGuildType()) == false) if (target != null && caster.guild.getGuildType().equals(target.guild.getGuildType()) == false && target.getObjectType().equals(GameObjectType.Building) == false) {
RecyclePowerMsg recyclePowerMsg = new RecyclePowerMsg(msg.getPowerUsedID());
Dispatch dispatch = Dispatch.borrow(origin.getPlayerCharacter(), recyclePowerMsg);
DispatchManager.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY);
// Send Fail to cast message
PlayerCharacter pc = SessionManager
.getPlayerCharacter(origin);
if (pc != null) {
sendPowerMsg(pc, 2, msg);
if (pc.isCasting()) {
pc.update();
}
pc.setIsCasting(false);
}
return; return;
}
} }
} }
@@ -190,7 +207,7 @@ public enum PowersManager {
RecyclePowerMsg recyclePowerMsg = new RecyclePowerMsg(msg.getPowerUsedID()); RecyclePowerMsg recyclePowerMsg = new RecyclePowerMsg(msg.getPowerUsedID());
Dispatch dispatch = Dispatch.borrow(origin.getPlayerCharacter(), recyclePowerMsg); Dispatch dispatch = Dispatch.borrow(origin.getPlayerCharacter(), recyclePowerMsg);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY); DispatchManager.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY);
// Send Fail to cast message // Send Fail to cast message
PlayerCharacter pc = SessionManager PlayerCharacter pc = SessionManager
@@ -243,7 +260,7 @@ public enum PowersManager {
RecyclePowerMsg recyclePowerMsg = new RecyclePowerMsg(msg.getPowerUsedID()); RecyclePowerMsg recyclePowerMsg = new RecyclePowerMsg(msg.getPowerUsedID());
Dispatch dispatch = Dispatch.borrow(playerCharacter, recyclePowerMsg); Dispatch dispatch = Dispatch.borrow(playerCharacter, recyclePowerMsg);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY); DispatchManager.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY);
return false; return false;
} }
@@ -331,8 +348,8 @@ public enum PowersManager {
// verify player is not stunned or prohibited from casting // verify player is not stunned or prohibited from casting
PlayerBonuses bonus = playerCharacter.getBonuses(); PlayerBonuses bonus = playerCharacter.getBonuses();
SourceType sourceType = SourceType.GetSourceType(pb.getCategory()); EffectSourceType sourceType = EffectSourceType.getEffectSourceType(pb.getCategory());
if (bonus != null && (bonus.getBool(ModType.Stunned, SourceType.None) || bonus.getBool(ModType.CannotCast, SourceType.None) || bonus.getBool(ModType.BlockedPowerType, sourceType))) if (bonus != null && (bonus.getBool(ModType.Stunned, EffectSourceType.None) || bonus.getBool(ModType.CannotCast, EffectSourceType.None) || bonus.getBool(ModType.BlockedPowerType, sourceType)))
return true; return true;
// if moving make sure spell valid for movement // if moving make sure spell valid for movement
@@ -468,7 +485,7 @@ public enum PowersManager {
cost = 0; cost = 0;
if (bonus != null) if (bonus != null)
cost *= (1 + bonus.getFloatPercentAll(ModType.PowerCost, SourceType.None)); cost *= (1 + bonus.getFloatPercentAll(ModType.PowerCost, EffectSourceType.None));
if (playerCharacter.getAltitude() > 0) if (playerCharacter.getAltitude() > 0)
cost *= 1.5f; cost *= 1.5f;
@@ -487,7 +504,7 @@ public enum PowersManager {
0f, 0f, 0, null, 0f, 0f, 0, null,
9999, 0); 9999, 0);
mhm.setOmitFromChat(1); mhm.setOmitFromChat(1);
DispatchMessage.dispatchMsgToInterestArea(playerCharacter, mhm, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false); DispatchManager.dispatchMsgToInterestArea(playerCharacter, mhm, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false);
} }
else if (pb.useMana()) else if (pb.useMana())
if (playerCharacter.getMana() < cost) if (playerCharacter.getMana() < cost)
@@ -518,7 +535,7 @@ public enum PowersManager {
// else send recycle message to unlock power // else send recycle message to unlock power
RecyclePowerMsg recyclePowerMsg = new RecyclePowerMsg(msg.getPowerUsedID()); RecyclePowerMsg recyclePowerMsg = new RecyclePowerMsg(msg.getPowerUsedID());
Dispatch dispatch = Dispatch.borrow(playerCharacter, recyclePowerMsg); Dispatch dispatch = Dispatch.borrow(playerCharacter, recyclePowerMsg);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY); DispatchManager.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY);
} }
//what the fuck? //what the fuck?
@@ -528,7 +545,7 @@ public enum PowersManager {
// else // else
// msg.setUnknown04(1); // Regular Race, use mana? // msg.setUnknown04(1); // Regular Race, use mana?
int tr = msg.getNumTrains(); int tr = msg.getNumTrains();
DispatchMessage.dispatchMsgToInterestArea(playerCharacter, msg, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, sendCastToSelf, false); DispatchManager.dispatchMsgToInterestArea(playerCharacter, msg, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, sendCastToSelf, false);
//Make new msg.. //Make new msg..
PerformActionMsg copyMsg = new PerformActionMsg(msg); PerformActionMsg copyMsg = new PerformActionMsg(msg);
@@ -539,7 +556,7 @@ public enum PowersManager {
playerCharacter.update(); playerCharacter.update();
playerCharacter.setSit(false); playerCharacter.setSit(false);
UpdateStateMsg updateStateMsg = new UpdateStateMsg(playerCharacter); UpdateStateMsg updateStateMsg = new UpdateStateMsg(playerCharacter);
DispatchMessage.dispatchMsgToInterestArea(playerCharacter, updateStateMsg, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false); DispatchManager.dispatchMsgToInterestArea(playerCharacter, updateStateMsg, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false);
} }
@@ -614,8 +631,8 @@ public enum PowersManager {
// verify player is in correct mode (combat/nonCombat) // verify player is in correct mode (combat/nonCombat)
// verify player is not stunned or prohibited from casting // verify player is not stunned or prohibited from casting
PlayerBonuses bonus = caster.getBonuses(); PlayerBonuses bonus = caster.getBonuses();
SourceType sourceType = SourceType.GetSourceType(pb.getCategory()); EffectSourceType sourceType = EffectSourceType.getEffectSourceType(pb.getCategory());
if (bonus != null && (bonus.getBool(ModType.Stunned, SourceType.None) || bonus.getBool(ModType.CannotCast, SourceType.None) || bonus.getBool(ModType.BlockedPowerType, sourceType))) if (bonus != null && (bonus.getBool(ModType.Stunned, EffectSourceType.None) || bonus.getBool(ModType.CannotCast, EffectSourceType.None) || bonus.getBool(ModType.BlockedPowerType, sourceType)))
return true; return true;
// if moving make sure spell valid for movement // if moving make sure spell valid for movement
@@ -682,8 +699,8 @@ public enum PowersManager {
msg.setNumTrains(9999); msg.setNumTrains(9999);
DispatchMessage.sendToAllInRange(caster, msg); DispatchManager.sendToAllInRange(caster, msg);
DispatchMessage.sendToAllInRange(caster, msg); DispatchManager.sendToAllInRange(caster, msg);
msg.setNumTrains(tr); msg.setNumTrains(tr);
@@ -750,7 +767,7 @@ public enum PowersManager {
performActionMsg.setUnknown04(2); performActionMsg.setUnknown04(2);
dispatch = Dispatch.borrow(playerCharacter, performActionMsg); dispatch = Dispatch.borrow(playerCharacter, performActionMsg);
DispatchMessage.dispatchMsgToInterestArea(playerCharacter, performActionMsg, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false); DispatchManager.dispatchMsgToInterestArea(playerCharacter, performActionMsg, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false);
return; return;
} }
@@ -775,10 +792,10 @@ public enum PowersManager {
PlayerBonuses bonus = playerCharacter.getBonuses(); PlayerBonuses bonus = playerCharacter.getBonuses();
if (bonus != null) { if (bonus != null) {
if (bonus.getBool(ModType.Stunned, SourceType.None)) if (bonus.getBool(ModType.Stunned, EffectSourceType.None))
return; return;
SourceType sourceType = SourceType.GetSourceType(pb.getCategory()); EffectSourceType sourceType = EffectSourceType.getEffectSourceType(pb.getCategory());
if (bonus.getBool(ModType.BlockedPowerType, sourceType)) { if (bonus.getBool(ModType.BlockedPowerType, sourceType)) {
finishRecycleTime(msg.getPowerUsedID(), playerCharacter, true); finishRecycleTime(msg.getPowerUsedID(), playerCharacter, true);
return; return;
@@ -908,10 +925,6 @@ public enum PowersManager {
if (pb.isHarmful()) if (pb.isHarmful())
mobTarget.handleDirectAggro(playerCharacter); mobTarget.handleDirectAggro(playerCharacter);
} }
//Power is aiding a target, handle aggro if combat target is a Mob.
if (!pb.isHarmful() && target.getObjectType() == GameObjectType.PlayerCharacter) {
PlayerCharacter pcTarget = (PlayerCharacter) target;
}
// update target of used power timer // update target of used power timer
@@ -933,8 +946,7 @@ public enum PowersManager {
continue; continue;
// If something blocks the action, then stop // If something blocks the action, then stop
if (ab.blocked(target, pb, trains)) { if (ab.blocked(target,pb.vampDrain)) {
PowersManager.sendEffectMsg(playerCharacter, 5, ab, pb); PowersManager.sendEffectMsg(playerCharacter, 5, ab, pb);
continue; continue;
} }
@@ -991,7 +1003,7 @@ public enum PowersManager {
PerformActionMsg castMsg = new PerformActionMsg(msg); PerformActionMsg castMsg = new PerformActionMsg(msg);
castMsg.setNumTrains(9999); castMsg.setNumTrains(9999);
castMsg.setUnknown04(2); castMsg.setUnknown04(2);
DispatchMessage.dispatchMsgToInterestArea(playerCharacter, castMsg, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false); DispatchManager.dispatchMsgToInterestArea(playerCharacter, castMsg, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false);
msgCasted = true; msgCasted = true;
} }
} }
@@ -1001,7 +1013,7 @@ public enum PowersManager {
PerformActionMsg castMsg = new PerformActionMsg(msg); PerformActionMsg castMsg = new PerformActionMsg(msg);
castMsg.setNumTrains(9999); castMsg.setNumTrains(9999);
castMsg.setUnknown04(2); castMsg.setUnknown04(2);
DispatchMessage.dispatchMsgToInterestArea(playerCharacter, castMsg, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false); DispatchManager.dispatchMsgToInterestArea(playerCharacter, castMsg, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false);
msgCasted = true; msgCasted = true;
} }
@@ -1053,16 +1065,16 @@ public enum PowersManager {
// verify player is not stunned or power type is blocked // verify player is not stunned or power type is blocked
PlayerBonuses bonus = caster.getBonuses(); PlayerBonuses bonus = caster.getBonuses();
if (bonus != null) { if (bonus != null) {
if (bonus.getBool(ModType.Stunned, SourceType.None)) if (bonus.getBool(ModType.Stunned, EffectSourceType.None))
return; return;
SourceType sourceType = SourceType.GetSourceType(pb.getCategory()); EffectSourceType sourceType = EffectSourceType.getEffectSourceType(pb.getCategory());
if (bonus.getBool(ModType.BlockedPowerType, sourceType)) if (bonus.getBool(ModType.BlockedPowerType, sourceType))
return; return;
} }
msg.setNumTrains(9999); msg.setNumTrains(9999);
msg.setUnknown04(2); msg.setUnknown04(2);
DispatchMessage.sendToAllInRange(caster, msg); DispatchManager.sendToAllInRange(caster, msg);
// get target loc // get target loc
Vector3fImmutable targetLoc = msg.getTargetLoc(); Vector3fImmutable targetLoc = msg.getTargetLoc();
@@ -1109,7 +1121,7 @@ public enum PowersManager {
continue; continue;
// If something blocks the action, then stop // If something blocks the action, then stop
if (ab.blocked(target, pb, trains)) if (ab.blocked(target,pb.vampDrain))
continue; continue;
// TODO handle overwrite stack order here // TODO handle overwrite stack order here
String stackType = ab.getStackType(); String stackType = ab.getStackType();
@@ -1169,7 +1181,7 @@ public enum PowersManager {
// TODO echo power use to everyone else // TODO echo power use to everyone else
msg.setNumTrains(9999); msg.setNumTrains(9999);
msg.setUnknown04(2); msg.setUnknown04(2);
DispatchMessage.sendToAllInRange(caster, msg); DispatchManager.sendToAllInRange(caster, msg);
} }
@@ -1247,7 +1259,7 @@ public enum PowersManager {
RecyclePowerMsg recyclePowerMsg = new RecyclePowerMsg(token); RecyclePowerMsg recyclePowerMsg = new RecyclePowerMsg(token);
Dispatch dispatch = Dispatch.borrow(origin.getPlayerCharacter(), recyclePowerMsg); Dispatch dispatch = Dispatch.borrow(origin.getPlayerCharacter(), recyclePowerMsg);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY); DispatchManager.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY);
} }
@@ -1373,7 +1385,7 @@ public enum PowersManager {
PerformActionMsg msg = new PerformActionMsg(pb.getToken(), PerformActionMsg msg = new PerformActionMsg(pb.getToken(),
trains, ac.getObjectType().ordinal(), ac.getObjectUUID(), tarType, tarID, 0, trains, ac.getObjectType().ordinal(), ac.getObjectUUID(), tarType, tarID, 0,
0, 0, 1, 0); 0, 0, 1, 0);
DispatchMessage.sendToAllInRange(target, msg); DispatchManager.sendToAllInRange(target, msg);
ConcurrentHashMap<String, JobContainer> timers = ac.getTimers(); ConcurrentHashMap<String, JobContainer> timers = ac.getTimers();
@@ -1423,7 +1435,7 @@ public enum PowersManager {
if (trains < ab.getMinTrains() || trains > ab.getMaxTrains()) if (trains < ab.getMinTrains() || trains > ab.getMaxTrains())
continue; continue;
// If something blocks the action, then stop // If something blocks the action, then stop
if (ab.blocked(target, pb, trains)) if (ab.blocked(target,pb.vampDrain))
// sendPowerMsg(pc, 5, msg); // sendPowerMsg(pc, 5, msg);
continue; continue;
// TODO handle overwrite stack order here // TODO handle overwrite stack order here
@@ -1491,7 +1503,7 @@ public enum PowersManager {
.getObjectType().ordinal(), ac.getObjectUUID(), target.getObjectType().ordinal(), .getObjectType().ordinal(), ac.getObjectUUID(), target.getObjectType().ordinal(),
target.getObjectUUID(), 0, 0, 0, 2, 0); target.getObjectUUID(), 0, 0, 0, 2, 0);
DispatchMessage.sendToAllInRange(ac, msg); DispatchManager.sendToAllInRange(ac, msg);
} }
} }
@@ -1688,7 +1700,7 @@ public enum PowersManager {
PlayerCharacter pcc = (PlayerCharacter) awo; PlayerCharacter pcc = (PlayerCharacter) awo;
PlayerBonuses bonuses = pcc.getBonuses(); PlayerBonuses bonuses = pcc.getBonuses();
if (bonuses != null && bonuses.getBool(ModType.ImmuneToPowers, SourceType.None)) { if (bonuses != null && bonuses.getBool(ModType.ImmuneToPowers, EffectSourceType.None)) {
awolist.remove(); awolist.remove();
continue; continue;
} }
@@ -1838,7 +1850,7 @@ public enum PowersManager {
// Remove players who are in safe mode // Remove players who are in safe mode
PlayerCharacter pcc = (PlayerCharacter) awo; PlayerCharacter pcc = (PlayerCharacter) awo;
PlayerBonuses bonuses = pcc.getBonuses(); PlayerBonuses bonuses = pcc.getBonuses();
if (bonuses != null && bonuses.getBool(ModType.ImmuneToPowers, SourceType.None)) { if (bonuses != null && bonuses.getBool(ModType.ImmuneToPowers, EffectSourceType.None)) {
awolist.remove(); awolist.remove();
continue; continue;
} }
@@ -1942,7 +1954,7 @@ public enum PowersManager {
RecyclePowerMsg recyclePowerMsg = new RecyclePowerMsg(token); RecyclePowerMsg recyclePowerMsg = new RecyclePowerMsg(token);
Dispatch dispatch = Dispatch.borrow(pc, recyclePowerMsg); Dispatch dispatch = Dispatch.borrow(pc, recyclePowerMsg);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY); DispatchManager.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY);
} }
@@ -2102,12 +2114,12 @@ public enum PowersManager {
case 3: case 3:
case 4: case 4:
msg.setUnknown04(2); msg.setUnknown04(2);
DispatchMessage.dispatchMsgToInterestArea(playerCharacter, msg, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false); DispatchManager.dispatchMsgToInterestArea(playerCharacter, msg, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false);
break; break;
default: default:
msg.setUnknown04(1); msg.setUnknown04(1);
Dispatch dispatch = Dispatch.borrow(playerCharacter, msg); Dispatch dispatch = Dispatch.borrow(playerCharacter, msg);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY); DispatchManager.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY);
} }
} }
@@ -2125,7 +2137,7 @@ public enum PowersManager {
ApplyEffectMsg aem = new ApplyEffectMsg(pc, pc, 0, eb.getToken(), 9, pb.getToken(), pb.getName()); ApplyEffectMsg aem = new ApplyEffectMsg(pc, pc, 0, eb.getToken(), 9, pb.getToken(), pb.getName());
aem.setUnknown03(type); aem.setUnknown03(type);
DispatchMessage.dispatchMsgToInterestArea(pc, aem, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false); DispatchManager.dispatchMsgToInterestArea(pc, aem, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false);
} catch (Exception e) { } catch (Exception e) {
@@ -2146,7 +2158,7 @@ public enum PowersManager {
aem.setUnknown03(type); aem.setUnknown03(type);
aem.setUnknown05(1); aem.setUnknown05(1);
DispatchMessage.dispatchMsgToInterestArea(pc, aem, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false); DispatchManager.dispatchMsgToInterestArea(pc, aem, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false);
} catch (Exception e) { } catch (Exception e) {
@@ -2161,7 +2173,7 @@ public enum PowersManager {
switch (type) { switch (type) {
case 3: case 3:
case 4: case 4:
DispatchMessage.sendToAllInRange(mob, msg); DispatchManager.sendToAllInRange(mob, msg);
} }
} }
@@ -2400,7 +2412,7 @@ public enum PowersManager {
if (pam != null) { if (pam != null) {
pam.setNumTrains(9999); pam.setNumTrains(9999);
pam.setUnknown04(2); pam.setUnknown04(2);
DispatchMessage.sendToAllInRange(ac, pam); DispatchManager.sendToAllInRange(ac, pam);
} }
} }
} }
@@ -2464,7 +2476,7 @@ public enum PowersManager {
PerformActionMsg pam = new PerformActionMsg(pb.getToken(), 9999, ac PerformActionMsg pam = new PerformActionMsg(pb.getToken(), 9999, ac
.getObjectType().ordinal(), ac.getObjectUUID(), target.getObjectType().ordinal(), .getObjectType().ordinal(), ac.getObjectUUID(), target.getObjectType().ordinal(),
target.getObjectUUID(), 0, 0, 0, 2, 0); target.getObjectUUID(), 0, 0, 0, 2, 0);
DispatchMessage.sendToAllInRange(ac, pam); DispatchManager.sendToAllInRange(ac, pam);
} }
} }
+13 -8
View File
@@ -24,10 +24,16 @@ import java.time.Duration;
import java.time.Instant; import java.time.Instant;
import java.util.Collection; import java.util.Collection;
/* // MB Dev Notes:
* This class contains all methods necessary to drive periodic //
* updates of the game simulation from the main _exec loop. // Class models timers that drive Magicbane simulation ticks used
*/ // for movement updates, triggers and more. Eventually we hope to
// refactor to more of a traditional simulation appropriate for a
// mmo with a transform class and other bells and whistles.
//
// Do as little as possible in here. For any tick you do not want
// deltaTime to approach 1.0f.
public enum SimulationManager { public enum SimulationManager {
SERVERHEARTBEAT; SERVERHEARTBEAT;
@@ -35,15 +41,14 @@ public enum SimulationManager {
private static final long CITY_PULSE = 2000; private static final long CITY_PULSE = 2000;
private static final long RUNEGATE_PULSE = 3000; private static final long RUNEGATE_PULSE = 3000;
private static final long UPDATE_PULSE = 1000; private static final long UPDATE_PULSE = 1000;
private static final long FlIGHT_PULSE = 100; private static final long FLIGHT_PULSE = 100;
public static Duration executionTime = Duration.ofNanos(1); public static Duration executionTime = Duration.ofNanos(1);
public static Duration executionMax = Duration.ofNanos(1); public static Duration executionMax = Duration.ofNanos(1);
private static SimulationManager instance = null;
private long _cityPulseTime = System.currentTimeMillis() + CITY_PULSE; private long _cityPulseTime = System.currentTimeMillis() + CITY_PULSE;
private long _runegatePulseTime = System.currentTimeMillis() private long _runegatePulseTime = System.currentTimeMillis()
+ RUNEGATE_PULSE; + RUNEGATE_PULSE;
private long _updatePulseTime = System.currentTimeMillis() + UPDATE_PULSE; private long _updatePulseTime = System.currentTimeMillis() + UPDATE_PULSE;
private long _flightPulseTime = System.currentTimeMillis() + FlIGHT_PULSE; private long _flightPulseTime = System.currentTimeMillis() + FLIGHT_PULSE;
private SimulationManager() { private SimulationManager() {
@@ -181,7 +186,7 @@ public enum SimulationManager {
player.updateFlight(); player.updateFlight();
} }
_flightPulseTime = System.currentTimeMillis() + FlIGHT_PULSE; _flightPulseTime = System.currentTimeMillis() + FLIGHT_PULSE;
} }
private void pulseCities() { private void pulseCities() {
+1 -1
View File
@@ -8,12 +8,12 @@
package engine.gameManager; package engine.gameManager;
import engine.mbEnums;
import engine.InterestManagement.Terrain; import engine.InterestManagement.Terrain;
import engine.math.Bounds; import engine.math.Bounds;
import engine.math.Vector2f; import engine.math.Vector2f;
import engine.math.Vector3f; import engine.math.Vector3f;
import engine.math.Vector3fImmutable; import engine.math.Vector3fImmutable;
import engine.mbEnums;
import engine.objects.Building; import engine.objects.Building;
import engine.objects.City; import engine.objects.City;
import engine.objects.Zone; import engine.objects.Zone;
+2 -2
View File
@@ -10,10 +10,10 @@
package engine.jobs; package engine.jobs;
import engine.gameManager.DbManager; import engine.gameManager.DbManager;
import engine.gameManager.DispatchManager;
import engine.job.AbstractScheduleJob; import engine.job.AbstractScheduleJob;
import engine.mbEnums; import engine.mbEnums;
import engine.mbEnums.ChatChannelType; import engine.mbEnums.ChatChannelType;
import engine.net.DispatchMessage;
import engine.net.client.msg.chat.ChatSystemMsg; import engine.net.client.msg.chat.ChatSystemMsg;
import engine.objects.City; import engine.objects.City;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
@@ -66,7 +66,7 @@ public class ActivateBaneJob extends AbstractScheduleJob {
msg.setMessageType(4); // Error message msg.setMessageType(4); // Error message
msg.setChannel(ChatChannelType.SYSTEM.getChannelID()); msg.setChannel(ChatChannelType.SYSTEM.getChannelID());
DispatchMessage.dispatchMsgToAll(msg); DispatchManager.dispatchMsgToAll(msg);
} }
@Override @Override
+2 -2
View File
@@ -11,9 +11,9 @@ package engine.jobs;
import engine.gameManager.PowersManager; import engine.gameManager.PowersManager;
import engine.gameManager.SessionManager; import engine.gameManager.SessionManager;
import engine.mbEnums.EffectSourceType;
import engine.mbEnums.GameObjectType; import engine.mbEnums.GameObjectType;
import engine.mbEnums.ModType; import engine.mbEnums.ModType;
import engine.mbEnums.SourceType;
import engine.objects.AbstractCharacter; import engine.objects.AbstractCharacter;
import engine.objects.AbstractWorldObject; import engine.objects.AbstractWorldObject;
import engine.objects.PlayerBonuses; import engine.objects.PlayerBonuses;
@@ -52,7 +52,7 @@ public class ChantJob extends AbstractEffectJob {
PowersManager.finishEffectTime(this.source, this.target, this.action, this.trains); PowersManager.finishEffectTime(this.source, this.target, this.action, this.trains);
if (AbstractWorldObject.IsAbstractCharacter(source)) if (AbstractWorldObject.IsAbstractCharacter(source))
((AbstractCharacter) source).cancelLastChant(); ((AbstractCharacter) source).cancelLastChant();
} else if (bonuses != null && bonuses.getBool(ModType.Silenced, SourceType.None)) { } else if (bonuses != null && bonuses.getBool(ModType.Silenced, EffectSourceType.None)) {
PowersManager.finishEffectTime(this.source, this.target, this.action, this.trains); PowersManager.finishEffectTime(this.source, this.target, this.action, this.trains);
if (AbstractWorldObject.IsAbstractCharacter(source)) if (AbstractWorldObject.IsAbstractCharacter(source))
((AbstractCharacter) source).cancelLastChant(); ((AbstractCharacter) source).cancelLastChant();
+3 -3
View File
@@ -9,9 +9,9 @@
package engine.jobs; package engine.jobs;
import engine.mbEnums.DoorState; import engine.gameManager.DispatchManager;
import engine.job.AbstractScheduleJob; import engine.job.AbstractScheduleJob;
import engine.net.DispatchMessage; import engine.mbEnums.DoorState;
import engine.net.client.msg.DoorTryOpenMsg; import engine.net.client.msg.DoorTryOpenMsg;
import engine.objects.Blueprint; import engine.objects.Blueprint;
import engine.objects.Building; import engine.objects.Building;
@@ -40,7 +40,7 @@ public class DoorCloseJob extends AbstractScheduleJob {
this.building.setDoorState(doorNumber, DoorState.CLOSED); this.building.setDoorState(doorNumber, DoorState.CLOSED);
DoorTryOpenMsg msg = new DoorTryOpenMsg(door, this.building.getObjectUUID(), 0, (byte) 0); DoorTryOpenMsg msg = new DoorTryOpenMsg(door, this.building.getObjectUUID(), 0, (byte) 0);
DispatchMessage.sendToAllInRange(building, msg); DispatchManager.sendToAllInRange(building, msg);
} }
+3 -3
View File
@@ -9,11 +9,11 @@
package engine.jobs; package engine.jobs;
import engine.mbEnums.ModType;
import engine.mbEnums.SourceType;
import engine.gameManager.PowersManager; import engine.gameManager.PowersManager;
import engine.job.AbstractScheduleJob; import engine.job.AbstractScheduleJob;
import engine.job.JobContainer; import engine.job.JobContainer;
import engine.mbEnums.EffectSourceType;
import engine.mbEnums.ModType;
import engine.net.client.msg.ErrorPopupMsg; import engine.net.client.msg.ErrorPopupMsg;
import engine.objects.PlayerCharacter; import engine.objects.PlayerCharacter;
@@ -55,7 +55,7 @@ public class FinishSummonsJob extends AbstractScheduleJob {
return; return;
} }
if (this.target.getBonuses() != null && this.target.getBonuses().getBool(ModType.BlockedPowerType, SourceType.SUMMON)) { if (this.target.getBonuses() != null && this.target.getBonuses().getBool(ModType.BlockedPowerType, EffectSourceType.Summon)) {
ErrorPopupMsg.sendErrorMsg(this.target, "You have been blocked from receiving summons!"); ErrorPopupMsg.sendErrorMsg(this.target, "You have been blocked from receiving summons!");
ErrorPopupMsg.sendErrorMsg(this.source, "Target is blocked from receiving summons!"); ErrorPopupMsg.sendErrorMsg(this.source, "Target is blocked from receiving summons!");
return; return;
+3 -3
View File
@@ -9,11 +9,11 @@
package engine.jobs; package engine.jobs;
import engine.mbEnums; import engine.gameManager.DispatchManager;
import engine.gameManager.PowersManager; import engine.gameManager.PowersManager;
import engine.math.Vector3fImmutable; import engine.math.Vector3fImmutable;
import engine.mbEnums;
import engine.net.Dispatch; import engine.net.Dispatch;
import engine.net.DispatchMessage;
import engine.net.client.msg.TrackArrowMsg; import engine.net.client.msg.TrackArrowMsg;
import engine.objects.AbstractWorldObject; import engine.objects.AbstractWorldObject;
import engine.objects.PlayerCharacter; import engine.objects.PlayerCharacter;
@@ -84,7 +84,7 @@ public class TrackJob extends AbstractEffectJob {
TrackArrowMsg tam = new TrackArrowMsg(rotation); TrackArrowMsg tam = new TrackArrowMsg(rotation);
Dispatch dispatch = Dispatch.borrow(pc, tam); Dispatch dispatch = Dispatch.borrow(pc, tam);
DispatchMessage.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.PRIMARY); DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.PRIMARY);
} }
} }
+1 -1
View File
@@ -9,9 +9,9 @@
package engine.jobs; package engine.jobs;
import engine.mbEnums.GameObjectType;
import engine.InterestManagement.WorldGrid; import engine.InterestManagement.WorldGrid;
import engine.job.AbstractScheduleJob; import engine.job.AbstractScheduleJob;
import engine.mbEnums.GameObjectType;
import engine.objects.AbstractCharacter; import engine.objects.AbstractCharacter;
import engine.objects.Mob; import engine.objects.Mob;
import engine.objects.NPC; import engine.objects.NPC;
+281
View File
@@ -0,0 +1,281 @@
// ·. · · · · .
// · ·
// · ·
//
// · · ·
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
package engine.loot;
import engine.gameManager.DbManager;
import engine.gameManager.ForgeManager;
import engine.mbEnums;
import engine.objects.Item;
import engine.objects.ItemTemplate;
import engine.objects.NPC;
import engine.objects.Warehouse;
import org.json.JSONArray;
import org.json.JSONObject;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
public class WorkOrder implements Delayed {
// MB Dev notes:
// Class defines a Forge rolling request made through a vendor
// interaction; submitted to the ForgeManager singleton for completion.
//
// A workOrder once created will last until all items are either
// completed or junked. They are persisted in the table dyn_workorders.
public int workOrderID;
public NPC vendor;
public AtomicInteger slots_used = new AtomicInteger(0);
public int total_to_produce;
public int total_produced;
public boolean multiple_slot_request;
public HashMap<mbEnums.ResourceType, Integer> production_cost = new HashMap<>();
public HashMap<mbEnums.ResourceType, Integer> production_cost_total = new HashMap<>();
public int templateID;
public String item_name_override;
public int prefixToken;
public int suffixToken;
public long rollingDuration;
public long completionTime;
public AtomicBoolean runCompleted = new AtomicBoolean(false);
// This collection is serialized to the vendor rolling window in ManageNPCMsg.
public ConcurrentHashMap.KeySetView<Item, Boolean> cooking = ConcurrentHashMap.newKeySet();
public WorkOrder() {
}
public WorkOrder(JSONObject jsonWorkOrder) {
// This constructor is used to load workOrders from disk
// during bootstrap. (dyn_workorders)
this.workOrderID = jsonWorkOrder.getInt("workOrderID");
this.vendor = NPC.getNPC(jsonWorkOrder.getInt("vendor"));
this.slots_used.set(jsonWorkOrder.getInt("slots_used"));
this.total_to_produce = jsonWorkOrder.getInt("total_to_produce");
this.total_produced = jsonWorkOrder.getInt("total_produced");
this.multiple_slot_request = jsonWorkOrder.getBoolean("multiple_slot_request");
this.templateID = jsonWorkOrder.getInt("templateID");
this.item_name_override = jsonWorkOrder.getString("item_name_override");
this.prefixToken = jsonWorkOrder.getInt("prefixToken");
this.suffixToken = jsonWorkOrder.getInt("suffixToken");
this.rollingDuration = jsonWorkOrder.getLong("rollingDuration");
this.completionTime = jsonWorkOrder.getLong("completionTime");
this.runCompleted.set(jsonWorkOrder.getBoolean("runCompleted"));
// Vendor sanity check. Might have been deleted
if (this.vendor == null)
return;
JSONObject productionCostMap = jsonWorkOrder.getJSONObject("production_cost");
for (String key : productionCostMap.keySet()) {
mbEnums.ResourceType resourceType = mbEnums.ResourceType.valueOf(key);
int value = productionCostMap.getInt(key);
this.production_cost.put(resourceType, value);
}
JSONObject productionTotalCostMap = jsonWorkOrder.getJSONObject("production_cost_total");
for (String key : productionTotalCostMap.keySet()) {
mbEnums.ResourceType resourceType = mbEnums.ResourceType.valueOf(key);
int value = productionTotalCostMap.getInt(key);
this.production_cost_total.put(resourceType, value);
}
// Reconstruct cooking items
JSONArray tokenList = jsonWorkOrder.getJSONArray("cookingTokens");
for (Object o : tokenList) {
int prefix = ((JSONArray) o).getInt(0);
int suffix = ((JSONArray) o).getInt(1);
Item cookingItem = ForgeManager.forgeItem(this);
cookingItem.prefixToken = prefix;
cookingItem.suffixToken = suffix;
cookingItem.setDateToUpgrade(this.completionTime);
}
}
public static int validate(WorkOrder workOrder) {
// Validate that a workOrder can be completed by both
// the vendor and the forge.
int validation_result = 0;
ItemTemplate template = ItemTemplate.templates.get(workOrder.templateID);
if (workOrder.vendor.getBuilding() == null)
return 58; //58: The formula is beyond the means of this facility
if (!workOrder.vendor.charItemManager.hasRoomInventory(template.item_wt))
return 30; //30: That person cannot carry that item
if (!workOrder.vendor.getItemModTable().contains((template.modTable)))
return 59; //59: This hireling does not have this formula
if (!Warehouse.calcCostOverrun(workOrder).isEmpty())
return 10; //18: You can't really afford that
// Forge must be protected in order to access warehouse.
if (ForgeManager.calcProductionCost(workOrder).size() > 1)
if (!EnumSet.of(mbEnums.ProtectionState.PROTECTED, mbEnums.ProtectionState.CONTRACT).contains(workOrder.vendor.building.protectionState))
return 193; //193: Production denied: This building must be protected to gain access to warehouse
return validation_result;
}
public static boolean withdrawWorkOrderCost(WorkOrder workOrder) {
HashMap<mbEnums.ResourceType, Integer> modified_production_cost = new HashMap<>(workOrder.production_cost_total);
if (workOrder.vendor.building.getCity() == null)
return false;
int strongbox = workOrder.vendor.building.getStrongboxValue();
// Early exit if strongbox can cover gold only roll.
if (workOrder.production_cost_total.size() == 1 && workOrder.production_cost_total.get(mbEnums.ResourceType.GOLD) <= strongbox) {
workOrder.vendor.building.setStrongboxValue(strongbox - workOrder.production_cost_total.get(mbEnums.ResourceType.GOLD));
return true;
}
// Warehouse is required after this point
Warehouse warehouse = workOrder.vendor.building.getCity().warehouse;
if (warehouse == null)
return false;
// Take from strongbox first and deduct from production cost total
if (workOrder.production_cost_total.get(mbEnums.ResourceType.GOLD) <= strongbox) {
workOrder.vendor.building.setStrongboxValue(strongbox - workOrder.production_cost_total.get(mbEnums.ResourceType.GOLD));
modified_production_cost.put(mbEnums.ResourceType.GOLD, 0);
} else {
int overflowAmount = workOrder.production_cost_total.get(mbEnums.ResourceType.GOLD) - strongbox;
workOrder.vendor.building.setStrongboxValue(0);
modified_production_cost.put(mbEnums.ResourceType.GOLD, overflowAmount);
}
// Deduct total production cost from warehouse
modified_production_cost.forEach((key, value) -> warehouse.resources.put(key, warehouse.resources.get(key) - value));
DbManager.WarehouseQueries.UPDATE_WAREHOUSE(warehouse);
return true;
}
public static JSONObject toJson(WorkOrder workOrder) {
// Workorders are persisted in JSON format.
JSONObject jsonWorkOrder = new JSONObject();
jsonWorkOrder.put("workOrderID", workOrder.workOrderID);
jsonWorkOrder.put("vendor", workOrder.vendor.getObjectUUID());
jsonWorkOrder.put("slots_used", workOrder.slots_used.get());
jsonWorkOrder.put("total_to_produce", workOrder.total_to_produce);
jsonWorkOrder.put("total_produced", workOrder.total_produced);
jsonWorkOrder.put("multiple_slot_request", workOrder.multiple_slot_request);
jsonWorkOrder.put("production_cost", workOrder.production_cost);
jsonWorkOrder.put("production_cost_total", workOrder.production_cost_total);
jsonWorkOrder.put("templateID", workOrder.templateID);
jsonWorkOrder.put("item_name_override", workOrder.item_name_override);
jsonWorkOrder.put("prefixToken", workOrder.prefixToken);
jsonWorkOrder.put("suffixToken", workOrder.suffixToken);
jsonWorkOrder.put("rollingDuration", workOrder.rollingDuration);
jsonWorkOrder.put("completionTime", workOrder.completionTime);
jsonWorkOrder.put("runCompleted", workOrder.runCompleted.get());
ArrayList<Integer[]> cookingTokens = new ArrayList<>();
for (Item item : workOrder.cooking)
cookingTokens.add(new Integer[]{item.prefixToken, item.suffixToken});
jsonWorkOrder.put("cookingTokens", cookingTokens);
return jsonWorkOrder;
}
public String toString() {
LocalDateTime localDateTime = Instant.ofEpochMilli(this.completionTime)
.atZone(ZoneId.systemDefault()).toLocalDateTime();
Duration duration = Duration.ofMillis(this.rollingDuration);
String outSTring = "\r\nwordOrderID: " + this.workOrderID + "\r\n" +
"vendor: " + this.vendor.getObjectUUID() + "\r\n" +
"slots_used: " + this.slots_used.get() + "\r\n" +
"total_to_produce: " + this.total_to_produce + "\r\n" +
"total_produced: " + this.total_produced + "\r\n" +
"templateID: " + this.templateID + "\r\n" +
"item_name_override: " + this.item_name_override + "\r\n" +
"prefixToken: " + this.prefixToken + "\r\n" +
"suffixToken: " + this.suffixToken + "\r\n" +
"rollingDuration: " + duration + "\r\n" +
"completionTime: " + localDateTime + "\r\n" +
"runCompleted: " + this.runCompleted.get() + "\r\n" +
"productionCost: " + this.production_cost.toString() + "\r\n" +
"totalProductionCost:: " + this.production_cost_total.toString();
return outSTring;
}
@Override
public long getDelay(TimeUnit unit) {
long timeRemaining = completionTime - System.currentTimeMillis();
return unit.convert(timeRemaining, TimeUnit.MILLISECONDS);
}
@Override
public int compareTo(Delayed o) {
return Long.compare(this.completionTime, ((WorkOrder) o).completionTime);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null || getClass() != obj.getClass())
return false;
WorkOrder otherWorkOrder = (WorkOrder) obj;
return workOrderID == otherWorkOrder.workOrderID;
}
@Override
public int hashCode() {
return Objects.hash(workOrderID);
}
}
+141 -313
View File
@@ -14,7 +14,10 @@ import engine.gameManager.ZoneManager;
import engine.math.Vector2f; import engine.math.Vector2f;
import engine.math.Vector3f; import engine.math.Vector3f;
import engine.math.Vector3fImmutable; import engine.math.Vector3fImmutable;
import engine.objects.*; import engine.objects.AbstractCharacter;
import engine.objects.ItemTemplate;
import engine.objects.Shrine;
import engine.objects.Zone;
import engine.powers.EffectsBase; import engine.powers.EffectsBase;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
@@ -34,6 +37,16 @@ import java.util.concurrent.ThreadLocalRandom;
public class mbEnums { public class mbEnums {
public static <T extends Enum<T>> int toInt(EnumSet<T> enumSet) {
int bitvector = 0;
for (T value : enumSet)
bitvector |= 1 << value.ordinal();
return bitvector;
}
public static <T extends Enum<T>> long toLong(EnumSet<T> enumSet) { public static <T extends Enum<T>> long toLong(EnumSet<T> enumSet) {
long bitvector = 0L; long bitvector = 0L;
@@ -818,16 +831,22 @@ public class mbEnums {
SPIRES, SPIRES,
SNARE, SNARE,
STUN, STUN,
BLIND, BLINDNESS,
ROOT, ROOT,
FEAR, FEAR,
CHARM, CHARM,
POWERBLOCK, POWERINHIBITOR,
DEBUFF, DEBUFF,
STEAL, STEAL,
DRAIN; DRAIN;
public static DamageType getDamageType(String modName) { public static DamageType getDamageType(String modName) {
if(modName.toLowerCase().equals("blind"))
modName = "BLINDNESS";
if(modName.toLowerCase().equals("powerblock"))
modName = "POWERINHIBITOR";
DamageType damageType; DamageType damageType;
if (modName.isEmpty()) if (modName.isEmpty())
return DamageType.NONE; return DamageType.NONE;
@@ -842,176 +861,6 @@ public class mbEnums {
} }
} }
public enum SourceType {
None,
Abjuration,
Acid,
AntiSiege,
Archery,
Axe,
Bardsong,
Beastcraft,
Benediction,
BladeWeaving,
Bleeding,
Blind,
Block,
Bloodcraft,
Bow,
Buff,
Channeling,
Charm,
Cold,
COLD,
Constitution,
Corruption,
Crossbow,
Crushing,
Dagger,
DaggerMastery,
DeBuff,
Dexterity,
Disease,
Dodge,
Dragon,
Drain,
Earth,
Effect,
Exorcism,
Fear,
Fire,
FIRE,
Fly,
Giant,
GreatAxeMastery,
GreatSwordMastery,
Hammer,
Heal,
Healing,
Holy,
HOLY,
ImmuneToAttack,
ImmuneToPowers,
Intelligence,
Invisible,
Lightning,
LIGHTNING,
Liturgy,
Magic,
MAGIC,
Mental,
MENTAL,
NatureLore,
Necromancy,
Parry,
Piercing,
Poison,
POISON,
PoleArm,
Powerblock,
Rat,
ResistDeBuff,
Restoration,
Root,
Shadowmastery,
Siege,
Slashing,
Snare,
Sorcery,
Spear,
SpearMastery,
Spirit,
Staff,
Stormcalling,
Strength,
Stun,
Summon,
Sword,
SwordMastery,
Thaumaturgy,
Theurgy,
Transform,
UnarmedCombat,
UnarmedCombatMastery,
Unholy,
UNHOLY,
Unknown,
Warding,
Warlockry,
WayoftheGaana,
WearArmorHeavy,
WearArmorLight,
WearArmorMedium,
Wereform,
Athletics,
AxeMastery,
Bargaining,
BladeMastery,
FlameCalling,
GreatHammerMastery,
HammerMastery,
Leadership,
PoleArmMastery,
Running,
StaffMastery,
Throwing,
Toughness,
WayoftheWolf,
WayoftheRat,
WayoftheBear,
Orthanatos,
SunDancing,
//Power categories.
AE,
AEDAMAGE,
BEHAVIOR,
BLESSING,
BOONCLASS,
BOONRACE,
BREAKFLY,
BUFF,
CHANT,
DAMAGE,
DEBUFF,
DISPEL,
FLIGHT,
GROUPBUFF,
GROUPHEAL,
HEAL,
INVIS,
MOVE,
RECALL,
SPECIAL,
SPIREDISABLE,
SPIREPROOFTELEPORT,
STANCE,
STUN,
SUMMON,
TELEPORT,
THIEF,
TRACK,
TRANSFORM,
VAMPDRAIN,
WEAPON,
Wizardry;
public static SourceType GetSourceType(String modName) {
SourceType returnMod;
if (modName.isEmpty())
return SourceType.None;
try {
returnMod = SourceType.valueOf(modName.replace(",", ""));
} catch (Exception e) {
Logger.error(modName);
Logger.error(e);
return SourceType.None;
}
return returnMod;
}
}
public enum EffectSourceType { public enum EffectSourceType {
None, None,
AttackSpeedBuff, AttackSpeedBuff,
@@ -1071,7 +920,7 @@ public class mbEnums {
WereformSPRecBuff, WereformSPRecBuff,
WereformStrBuff; WereformStrBuff;
public static EffectSourceType GetEffectSourceType(String modName) { public static EffectSourceType getEffectSourceType(String modName) {
EffectSourceType returnMod; EffectSourceType returnMod;
if (modName.isEmpty()) if (modName.isEmpty())
return EffectSourceType.None; return EffectSourceType.None;
@@ -2230,7 +2079,8 @@ public class mbEnums {
NONE("None", new String[][]{{"None"}}, new String[]{"Thearchy", "Common Rule", "Theocracy", "Republic Rule"}, NONE("None", new String[][]{{"None"}}, new String[]{"Thearchy", "Common Rule", "Theocracy", "Republic Rule"},
EnumSet.noneOf(ClassType.class), EnumSet.noneOf(ClassType.class),
EnumSet.noneOf(MonsterType.class), EnumSet.noneOf(MonsterType.class),
EnumSet.noneOf(SexType.class)), EnumSet.noneOf(SexType.class),
0),
CATHEDRAL("Church of the All-Father", new String[][]{ CATHEDRAL("Church of the All-Father", new String[][]{
{"Acolyte", "Acolyte"}, {"Acolyte", "Acolyte"},
@@ -2246,7 +2096,8 @@ public class mbEnums {
ClassType.Prelate, ClassType.Priest, ClassType.Sentinel, ClassType.Scout), ClassType.Prelate, ClassType.Priest, ClassType.Sentinel, ClassType.Scout),
EnumSet.of(MonsterType.Aelfborn, MonsterType.Centaur, MonsterType.Elf, MonsterType.HalfGiant, EnumSet.of(MonsterType.Aelfborn, MonsterType.Centaur, MonsterType.Elf, MonsterType.HalfGiant,
MonsterType.Human), MonsterType.Human),
EnumSet.allOf(SexType.class)), EnumSet.allOf(SexType.class),
559),
MILITARY("Military", new String[][]{ MILITARY("Military", new String[][]{
{"Recruit"}, {"Recruit"},
{"Footman"}, {"Footman"},
@@ -2260,7 +2111,8 @@ public class mbEnums {
EnumSet.of(ClassType.Bard, ClassType.Priest, ClassType.Scout, ClassType.Warlock, EnumSet.of(ClassType.Bard, ClassType.Priest, ClassType.Scout, ClassType.Warlock,
ClassType.Warrior, ClassType.Wizard), ClassType.Warrior, ClassType.Wizard),
EnumSet.of(MonsterType.Centaur, MonsterType.HalfGiant, MonsterType.Human), EnumSet.of(MonsterType.Centaur, MonsterType.HalfGiant, MonsterType.Human),
EnumSet.allOf(SexType.class)), EnumSet.allOf(SexType.class),
560),
TEMPLE("Temple of the Cleansing Flame", new String[][]{ TEMPLE("Temple of the Cleansing Flame", new String[][]{
{"Aspirant"}, {"Aspirant"},
{"Novice"}, {"Novice"},
@@ -2275,7 +2127,8 @@ public class mbEnums {
EnumSet.of(ClassType.Assassin, ClassType.Bard, ClassType.Channeler, ClassType.Confessor, EnumSet.of(ClassType.Assassin, ClassType.Bard, ClassType.Channeler, ClassType.Confessor,
ClassType.Nightstalker, ClassType.Priest, ClassType.Scout, ClassType.Templar), ClassType.Nightstalker, ClassType.Priest, ClassType.Scout, ClassType.Templar),
EnumSet.of(MonsterType.HalfGiant, MonsterType.Human), EnumSet.of(MonsterType.HalfGiant, MonsterType.Human),
EnumSet.allOf(SexType.class)), EnumSet.allOf(SexType.class),
561),
BARBARIAN("Barbarian Clan", new String[][]{ BARBARIAN("Barbarian Clan", new String[][]{
{"Barbarian"}, {"Barbarian"},
{"Skald"}, {"Skald"},
@@ -2288,7 +2141,8 @@ public class mbEnums {
EnumSet.of(ClassType.Barbarian, ClassType.Bard, ClassType.Doomsayer, ClassType.Fury, EnumSet.of(ClassType.Barbarian, ClassType.Bard, ClassType.Doomsayer, ClassType.Fury,
ClassType.Priest, ClassType.Scout, ClassType.Thief, ClassType.Warrior), ClassType.Priest, ClassType.Scout, ClassType.Thief, ClassType.Warrior),
EnumSet.of(MonsterType.Aelfborn, MonsterType.HalfGiant, MonsterType.Human, MonsterType.Minotaur), EnumSet.of(MonsterType.Aelfborn, MonsterType.HalfGiant, MonsterType.Human, MonsterType.Minotaur),
EnumSet.allOf(SexType.class)), EnumSet.allOf(SexType.class),
562),
RANGER("Ranger's Brotherhood", new String[][]{ RANGER("Ranger's Brotherhood", new String[][]{
{"Yeoman"}, {"Yeoman"},
{"Pathfinder"}, {"Pathfinder"},
@@ -2301,7 +2155,8 @@ public class mbEnums {
EnumSet.of(ClassType.Bard, ClassType.Channeler, ClassType.Druid, ClassType.Priest, EnumSet.of(ClassType.Bard, ClassType.Channeler, ClassType.Druid, ClassType.Priest,
ClassType.Ranger, ClassType.Scout, ClassType.Warrior), ClassType.Ranger, ClassType.Scout, ClassType.Warrior),
EnumSet.of(MonsterType.Aelfborn, MonsterType.Elf, MonsterType.HalfGiant, MonsterType.Human, MonsterType.Shade), EnumSet.of(MonsterType.Aelfborn, MonsterType.Elf, MonsterType.HalfGiant, MonsterType.Human, MonsterType.Shade),
EnumSet.allOf(SexType.class)), EnumSet.allOf(SexType.class),
563),
AMAZON("Amazon Temple", new String[][]{ AMAZON("Amazon Temple", new String[][]{
{"Amazon Thrall", "Amazon"}, {"Amazon Thrall", "Amazon"},
{"Amazon Slave", "Amazon Warrior"}, {"Amazon Slave", "Amazon Warrior"},
@@ -2313,7 +2168,8 @@ public class mbEnums {
EnumSet.of(ClassType.Bard, ClassType.Druid, ClassType.Fury, ClassType.Huntress, EnumSet.of(ClassType.Bard, ClassType.Druid, ClassType.Fury, ClassType.Huntress,
ClassType.Priest, ClassType.Scout, ClassType.Warrior, ClassType.Wizard), ClassType.Priest, ClassType.Scout, ClassType.Warrior, ClassType.Wizard),
EnumSet.of(MonsterType.Aelfborn, MonsterType.Elf, MonsterType.HalfGiant, MonsterType.Human), EnumSet.of(MonsterType.Aelfborn, MonsterType.Elf, MonsterType.HalfGiant, MonsterType.Human),
EnumSet.of(SexType.FEMALE)), EnumSet.of(SexType.FEMALE),
564),
NOBLE("Noble House", new String[][]{ NOBLE("Noble House", new String[][]{
{"Serf"}, {"Serf"},
{"Vassal"}, {"Vassal"},
@@ -2328,7 +2184,8 @@ public class mbEnums {
EnumSet.of(ClassType.Assassin, ClassType.Bard, ClassType.Channeler, ClassType.Priest, EnumSet.of(ClassType.Assassin, ClassType.Bard, ClassType.Channeler, ClassType.Priest,
ClassType.Scout, ClassType.Thief, ClassType.Warlock, ClassType.Warrior, ClassType.Wizard), ClassType.Scout, ClassType.Thief, ClassType.Warlock, ClassType.Warrior, ClassType.Wizard),
EnumSet.of(MonsterType.Aelfborn, MonsterType.HalfGiant, MonsterType.Human), EnumSet.of(MonsterType.Aelfborn, MonsterType.HalfGiant, MonsterType.Human),
EnumSet.allOf(SexType.class)), EnumSet.allOf(SexType.class),
565),
WIZARD("Wizard's Conclave", new String[][]{ WIZARD("Wizard's Conclave", new String[][]{
{"Apprentice"}, {"Apprentice"},
{"Neophyte"}, {"Neophyte"},
@@ -2341,7 +2198,8 @@ public class mbEnums {
EnumSet.of(ClassType.Assassin, ClassType.Bard, ClassType.Channeler, ClassType.Doomsayer, EnumSet.of(ClassType.Assassin, ClassType.Bard, ClassType.Channeler, ClassType.Doomsayer,
ClassType.Fury, ClassType.Necromancer, ClassType.Priest, ClassType.Warlock, ClassType.Wizard), ClassType.Fury, ClassType.Necromancer, ClassType.Priest, ClassType.Warlock, ClassType.Wizard),
EnumSet.of(MonsterType.Aelfborn, MonsterType.Elf, MonsterType.Human, MonsterType.Nephilim, MonsterType.Shade), EnumSet.of(MonsterType.Aelfborn, MonsterType.Elf, MonsterType.Human, MonsterType.Nephilim, MonsterType.Shade),
EnumSet.allOf(SexType.class)), EnumSet.allOf(SexType.class),
566),
MERCENARY("Mercenary Company", new String[][]{ MERCENARY("Mercenary Company", new String[][]{
{"Soldier"}, {"Soldier"},
{"Man-at-Arms"}, {"Man-at-Arms"},
@@ -2355,7 +2213,8 @@ public class mbEnums {
EnumSet.of(ClassType.Assassin, ClassType.Bard, ClassType.Priest, ClassType.Scout, EnumSet.of(ClassType.Assassin, ClassType.Bard, ClassType.Priest, ClassType.Scout,
ClassType.Thief, ClassType.Warlock, ClassType.Warrior), ClassType.Thief, ClassType.Warlock, ClassType.Warrior),
EnumSet.of(MonsterType.Aelfborn, MonsterType.Aracoix, MonsterType.HalfGiant, MonsterType.Human, MonsterType.Shade), EnumSet.of(MonsterType.Aelfborn, MonsterType.Aracoix, MonsterType.HalfGiant, MonsterType.Human, MonsterType.Shade),
EnumSet.allOf(SexType.class)), EnumSet.allOf(SexType.class),
567),
THIEVES("Thieve's Den", new String[][]{ THIEVES("Thieve's Den", new String[][]{
{"Urchin"}, {"Urchin"},
{"Footpad"}, {"Footpad"},
@@ -2371,7 +2230,8 @@ public class mbEnums {
ClassType.Scout, ClassType.Thief, ClassType.Wizard), ClassType.Scout, ClassType.Thief, ClassType.Wizard),
EnumSet.of(MonsterType.Aelfborn, MonsterType.Aracoix, MonsterType.Elf, MonsterType.Human, MonsterType.Irekei, EnumSet.of(MonsterType.Aelfborn, MonsterType.Aracoix, MonsterType.Elf, MonsterType.Human, MonsterType.Irekei,
MonsterType.Nephilim, MonsterType.Shade, MonsterType.Vampire), MonsterType.Nephilim, MonsterType.Shade, MonsterType.Vampire),
EnumSet.allOf(SexType.class)), EnumSet.allOf(SexType.class),
568),
DWARF("Dwarf Hold", new String[][]{ DWARF("Dwarf Hold", new String[][]{
{"Citizen"}, {"Citizen"},
{"Master"}, {"Master"},
@@ -2383,7 +2243,8 @@ public class mbEnums {
EnumSet.of(ClassType.Crusader, ClassType.Prelate, ClassType.Priest, ClassType.Sentinel, EnumSet.of(ClassType.Crusader, ClassType.Prelate, ClassType.Priest, ClassType.Sentinel,
ClassType.Warrior), ClassType.Warrior),
EnumSet.of(MonsterType.Dwarf), EnumSet.of(MonsterType.Dwarf),
EnumSet.allOf(SexType.class)), EnumSet.allOf(SexType.class),
569),
HIGHCOURT("High Court", new String[][]{ HIGHCOURT("High Court", new String[][]{
{"Eccekebe"}, {"Eccekebe"},
{"Saedulor"}, {"Saedulor"},
@@ -2399,7 +2260,8 @@ public class mbEnums {
ClassType.Necromancer, ClassType.Priest, ClassType.Ranger, ClassType.Scout, ClassType.Necromancer, ClassType.Priest, ClassType.Ranger, ClassType.Scout,
ClassType.Thief, ClassType.Warrior, ClassType.Wizard), ClassType.Thief, ClassType.Warrior, ClassType.Wizard),
EnumSet.of(MonsterType.Elf, MonsterType.Minotaur), EnumSet.of(MonsterType.Elf, MonsterType.Minotaur),
EnumSet.allOf(SexType.class)), EnumSet.allOf(SexType.class),
570),
VIRAKT("Virakt", new String[][]{ VIRAKT("Virakt", new String[][]{
{"Jov'uus"}, {"Jov'uus"},
{"Urikhan"}, {"Urikhan"},
@@ -2414,7 +2276,8 @@ public class mbEnums {
ClassType.Huntress, ClassType.Nightstalker, ClassType.Priest, ClassType.Ranger, ClassType.Huntress, ClassType.Nightstalker, ClassType.Priest, ClassType.Ranger,
ClassType.Scout, ClassType.Thief, ClassType.Warrior, ClassType.Wizard), ClassType.Scout, ClassType.Thief, ClassType.Warrior, ClassType.Wizard),
EnumSet.of(MonsterType.Irekei), EnumSet.of(MonsterType.Irekei),
EnumSet.allOf(SexType.class)), EnumSet.allOf(SexType.class),
571),
BRIALIA("Coven of Brialia", new String[][]{ // Unknown Rank names BRIALIA("Coven of Brialia", new String[][]{ // Unknown Rank names
{"Devotee"}, {"Devotee"},
{"Initiated"}, {"Initiated"},
@@ -2427,8 +2290,8 @@ public class mbEnums {
new String[]{"Despot Rule", "Common Rule", "Council Rule", "Republic Rule"}, new String[]{"Despot Rule", "Common Rule", "Council Rule", "Republic Rule"},
EnumSet.allOf(ClassType.class), EnumSet.allOf(ClassType.class),
EnumSet.allOf(MonsterType.class), EnumSet.allOf(MonsterType.class),
EnumSet.allOf(SexType.class)), EnumSet.allOf(SexType.class),
577),
UNHOLY("Unholy Legion", new String[][]{ // Unknown Rank names UNHOLY("Unholy Legion", new String[][]{ // Unknown Rank names
{"Footman"}, {"Footman"},
{"Fell Legionaire"}, {"Fell Legionaire"},
@@ -2443,7 +2306,8 @@ public class mbEnums {
ClassType.Scout, ClassType.Thief, ClassType.Warlock, ClassType.Warrior, ClassType.Scout, ClassType.Thief, ClassType.Warlock, ClassType.Warrior,
ClassType.Wizard), ClassType.Wizard),
EnumSet.of(MonsterType.Human, MonsterType.Shade, MonsterType.Vampire), EnumSet.of(MonsterType.Human, MonsterType.Shade, MonsterType.Vampire),
EnumSet.allOf(SexType.class)), EnumSet.allOf(SexType.class),
575),
SCOURGE("Cult of the Scourge", new String[][]{ SCOURGE("Cult of the Scourge", new String[][]{
{"Thrall"}, {"Thrall"},
{"Mudir"}, {"Mudir"},
@@ -2454,7 +2318,8 @@ public class mbEnums {
EnumSet.of(ClassType.Bard, ClassType.Channeler, ClassType.Doomsayer, ClassType.Priest, EnumSet.of(ClassType.Bard, ClassType.Channeler, ClassType.Doomsayer, ClassType.Priest,
ClassType.Scout, ClassType.Warrior, ClassType.Wizard), ClassType.Scout, ClassType.Warrior, ClassType.Wizard),
EnumSet.of(MonsterType.Aelfborn, MonsterType.Human, MonsterType.Minotaur, MonsterType.Nephilim), EnumSet.of(MonsterType.Aelfborn, MonsterType.Human, MonsterType.Minotaur, MonsterType.Nephilim),
EnumSet.allOf(SexType.class)), EnumSet.allOf(SexType.class),
572),
PIRATE("Pirate Crew", new String[][]{ PIRATE("Pirate Crew", new String[][]{
{"Midshipman", "Midshipwoman"}, {"Midshipman", "Midshipwoman"},
{"Sailor"}, {"Sailor"},
@@ -2465,7 +2330,8 @@ public class mbEnums {
new String[]{"Despot Rule", "Common Rule", "Council Rule", "Republic Rule"}, new String[]{"Despot Rule", "Common Rule", "Council Rule", "Republic Rule"},
EnumSet.allOf(ClassType.class), EnumSet.allOf(ClassType.class),
EnumSet.allOf(MonsterType.class), EnumSet.allOf(MonsterType.class),
EnumSet.allOf(SexType.class)), EnumSet.allOf(SexType.class),
576),
HERALD("Academy of Heralds", new String[][]{ HERALD("Academy of Heralds", new String[][]{
{"Pupil"}, {"Pupil"},
{"Scribe"}, {"Scribe"},
@@ -2478,7 +2344,8 @@ public class mbEnums {
new String[]{"Despot Rule", "Common Rule", "Council Rule", "Republic Rule"}, new String[]{"Despot Rule", "Common Rule", "Council Rule", "Republic Rule"},
EnumSet.allOf(ClassType.class), EnumSet.allOf(ClassType.class),
EnumSet.allOf(MonsterType.class), EnumSet.allOf(MonsterType.class),
EnumSet.allOf(SexType.class)), EnumSet.allOf(SexType.class),
582),
CENTAUR("Centaur Cohort", new String[][]{ CENTAUR("Centaur Cohort", new String[][]{
{"Hoplite"}, {"Hoplite"},
{"Peltast"}, {"Peltast"},
@@ -2493,7 +2360,8 @@ public class mbEnums {
ClassType.Prelate, ClassType.Priest, ClassType.Ranger, ClassType.Sentinel, ClassType.Prelate, ClassType.Priest, ClassType.Ranger, ClassType.Sentinel,
ClassType.Warrior), ClassType.Warrior),
EnumSet.of(MonsterType.Centaur), EnumSet.of(MonsterType.Centaur),
EnumSet.allOf(SexType.class)), EnumSet.allOf(SexType.class),
574),
KHREE("Aracoix Kh'ree", new String[][]{ KHREE("Aracoix Kh'ree", new String[][]{
{"Duriacor"}, {"Duriacor"},
{"Exarch"}, {"Exarch"},
@@ -2510,121 +2378,51 @@ public class mbEnums {
ClassType.Priest, ClassType.Ranger, ClassType.Scout, ClassType.Thief, ClassType.Priest, ClassType.Ranger, ClassType.Scout, ClassType.Thief,
ClassType.Warlock, ClassType.Warrior), ClassType.Warlock, ClassType.Warrior),
EnumSet.of(MonsterType.Aracoix), EnumSet.of(MonsterType.Aracoix),
EnumSet.allOf(SexType.class)); EnumSet.allOf(SexType.class),
573);
public final EnumSet<ClassType> requiredClasses; public final EnumSet<ClassType> requiredClasses;
public final EnumSet<MonsterType> requiredRaces; public final EnumSet<MonsterType> requiredRaces;
public final EnumSet<SexType> sexRequired; public final EnumSet<SexType> sexRequired;
private final String name; public final String name;
private final String[][] ranks; //Stored Rank#->Gender(M,F) private final String[][] ranks; //Stored Rank#->Gender(M,F)
private final String[] leadershipTypes; private final String[] leadershipTypes;
public final int templateID;
public static HashMap<Integer, GuildCharterType> templateLookup = new HashMap<>();
GuildCharterType(String name, String[][] ranks, String[] leadershipTypes, EnumSet<ClassType> requiredClasses, GuildCharterType(String name, String[][] ranks, String[] leadershipTypes, EnumSet<ClassType> requiredClasses,
EnumSet<MonsterType> requiredRaces, EnumSet<SexType> sexRequired) { EnumSet<MonsterType> requiredRaces, EnumSet<SexType> sexRequired, int templateID) {
this.name = name; this.name = name;
this.ranks = ranks; this.ranks = ranks;
this.leadershipTypes = leadershipTypes; this.leadershipTypes = leadershipTypes;
this.requiredClasses = requiredClasses; this.requiredClasses = requiredClasses;
this.requiredRaces = requiredRaces; this.requiredRaces = requiredRaces;
this.sexRequired = sexRequired; this.sexRequired = sexRequired;
this.templateID = templateID;
} }
public static GuildCharterType getGuildTypeFromCharter(Item charter) { public static void init() {
for (GuildCharterType guildCharterType : GuildCharterType.values())
GuildCharterType charterType; GuildCharterType.templateLookup.put(guildCharterType.templateID, guildCharterType);
// Must be a valid charter object
if (charter.template.item_type.equals(ItemType.CHARTER) == false)
return GuildCharterType.NONE; //No guild Type
switch (charter.template.template_id) {
case 559:
charterType = GuildCharterType.CATHEDRAL;
break;
case 560:
charterType = GuildCharterType.MILITARY;
break;
case 561:
charterType = GuildCharterType.TEMPLE;
break;
case 562:
charterType = GuildCharterType.BARBARIAN;
break;
case 563:
charterType = GuildCharterType.RANGER;
break;
case 564:
charterType = GuildCharterType.AMAZON;
break;
case 565:
charterType = GuildCharterType.NOBLE;
break;
case 566:
charterType = GuildCharterType.WIZARD;
break;
case 567:
charterType = GuildCharterType.MERCENARY;
break;
case 568:
charterType = GuildCharterType.THIEVES;
break;
case 569:
charterType = GuildCharterType.DWARF;
break;
case 570:
charterType = GuildCharterType.HIGHCOURT;
break;
case 571:
charterType = GuildCharterType.VIRAKT;
break;
case 572:
charterType = GuildCharterType.SCOURGE;
break;
case 573:
charterType = GuildCharterType.KHREE;
break;
case 574:
charterType = GuildCharterType.CENTAUR;
break;
case 575:
charterType = GuildCharterType.UNHOLY;
break;
case 576:
charterType = GuildCharterType.PIRATE;
break;
case 577:
charterType = GuildCharterType.BRIALIA;
break;
default:
charterType = GuildCharterType.HERALD;
}
return charterType;
} }
public static GuildCharterType getGuildTypeFromInt(int i) { public static GuildCharterType getGuildTypeFromInt(int i) {
return GuildCharterType.values()[i]; return GuildCharterType.values()[i];
} }
public String getCharterName() {
return this.name;
}
public int getNumberOfRanks() { public int getNumberOfRanks() {
return ranks.length; return ranks.length;
} }
public String getRankForGender(int rank, boolean male) { public String getRankForGender(int rank, boolean male) {
if (ranks.length < rank) {
return "";
}
if (ranks[rank].length != 1 && !male) { if (ranks.length < rank)
return "";
if (ranks[rank].length != 1 && !male)
return ranks[rank][1]; return ranks[rank][1];
}
return ranks[rank][0]; return ranks[rank][0];
} }
@@ -2633,7 +2431,14 @@ public class mbEnums {
} }
public boolean canJoin(AbstractCharacter character) { public boolean canJoin(AbstractCharacter character) {
return this.requiredRaces.contains(character.absRace) && this.requiredClasses.contains(character.absPromotionClass) && this.sexRequired.contains(character.absGender); if (this.requiredRaces.contains(character.absRace) == false)
return false;
if (this.requiredClasses.contains(character.absBaseClass) == false && this.requiredClasses.contains(character.absPromotionClass) == false)
return false;
if (this.sexRequired.contains(character.absGender) == false)
return false;
return true;
} }
} }
@@ -2746,42 +2551,45 @@ public class mbEnums {
public enum ResourceType { public enum ResourceType {
GOLD(7, 2308551, 100000000, 10), GOLD(7, -1670881623, 2308551, 100000000, 50000),
ADAMANT(1580003, -1741189964, 1000, 10), ADAMANT(1580003, 1557001525, -1741189964, 1000, 10),
AGATE(1580009, 75173057, 2000, 10), AGATE(1580009, -1096157543, 75173057, 2000, 20),
ANTIMONY(1580014, 452320058, 1000, 10), ANTIMONY(1580014, 1256147265, 452320058, 1000, 10),
AZOTH(1580012, 78329697, 2000, 10), AZOTH(1580012, -1205326951, 78329697, 2000, 20),
BLOODSTONE(1580020, -1569826353, 500, 10), BLOODSTONE(1580020, -1912381716, -1569826353, 500, 5),
BRONZEWOOD(1580006, 1334770447, 500, 10), BRONZEWOOD(1580006, -519681813, 1334770447, 1000, 30),
COAL(1580008, 2559427, 3000, 10), COAL(1580008, -1672872311, 2559427, 3000, 30),
DIAMOND(1580010, -1730704107, 2000, 10), DIAMOND(1580010, 1540225085, -1730704107, 2000, 20),
GALVOR(1580017, -1596311545, 2000, 10), GALVOR(1580017, -1683992404, -1596311545, 2000, 5),
IRON(1580002, 2504297, 2000, 10), IRON(1580002, -1673518119, 2504297, 2000, 20),
LUMBER(1580004, -1603256692, 10000, 10), LUMBER(1580004, 1628412684, -1603256692, 10000, 100),
MANDRAKE(1580007, 1191391799, 1000, 10), MANDRAKE(1580007, 1519910613, 1191391799, 1000, 10),
MITHRIL(1580021, -1761257186, 500, 10), MITHRIL(1580021, 626743397, -1761257186, 500, 5),
OAK(1580005, 74767, 3000, 10), OAK(1580005, -1653034775, 74767, 3000, 30),
OBSIDIAN(1580019, -697973233, 500, 10), OBSIDIAN(1580019, 778019055, -697973233, 500, 5),
ONYX(1580011, 2977263, 1000, 10), ONYX(1580011, -1675952151, 2977263, 1000, 10),
ORICHALK(1580013, -2036290524, 3000, 10), ORICHALK(1580013, -1468730955, -2036290524, 3000, 30),
QUICKSILVER(1580016, -472884509, 1000, 10), QUICKSILVER(1580016, -2081208434, -472884509, 1000, 10),
STONE(1580000, 74856115, 10000, 10), STONE(1580000, -1094703863, 74856115, 10000, 100),
SULFUR(1580015, -1586349421, 1000, 10), SULFUR(1580015, -1763687412, -1586349421, 1000, 10),
TRUESTEEL(1580001, -317484979, 2000, 10), TRUESTEEL(1580001, -169012482, -317484979, 2000, 20),
WORMWOOD(1580018, 1532478436, 500, 10); WORMWOOD(1580018, 1204785075, 1532478436, 500, 5);
public static HashMap<Integer, ResourceType> resourceLookup = new HashMap<>(); public static HashMap<Integer, ResourceType> templateLookup = new HashMap<>();
public static HashMap<Integer, ResourceType> hashLookup = new HashMap<>(); public static HashMap<Integer, ResourceType> templateHashLookup = new HashMap<>();
public static HashMap<Integer, ResourceType> resourceHashLookup = new HashMap<>();
public int templateID; public int templateID;
public ItemTemplate template; public ItemTemplate template;
public int hash; public int resourceHash;
public int templateHash;
public int deposit_limit; public int deposit_limit;
public int mine_production; public int mine_production;
ResourceType(int templateID, int hash, int deposit_limit, int mine_production) { ResourceType(int templateID, int resourceHash, int templateHash, int deposit_limit, int mine_production) {
this.templateID = templateID; this.templateID = templateID;
this.template = ItemTemplate.templates.get(this.templateID); this.template = ItemTemplate.templates.get(this.templateID);
this.hash = hash; this.resourceHash = resourceHash;
this.templateHash = templateHash;
this.deposit_limit = deposit_limit; this.deposit_limit = deposit_limit;
this.mine_production = mine_production; this.mine_production = mine_production;
} }
@@ -2789,11 +2597,11 @@ public class mbEnums {
public static void InitializeResourceTypes() { public static void InitializeResourceTypes() {
for (ResourceType resourceType : ResourceType.values()) { for (ResourceType resourceType : ResourceType.values()) {
resourceLookup.put(resourceType.templateID, resourceType); templateLookup.put(resourceType.templateID, resourceType);
hashLookup.put(resourceType.hash, resourceType); templateHashLookup.put(resourceType.templateHash, resourceType);
resourceHashLookup.put(resourceType.resourceHash, resourceType);
} }
} }
} }
@@ -3024,5 +2832,25 @@ public class mbEnums {
} }
} }
public enum ProductionActionType {
NONE,
PRODUCE,
JUNK,
RECYCLE,
COMPLETE,
SETPRICE,
DEPOSIT,
TAKE,
CONFIRM_PRODUCE,
CONFIRM_SETPRICE,
CONFIRM_DEPOSIT,
CONFIRM_TAKE;
}
public enum ItemModType {
PREFIX,
SUFFIX;
}
} }
+208 -167
View File
@@ -8,6 +8,7 @@
package engine.mobileAI; package engine.mobileAI;
import engine.InterestManagement.RealmMap;
import engine.InterestManagement.WorldGrid; import engine.InterestManagement.WorldGrid;
import engine.gameManager.*; import engine.gameManager.*;
import engine.math.Vector3f; import engine.math.Vector3f;
@@ -15,9 +16,8 @@ import engine.math.Vector3fImmutable;
import engine.mbEnums; import engine.mbEnums;
import engine.mbEnums.DispatchChannel; import engine.mbEnums.DispatchChannel;
import engine.mobileAI.Threads.MobAIThread; import engine.mobileAI.Threads.MobAIThread;
import engine.mobileAI.Threads.Respawner; import engine.mobileAI.Threads.ReSpawner;
import engine.mobileAI.utilities.MovementUtilities; import engine.mobileAI.utilities.MovementUtilities;
import engine.net.DispatchMessage;
import engine.net.client.msg.PerformActionMsg; import engine.net.client.msg.PerformActionMsg;
import engine.net.client.msg.PowerProjectileMsg; import engine.net.client.msg.PowerProjectileMsg;
import engine.objects.*; import engine.objects.*;
@@ -30,6 +30,7 @@ import org.pmw.tinylog.Logger;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
@@ -37,8 +38,15 @@ import static engine.math.FastMath.sqr;
public class MobAI { public class MobAI {
// MB Dev notes:
// Class implements mobile AI mechanics for Magicbane.
//
// Controls all mob actions from regular mobs to pets and guards.
// Initiates in the "DetermineAction" method and branches from there
//
// CombatManager.class implements shared combat routines for all avatars.
private static void AttackTarget(Mob mob, AbstractWorldObject target) { private static void attackTarget(Mob mob, AbstractWorldObject target) {
try { try {
@@ -50,15 +58,14 @@ public class MobAI {
return; return;
} }
if (target.getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter) && if (target.getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter) && !mob.canSee((AbstractCharacter) target)) {
!mob.canSee((AbstractCharacter) target)) {
mob.setCombatTarget(null); mob.setCombatTarget(null);
return; return;
} }
if (target.getObjectType() == mbEnums.GameObjectType.PlayerCharacter && canCast(mob)) { if (target.getObjectType() == mbEnums.GameObjectType.PlayerCharacter && canCast(mob)) {
if (MobCast(mob)) { if (mobCast(mob)) {
mob.updateLocation(); mob.updateLocation();
return; return;
} }
@@ -71,15 +78,15 @@ public class MobAI {
switch (target.getObjectType()) { switch (target.getObjectType()) {
case PlayerCharacter: case PlayerCharacter:
PlayerCharacter targetPlayer = (PlayerCharacter) target; PlayerCharacter targetPlayer = (PlayerCharacter) target;
AttackPlayer(mob, targetPlayer); attackPlayer(mob, targetPlayer);
break; break;
case Building: case Building:
Building targetBuilding = (Building) target; Building targetBuilding = (Building) target;
AttackBuilding(mob, targetBuilding); attackBuilding(mob, targetBuilding);
break; break;
case Mob: case Mob:
Mob targetMob = (Mob) target; Mob targetMob = (Mob) target;
AttackMob(mob, targetMob); attackMob(mob, targetMob);
break; break;
} }
@@ -90,17 +97,20 @@ public class MobAI {
} }
} }
public static void AttackPlayer(Mob mob, PlayerCharacter target) { public static void attackPlayer(Mob mob, PlayerCharacter target) {
try { try {
if (target == null || !target.isAlive() || !target.isActive()) {
mob.setCombatTarget(null);
return;
}
if (!mob.canSee(target)) { if (!mob.canSee(target)) {
mob.setCombatTarget(null); mob.setCombatTarget(null);
return; return;
} }
if (mob.behaviourType.callsForHelp) if (mob.behaviourType.callsForHelp)
MobCallForHelp(mob); mobCallForHelp(mob);
if (!MovementUtilities.inRangeDropAggro(mob, target)) { if (!MovementUtilities.inRangeDropAggro(mob, target)) {
mob.setCombatTarget(null); mob.setCombatTarget(null);
@@ -115,11 +125,11 @@ public class MobAI {
if (mob.isMoving() && mob.getRange() > 20) if (mob.isMoving() && mob.getRange() > 20)
return; return;
CombatManager.combatCycle(mob, mob.combatTarget); CombatManager.combatCycle(mob, target);
} }
if (target.getPet() != null) if (target.getPet() != null)
if (target.getPet().getCombatTarget() == null && target.getPet().assist == true) if (target.getPet().getCombatTarget() == null && target.getPet().assist)
target.getPet().setCombatTarget(mob); target.getPet().setCombatTarget(mob);
} catch (Exception e) { } catch (Exception e) {
@@ -128,7 +138,7 @@ public class MobAI {
} }
public static void AttackBuilding(Mob mob, Building target) { public static void attackBuilding(Mob mob, Building target) {
try { try {
@@ -154,7 +164,7 @@ public class MobAI {
if (mob.isSiege()) { if (mob.isSiege()) {
PowerProjectileMsg ppm = new PowerProjectileMsg(mob, target); PowerProjectileMsg ppm = new PowerProjectileMsg(mob, target);
ppm.setRange(50); ppm.setRange(50);
DispatchMessage.dispatchMsgToInterestArea(mob, ppm, DispatchChannel.SECONDARY, MBServerStatics.CHARACTER_LOAD_RANGE, false, false); DispatchManager.dispatchMsgToInterestArea(mob, ppm, DispatchChannel.SECONDARY, MBServerStatics.CHARACTER_LOAD_RANGE, false, false);
} }
} catch (Exception e) { } catch (Exception e) {
@@ -162,16 +172,17 @@ public class MobAI {
} }
} }
public static void AttackMob(Mob mob, Mob target) { public static void attackMob(Mob mob, Mob target) {
try { try {
if (mob == null || target == null)
return;
if (mob.getRange() >= 30 && mob.isMoving()) if (mob.getRange() >= 30 && mob.isMoving())
return; return;
//no weapons, default mob attack speed 3 seconds. //no weapons, default mob attack speed 3 seconds.
CombatManager.combatCycle(mob, target); CombatManager.combatCycle(mob, target);
} catch (Exception e) { } catch (Exception e) {
@@ -179,7 +190,7 @@ public class MobAI {
} }
} }
private static void Patrol(Mob mob) { private static void patrol(Mob mob) {
try { try {
@@ -188,10 +199,9 @@ public class MobAI {
// early exit while waiting to patrol again. // early exit while waiting to patrol again.
// Minions are force marched if captain is alive // Minions are force marched if captain is alive
boolean forced = mob.agentType.equals(mbEnums.AIAgentType.GUARDMINION) && boolean forced = mob.agentType.equals(mbEnums.AIAgentType.GUARDMINION) && mob.guardCaptain.isAlive();
mob.guardCaptain.isAlive();
if (mob.stopPatrolTime + (patrolDelay * 1000) > System.currentTimeMillis()) if (mob.stopPatrolTime + (patrolDelay * 1000L) > System.currentTimeMillis())
if (!forced) if (!forced)
return; return;
@@ -210,6 +220,7 @@ public class MobAI {
} }
} }
assert mob.patrolPoints != null;
if (mob.lastPatrolPointIndex > mob.patrolPoints.size() - 1) if (mob.lastPatrolPointIndex > mob.patrolPoints.size() - 1)
mob.lastPatrolPointIndex = 0; mob.lastPatrolPointIndex = 0;
@@ -229,8 +240,9 @@ public class MobAI {
if (mob.agentType.equals(mbEnums.AIAgentType.GUARDCAPTAIN)) if (mob.agentType.equals(mbEnums.AIAgentType.GUARDCAPTAIN))
for (Integer minionUUID : mob.minions) { for (Integer minionUUID : mob.minions) {
Mob minion = Mob.getMob(minionUUID); Mob minion = Mob.getMob(minionUUID);
assert minion != null;
if (minion.isAlive() && minion.combatTarget == null) if (minion.isAlive() && minion.combatTarget == null)
MobAI.Patrol(minion); MobAI.patrol(minion);
} }
MovementUtilities.aiMove(mob, mob.destination, true); MovementUtilities.aiMove(mob, mob.destination, true);
@@ -252,7 +264,7 @@ public class MobAI {
if (mob == null) if (mob == null)
return false; return false;
if (mob.isPlayerGuard() == true) { if (mob.isPlayerGuard()) {
if (mob.agentType.equals(mbEnums.AIAgentType.GUARDWALLARCHER)) if (mob.agentType.equals(mbEnums.AIAgentType.GUARDWALLARCHER))
return false; //wall archers don't cast return false; //wall archers don't cast
@@ -263,14 +275,13 @@ public class MobAI {
// exception allowing werewolf and werebear guard captains to cast // exception allowing werewolf and werebear guard captains to cast
if (mbEnums.MinionType.ContractToMinionMap.get(contractID).isMage() == false && contractID != 980103 && contractID != 980104) if (!mbEnums.MinionType.ContractToMinionMap.get(contractID).isMage() && contractID != 980103 && contractID != 980104)
return false; return false;
} }
// Mobile has no powers defined in mobbase or contract.. // Mobile has no powers defined in mobbase or contract..
if (PowersManager.getPowersForRune(mob.getMobBaseID()).isEmpty() && if (PowersManager.getPowersForRune(mob.getMobBaseID()).isEmpty() && PowersManager.getPowersForRune(contractID).isEmpty())
PowersManager.getPowersForRune(contractID).isEmpty())
return false; return false;
if (mob.nextCastTime == 0) if (mob.nextCastTime == 0)
@@ -284,7 +295,7 @@ public class MobAI {
return false; return false;
} }
public static boolean MobCast(Mob mob) { public static boolean mobCast(Mob mob) {
try { try {
// Method picks a random spell from a mobile's list of powers // Method picks a random spell from a mobile's list of powers
@@ -296,7 +307,7 @@ public class MobAI {
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.
@@ -370,7 +381,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) * 1000L) * MobAIThread.AI_CAST_FREQUENCY);
mob.nextCastTime = System.currentTimeMillis() + randomCooldown; mob.nextCastTime = System.currentTimeMillis() + randomCooldown;
return true; return true;
@@ -410,7 +421,7 @@ public class MobAI {
return powerRank; return powerRank;
} }
public static void MobCallForHelp(Mob mob) { public static void mobCallForHelp(Mob mob) {
try { try {
@@ -426,7 +437,7 @@ public class MobAI {
ChatManager.chatSayInfo(null, mob.getName() + " calls for help!"); ChatManager.chatSayInfo(null, mob.getName() + " calls for help!");
Zone mobCamp = mob.getParentZone(); Zone mobCamp = mob.parentZone;
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)) {
@@ -445,7 +456,7 @@ public class MobAI {
} }
} }
public static void DetermineAction(Mob mob) { public static void determineAction(Mob mob) {
try { try {
@@ -454,7 +465,7 @@ public class MobAI {
if (mob == null) if (mob == null)
return; return;
if (mob.getTimestamps().containsKey("lastExecution") == false) if (!mob.getTimestamps().containsKey("lastExecution"))
mob.getTimestamps().put("lastExecution", System.currentTimeMillis()); mob.getTimestamps().put("lastExecution", System.currentTimeMillis());
if (System.currentTimeMillis() < mob.getTimeStamp("lastExecution")) if (System.currentTimeMillis() < mob.getTimeStamp("lastExecution"))
@@ -465,7 +476,7 @@ public class MobAI {
//trebuchet spawn handler //trebuchet spawn handler
if (mob.despawned && mob.getMobBase().getLoadID() == 13171) { if (mob.despawned && mob.getMobBase().getLoadID() == 13171) {
CheckForRespawn(mob); checkForRespawn(mob);
return; return;
} }
@@ -474,11 +485,11 @@ public class MobAI {
if (mob.despawned && mob.isPlayerGuard()) { if (mob.despawned && mob.isPlayerGuard()) {
if (mob.agentType.equals(mbEnums.AIAgentType.GUARDMINION)) { if (mob.agentType.equals(mbEnums.AIAgentType.GUARDMINION)) {
if (mob.guardCaptain.isAlive() == false || ((Mob) mob.guardCaptain).despawned == true) { if (!mob.guardCaptain.isAlive() || ((Mob) mob.guardCaptain).despawned) {
//minions don't respawn while guard captain is dead //minions don't respawn while guard captain is dead
if (mob.isAlive() == false) { if (!mob.isAlive()) {
mob.deathTime = System.currentTimeMillis(); mob.deathTime = System.currentTimeMillis();
return; return;
} }
@@ -486,12 +497,12 @@ public class MobAI {
} }
} }
CheckForRespawn(mob); checkForRespawn(mob);
//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.agentType.equals(mbEnums.AIAgentType.PET)) if (!mob.agentType.equals(mbEnums.AIAgentType.PET))
CheckToSendMobHome(mob); checkToSendMobHome(mob);
return; return;
} }
@@ -499,7 +510,7 @@ public class MobAI {
//no need to continue if mob is dead, check for respawn and move on //no need to continue if mob is dead, check for respawn and move on
if (!mob.isAlive()) { if (!mob.isAlive()) {
CheckForRespawn(mob); checkForRespawn(mob);
return; return;
} }
@@ -519,12 +530,12 @@ public class MobAI {
} }
if (mob.agentType.equals(mbEnums.AIAgentType.PET) == false) if (!mob.agentType.equals(mbEnums.AIAgentType.PET))
CheckToSendMobHome(mob); checkToSendMobHome(mob);
if (mob.getCombatTarget() != null) { if (mob.getCombatTarget() != null) {
if (mob.getCombatTarget().isAlive() == false) { if (!mob.getCombatTarget().isAlive()) {
mob.setCombatTarget(null); mob.setCombatTarget(null);
return; return;
} }
@@ -533,12 +544,12 @@ public class MobAI {
PlayerCharacter target = (PlayerCharacter) mob.getCombatTarget(); PlayerCharacter target = (PlayerCharacter) mob.getCombatTarget();
if (mob.playerAgroMap.containsKey(target.getObjectUUID()) == false) { if (!mob.playerAgroMap.containsKey(target.getObjectUUID())) {
mob.setCombatTarget(null); mob.setCombatTarget(null);
return; return;
} }
if (mob.canSee((PlayerCharacter) mob.getCombatTarget()) == false) { if (!mob.canSee((PlayerCharacter) mob.getCombatTarget())) {
mob.setCombatTarget(null); mob.setCombatTarget(null);
return; return;
} }
@@ -550,17 +561,17 @@ public class MobAI {
case GuardCaptain: case GuardCaptain:
case GuardMinion: case GuardMinion:
case GuardWallArcher: case GuardWallArcher:
GuardLogic(mob); guardLogic(mob);
break; break;
case Pet1: case Pet1:
case SiegeEngine: case SiegeEngine:
PetLogic(mob); petLogic(mob);
break; break;
case HamletGuard: case HamletGuard:
HamletGuardLogic(mob); hamletGuardLogic(mob);
break; break;
default: default:
DefaultLogic(mob); defaultLogic(mob);
break; break;
} }
} catch (Exception e) { } catch (Exception e) {
@@ -568,7 +579,7 @@ public class MobAI {
} }
} }
private static void CheckForAggro(Mob aiAgent) { private static void checkForAggro(Mob aiAgent) {
try { try {
@@ -579,9 +590,9 @@ public class MobAI {
ConcurrentHashMap<Integer, Float> loadedPlayers = aiAgent.playerAgroMap; ConcurrentHashMap<Integer, Float> loadedPlayers = aiAgent.playerAgroMap;
for (Entry playerEntry : loadedPlayers.entrySet()) { for (Entry<Integer, Float> playerEntry : loadedPlayers.entrySet()) {
int playerID = (int) playerEntry.getKey(); int playerID = playerEntry.getKey();
PlayerCharacter loadedPlayer = PlayerCharacter.getPlayerCharacter(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.
@@ -605,12 +616,12 @@ public class MobAI {
// No aggro for this race type // No aggro for this race type
if (aiAgent.notEnemy.size() > 0 && aiAgent.notEnemy.contains(loadedPlayer.race.getRaceType().getMonsterType()) == true) if (!aiAgent.notEnemy.isEmpty() && aiAgent.notEnemy.contains(loadedPlayer.race.getRaceType().getMonsterType()))
continue; continue;
//mob has enemies and this player race is not it //mob has enemies and this player race is not it
if (aiAgent.enemy.size() > 0 && aiAgent.enemy.contains(loadedPlayer.race.getRaceType().getMonsterType()) == false) if (!aiAgent.enemy.isEmpty() && !aiAgent.enemy.contains(loadedPlayer.race.getRaceType().getMonsterType()))
continue; continue;
if (MovementUtilities.inRangeToAggro(aiAgent, loadedPlayer)) { if (MovementUtilities.inRangeToAggro(aiAgent, loadedPlayer)) {
@@ -642,7 +653,7 @@ public class MobAI {
} }
} }
private static void CheckMobMovement(Mob mob) { private static void checkMobMovement(Mob mob) {
try { try {
@@ -651,56 +662,51 @@ public class MobAI {
mob.updateLocation(); mob.updateLocation();
switch (mob.behaviourType) { if (mob.behaviourType == mbEnums.MobBehaviourType.Pet1) {
if (mob.guardCaptain == null)
return;
case Pet1: //mob no longer has its owner loaded, translate pet to owner
if (mob.guardCaptain == null) if (!mob.playerAgroMap.containsKey(mob.guardCaptain.getObjectUUID())) {
MovementManager.translocate(mob, mob.guardCaptain.getLoc());
return;
}
if (mob.getCombatTarget() == null) {
//move back to owner
if (mob.getRange() * mob.getRange() >= mob.loc.distanceSquared(mob.guardCaptain.loc))
return; return;
//mob no longer has its owner loaded, translate pet to owner mob.destination = mob.guardCaptain.getLoc();
MovementUtilities.moveToLocation(mob, mob.destination, 5, false);
} else
chaseTarget(mob);
} else {
if (mob.getCombatTarget() == null) {
if (!mob.playerAgroMap.containsKey(mob.guardCaptain.getObjectUUID())) { if (!mob.isMoving()) {
MovementManager.translocate(mob, mob.guardCaptain.getLoc());
return;
}
if (mob.getCombatTarget() == null) { // Minions only patrol on their own if captain is dead.
//move back to owner if (!mob.agentType.equals(mbEnums.AIAgentType.GUARDMINION))
patrol(mob);
if (mob.getRange() * mob.getRange() >= mob.loc.distanceSquared(mob.guardCaptain.loc)) else if (!mob.guardCaptain.isAlive())
return; patrol(mob);
mob.destination = mob.guardCaptain.getLoc();
MovementUtilities.moveToLocation(mob, mob.destination, 5, false);
} else } else
chaseTarget(mob); mob.stopPatrolTime = System.currentTimeMillis();
break; } else {
default: chaseTarget(mob);
if (mob.getCombatTarget() == null) { }
if (!mob.isMoving()) {
// Minions only patrol on their own if captain is dead.
if (mob.agentType.equals(mbEnums.AIAgentType.GUARDMINION) == false)
Patrol(mob);
else if (mob.guardCaptain.isAlive() == false)
Patrol(mob);
} else
mob.stopPatrolTime = System.currentTimeMillis();
} else {
chaseTarget(mob);
}
break;
} }
} catch (Exception e) { } catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: CheckMobMovement" + " " + e.getMessage()); Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: CheckMobMovement" + " " + e.getMessage());
} }
} }
private static void CheckForRespawn(Mob aiAgent) { private static void checkForRespawn(Mob aiAgent) {
try { try {
@@ -718,7 +724,6 @@ public class MobAI {
if (System.currentTimeMillis() > aiAgent.deathTime + MBServerStatics.DESPAWN_TIMER_WITH_LOOT) { if (System.currentTimeMillis() > aiAgent.deathTime + MBServerStatics.DESPAWN_TIMER_WITH_LOOT) {
aiAgent.despawn(); aiAgent.despawn();
aiAgent.deathTime = System.currentTimeMillis(); aiAgent.deathTime = System.currentTimeMillis();
return;
} }
//No items in inventory. //No items in inventory.
} else { } else {
@@ -727,62 +732,48 @@ public class MobAI {
if (System.currentTimeMillis() > aiAgent.deathTime + MBServerStatics.DESPAWN_TIMER_ONCE_LOOTED) { if (System.currentTimeMillis() > aiAgent.deathTime + MBServerStatics.DESPAWN_TIMER_ONCE_LOOTED) {
aiAgent.despawn(); aiAgent.despawn();
aiAgent.deathTime = System.currentTimeMillis(); aiAgent.deathTime = System.currentTimeMillis();
return;
} }
//Mob never had Loot. //Mob never had Loot.
} else { } else {
if (System.currentTimeMillis() > aiAgent.deathTime + MBServerStatics.DESPAWN_TIMER) { if (System.currentTimeMillis() > aiAgent.deathTime + MBServerStatics.DESPAWN_TIMER) {
aiAgent.despawn(); aiAgent.despawn();
aiAgent.deathTime = System.currentTimeMillis(); aiAgent.deathTime = System.currentTimeMillis();
return;
} }
} }
} }
} else if (System.currentTimeMillis() > aiAgent.deathTime + (aiAgent.spawnDelay * 1000L)) { } else if (System.currentTimeMillis() > aiAgent.deathTime + (aiAgent.spawnDelay * 1000L)) {
aiAgent.respawnTime = aiAgent.deathTime + (aiAgent.spawnDelay * 1000L); aiAgent.respawnTime = aiAgent.deathTime + (aiAgent.spawnDelay * 1000L);
Respawner.respawnQueue.put(aiAgent); ReSpawner.respawnQueue.put(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());
} }
} }
public static void CheckForAttack(Mob mob) { public static void checkForAttack(Mob mob) {
try { try {
//checks if mob can attack based on attack timer and range //checks if mob can attack based on attack timer and range
if (mob.isAlive() == false) if (!mob.isAlive())
return; return;
if (mob.getCombatTarget() == null) if (mob.getCombatTarget() == null)
return; return;
if (mob.getCombatTarget().getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter) && MovementUtilities.inRangeDropAggro(mob, (PlayerCharacter) mob.getCombatTarget()) == false && if (mob.getCombatTarget().getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter) && !MovementUtilities.inRangeDropAggro(mob, (PlayerCharacter) mob.getCombatTarget()) && !mob.agentType.equals(mbEnums.AIAgentType.PET)) {
mob.agentType.equals(mbEnums.AIAgentType.PET) == false) {
mob.setCombatTarget(null); mob.setCombatTarget(null);
return; return;
} }
if (System.currentTimeMillis() > mob.getNextAttackTime()) { attackTarget(mob, mob.getCombatTarget());
int delay = 3000;
if (mob.charItemManager.getEquipped().get(mbEnums.EquipSlotType.RHELD) != null) {
delay = (int) (mob.charItemManager.getEquipped().get(mbEnums.EquipSlotType.RHELD).template.item_weapon_wepspeed * 100);
}
if (mob.charItemManager.getEquipped().get(mbEnums.EquipSlotType.LHELD) != null && mob.charItemManager.getEquipped().get(mbEnums.EquipSlotType.LHELD).template.item_type.equals(mbEnums.ItemType.WEAPON)) {
delay += (int) (mob.charItemManager.getEquipped().get(mbEnums.EquipSlotType.LHELD).template.item_weapon_wepspeed * 100);
}
mob.nextAttackTime = System.currentTimeMillis() + delay;
AttackTarget(mob, mob.getCombatTarget());
}
} catch (Exception e) { } catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: CheckForAttack" + " " + e.getMessage()); Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: CheckForAttack" + " " + e.getMessage());
} }
} }
private static void CheckToSendMobHome(Mob mob) { private static void checkToSendMobHome(Mob mob) {
try { try {
@@ -793,7 +784,7 @@ public class MobAI {
City current = ZoneManager.getCityAtLocation(mob.getLoc()); City current = ZoneManager.getCityAtLocation(mob.getLoc());
if (current == null || current.equals(mob.getGuild().getOwnedCity()) == false) { if (current == null || !current.equals(mob.getGuild().getOwnedCity())) {
PowersBase recall = PowersManager.getPowerByToken(-1994153779); PowersBase recall = PowersManager.getPowerByToken(-1994153779);
PowersManager.useMobPower(mob, mob, recall, 40); PowersManager.useMobPower(mob, mob, recall, 40);
@@ -807,18 +798,18 @@ public class MobAI {
Mob minion = Mob.getMob(minionUUID); Mob minion = Mob.getMob(minionUUID);
PowersManager.useMobPower(minion, minion, recall, 40); PowersManager.useMobPower(minion, minion, recall, 40);
assert minion != null;
minion.setCombatTarget(null); minion.setCombatTarget(null);
} }
} }
} }
} else if (MovementUtilities.inRangeOfBindLocation(mob) == false) { } else if (!MovementUtilities.inRangeOfBindLocation(mob)) {
PowersBase recall = PowersManager.getPowerByToken(-1994153779); PowersBase recall = PowersManager.getPowerByToken(-1994153779);
PowersManager.useMobPower(mob, mob, recall, 40); PowersManager.useMobPower(mob, mob, recall, 40);
mob.setCombatTarget(null); mob.setCombatTarget(null);
for (Integer playerEntry : mob.playerAgroMap.keySet()) mob.playerAgroMap.replaceAll((e, v) -> 0f);
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());
@@ -829,9 +820,9 @@ public class MobAI {
try { try {
if (mob.getTimestamps().containsKey("lastChase") == false) if (!mob.getTimestamps().containsKey("lastChase"))
mob.getTimestamps().put("lastChase", System.currentTimeMillis()); mob.getTimestamps().put("lastChase", System.currentTimeMillis());
else if (System.currentTimeMillis() < mob.getTimestamps().get("lastChase").longValue() + (750 + ThreadLocalRandom.current().nextInt(0, 500))) else if (System.currentTimeMillis() < mob.getTimestamps().get("lastChase") + (750 + ThreadLocalRandom.current().nextInt(0, 500)))
return; return;
mob.getTimestamps().put("lastChase", System.currentTimeMillis()); mob.getTimestamps().put("lastChase", System.currentTimeMillis());
@@ -864,7 +855,7 @@ public class MobAI {
} }
} }
private static void SafeGuardAggro(Mob mob) { private static void safeGuardAggro(Mob mob) {
try { try {
HashSet<AbstractWorldObject> awoList = WorldGrid.getObjectsInRangePartial(mob, 100, MBServerStatics.MASK_MOB); HashSet<AbstractWorldObject> awoList = WorldGrid.getObjectsInRangePartial(mob, 100, MBServerStatics.MASK_MOB);
@@ -879,7 +870,7 @@ public class MobAI {
Mob aggroMob = (Mob) awoMob; Mob aggroMob = (Mob) awoMob;
//don't attack other guards //don't attack other guards
if (aggroMob.isGuard() == true) if (aggroMob.isGuard())
continue; continue;
//don't attack pets //don't attack pets
@@ -896,19 +887,19 @@ public class MobAI {
} }
} }
public static void GuardLogic(Mob mob) { public static void guardLogic(Mob mob) {
try { try {
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 //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) {
if (newTarget.getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter)) { if (newTarget.getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter)) {
if (GuardCanAggro(mob, (PlayerCharacter) newTarget)) if (guardCanAggro(mob, (PlayerCharacter) newTarget))
mob.setCombatTarget(newTarget); mob.setCombatTarget(newTarget);
} else } else
mob.setCombatTarget(newTarget); mob.setCombatTarget(newTarget);
@@ -916,38 +907,38 @@ public class MobAI {
} }
if (mob.behaviourType.canRoam) if (mob.behaviourType.canRoam)
CheckMobMovement(mob);//all guards that can move check to move checkMobMovement(mob);//all guards that can move check to move
if (mob.combatTarget != null) if (mob.combatTarget != null)
CheckForAttack(mob); //only check to attack if combat target is not null checkForAttack(mob); //only check to attack if combat target is not null
} catch (Exception e) { } catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: GuardLogic" + " " + e.getMessage()); Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: GuardLogic" + " " + e.getMessage());
} }
} }
private static void PetLogic(Mob mob) { private static void petLogic(Mob mob) {
try { try {
if (mob.guardCaptain == null && mob.isNecroPet() == false && mob.isSiege() == false) if (mob.guardCaptain == null && !mob.isNecroPet() && !mob.isSiege())
if (ZoneManager.seaFloor.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);
//recover health //recover health
if (mob.getTimestamps().containsKey("HEALTHRECOVERED") == false) if (!mob.getTimestamps().containsKey("HEALTHRECOVERED"))
mob.getTimestamps().put("HEALTHRECOVERED", System.currentTimeMillis()); mob.getTimestamps().put("HEALTHRECOVERED", System.currentTimeMillis());
if (mob.isSit() && mob.getTimeStamp("HEALTHRECOVERED") < System.currentTimeMillis() + 3000) if (mob.isSit() && mob.getTimeStamp("HEALTHRECOVERED") < System.currentTimeMillis() + 3000)
if (mob.getHealth() < mob.getHealthMax()) { if (mob.getHealth() < mob.getHealthMax()) {
float recoveredHealth = mob.getHealthMax() * ((1 + mob.getBonuses().getFloatPercentAll(mbEnums.ModType.HealthRecoverRate, mbEnums.SourceType.None)) * 0.01f); float recoveredHealth = mob.getHealthMax() * ((1 + mob.getBonuses().getFloatPercentAll(mbEnums.ModType.HealthRecoverRate, mbEnums.EffectSourceType.None)) * 0.01f);
mob.setHealth(mob.getHealth() + recoveredHealth); mob.setHealth(mob.getHealth() + recoveredHealth);
mob.getTimestamps().put("HEALTHRECOVERED", System.currentTimeMillis()); mob.getTimestamps().put("HEALTHRECOVERED", System.currentTimeMillis());
@@ -959,43 +950,84 @@ public class MobAI {
} }
} }
private static void HamletGuardLogic(Mob mob) { private static void hamletGuardLogic(Mob mob) {
try { try {
//safehold guard
if (mob.getCombatTarget() == null) if (ConfigManager.MB_RULESET.getValue().equals("LORE")) {
SafeGuardAggro(mob); //lore guard aggro to kill members of opposing charters
else if (mob.getCombatTarget().isAlive() == false) if (mob.getCombatTarget() == null || !mob.combatTarget.isAlive())
SafeGuardAggro(mob); hamletGuardAggro(mob);
else if (!mob.getCombatTarget().isAlive())
hamletGuardAggro(mob);
} else {
//safehold guard
CheckForAttack(mob); if (mob.getCombatTarget() == null || !mob.combatTarget.isAlive())
safeGuardAggro(mob);
else if (!mob.getCombatTarget().isAlive())
safeGuardAggro(mob);
}
checkForAttack(mob);
} catch (Exception e) { } catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: HamletGuardLogic" + " " + e.getMessage()); Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: HamletGuardLogic" + " " + e.getMessage());
} }
} }
private static void DefaultLogic(Mob mob) { private static void hamletGuardAggro(Mob mob) {
Realm realm = RealmMap.getRealmAtLocation(mob.loc);
if (realm.getRealmName().equals("Uthgaard")) {
HashSet<AbstractWorldObject> loadedMobs = WorldGrid.getObjectsInRangePartial(mob.loc, MobAIThread.AI_BASE_AGGRO_RANGE, MBServerStatics.MASK_MOB);
for (AbstractWorldObject awo : loadedMobs) {
Mob targetMob = (Mob) awo;
if (targetMob.equals(mob))
continue;
if (!targetMob.isAlive() || targetMob.despawned)
continue;
if (targetMob.isPet())
continue;
mob.combatTarget = targetMob;
return;
}
return;
}
HashSet<AbstractWorldObject> loadedPlayers = WorldGrid.getObjectsInRangePartial(mob.loc, MobAIThread.AI_BASE_AGGRO_RANGE, MBServerStatics.MASK_PLAYER);
for (AbstractWorldObject awo : loadedPlayers) {
PlayerCharacter pc = (PlayerCharacter) awo;
if (!pc.isAlive() || !pc.isActive())
continue;
if (pc.guild.equals(Guild.getErrantGuild())) {
mob.combatTarget = pc;
return;
}
if (pc.guild.charter.equals(mob.guild.charter))
continue;
mob.combatTarget = pc;
return;
}
}
private static void defaultLogic(Mob mob) {
try { try {
//check for players that can be aggroed if mob is agressive and has no target //check for players that can be aggroed if mob is agressive and has no target
if (mob.getCombatTarget() != null && mob.playerAgroMap.containsKey(mob.getCombatTarget().getObjectUUID()) == false) if (mob.getCombatTarget() != null && !mob.playerAgroMap.containsKey(mob.getCombatTarget().getObjectUUID()))
mob.setCombatTarget(null); mob.setCombatTarget(null);
if (mob.behaviourType.isAgressive) { if (mob.behaviourType.isAgressive) {
AbstractWorldObject newTarget = ChangeTargetFromHateValue(mob); AbstractWorldObject newTarget = changeTargetFromHateValue(mob);
if (newTarget != null) if (newTarget != null)
mob.setCombatTarget(newTarget); mob.setCombatTarget(newTarget);
else { else {
if (mob.getCombatTarget() == null) { if (mob.getCombatTarget() == null) {
if (mob.behaviourType == mbEnums.MobBehaviourType.HamletGuard) if (mob.behaviourType == mbEnums.MobBehaviourType.HamletGuard)
SafeGuardAggro(mob); //safehold guard safeGuardAggro(mob); //safehold guard
else else
CheckForAggro(mob); //normal aggro checkForAggro(mob); //normal aggro
} }
} }
} }
@@ -1003,19 +1035,19 @@ 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) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: DefaultLogic" + " " + e.getMessage()); Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: DefaultLogic" + " " + e.getMessage());
} }
} }
public static void CheckForPlayerGuardAggro(Mob mob) { public static void checkForPlayerGuardAggro(Mob mob) {
try { try {
@@ -1026,18 +1058,16 @@ public class MobAI {
// Defer to captain if possible for current target // Defer to captain if possible for current target
if (mob.agentType.equals(mbEnums.AIAgentType.GUARDMINION) && if (mob.agentType.equals(mbEnums.AIAgentType.GUARDMINION) && mob.guardCaptain.isAlive() && mob.guardCaptain.combatTarget != null) {
mob.guardCaptain.isAlive()
&& mob.guardCaptain.combatTarget != null) {
mob.setCombatTarget(mob.guardCaptain.combatTarget); mob.setCombatTarget(mob.guardCaptain.combatTarget);
return; return;
} }
ConcurrentHashMap<Integer, Float> loadedPlayers = mob.playerAgroMap; ConcurrentHashMap<Integer, Float> loadedPlayers = mob.playerAgroMap;
for (Entry playerEntry : loadedPlayers.entrySet()) { for (Entry<Integer, Float> playerEntry : loadedPlayers.entrySet()) {
int playerID = (int) playerEntry.getKey(); int playerID = playerEntry.getKey();
PlayerCharacter loadedPlayer = PlayerCharacter.getPlayerCharacter(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.
@@ -1061,7 +1091,7 @@ public class MobAI {
// No aggro for this player // No aggro for this player
if (GuardCanAggro(mob, loadedPlayer) == false) if (!guardCanAggro(mob, loadedPlayer))
continue; continue;
if (MovementUtilities.inRangeToAggro(mob, loadedPlayer) && mob.getCombatTarget() == null) { if (MovementUtilities.inRangeToAggro(mob, loadedPlayer) && mob.getCombatTarget() == null) {
@@ -1079,7 +1109,7 @@ public class MobAI {
Mob aggroMob = (Mob) awoMob; Mob aggroMob = (Mob) awoMob;
if (GuardCanAggro(mob, aggroMob)) { if (guardCanAggro(mob, aggroMob)) {
mob.setCombatTarget(aggroMob); mob.setCombatTarget(aggroMob);
return; return;
} }
@@ -1091,11 +1121,16 @@ public class MobAI {
} }
} }
public static Boolean GuardCanAggro(Mob mob, AbstractCharacter target) { public static Boolean guardCanAggro(Mob mob, AbstractCharacter target) {
try { try {
if (mob.guardedCity.cityOutlaws.contains(target.getObjectUUID()) == true) if (ConfigManager.MB_RULESET.getValue().equals("LORE") && !target.guild.equals(Guild.getErrantGuild())) {
if (mob.guild.charter.equals(target.guild.charter))
return false;
}
if (mob.guardedCity != null && mob.guardedCity.cityOutlaws.contains(target.getObjectUUID()))
return true; return true;
if (mob.getGuild().getNation().equals(target.getGuild().getNation())) if (mob.getGuild().getNation().equals(target.getGuild().getNation()))
@@ -1103,8 +1138,8 @@ public class MobAI {
//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 (Objects.requireNonNull(ZoneManager.getCityAtLocation(mob.getLoc())).getTOL().reverseKOS) {
for (Entry<Integer, Condemned> entry : ZoneManager.getCityAtLocation(mob.getLoc()).getTOL().getCondemned().entrySet()) { for (Entry<Integer, Condemned> entry : Objects.requireNonNull(ZoneManager.getCityAtLocation(mob.getLoc())).getTOL().getCondemned().entrySet()) {
//target is listed individually //target is listed individually
@@ -1126,7 +1161,7 @@ public class MobAI {
//allies button is not checked //allies button is not checked
for (Entry<Integer, Condemned> entry : ZoneManager.getCityAtLocation(mob.getLoc()).getTOL().getCondemned().entrySet()) { for (Entry<Integer, Condemned> entry : Objects.requireNonNull(ZoneManager.getCityAtLocation(mob.getLoc())).getTOL().getCondemned().entrySet()) {
//target is listed individually //target is listed individually
@@ -1157,7 +1192,7 @@ public class MobAI {
//early exit for a mob who is already moving to a patrol point //early exit for a mob who is already moving to a patrol point
//while mob moving, update lastPatrolTime so that when they stop moving the 10 second timer can begin //while mob moving, update lastPatrolTime so that when they stop moving the 10 second timer can begin
if (mob.isMoving() == true) { if (mob.isMoving()) {
mob.stopPatrolTime = System.currentTimeMillis(); mob.stopPatrolTime = System.currentTimeMillis();
return; return;
} }
@@ -1185,7 +1220,8 @@ public class MobAI {
//make sure mob is out of combat stance //make sure mob is out of combat stance
if (minion.despawned == false) { assert minion != null;
if (!minion.despawned) {
if (MovementUtilities.canMove(minion)) { if (MovementUtilities.canMove(minion)) {
Vector3f minionOffset = mbEnums.FormationType.getOffset(2, mob.minions.indexOf(minionUUID) + 3); Vector3f minionOffset = mbEnums.FormationType.getOffset(2, mob.minions.indexOf(minionUUID) + 3);
minion.updateLocation(); minion.updateLocation();
@@ -1200,26 +1236,31 @@ public class MobAI {
} }
} }
public static AbstractWorldObject ChangeTargetFromHateValue(Mob mob) { public static AbstractWorldObject changeTargetFromHateValue(Mob mob) {
try { try {
float CurrentHateValue = 0; float CurrentHateValue = 0;
if (mob.getCombatTarget() != null && mob.getCombatTarget().getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter)) if (mob.getCombatTarget() != null && mob.getCombatTarget().getObjectType().equals(mbEnums.GameObjectType.PlayerCharacter))
CurrentHateValue = mob.playerAgroMap.get(mob.combatTarget.getObjectUUID()).floatValue(); CurrentHateValue = mob.playerAgroMap.get(mob.combatTarget.getObjectUUID());
AbstractWorldObject mostHatedTarget = null; AbstractWorldObject mostHatedTarget = null;
for (Entry playerEntry : mob.playerAgroMap.entrySet()) { for (Entry<Integer, Float> playerEntry : mob.playerAgroMap.entrySet()) {
PlayerCharacter potentialTarget = PlayerCharacter.getPlayerCharacter((int) playerEntry.getKey()); PlayerCharacter potentialTarget = PlayerCharacter.getPlayerCharacter(playerEntry.getKey());
if (potentialTarget.equals(mob.getCombatTarget())) if (potentialTarget.equals(mob.getCombatTarget()))
continue; continue;
if (potentialTarget != null && mob.playerAgroMap.get(potentialTarget.getObjectUUID()).floatValue() > CurrentHateValue && MovementUtilities.inRangeToAggro(mob, potentialTarget)) { if (ConfigManager.MB_RULESET.getValue().equals("LORE") && !potentialTarget.guild.equals(Guild.getErrantGuild())) {
CurrentHateValue = mob.playerAgroMap.get(potentialTarget.getObjectUUID()).floatValue(); if (mob.guild.charter.equals(potentialTarget.guild.charter))
continue;
}
if (mob.playerAgroMap.get(potentialTarget.getObjectUUID()) > CurrentHateValue && MovementUtilities.inRangeToAggro(mob, potentialTarget)) {
CurrentHateValue = mob.playerAgroMap.get(potentialTarget.getObjectUUID());
mostHatedTarget = potentialTarget; mostHatedTarget = potentialTarget;
} }
+5 -9
View File
@@ -13,32 +13,28 @@ public class MobAIThread implements Runnable {
public static int AI_PULSE_MOB_THRESHOLD = 200; public static int AI_PULSE_MOB_THRESHOLD = 200;
public static int AI_PATROL_DIVISOR = 15; public static int AI_PATROL_DIVISOR = 15;
public static float AI_CAST_FREQUENCY; public static float AI_CAST_FREQUENCY;
// Thread constructor
public MobAIThread() { public MobAIThread() {
Logger.info(" MobAIThread thread has started!"); Logger.info(" MobAIThread thread has started!");
} }
@Override @Override
public void run() { public void run() {
//cache config value for mobile casting delay //cache config value for mobile casting delay
AI_CAST_FREQUENCY = Float.parseFloat(ConfigManager.MB_AI_CAST_FREQUENCY.getValue()); AI_CAST_FREQUENCY = Float.parseFloat(ConfigManager.MB_AI_CAST_FREQUENCY.getValue());
AI_BASE_AGGRO_RANGE = (int) (60 * Float.parseFloat(ConfigManager.MB_AI_AGGRO_RANGE.getValue())); AI_BASE_AGGRO_RANGE = (int) (60 * Float.parseFloat(ConfigManager.MB_AI_AGGRO_RANGE.getValue()));
while (true) { while (true) {
for (Zone zone : ZoneManager.getAllZones()) { for (Zone zone : ZoneManager.getAllZones())
for (Mob mob : zone.zoneMobSet)
for (Mob mob : zone.zoneMobSet) {
try { try {
if (mob != null) if (mob != null)
MobAI.DetermineAction(mob); MobAI.determineAction(mob);
} catch (Exception e) { } catch (Exception e) {
Logger.error("Mob: " + mob.getName() + " UUID: " + mob.getObjectUUID() + " ERROR: " + e); Logger.error("Mob: " + mob.getName() + " UUID: " + mob.getObjectUUID() + " ERROR: " + e);
e.printStackTrace(); e.printStackTrace();
} }
}
}
} }
} }
@@ -15,9 +15,18 @@ import org.pmw.tinylog.Logger;
import java.util.concurrent.BlockingQueue; import java.util.concurrent.BlockingQueue;
import java.util.concurrent.DelayQueue; import java.util.concurrent.DelayQueue;
public enum Respawner implements Runnable { public enum ReSpawner implements Runnable {
// MB Dev Notes:
//
// Thread acts as a throttle for messages to the client. Mobiles are
// respawned over a short time so as not to flood client when
// entire camp respawns at once. Client has a tendency to drop
// messages when given too much to digest.
RESPAWNER; RESPAWNER;
public static BlockingQueue<Mob> respawnQueue = new DelayQueue();
public static final BlockingQueue<Mob> respawnQueue = new DelayQueue<>();
@Override @Override
public void run() { public void run() {
@@ -9,13 +9,12 @@
package engine.mobileAI.utilities; package engine.mobileAI.utilities;
import engine.exception.MsgSendException;
import engine.gameManager.MovementManager; import engine.gameManager.MovementManager;
import engine.math.Vector3fImmutable; import engine.math.Vector3fImmutable;
import engine.mbEnums; import engine.mbEnums;
import engine.mbEnums.EffectSourceType;
import engine.mbEnums.GameObjectType; import engine.mbEnums.GameObjectType;
import engine.mbEnums.ModType; import engine.mbEnums.ModType;
import engine.mbEnums.SourceType;
import engine.mobileAI.Threads.MobAIThread; import engine.mobileAI.Threads.MobAIThread;
import engine.net.client.msg.MoveToPointMsg; import engine.net.client.msg.MoveToPointMsg;
import engine.objects.*; import engine.objects.*;
@@ -68,8 +67,9 @@ public class MovementUtilities {
float zoneRange = 250; float zoneRange = 250;
if (agent.getParentZone() != null) { if (agent.getParentZone() != null) {
if (agent.getParentZone().bounds != null) if (agent.getParentZone().bounds != null) {
zoneRange = agent.getParentZone().bounds.getHalfExtents().x * 2; zoneRange = agent.getParentZone().bounds.getHalfExtents().x * 2;
}
} }
if (zoneRange > 300) if (zoneRange > 300)
@@ -169,7 +169,7 @@ public class MovementUtilities {
if (agent.getMobBase() != null && agent.getMobBase().getFlags().contains(mbEnums.MobFlagType.SENTINEL)) if (agent.getMobBase() != null && agent.getMobBase().getFlags().contains(mbEnums.MobFlagType.SENTINEL))
return false; return false;
return (agent.isAlive() && !agent.getBonuses().getBool(ModType.Stunned, SourceType.None) && !agent.getBonuses().getBool(ModType.CannotMove, SourceType.None)); return (agent.isAlive() && !agent.getBonuses().getBool(ModType.Stunned, EffectSourceType.None) && !agent.getBonuses().getBool(ModType.CannotMove, EffectSourceType.None));
} }
public static Vector3fImmutable randomPatrolLocation(Mob agent, Vector3fImmutable center, float radius) { public static Vector3fImmutable randomPatrolLocation(Mob agent, Vector3fImmutable center, float radius) {
@@ -252,7 +252,7 @@ public class MovementUtilities {
try { try {
MovementManager.movement(msg, agent); MovementManager.movement(msg, agent);
} catch (MsgSendException e) { } catch (Exception e) {
// TODO Figure out how we want to handle the msg send exception // TODO Figure out how we want to handle the msg send exception
e.printStackTrace(); e.printStackTrace();
} }
-4
View File
@@ -10,7 +10,6 @@
package engine.net; package engine.net;
import engine.job.JobManager; import engine.job.JobManager;
import engine.net.client.Protocol;
import engine.net.client.msg.ClientNetMsg; import engine.net.client.msg.ClientNetMsg;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
@@ -20,7 +19,6 @@ import java.nio.ByteBuffer;
import java.nio.channels.ClosedChannelException; import java.nio.channels.ClosedChannelException;
import java.nio.channels.NotYetConnectedException; import java.nio.channels.NotYetConnectedException;
import java.nio.channels.SocketChannel; import java.nio.channels.SocketChannel;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
@@ -42,8 +40,6 @@ public abstract class AbstractConnection implements
protected long lastKeepAliveTime = System.currentTimeMillis(); protected long lastKeepAliveTime = System.currentTimeMillis();
protected long lastOpcode = -1; protected long lastOpcode = -1;
protected ConcurrentLinkedQueue<ByteBuffer> outbox = new ConcurrentLinkedQueue<>(); protected ConcurrentLinkedQueue<ByteBuffer> outbox = new ConcurrentLinkedQueue<>();
protected ByteBuffer outBuf = null;
protected ConcurrentHashMap<Long, Byte> cacheList;
protected long nextWriteTime = 0L; protected long nextWriteTime = 0L;
//Opcode tracking //Opcode tracking
+1 -3
View File
@@ -9,8 +9,6 @@
package engine.net; package engine.net;
import engine.exception.SerializationException;
import engine.net.client.Protocol;
import engine.server.MBServerStatics; import engine.server.MBServerStatics;
import engine.util.StringUtils; import engine.util.StringUtils;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
@@ -96,7 +94,7 @@ public abstract class AbstractNetMsg {
* @throws Exception * @throws Exception
*/ */
protected abstract void _serialize(ByteBufferWriter writer) protected abstract void _serialize(ByteBufferWriter writer)
throws SerializationException; ;
/** /**
* Attempts to serialize this NetMsg into a ByteBuffer. ByteBuffer is * Attempts to serialize this NetMsg into a ByteBuffer. ByteBuffer is
@@ -9,7 +9,6 @@
package engine.net; package engine.net;
import engine.job.AbstractJob; import engine.job.AbstractJob;
import engine.net.client.Protocol;
import engine.net.client.msg.ClientNetMsg; import engine.net.client.msg.ClientNetMsg;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
-135
View File
@@ -1,135 +0,0 @@
// ·. · · · · .
// · ·
// · ·
//
// · · ·
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
package engine.net;
import engine.mbEnums.DispatchChannel;
import engine.objects.ProducedItem;
import org.pmw.tinylog.Logger;
import java.util.HashSet;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.atomic.LongAdder;
/**
* 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 enum ItemProductionManager implements Runnable {
ITEMPRODUCTIONMANAGER;
// Instance variables
@SuppressWarnings("unchecked") // Cannot have arrays of generics in java.
private static final DelayQueue<ItemQueue> producedQueue = new DelayQueue<>();
public static volatile long[] messageCount = new long[DispatchChannel.values().length];
// Class variables
public static LongAdder[] dispatchCount = new LongAdder[DispatchChannel.values().length];
// Performance metrics
public static volatile long[] maxRecipients = new long[DispatchChannel.values().length];
public static LongAdder dispatchPoolSize = new LongAdder();
public static HashSet<ProducedItem> FailedItems = new HashSet<>();
public Thread itemProductionThread = null;
private ItemQueue itemQueue;
private long nextFailedItemAudit;
// Thread constructor
public static void send(ItemQueue item) {
// Don't queue up empty dispatches!
if (item == null)
return;
producedQueue.add(item);
}
public static String getNetstatString() {
String outString = null;
String newLine = System.getProperty("line.separator");
outString = "[LUA_NETSTA()]" + newLine;
outString += "poolSize: " + dispatchPoolSize.longValue() + '\n';
for (DispatchChannel dispatchChannel : DispatchChannel.values()) {
outString += "Channel: " + dispatchChannel.name() + '\n';
outString += "Dispatches: " + dispatchCount[dispatchChannel.getChannelID()].longValue() + '\n';
outString += "Messages: " + messageCount[dispatchChannel.getChannelID()] + '\n';
outString += "maxRecipients: " + maxRecipients[dispatchChannel.getChannelID()] + '\n';
}
return outString;
}
public void startMessagePump() {
itemProductionThread = new Thread(this);
itemProductionThread.setName("ItemProductionManager");
}
public void initialize() {
itemProductionThread.start();
}
@Override
public void run() {
while (true) {
try {
this.itemQueue = producedQueue.take();
if (this.itemQueue == null) {
return;
}
if (this.itemQueue != null) {
if (this.itemQueue.item == null) {
this.itemQueue.release();
return;
}
boolean created = this.itemQueue.item.finishProduction();
if (!created)
FailedItems.add(this.itemQueue.item);
this.itemQueue.release();
}
} catch (Exception e) {
Logger.error(e);
}
}
}
// For Debugging:
//Logger.error("MessageDispatcher", messageDispatch.msg.getOpcodeAsString() + " sent to " + messageDispatch.playerList.size() + " players");
}
-86
View File
@@ -1,86 +0,0 @@
// ·. · · · · .
// · ·
// · ·
//
// · · ·
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
package engine.net;
import engine.objects.ProducedItem;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;
import static engine.net.MessageDispatcher.itemPoolSize;
/**
* Data class holds a message and a distribution list
*/
public class ItemQueue implements Delayed {
private static final ConcurrentLinkedQueue<ItemQueue> itemPool = new ConcurrentLinkedQueue<>();
public ProducedItem item;
public long delayTime;
public ItemQueue(ProducedItem item, long delayTime) {
this.item = item;
this.delayTime = System.currentTimeMillis() + delayTime;
}
public static ItemQueue borrow(ProducedItem item, long delayTime) {
ItemQueue itemQueue;
itemQueue = itemPool.poll();
if (itemQueue == null) {
itemQueue = new ItemQueue(item, delayTime);
} else {
itemQueue.item = item;
itemQueue.delayTime = System.currentTimeMillis() + delayTime;
itemPoolSize.decrement();
}
return itemQueue;
}
public void reset() {
this.item = null;
this.delayTime = 0;
}
public void release() {
this.reset();
itemPool.add(this);
itemPoolSize.increment();
}
@Override
public int compareTo(Delayed another) {
ItemQueue anotherTask = (ItemQueue) another;
if (this.delayTime < anotherTask.delayTime) {
return -1;
}
if (this.delayTime > anotherTask.delayTime) {
return 1;
}
return 0;
}
@Override
public long getDelay(TimeUnit unit) {
long difference = delayTime - System.currentTimeMillis();
return unit.convert(difference, TimeUnit.MILLISECONDS);
}
}
+49 -51
View File
@@ -9,6 +9,7 @@
package engine.net; package engine.net;
import engine.gameManager.DispatchManager;
import engine.mbEnums.DispatchChannel; import engine.mbEnums.DispatchChannel;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
@@ -17,36 +18,32 @@ import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.LongAdder; import java.util.concurrent.atomic.LongAdder;
import java.util.regex.Pattern; import java.util.regex.Pattern;
/** // MB Dev Notes:
* Thread blocks until MagicBane dispatch messages are // All outgoing Protocol messages to the player are managed through the MessageDispatcher.class.
* enqueued then processes them in FIFO order. The collection // All incoming Protocol messages from the player are managed by the Protocol.class.
* is thread safe. //
* <p> // A Dispatch is configured wrapping a Protocol message and a distribution list is built.
* Any large messages not time sensitive such as load object //
* sent to more than a single individual should be spawned // The system interleaves dispatches between two channels. This is to ensure that
* individually on a DispatchMessageThread. // a critical combat or movement message will not be delayed by spam clicking a larger
*/ // message with no temporal immediacy. Pick the correct channel will this in mind.
public class MessageDispatcher implements Runnable { public class MessageDispatcher implements Runnable {
// Instance variables // Class variables
@SuppressWarnings("unchecked") // Cannot have arrays of generics in java.
private static final ConcurrentLinkedQueue<Dispatch>[] _messageQueue = new ConcurrentLinkedQueue[DispatchChannel.values().length]; private static final ConcurrentLinkedQueue<Dispatch>[] _messageQueue = new ConcurrentLinkedQueue[DispatchChannel.values().length];
private static final LinkedBlockingQueue<Boolean> _blockingQueue = new LinkedBlockingQueue<>(); private static final LinkedBlockingQueue<Boolean> _blockingQueue = new LinkedBlockingQueue<>();
// Class variables
public static volatile long[] messageCount = new long[DispatchChannel.values().length]; public static volatile long[] messageCount = new long[DispatchChannel.values().length];
public static LongAdder[] dispatchCount = new LongAdder[DispatchChannel.values().length]; public static LongAdder[] dispatchCount = new LongAdder[DispatchChannel.values().length];
// Performance metrics // Performance metrics
public static volatile long[] maxRecipients = new long[DispatchChannel.values().length]; public static volatile long[] maxRecipients = new long[DispatchChannel.values().length];
public static LongAdder itemPoolSize = new LongAdder(); public static LongAdder itemPoolSize = new LongAdder();
private final Pattern filterPattern; // Unused, but just in case private final Pattern filterPattern; // Unused, but just in case
private Dispatch messageDispatch; private Dispatch messageDispatch;
// Thread constructor
public MessageDispatcher() { public MessageDispatcher() {
// Create new FIFO queues for this network thread // Create new FIFO queues for this network thread
@@ -61,39 +58,6 @@ public class MessageDispatcher implements Runnable {
} }
public static void send(Dispatch messageDispatch, DispatchChannel dispatchChannel) {
// Don't queue up empty dispatches!
if (messageDispatch.player == null)
return;
_messageQueue[dispatchChannel.getChannelID()].add(messageDispatch);
_blockingQueue.add(true);
// Update performance metrics
messageCount[dispatchChannel.getChannelID()]++;
}
public static String getNetstatString() {
String outString = null;
String newLine = System.getProperty("line.separator");
outString = "[LUA_NETSTA()]" + newLine;
outString += "poolSize: " + itemPoolSize.longValue() + '\n';
for (DispatchChannel dispatchChannel : DispatchChannel.values()) {
outString += "Channel: " + dispatchChannel.name() + '\n';
outString += "Dispatches: " + dispatchCount[dispatchChannel.getChannelID()].longValue() + '\n';
outString += "Messages: " + messageCount[dispatchChannel.getChannelID()] + '\n';
outString += "maxRecipients: " + maxRecipients[dispatchChannel.getChannelID()] + '\n';
}
return outString;
}
@Override @Override
public void run() { public void run() {
@@ -109,15 +73,13 @@ public class MessageDispatcher implements Runnable {
this.messageDispatch = _messageQueue[dispatchChannel.getChannelID()].poll(); this.messageDispatch = _messageQueue[dispatchChannel.getChannelID()].poll();
if (this.messageDispatch != null) { if (this.messageDispatch != null) {
DispatchMessage.serializeDispatch(this.messageDispatch); DispatchManager.serializeDispatch(this.messageDispatch);
shouldBlock = false; shouldBlock = false;
} }
} }
if (shouldBlock == true) if (shouldBlock == true)
shouldBlock = _blockingQueue.take(); shouldBlock = _blockingQueue.take();
} catch (Exception e) { } catch (Exception e) {
Logger.error(e); Logger.error(e);
} }
@@ -125,6 +87,42 @@ public class MessageDispatcher implements Runnable {
} }
} }
public static void send(Dispatch messageDispatch, DispatchChannel dispatchChannel) {
// Use Dispatch.borrow() for a new dispatch.
// The Dispatch will be released by the system
// once delivered.
// Don't queue up empty dispatches!
if (messageDispatch.player == null)
return;
_messageQueue[dispatchChannel.getChannelID()].add(messageDispatch);
_blockingQueue.add(true);
// Update performance metrics
messageCount[dispatchChannel.getChannelID()]++;
}
public static String getNetstatString() {
String outString;
String newLine = System.getProperty("line.separator");
outString = "[LUA_NETSTA()]" + newLine;
outString += "poolSize: " + itemPoolSize.longValue() + '\n';
for (DispatchChannel dispatchChannel : DispatchChannel.values()) {
outString += "Channel: " + dispatchChannel.name() + '\n';
outString += "Dispatches: " + dispatchCount[dispatchChannel.getChannelID()].longValue() + '\n';
outString += "Messages: " + messageCount[dispatchChannel.getChannelID()] + '\n';
outString += "maxRecipients: " + maxRecipients[dispatchChannel.getChannelID()] + '\n';
}
return outString;
}
// For Debugging: // For Debugging:
//Logger.error("MessageDispatcher", messageDispatch.msg.getOpcodeAsString() + " sent to " + messageDispatch.playerList.size() + " players"); //Logger.error("MessageDispatcher", messageDispatch.msg.getOpcodeAsString() + " sent to " + messageDispatch.playerList.size() + " players");
} }
-1
View File
@@ -12,7 +12,6 @@ package engine.net;
import engine.exception.FactoryBuildException; import engine.exception.FactoryBuildException;
import engine.gameManager.ChatManager; import engine.gameManager.ChatManager;
import engine.net.client.ClientConnection; import engine.net.client.ClientConnection;
import engine.net.client.Protocol;
import engine.objects.PlayerCharacter; import engine.objects.PlayerCharacter;
import engine.server.MBServerStatics; import engine.server.MBServerStatics;
import org.joda.time.DateTime; import org.joda.time.DateTime;
-2
View File
@@ -9,8 +9,6 @@
package engine.net; package engine.net;
import engine.net.client.Protocol;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicLong;
@@ -1,11 +1,13 @@
package engine.net.client; // ·. · · · · .
// · ·
// · ·
//
// · · ·
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
package engine.net;
/* This class defines Magicbane's application network protocol.
--> Name / Opcode / Message / Handler
*/
import engine.net.AbstractConnection;
import engine.net.ByteBufferReader;
import engine.net.client.handlers.*; import engine.net.client.handlers.*;
import engine.net.client.msg.*; import engine.net.client.msg.*;
import engine.net.client.msg.chat.*; import engine.net.client.msg.chat.*;
@@ -18,6 +20,13 @@ import org.pmw.tinylog.Logger;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.util.HashMap; import java.util.HashMap;
// MB Dev Notes:
// This class defines the application network protocol used by SB.
// --> Name / Opcode / Message / Handler
//
// All incoming Protocol messages from the player are managed by the Protocol.class.
// All outgoing Protocol messages to the player are managed through the MessageDispatcher.class.
public enum Protocol { public enum Protocol {
NONE(0x0, null, null), NONE(0x0, null, null),
@@ -288,9 +297,7 @@ public enum Protocol {
public static boolean handleClientMsg(ClientNetMsg msg) { public static boolean handleClientMsg(ClientNetMsg msg) {
// Main message handler for Magicbane. All messages // Process incoming Protocol message from client.
// incoming from the client are executed here for
// both the login and world servers.
if (msg == null) if (msg == null)
return false; return false;
@@ -342,7 +349,6 @@ public enum Protocol {
} }
} }
public static int FindNextValidOpcode(ByteBufferReader reader) { public static int FindNextValidOpcode(ByteBufferReader reader) {
int startPos = reader.position(); int startPos = reader.position();
int bytesLeft = reader.remaining(); int bytesLeft = reader.remaining();
@@ -17,6 +17,7 @@ import engine.mbEnums;
import engine.net.AbstractConnection; import engine.net.AbstractConnection;
import engine.net.AbstractNetMsg; import engine.net.AbstractNetMsg;
import engine.net.Network; import engine.net.Network;
import engine.net.Protocol;
import engine.net.client.msg.ClientNetMsg; import engine.net.client.msg.ClientNetMsg;
import engine.net.client.msg.login.LoginErrorMsg; import engine.net.client.msg.login.LoginErrorMsg;
import engine.objects.Account; import engine.objects.Account;
@@ -1,6 +1,5 @@
package engine.net.client.handlers; package engine.net.client.handlers;
import engine.exception.MsgSendException;
import engine.gameManager.*; import engine.gameManager.*;
import engine.mbEnums; import engine.mbEnums;
import engine.mbEnums.BuildingGroup; import engine.mbEnums.BuildingGroup;
@@ -22,7 +21,7 @@ public class AbandonAssetMsgHandler extends AbstractClientMsgHandler {
// Instance variables // Instance variables
public AbandonAssetMsgHandler() { public AbandonAssetMsgHandler() {
super(AbandonAssetMsg.class); super();
} }
@@ -48,7 +47,7 @@ public class AbandonAssetMsgHandler extends AbstractClientMsgHandler {
} }
@Override @Override
protected boolean _handleNetMsg(ClientNetMsg baseMsg, ClientConnection origin) throws MsgSendException { protected boolean _handleNetMsg(ClientNetMsg baseMsg, ClientConnection origin) {
// Member variable declaration // Member variable declaration
PlayerCharacter player; PlayerCharacter player;
@@ -8,10 +8,9 @@
package engine.net.client.handlers; package engine.net.client.handlers;
import engine.exception.MsgSendException;
import engine.gameManager.ChatManager; import engine.gameManager.ChatManager;
import engine.net.Protocol;
import engine.net.client.ClientConnection; import engine.net.client.ClientConnection;
import engine.net.client.Protocol;
import engine.net.client.msg.ClientNetMsg; import engine.net.client.msg.ClientNetMsg;
import engine.net.client.msg.chat.*; import engine.net.client.msg.chat.*;
import engine.objects.PlayerCharacter; import engine.objects.PlayerCharacter;
@@ -22,11 +21,11 @@ import static engine.gameManager.ChatManager.FLOOD_TIME_THRESHOLD;
public class AbstractChatMsgHandler extends AbstractClientMsgHandler { public class AbstractChatMsgHandler extends AbstractClientMsgHandler {
public AbstractChatMsgHandler() { public AbstractChatMsgHandler() {
super(AbstractChatMsg.class); super();
} }
@Override @Override
protected boolean _handleNetMsg(ClientNetMsg baseMsg, ClientConnection origin) throws MsgSendException { protected boolean _handleNetMsg(ClientNetMsg baseMsg, ClientConnection origin) {
PlayerCharacter playerCharacter = origin.getPlayerCharacter(); PlayerCharacter playerCharacter = origin.getPlayerCharacter();
@@ -1,6 +1,5 @@
package engine.net.client.handlers; package engine.net.client.handlers;
import engine.exception.MsgSendException;
import engine.net.client.ClientConnection; import engine.net.client.ClientConnection;
import engine.net.client.msg.ClientNetMsg; import engine.net.client.msg.ClientNetMsg;
@@ -10,10 +9,8 @@ import engine.net.client.msg.ClientNetMsg;
*/ */
public abstract class AbstractClientMsgHandler { public abstract class AbstractClientMsgHandler {
private final Class<? extends ClientNetMsg> handler;
public AbstractClientMsgHandler(Class<? extends ClientNetMsg> handler) { public AbstractClientMsgHandler() {
this.handler = handler;
} }
public boolean handleNetMsg(ClientNetMsg msg) { public boolean handleNetMsg(ClientNetMsg msg) {
@@ -22,7 +19,7 @@ public abstract class AbstractClientMsgHandler {
try { try {
executionSucceded = _handleNetMsg(msg, (ClientConnection) msg.getOrigin()); executionSucceded = _handleNetMsg(msg, (ClientConnection) msg.getOrigin());
} catch (MsgSendException e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
executionSucceded = false; executionSucceded = false;
} }
@@ -30,5 +27,5 @@ public abstract class AbstractClientMsgHandler {
return executionSucceded; return executionSucceded;
} }
protected abstract boolean _handleNetMsg(ClientNetMsg msg, ClientConnection origin) throws MsgSendException; protected abstract boolean _handleNetMsg(ClientNetMsg msg, ClientConnection origin);
} }
@@ -9,16 +9,11 @@
package engine.net.client.handlers; package engine.net.client.handlers;
import engine.exception.MsgSendException; import engine.gameManager.*;
import engine.gameManager.ChatManager;
import engine.gameManager.DbManager;
import engine.gameManager.GuildManager;
import engine.gameManager.SessionManager;
import engine.mbEnums; import engine.mbEnums;
import engine.mbEnums.GameObjectType; import engine.mbEnums.GameObjectType;
import engine.mbEnums.GuildHistoryType; import engine.mbEnums.GuildHistoryType;
import engine.net.Dispatch; import engine.net.Dispatch;
import engine.net.DispatchMessage;
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.ErrorPopupMsg; import engine.net.client.msg.ErrorPopupMsg;
@@ -32,11 +27,11 @@ import org.joda.time.DateTime;
public class AcceptInviteToGuildHandler extends AbstractClientMsgHandler { public class AcceptInviteToGuildHandler extends AbstractClientMsgHandler {
public AcceptInviteToGuildHandler() { public AcceptInviteToGuildHandler() {
super(AcceptInviteToGuildMsg.class); super();
} }
@Override @Override
protected boolean _handleNetMsg(ClientNetMsg baseMsg, ClientConnection origin) throws MsgSendException { protected boolean _handleNetMsg(ClientNetMsg baseMsg, ClientConnection origin) {
PlayerCharacter player; PlayerCharacter player;
AcceptInviteToGuildMsg msg; AcceptInviteToGuildMsg msg;
@@ -86,9 +81,9 @@ public class AcceptInviteToGuildHandler extends AbstractClientMsgHandler {
player.resetGuildStatuses(); player.resetGuildStatuses();
Dispatch dispatch = Dispatch.borrow(player, msg); Dispatch dispatch = Dispatch.borrow(player, msg);
DispatchMessage.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY); DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY);
DispatchMessage.sendToAllInRange(player, new GuildInfoMsg(player, guild, 2)); DispatchManager.sendToAllInRange(player, new GuildInfoMsg(player, guild, 2));
player.incVer(); player.incVer();
@@ -9,15 +9,14 @@
package engine.net.client.handlers; package engine.net.client.handlers;
import engine.exception.MsgSendException;
import engine.gameManager.ChatManager; import engine.gameManager.ChatManager;
import engine.gameManager.DbManager; import engine.gameManager.DbManager;
import engine.gameManager.DispatchManager;
import engine.gameManager.SessionManager; import engine.gameManager.SessionManager;
import engine.mbEnums; import engine.mbEnums;
import engine.mbEnums.GameObjectType; import engine.mbEnums.GameObjectType;
import engine.mbEnums.GuildState; import engine.mbEnums.GuildState;
import engine.net.Dispatch; import engine.net.Dispatch;
import engine.net.DispatchMessage;
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.ErrorPopupMsg; import engine.net.client.msg.ErrorPopupMsg;
@@ -31,11 +30,11 @@ import java.util.ArrayList;
public class AcceptSubInviteHandler extends AbstractClientMsgHandler { public class AcceptSubInviteHandler extends AbstractClientMsgHandler {
public AcceptSubInviteHandler() { public AcceptSubInviteHandler() {
super(AcceptSubInviteMsg.class); super();
} }
@Override @Override
protected boolean _handleNetMsg(ClientNetMsg baseMsg, ClientConnection origin) throws MsgSendException { protected boolean _handleNetMsg(ClientNetMsg baseMsg, ClientConnection origin) {
AcceptSubInviteMsg msg = (AcceptSubInviteMsg) baseMsg; AcceptSubInviteMsg msg = (AcceptSubInviteMsg) baseMsg;
PlayerCharacter sourcePlayer; PlayerCharacter sourcePlayer;
@@ -98,7 +97,7 @@ public class AcceptSubInviteHandler extends AbstractClientMsgHandler {
msg.setUnknown02(1); msg.setUnknown02(1);
msg.setResponse("Your guild is now a " + sourceGuild.getGuildState().name() + '.'); msg.setResponse("Your guild is now a " + sourceGuild.getGuildState().name() + '.');
dispatch = Dispatch.borrow(sourcePlayer, msg); dispatch = Dispatch.borrow(sourcePlayer, msg);
DispatchMessage.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY); DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY);
ChatManager.chatSystemInfo(sourcePlayer, "Your guild is now a " + sourceGuild.getGuildState().name() + '.'); ChatManager.chatSystemInfo(sourcePlayer, "Your guild is now a " + sourceGuild.getGuildState().name() + '.');
return true; return true;
@@ -8,10 +8,9 @@
package engine.net.client.handlers; package engine.net.client.handlers;
import engine.exception.MsgSendException; import engine.gameManager.DispatchManager;
import engine.mbEnums; import engine.mbEnums;
import engine.net.Dispatch; import engine.net.Dispatch;
import engine.net.DispatchMessage;
import engine.net.client.ClientConnection; import engine.net.client.ClientConnection;
import engine.net.client.msg.AcceptTradeRequestMsg; import engine.net.client.msg.AcceptTradeRequestMsg;
import engine.net.client.msg.ClientNetMsg; import engine.net.client.msg.ClientNetMsg;
@@ -28,11 +27,11 @@ import static engine.objects.CharacterItemManager.canTrade;
public class AcceptTradeRequestMsgHandler extends AbstractClientMsgHandler { public class AcceptTradeRequestMsgHandler extends AbstractClientMsgHandler {
public AcceptTradeRequestMsgHandler() { public AcceptTradeRequestMsgHandler() {
super(AcceptTradeRequestMsg.class); super();
} }
@Override @Override
protected boolean _handleNetMsg(ClientNetMsg baseMsg, ClientConnection origin) throws MsgSendException { protected boolean _handleNetMsg(ClientNetMsg baseMsg, ClientConnection origin) {
// Member variable declaration // Member variable declaration
@@ -92,10 +91,10 @@ public class AcceptTradeRequestMsgHandler extends AbstractClientMsgHandler {
UpdateVaultMsg uvmTarget = new UpdateVaultMsg(targetAccount); UpdateVaultMsg uvmTarget = new UpdateVaultMsg(targetAccount);
dispatch = Dispatch.borrow(source, uvmSource); dispatch = Dispatch.borrow(source, uvmSource);
DispatchMessage.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.PRIMARY); DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.PRIMARY);
dispatch = Dispatch.borrow(target, uvmTarget); dispatch = Dispatch.borrow(target, uvmTarget);
DispatchMessage.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.PRIMARY); DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.PRIMARY);
source.charItemManager.setVaultOpen(false); source.charItemManager.setVaultOpen(false);
toTradeWith.setVaultOpen(false); toTradeWith.setVaultOpen(false);
@@ -118,10 +117,10 @@ public class AcceptTradeRequestMsgHandler extends AbstractClientMsgHandler {
toTradeWith.tradeID = msg.getUnknown01(); toTradeWith.tradeID = msg.getUnknown01();
dispatch = Dispatch.borrow(source, otwm); dispatch = Dispatch.borrow(source, otwm);
DispatchMessage.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.PRIMARY); DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.PRIMARY);
dispatch = Dispatch.borrow(target, otwm); dispatch = Dispatch.borrow(target, otwm);
DispatchMessage.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.PRIMARY); DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.PRIMARY);
return true; return true;
} }
@@ -1,11 +1,9 @@
package engine.net.client.handlers; package engine.net.client.handlers;
import engine.exception.MsgSendException;
import engine.gameManager.*; import engine.gameManager.*;
import engine.mbEnums; import engine.mbEnums;
import engine.mbEnums.ItemType; import engine.mbEnums.ItemType;
import engine.net.Dispatch; import engine.net.Dispatch;
import engine.net.DispatchMessage;
import engine.net.client.ClientConnection; import engine.net.client.ClientConnection;
import engine.net.client.msg.ActivateNPCMessage; import engine.net.client.msg.ActivateNPCMessage;
import engine.net.client.msg.ClientNetMsg; import engine.net.client.msg.ClientNetMsg;
@@ -23,11 +21,11 @@ import java.util.ArrayList;
public class ActivateNPCMsgHandler extends AbstractClientMsgHandler { public class ActivateNPCMsgHandler extends AbstractClientMsgHandler {
public ActivateNPCMsgHandler() { public ActivateNPCMsgHandler() {
super(ActivateNPCMessage.class); super();
} }
@Override @Override
protected boolean _handleNetMsg(ClientNetMsg baseMsg, ClientConnection origin) throws MsgSendException { protected boolean _handleNetMsg(ClientNetMsg baseMsg, ClientConnection origin) {
ActivateNPCMessage msg; ActivateNPCMessage msg;
PlayerCharacter player; PlayerCharacter player;
@@ -66,7 +64,7 @@ public class ActivateNPCMsgHandler extends AbstractClientMsgHandler {
anm.setSize(ItemLists.size()); anm.setSize(ItemLists.size());
anm.setItemList(ItemLists); anm.setItemList(ItemLists);
Dispatch dispatch = Dispatch.borrow(player, anm); Dispatch dispatch = Dispatch.borrow(player, anm);
DispatchMessage.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY); DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY);
} }
if (msg.getUnknown01() == 0) { if (msg.getUnknown01() == 0) {
@@ -125,7 +123,7 @@ public class ActivateNPCMsgHandler 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(player, mca1);
DispatchMessage.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY); DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY);
} }
@@ -8,10 +8,9 @@
package engine.net.client.handlers; package engine.net.client.handlers;
import engine.exception.MsgSendException; import engine.gameManager.DispatchManager;
import engine.mbEnums; import engine.mbEnums;
import engine.net.Dispatch; import engine.net.Dispatch;
import engine.net.DispatchMessage;
import engine.net.client.ClientConnection; import engine.net.client.ClientConnection;
import engine.net.client.msg.AddGoldToTradeWindowMsg; import engine.net.client.msg.AddGoldToTradeWindowMsg;
import engine.net.client.msg.ClientNetMsg; import engine.net.client.msg.ClientNetMsg;
@@ -27,11 +26,11 @@ import static engine.objects.CharacterItemManager.canTrade;
public class AddGoldToTradeWindowMsgHandler extends AbstractClientMsgHandler { public class AddGoldToTradeWindowMsgHandler extends AbstractClientMsgHandler {
public AddGoldToTradeWindowMsgHandler() { public AddGoldToTradeWindowMsgHandler() {
super(AddGoldToTradeWindowMsg.class); super();
} }
@Override @Override
protected boolean _handleNetMsg(ClientNetMsg baseMsg, ClientConnection origin) throws MsgSendException { protected boolean _handleNetMsg(ClientNetMsg baseMsg, ClientConnection origin) {
PlayerCharacter source = origin.getPlayerCharacter(); PlayerCharacter source = origin.getPlayerCharacter();
@@ -95,13 +94,13 @@ public class AddGoldToTradeWindowMsgHandler extends AbstractClientMsgHandler {
source.charItemManager.modifyCommitToTrade(); source.charItemManager.modifyCommitToTrade();
dispatch = Dispatch.borrow(source, utwm); dispatch = Dispatch.borrow(source, utwm);
DispatchMessage.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY); DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY);
dispatch = Dispatch.borrow(source, ugm); dispatch = Dispatch.borrow(source, ugm);
DispatchMessage.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY); DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY);
dispatch = Dispatch.borrow(other, utwmOther); dispatch = Dispatch.borrow(other, utwmOther);
DispatchMessage.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY); DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY);
return true; return true;
} }
@@ -8,10 +8,9 @@
package engine.net.client.handlers; package engine.net.client.handlers;
import engine.exception.MsgSendException; import engine.gameManager.DispatchManager;
import engine.mbEnums; import engine.mbEnums;
import engine.net.Dispatch; import engine.net.Dispatch;
import engine.net.DispatchMessage;
import engine.net.client.ClientConnection; import engine.net.client.ClientConnection;
import engine.net.client.msg.AddItemToTradeWindowMsg; import engine.net.client.msg.AddItemToTradeWindowMsg;
import engine.net.client.msg.ClientNetMsg; import engine.net.client.msg.ClientNetMsg;
@@ -25,11 +24,11 @@ import static engine.objects.CharacterItemManager.canTrade;
public class AddItemToTradeWindowMsgHandler extends AbstractClientMsgHandler { public class AddItemToTradeWindowMsgHandler extends AbstractClientMsgHandler {
public AddItemToTradeWindowMsgHandler() { public AddItemToTradeWindowMsgHandler() {
super(AddItemToTradeWindowMsg.class); super();
} }
@Override @Override
protected boolean _handleNetMsg(ClientNetMsg baseMsg, ClientConnection origin) throws MsgSendException { protected boolean _handleNetMsg(ClientNetMsg baseMsg, ClientConnection origin) {
// Member variable declaration // Member variable declaration
@@ -81,7 +80,7 @@ public class AddItemToTradeWindowMsgHandler extends AbstractClientMsgHandler {
if (!tradingWith.hasRoomTrade(item.template.item_wt)) { if (!tradingWith.hasRoomTrade(item.template.item_wt)) {
dispatch = Dispatch.borrow(source, msg); dispatch = Dispatch.borrow(source, msg);
DispatchMessage.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.PRIMARY); DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.PRIMARY);
return false; return false;
} }
@@ -93,12 +92,12 @@ public class AddItemToTradeWindowMsgHandler extends AbstractClientMsgHandler {
source.charItemManager.addItemToTrade(item); source.charItemManager.addItemToTrade(item);
dispatch = Dispatch.borrow(other, msg); dispatch = Dispatch.borrow(other, msg);
DispatchMessage.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.PRIMARY); DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.PRIMARY);
source.charItemManager.modifyCommitToTrade(); source.charItemManager.modifyCommitToTrade();
dispatch = Dispatch.borrow(other, utwm); dispatch = Dispatch.borrow(other, utwm);
DispatchMessage.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.PRIMARY); DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.PRIMARY);
return true; return true;
} }
@@ -1,11 +1,10 @@
package engine.net.client.handlers; package engine.net.client.handlers;
import engine.exception.MsgSendException; import engine.gameManager.DispatchManager;
import engine.gameManager.SessionManager; import engine.gameManager.SessionManager;
import engine.mbEnums; import engine.mbEnums;
import engine.mbEnums.AllianceType; import engine.mbEnums.AllianceType;
import engine.net.Dispatch; import engine.net.Dispatch;
import engine.net.DispatchMessage;
import engine.net.client.ClientConnection; import engine.net.client.ClientConnection;
import engine.net.client.msg.AllianceChangeMsg; import engine.net.client.msg.AllianceChangeMsg;
import engine.net.client.msg.ClientNetMsg; import engine.net.client.msg.ClientNetMsg;
@@ -21,7 +20,7 @@ import engine.objects.PlayerCharacter;
public class AllianceChangeMsgHandler extends AbstractClientMsgHandler { public class AllianceChangeMsgHandler extends AbstractClientMsgHandler {
public AllianceChangeMsgHandler() { public AllianceChangeMsgHandler() {
super(AllianceChangeMsg.class); super();
} }
private static void MakeEnemy(Guild fromGuild, Guild toGuild, AllianceChangeMsg msg, ClientConnection origin) { private static void MakeEnemy(Guild fromGuild, Guild toGuild, AllianceChangeMsg msg, ClientConnection origin) {
@@ -40,20 +39,20 @@ public class AllianceChangeMsgHandler extends AbstractClientMsgHandler {
if (!Guild.sameGuild(origin.getPlayerCharacter().getGuild(), fromGuild)) { if (!Guild.sameGuild(origin.getPlayerCharacter().getGuild(), fromGuild)) {
msg.setMsgType(AllianceChangeMsg.ERROR_NOT_SAME_GUILD); msg.setMsgType(AllianceChangeMsg.ERROR_NOT_SAME_GUILD);
dispatch = Dispatch.borrow(origin.getPlayerCharacter(), msg); dispatch = Dispatch.borrow(origin.getPlayerCharacter(), msg);
DispatchMessage.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY); DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY);
return; return;
} }
if (!GuildStatusController.isInnerCouncil(origin.getPlayerCharacter().getGuildStatus()) && !GuildStatusController.isGuildLeader(origin.getPlayerCharacter().getGuildStatus())) { if (!GuildStatusController.isInnerCouncil(origin.getPlayerCharacter().getGuildStatus()) && !GuildStatusController.isGuildLeader(origin.getPlayerCharacter().getGuildStatus())) {
msg.setMsgType(AllianceChangeMsg.ERROR_NOT_AUTHORIZED); msg.setMsgType(AllianceChangeMsg.ERROR_NOT_AUTHORIZED);
dispatch = Dispatch.borrow(origin.getPlayerCharacter(), msg); dispatch = Dispatch.borrow(origin.getPlayerCharacter(), msg);
DispatchMessage.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY); DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY);
return; return;
} }
dispatch = Dispatch.borrow(origin.getPlayerCharacter(), msg); dispatch = Dispatch.borrow(origin.getPlayerCharacter(), msg);
DispatchMessage.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY); DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY);
} }
@@ -72,7 +71,7 @@ public class AllianceChangeMsgHandler extends AbstractClientMsgHandler {
return; return;
dispatch = Dispatch.borrow(origin.getPlayerCharacter(), msg); dispatch = Dispatch.borrow(origin.getPlayerCharacter(), msg);
DispatchMessage.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY); DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY);
} }
@@ -91,13 +90,13 @@ public class AllianceChangeMsgHandler extends AbstractClientMsgHandler {
return; return;
dispatch = Dispatch.borrow(origin.getPlayerCharacter(), msg); dispatch = Dispatch.borrow(origin.getPlayerCharacter(), msg);
DispatchMessage.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY); DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY);
} }
@Override @Override
protected boolean _handleNetMsg(ClientNetMsg baseMsg, ClientConnection origin) throws MsgSendException { protected boolean _handleNetMsg(ClientNetMsg baseMsg, ClientConnection origin) {
// Member variable declaration // Member variable declaration
@@ -142,7 +141,7 @@ public class AllianceChangeMsgHandler extends AbstractClientMsgHandler {
} }
msg.setMsgType(AllianceChangeMsg.INFO_SUCCESS); msg.setMsgType(AllianceChangeMsg.INFO_SUCCESS);
Dispatch dispatch = Dispatch.borrow(player, msg); Dispatch dispatch = Dispatch.borrow(player, msg);
DispatchMessage.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY); DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY);
return true; return true;
@@ -1,10 +1,9 @@
package engine.net.client.handlers; package engine.net.client.handlers;
import engine.exception.MsgSendException; import engine.gameManager.DispatchManager;
import engine.gameManager.SessionManager; import engine.gameManager.SessionManager;
import engine.mbEnums; import engine.mbEnums;
import engine.net.Dispatch; import engine.net.Dispatch;
import engine.net.DispatchMessage;
import engine.net.client.ClientConnection; import engine.net.client.ClientConnection;
import engine.net.client.msg.AllyEnemyListMsg; import engine.net.client.msg.AllyEnemyListMsg;
import engine.net.client.msg.ClientNetMsg; import engine.net.client.msg.ClientNetMsg;
@@ -19,7 +18,7 @@ import engine.objects.PlayerCharacter;
public class AllyEnemyListMsgHandler extends AbstractClientMsgHandler { public class AllyEnemyListMsgHandler extends AbstractClientMsgHandler {
public AllyEnemyListMsgHandler() { public AllyEnemyListMsgHandler() {
super(AllyEnemyListMsg.class); super();
} }
private static void showAllyEnemyList(Guild fromGuild, Guild toGuild, AllyEnemyListMsg msg, ClientConnection origin) { private static void showAllyEnemyList(Guild fromGuild, Guild toGuild, AllyEnemyListMsg msg, ClientConnection origin) {
@@ -35,7 +34,7 @@ public class AllyEnemyListMsgHandler extends AbstractClientMsgHandler {
if (toGuild == null) if (toGuild == null)
return; return;
dispatch = Dispatch.borrow(origin.getPlayerCharacter(), msg); dispatch = Dispatch.borrow(origin.getPlayerCharacter(), msg);
DispatchMessage.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY); DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY);
// UpdateClientAlliancesMsg ucam = new UpdateClientAlliancesMsg(); // UpdateClientAlliancesMsg ucam = new UpdateClientAlliancesMsg();
// //
@@ -46,7 +45,7 @@ public class AllyEnemyListMsgHandler extends AbstractClientMsgHandler {
} }
@Override @Override
protected boolean _handleNetMsg(ClientNetMsg baseMsg, ClientConnection origin) throws MsgSendException { protected boolean _handleNetMsg(ClientNetMsg baseMsg, ClientConnection origin) {
// Member variable declaration // Member variable declaration
@@ -9,13 +9,12 @@
package engine.net.client.handlers; package engine.net.client.handlers;
import engine.exception.MsgSendException;
import engine.gameManager.ChatManager; import engine.gameManager.ChatManager;
import engine.gameManager.DispatchManager;
import engine.gameManager.GroupManager; import engine.gameManager.GroupManager;
import engine.gameManager.SessionManager; import engine.gameManager.SessionManager;
import engine.mbEnums; import engine.mbEnums;
import engine.net.Dispatch; import engine.net.Dispatch;
import engine.net.DispatchMessage;
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.group.AppointGroupLeaderMsg; import engine.net.client.msg.group.AppointGroupLeaderMsg;
@@ -26,11 +25,11 @@ import engine.objects.PlayerCharacter;
public class AppointGroupLeaderHandler extends AbstractClientMsgHandler { public class AppointGroupLeaderHandler extends AbstractClientMsgHandler {
public AppointGroupLeaderHandler() { public AppointGroupLeaderHandler() {
super(AppointGroupLeaderMsg.class); super();
} }
@Override @Override
protected boolean _handleNetMsg(ClientNetMsg baseMsg, ClientConnection origin) throws MsgSendException { protected boolean _handleNetMsg(ClientNetMsg baseMsg, ClientConnection origin) {
AppointGroupLeaderMsg msg = (AppointGroupLeaderMsg) baseMsg; AppointGroupLeaderMsg msg = (AppointGroupLeaderMsg) baseMsg;
PlayerCharacter source = SessionManager.getPlayerCharacter(origin); PlayerCharacter source = SessionManager.getPlayerCharacter(origin);
@@ -52,7 +51,7 @@ public class AppointGroupLeaderHandler extends AbstractClientMsgHandler {
AppointGroupLeaderMsg reply = new AppointGroupLeaderMsg(); AppointGroupLeaderMsg reply = new AppointGroupLeaderMsg();
reply.setResponse(1); reply.setResponse(1);
Dispatch dispatch = Dispatch.borrow(origin.getPlayerCharacter(), reply); Dispatch dispatch = Dispatch.borrow(origin.getPlayerCharacter(), reply);
DispatchMessage.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY); DispatchManager.dispatchMsgDispatch(dispatch, mbEnums.DispatchChannel.SECONDARY);
return false; return false;
} }
@@ -1,14 +1,11 @@
package engine.net.client.handlers; package engine.net.client.handlers;
import engine.exception.MsgSendException;
import engine.gameManager.*; import engine.gameManager.*;
import engine.job.JobScheduler; import engine.job.JobScheduler;
import engine.mbEnums; import engine.mbEnums;
import engine.mbEnums.DispatchChannel; import engine.mbEnums.DispatchChannel;
import engine.net.Dispatch; import engine.net.Dispatch;
import engine.net.DispatchMessage;
import engine.net.client.ClientConnection; import engine.net.client.ClientConnection;
import engine.net.client.msg.ArcLoginNotifyMsg;
import engine.net.client.msg.ClientNetMsg; import engine.net.client.msg.ClientNetMsg;
import engine.net.client.msg.HotzoneChangeMsg; import engine.net.client.msg.HotzoneChangeMsg;
import engine.net.client.msg.PetMsg; import engine.net.client.msg.PetMsg;
@@ -23,11 +20,11 @@ import org.pmw.tinylog.Logger;
public class ArcLoginNotifyMsgHandler extends AbstractClientMsgHandler { public class ArcLoginNotifyMsgHandler extends AbstractClientMsgHandler {
public ArcLoginNotifyMsgHandler() { public ArcLoginNotifyMsgHandler() {
super(ArcLoginNotifyMsg.class); super();
} }
@Override @Override
protected boolean _handleNetMsg(ClientNetMsg baseMsg, ClientConnection origin) throws MsgSendException { protected boolean _handleNetMsg(ClientNetMsg baseMsg, ClientConnection origin) {
PlayerCharacter player = SessionManager.getPlayerCharacter(origin); PlayerCharacter player = SessionManager.getPlayerCharacter(origin);
@@ -69,7 +66,7 @@ public class ArcLoginNotifyMsgHandler extends AbstractClientMsgHandler {
// Send branch string if available from ConfigManager. // Send branch string if available from ConfigManager.
if (ConfigManager.currentRepoBranch != "") if (!ConfigManager.currentRepoBranch.equals(""))
ChatManager.sendSystemMessage(player, ConfigManager.currentRepoBranch); ChatManager.sendSystemMessage(player, ConfigManager.currentRepoBranch);
// Set player mask for QT // Set player mask for QT
@@ -130,7 +127,7 @@ public class ArcLoginNotifyMsgHandler extends AbstractClientMsgHandler {
if (player.getPet() != null) { if (player.getPet() != null) {
PetMsg pm = new PetMsg(5, player.getPet()); PetMsg pm = new PetMsg(5, player.getPet());
Dispatch dispatch = Dispatch.borrow(player, pm); Dispatch dispatch = Dispatch.borrow(player, pm);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); DispatchManager.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
} }
//Send current hotzone //Send current hotzone
@@ -138,7 +135,7 @@ public class ArcLoginNotifyMsgHandler extends AbstractClientMsgHandler {
if (ZoneManager.hotZone != null) { if (ZoneManager.hotZone != null) {
HotzoneChangeMsg hcm = new HotzoneChangeMsg(mbEnums.GameObjectType.Zone.ordinal(), ZoneManager.hotZone.getObjectUUID()); HotzoneChangeMsg hcm = new HotzoneChangeMsg(mbEnums.GameObjectType.Zone.ordinal(), ZoneManager.hotZone.getObjectUUID());
Dispatch dispatch = Dispatch.borrow(player, hcm); Dispatch dispatch = Dispatch.borrow(player, hcm);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); DispatchManager.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
} }
if (player.getGuild() != null && !player.getGuild().isEmptyGuild()) { if (player.getGuild() != null && !player.getGuild().isEmptyGuild()) {
@@ -1,10 +1,9 @@
package engine.net.client.handlers; package engine.net.client.handlers;
import engine.exception.MsgSendException; import engine.gameManager.DispatchManager;
import engine.mbEnums; import engine.mbEnums;
import engine.mbEnums.DispatchChannel; import engine.mbEnums.DispatchChannel;
import engine.net.Dispatch; import engine.net.Dispatch;
import engine.net.DispatchMessage;
import engine.net.client.ClientConnection; import engine.net.client.ClientConnection;
import engine.net.client.msg.ArcMineChangeProductionMsg; import engine.net.client.msg.ArcMineChangeProductionMsg;
import engine.net.client.msg.ClientNetMsg; import engine.net.client.msg.ClientNetMsg;
@@ -21,11 +20,11 @@ import engine.objects.PlayerCharacter;
public class ArcMineChangeProductionMsgHandler extends AbstractClientMsgHandler { public class ArcMineChangeProductionMsgHandler extends AbstractClientMsgHandler {
public ArcMineChangeProductionMsgHandler() { public ArcMineChangeProductionMsgHandler() {
super(ArcMineChangeProductionMsg.class); super();
} }
@Override @Override
protected boolean _handleNetMsg(ClientNetMsg baseMsg, ClientConnection origin) throws MsgSendException { protected boolean _handleNetMsg(ClientNetMsg baseMsg, ClientConnection origin) {
PlayerCharacter playerCharacter = origin.getPlayerCharacter(); PlayerCharacter playerCharacter = origin.getPlayerCharacter();
ArcMineChangeProductionMsg changeProductionMsg = (ArcMineChangeProductionMsg) baseMsg; ArcMineChangeProductionMsg changeProductionMsg = (ArcMineChangeProductionMsg) baseMsg;
@@ -51,7 +50,7 @@ public class ArcMineChangeProductionMsgHandler extends AbstractClientMsgHandler
//make sure valid resource //make sure valid resource
mbEnums.ResourceType resource = mbEnums.ResourceType.hashLookup.get(changeProductionMsg.getResourceHash()); mbEnums.ResourceType resource = mbEnums.ResourceType.resourceHashLookup.get(changeProductionMsg.getResourceHash());
if (resource == null) if (resource == null)
return true; return true;
@@ -60,7 +59,7 @@ public class ArcMineChangeProductionMsgHandler extends AbstractClientMsgHandler
mine.changeProductionType(resource); mine.changeProductionType(resource);
Dispatch dispatch = Dispatch.borrow(playerCharacter, changeProductionMsg); Dispatch dispatch = Dispatch.borrow(playerCharacter, changeProductionMsg);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); DispatchManager.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
return true; return true;
} }

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