Compare commits

...
346 Commits
Author SHA1 Message Date
FatBoy 0b18afc211 player update optimized 2025-02-16 17:57:34 -06:00
FatBoy 5670da8d96 player update optimized 2025-02-16 17:52:34 -06:00
FatBoy d2d236aa93 player update optimized 2025-02-16 17:40:08 -06:00
FatBoy 9b5d32b70b mob AI aggro 2025-02-16 17:32:24 -06:00
FatBoy 8e158e1d27 mob AI aggro 2025-02-16 17:21:52 -06:00
FatBoy 8c166c8d4b mob AI aggro 2025-02-16 17:20:23 -06:00
FatBoy 3b12faee9e mob AI aggro 2025-02-16 17:17:04 -06:00
FatBoy 243403782d Revert "mob AI aggro"
This reverts commit 9e1e12b177.
2025-02-16 17:16:25 -06:00
FatBoy 9e1e12b177 mob AI aggro 2025-02-16 17:12:17 -06:00
FatBoy 1c1578595f mob AI aggro 2025-02-16 17:08:48 -06:00
FatBoy e5f47a7d73 mob AI aggro 2025-02-16 17:03:38 -06:00
FatBoy 7d80363d65 mob AI aggro 2025-02-16 16:55:15 -06:00
FatBoy 1a95bc8e27 dead players dont get XP 2025-02-16 16:45:49 -06:00
FatBoy 473003ed44 hot fix for regen 2025-02-16 16:44:31 -06:00
FatBoy fbdca5b917 xp range fix 2025-02-15 09:11:44 -06:00
FatBoy 78dfa0c68c invis mob solution 2025-02-15 07:52:39 -06:00
FatBoy a04ad2f382 break point 2025-02-15 07:23:34 -06:00
FatBoy 257a8aff15 break point 2025-02-15 07:21:07 -06:00
FatBoy 291a20c4d0 break point 2025-02-15 07:11:37 -06:00
FatBoy eec08ce962 break point 2025-02-15 07:07:27 -06:00
FatBoy 99183dc248 break point 2025-02-15 07:05:11 -06:00
FatBoy 6c7f01dc72 mobs will attack player pets 2025-02-15 06:46:17 -06:00
FatBoy 6ebeb9cadf must be in safezone to switch boxes 2025-02-15 06:44:16 -06:00
FatBoy 8e0f1090d9 fix white XP 2025-02-15 06:34:36 -06:00
FatBoy bc0bc577ea fix white XP 2025-02-15 06:32:38 -06:00
FatBoy 3b5c0e6210 must be in safezone to gain level up gold 2025-02-15 06:29:42 -06:00
FatBoy d6fa7dba9d fix XP range 2025-02-15 06:28:25 -06:00
FatBoy b5fbc8478d new Regen 2025-02-13 21:37:22 -06:00
FatBoy b79c827d81 new Regen 2025-02-13 21:25:09 -06:00
FatBoy b9b254f8e8 new Regen 2025-02-13 21:23:05 -06:00
FatBoy 6834146eb2 new Regen 2025-02-13 21:06:27 -06:00
FatBoy e9f1711120 pet assistance 2025-02-13 20:37:45 -06:00
FatBoy 29f054e192 retaliate handled properly 2025-02-13 20:32:16 -06:00
FatBoy 7d9c5d3498 huntress pets properly granted modifiers 2025-02-13 20:29:35 -06:00
FatBoy 618353c088 set mob level earlier in routine 2025-02-13 20:21:52 -06:00
FatBoy 24656b1030 expereince system rework 2025-02-13 19:16:43 -06:00
FatBoy 27cb704837 expereince system rework 2025-02-13 19:04:42 -06:00
FatBoy 6961b186a9 disable gimme command 2025-02-12 17:20:15 -06:00
FatBoy bee91a6aa7 catch weird city null error 2025-02-12 17:14:04 -06:00
FatBoy 8c5b1d56c2 proper XP group scaling 2025-02-12 17:06:44 -06:00
FatBoy f21e8c130b stam ticks 2025-02-11 20:15:45 -06:00
FatBoy 345c451ac8 stam ticks 2025-02-11 20:13:32 -06:00
FatBoy c3a7262a7f logging for failed to move item to vault or bank 2025-02-11 20:03:30 -06:00
FatBoy d1c6d9edec reveal thyself castable by all 2025-02-11 19:53:07 -06:00
FatBoy 1e865eecbc increase starting gold to 1500 2025-02-11 07:57:55 -06:00
FatBoy 5f735a49c1 mobs no longer double multiply for sitting target 2025-02-11 07:52:24 -06:00
FatBoy e609c015b9 Dwarvish Wrath added to exception list 2025-02-11 07:51:34 -06:00
FatBoy 5a198669b9 quick targeting check cleanup 2025-02-11 07:49:19 -06:00
FatBoy fe399664f3 targeting object checks only count when targeting players 2025-02-11 07:44:28 -06:00
FatBoy 3bc62e9baa 10 seconds for 7 stamina ticks in travel stance 2025-02-10 20:31:25 -06:00
FatBoy cf23266f31 10 seconds for 7 stamina ticks in travel stance 2025-02-10 20:13:19 -06:00
FatBoy b097472402 delete AI Players 2025-02-10 20:06:00 -06:00
FatBoy 57b18c2d15 AI Players as mobs 2025-02-10 19:59:45 -06:00
FatBoy 040eef576e disable AI Players 2025-02-10 19:50:55 -06:00
FatBoy d76403a0c8 Ai Players 2025-02-10 19:34:26 -06:00
FatBoy 8ce1054599 Ai Players 2025-02-10 19:25:45 -06:00
FatBoy 0daf8cfe4c Ai Players 2025-02-10 19:20:39 -06:00
FatBoy 898c4c2fa0 Ai Players 2025-02-10 19:19:55 -06:00
FatBoy ecba693105 Ai Players 2025-02-10 19:16:00 -06:00
FatBoy dbc0da20df pets issues fixed 2025-02-09 20:42:00 -06:00
FatBoy 354d0ab283 pets issues 2025-02-09 20:30:24 -06:00
FatBoy c1b66269bb new regen system 2025-02-09 20:23:57 -06:00
FatBoy 7981acb582 new regen system 2025-02-09 19:38:16 -06:00
FatBoy 03448397ee strike counter trash logging 2025-02-09 15:35:18 -06:00
FatBoy 685dc572e8 strike counter 2025-02-09 15:23:52 -06:00
FatBoy 5a161a0808 strike counter 2025-02-09 14:47:08 -06:00
FatBoy 3e4aad9db9 aimbot detection 2025-02-09 14:37:44 -06:00
FatBoy 47981872be network message validation 2025-02-09 14:13:28 -06:00
FatBoy daea835613 network message validation 2025-02-09 14:08:17 -06:00
FatBoy 55923559cd group tele allowe don all city zones 2025-02-08 09:50:48 -06:00
FatBoy 9efde874f3 remove level difference form passive chance 2025-02-08 09:48:35 -06:00
FatBoy 9b2b0073a5 gambler NPC 2025-02-07 20:00:53 -06:00
FatBoy 33328f74db gambler NPC 2025-02-07 19:42:20 -06:00
FatBoy 41023fb890 gambler NPC 2025-02-07 19:27:27 -06:00
FatBoy 54a279c3e6 track threads being used 2025-02-07 12:16:52 -06:00
FatBoy 29aea83217 track threads being used 2025-02-07 12:08:06 -06:00
FatBoy 30d27f8a68 job worker thread to prevent deadlocks 2025-02-07 11:50:43 -06:00
FatBoy 17e54ea4aa job worker thread 2025-02-07 11:38:12 -06:00
FatBoy 86c0bbb065 passives 2025-02-06 20:23:24 -06:00
FatBoy ec4cad5e19 added 250L wait to network selector 2025-02-06 17:48:29 -06:00
FatBoy b674625f7b reduced admin command spam 2025-02-06 17:29:11 -06:00
FatBoy d57b45ef9c fix event processing in network code 2025-02-06 17:27:41 -06:00
FatBoy 2a38c60a67 Revert "fix event processing in network code"
This reverts commit cd1e38b184.
2025-02-06 17:25:34 -06:00
FatBoy cd1e38b184 fix event processing in network code 2025-02-06 17:16:56 -06:00
FatBoy 69457d5f7e new curved map for hit chances 2025-02-05 20:23:15 -06:00
FatBoy 7728a800d9 new hit chance scaling 2025-02-05 20:02:45 -06:00
FatBoy 8b2c018103 mana can be recovered while casting - to match client 2025-02-05 19:04:35 -06:00
FatBoy 76d39f5cc3 mana can be recovered while casting - to match client 2025-02-05 18:55:41 -06:00
FatBoy 826457fb25 mana and stamina regen resynced 2025-02-05 18:11:21 -06:00
FatBoy 0681d3d116 tears of saedron remove stat runes 2025-02-05 17:59:07 -06:00
FatBoy ccdea6f970 players can teleport to their own cities 2025-02-04 20:17:09 -06:00
FatBoy ab00fd7a85 limit dev commands 2025-02-04 20:02:09 -06:00
FatBoy 70d67a2b7f update thread optimized 2025-02-04 19:57:40 -06:00
FatBoy f5b27e0c5b no reverse KoS 2025-02-04 19:50:43 -06:00
FatBoy 3c26df5f86 last tick on over time applies 2025-02-04 19:13:22 -06:00
FatBoy 9ed43b5891 combatstats cleanup 2025-02-04 18:58:05 -06:00
FatBoy 4814404f1c combatstats cleanup 2025-02-04 18:37:47 -06:00
FatBoy b1d41e8e85 update delay removed 2025-02-04 18:31:23 -06:00
FatBoy cc5aa4c140 ATR completed 2025-02-04 18:27:55 -06:00
FatBoy 934c0a98f8 atr buff/debuffs 2025-02-04 18:19:12 -06:00
FatBoy 91c2cd47fb def buff/debuffs 2025-02-04 18:00:59 -06:00
FatBoy 22f14fb8f1 treb spam 2025-02-04 17:07:15 -06:00
FatBoy 93a975dd42 optimized run time 2025-02-04 17:03:46 -06:00
FatBoy 7d1570fdca group tele limit recyle power properly 2025-02-03 20:25:39 -06:00
FatBoy 76db3e1f96 disable mob casting 2025-02-03 20:21:50 -06:00
FatBoy afbe23fc03 use calculated value son PC for combat stats 2025-02-03 20:20:01 -06:00
FatBoy 4e417c8810 audit hit/miss chances 2025-02-03 20:05:04 -06:00
FatBoy d79c69658a parry chance removed 10x 2025-02-03 19:04:04 -06:00
FatBoy 0d125e2640 hit chance 2025-02-03 19:03:26 -06:00
FatBoy e4a3405032 location sync and def formula 2025-02-03 19:02:34 -06:00
FatBoy c391272e5b can block spells 2025-02-02 21:02:21 -06:00
FatBoy 0d3423d51b can block spells 2025-02-02 19:24:10 -06:00
FatBoy 549ca25483 can block spells 2025-02-02 19:21:25 -06:00
FatBoy 603d4ca3a8 reconstructed passive chance formulas 2025-02-02 19:16:31 -06:00
FatBoy fababd3e42 reconstructed passive chance formulas 2025-02-02 18:39:15 -06:00
FatBoy bec6230a06 box limiter 2025-02-02 14:31:55 -06:00
FatBoy 773b6253b9 def formula 2025-02-02 14:29:26 -06:00
FatBoy 1ffcc1086b def formula 2025-02-02 14:25:36 -06:00
FatBoy 992d52a389 always allow parry on saetor 2025-02-02 09:59:54 -06:00
FatBoy 61088d0b59 box limiter 2025-02-02 09:05:22 -06:00
FatBoy 601e97eaca Revert "box limited config entry"
This reverts commit eae4675f85.
2025-02-02 08:57:58 -06:00
FatBoy eae4675f85 box limited config entry 2025-02-02 08:52:09 -06:00
FatBoy 84410114e7 mob casting time fixed 2025-02-01 19:48:41 -06:00
FatBoy 70855acbcf mob casting time 2025-02-01 19:44:05 -06:00
FatBoy 2a8e0dea73 mob casting time 2025-02-01 19:41:06 -06:00
FatBoy 6c4f18218c atr calculations 2025-02-01 19:03:18 -06:00
FatBoy 0b5f469b13 no footwear on saetors 2025-02-01 16:36:01 -06:00
FatBoy 68a43388ff saetor can only parry naturally 2025-02-01 16:26:27 -06:00
FatBoy 5fe12df436 mobs cannot cast debuffs 2025-02-01 16:24:29 -06:00
FatBoy caa0aa5172 AI cast frequency 2025-02-01 16:15:38 -06:00
FatBoy 37a81ed53e ATR system 2025-02-01 16:07:34 -06:00
FatBoy 39afb33186 old regen system 2025-02-01 15:57:19 -06:00
FatBoy 228152596c spell dodge chance resolved 2025-02-01 11:36:33 -06:00
FatBoy d75a052bd3 non siege pets can always roam as a flag 2025-02-01 11:22:51 -06:00
FatBoy 81d6a55096 stop bonus calc spam 2025-02-01 11:19:42 -06:00
FatBoy 55d9cf6d26 calculate base skill 2025-02-01 11:04:49 -06:00
FatBoy 9cf69ec73f calculate base skill 2025-02-01 10:59:28 -06:00
FatBoy 4595582def calculate base skill 2025-02-01 10:01:29 -06:00
FatBoy 0b2d598261 print new skill calculations to client 2025-01-31 21:06:31 -06:00
FatBoy cf342cd1a6 print new skill calculations to client 2025-01-31 21:05:11 -06:00
FatBoy 05bb323c0c print new skill calculations to client 2025-01-31 19:55:24 -06:00
FatBoy c415bb15e2 use new skill level calculations 2025-01-31 19:47:02 -06:00
FatBoy eac58b086b limiter for client syncing 2025-01-31 18:15:40 -06:00
FatBoy fea39ffa85 calculate modified and base skill values 2025-01-31 17:45:42 -06:00
FatBoy fb8971ce86 calculate modified and base skill values 2025-01-31 17:41:37 -06:00
FatBoy e44dd5e2cc properly sync client for regen 2025-01-31 17:09:26 -06:00
FatBoy 3ed303bec4 calculate combat stats spam fix 2025-01-30 19:53:34 -06:00
FatBoy f4267c3c92 calculate combat stats spam fix 2025-01-30 19:49:37 -06:00
FatBoy c5f678ea0e join heavens host allowed for prelates 2025-01-30 19:14:00 -06:00
FatBoy 4fe3d92b3f optimize PlayerCombatStats calling 2025-01-30 18:20:22 -06:00
FatBoy 284fc7e37e remove error logging spam 2025-01-30 18:16:35 -06:00
FatBoy 402d69312c use new regen calculations 2025-01-29 20:09:42 -06:00
FatBoy 198648d3db use new regen calculations 2025-01-29 20:02:02 -06:00
FatBoy 3a01dbf5f6 shade hide power block 2025-01-29 19:23:18 -06:00
FatBoy 0ec505e37f player lock fix 2025-01-29 19:15:20 -06:00
FatBoy 1e26d7f38c player lock fix 2025-01-29 17:44:43 -06:00
FatBoy 64f9f4d4b9 player lock fix 2025-01-29 17:38:00 -06:00
FatBoy 89c06f714f player lock fix 2025-01-29 17:36:56 -06:00
FatBoy 157d116626 player lock fix 2025-01-29 17:29:57 -06:00
FatBoy de229ddde5 dont load cities without ToL 2025-01-29 06:48:40 -06:00
FatBoy 8b456f66ef healers dont get ATR from def stance 2025-01-28 19:10:36 -06:00
FatBoy 2e35e35a6e fury no longer grounded at end of flight chant 2025-01-28 18:58:15 -06:00
FatBoy cca078f017 strip castable enchanst when moving to vault 2025-01-28 18:06:05 -06:00
FatBoy f658a30132 atr % bonus accounted for 2025-01-28 18:04:25 -06:00
FatBoy 0a827d2404 proper duel wield attack speed calc 2025-01-28 17:52:08 -06:00
FatBoy 806adee3de fortitude fix 2025-01-28 17:47:44 -06:00
FatBoy bdd108065b apply powerBlock on shade hide 2025-01-28 17:43:42 -06:00
FatBoy 8d41c5475c unfuck fortitude 2025-01-27 21:50:06 -06:00
FatBoy 99ad461a82 skin the beast work son all but templar 2025-01-27 17:35:39 -06:00
FatBoy 9da56b4226 3 second power block for hide 2025-01-27 16:07:04 -06:00
FatBoy beeca529cd fortitudes handled last 2025-01-27 15:55:40 -06:00
FatBoy ebb765ae82 use total skill percent when calculating ATR 2025-01-27 13:28:31 -06:00
FatBoy 65e391f6f7 Revert "use total skill instea dof modified for ATR"
This reverts commit ab45d92bd1.
2025-01-27 13:18:28 -06:00
FatBoy ab45d92bd1 use total skill instea dof modified for ATR 2025-01-27 13:17:55 -06:00
FatBoy a366c95941 can't TP to errant mines 2025-01-27 13:15:42 -06:00
FatBoy f2d9eb003c temporary enchant timers 2025-01-27 13:02:50 -06:00
FatBoy bb1a99912c temporary enchant stripping 2025-01-27 12:46:10 -06:00
FatBoy fd30e52741 temporary enchant stripping 2025-01-27 12:08:01 -06:00
FatBoy 58a0b6150f aI delay 2025-01-27 10:03:57 -06:00
FatBoy 9aa053beb6 aI delay 2025-01-27 10:00:53 -06:00
FatBoy 7eb084efaa aI delay 2025-01-27 09:46:48 -06:00
FatBoy 1568377725 dex reductions 2025-01-26 19:28:59 -06:00
FatBoy 7b32cfe235 shade backstabs 2025-01-26 19:06:48 -06:00
FatBoy 7ef3efafd3 shade backstabs 2025-01-26 18:55:50 -06:00
FatBoy ffdd79c497 blood mage fix 2025-01-26 18:25:13 -06:00
FatBoy b156da7ded AP applies only to mele damage 2025-01-26 17:39:06 -06:00
FatBoy 9278954f2f saetor can parry 2025-01-26 17:35:13 -06:00
FatBoy 4324ebe855 Phaedra's Fury added to exception list for form break 2025-01-26 17:14:35 -06:00
FatBoy 4a69dca5cc allow gimme 2025-01-26 08:58:52 -06:00
FatBoy 2cc54b4002 100 ms delay between mob spawns 2025-01-26 08:49:20 -06:00
FatBoy eac0aebd59 defense calc completed 2025-01-25 19:03:12 -06:00
FatBoy 172dcfb6d8 defense calc completed 2025-01-25 18:55:18 -06:00
FatBoy d320d83c22 defense calc completed 2025-01-25 18:51:28 -06:00
FatBoy af2dd004e4 defense calc 2025-01-25 18:01:59 -06:00
FatBoy dfbace76db defense calc 2025-01-25 17:49:04 -06:00
FatBoy 119f762492 defense calc 2025-01-25 17:39:44 -06:00
FatBoy e586c442c1 PlayerCombatStats dex penalty applied correctly 2025-01-25 16:39:27 -06:00
FatBoy c01e87ee8b PlayerCombatStats dex penalty applied correctly 2025-01-25 16:31:56 -06:00
FatBoy af4025d948 PlayerCombatStats dex penalty applied correctly 2025-01-25 14:48:51 -06:00
FatBoy b7c2b7a0d5 PlayerCombatStats dex penalty applied correctly 2025-01-25 14:27:25 -06:00
FatBoy f073a93d47 PlayerCombatStats dex penalty applied correctly 2025-01-25 14:23:18 -06:00
FatBoy 47914838f5 PlayerCombatStats dex penalty applied correctly 2025-01-25 14:20:04 -06:00
FatBoy 69e2630d77 PlayerCombatStats dex penalty applied correctly 2025-01-25 14:15:27 -06:00
FatBoy 08148c058c PlayerCombatStats defense formula 2025-01-25 07:53:54 -06:00
FatBoy a7ee8f553b PlayerCombatStats proc chances 2025-01-24 06:29:35 -06:00
FatBoy 8395bb80f1 PlayerCombatStats use in combat 2025-01-24 06:22:44 -06:00
FatBoy becd3cbf65 PlayerCombatStats use in combat 2025-01-24 06:21:11 -06:00
FatBoy 80ec681a2c PlayerCombatStats 30% damage reduction for duel wielding 2025-01-24 06:08:08 -06:00
FatBoy 96a80ce1b6 PlayerCombatStats attack delay 2025-01-24 06:06:04 -06:00
FatBoy f18cf5c8a6 PlayerCombatStats modified skills 2025-01-23 21:36:50 -06:00
FatBoy 4c21159553 PlayerCombatStats modified skills 2025-01-23 21:00:27 -06:00
FatBoy 475c0a9b09 PlayerCombatStats modified skills 2025-01-23 20:59:43 -06:00
FatBoy f80ad61179 PlayerCombatStats weapon speed enchants applied separately 2025-01-23 16:39:21 -06:00
FatBoy 10ccfb1086 PlayerCombatStats weapon speed enchants applied separately 2025-01-23 16:38:27 -06:00
FatBoy 44197fd83c PlayerCombatStats revision 2025-01-22 21:28:51 -06:00
FatBoy 0d9e03f848 PlayerCombatStats weapon speed calculations complete 2025-01-22 21:08:38 -06:00
FatBoy 810812d06b PlayerCombatStats weapon speed calculations 2025-01-22 20:53:07 -06:00
FatBoy 539d7f6e79 PlayerCombatStats def calculations completed 2025-01-22 20:44:33 -06:00
FatBoy 3358d9e943 PlayerCombatStats def calculations 2025-01-22 19:53:24 -06:00
FatBoy eeffd9b357 PlayerCombatStats atr calculations completed 2025-01-22 19:18:31 -06:00
FatBoy b33f41200e PlayerCombatStats atr 2025-01-22 16:56:25 -06:00
FatBoy 030d1110b9 PlayerCombatStats proper delays 2025-01-22 16:05:01 -06:00
FatBoy 09af8084b9 PlayerCombatStats final 2025-01-21 21:08:46 -06:00
FatBoy 0cff9524c2 PlayerCombatStats final 2025-01-21 21:07:17 -06:00
FatBoy f6299f5b97 PlayerCombatStats final 2025-01-21 20:37:17 -06:00
FatBoy b1250ae4e4 PlayerCombatStats proper stance calculations 2025-01-21 20:26:20 -06:00
FatBoy a9144471b1 PlayerCombatStats defense proper rounding 2025-01-21 20:24:15 -06:00
FatBoy 9f924da18b PlayerCombatStats min/max rounding final 2025-01-21 20:18:19 -06:00
FatBoy aac92f1760 PlayerCombatStats defense final 2025-01-21 20:08:50 -06:00
FatBoy fdf42bd913 PlayerCombatStats defense 2025-01-21 20:01:20 -06:00
FatBoy ecee2f2e8c PlayerCombatStats damage calc final 2025-01-21 19:55:32 -06:00
FatBoy 1b487fdbb6 PlayerCombatStats damage calc 2025-01-21 19:51:59 -06:00
FatBoy bb7bd6d71b PlayerCombatStats atr final 2025-01-21 19:43:16 -06:00
FatBoy 34178906a3 PlayerCombatStats attack speed final 2025-01-21 19:40:49 -06:00
FatBoy c689722459 PlayerCombatStats object 2025-01-21 18:43:56 -06:00
FatBoy 8e4ff8c67f PlayerCombatStats object 2025-01-21 18:43:27 -06:00
FatBoy 4ff22d1d20 PlayerCombatStats object 2025-01-21 13:33:49 -06:00
FatBoy 5ed7712aed PlayerCombatStats object 2025-01-21 13:23:04 -06:00
FatBoy a6fcb5ea00 weapon speed 2025-01-20 21:00:44 -06:00
FatBoy 8f402c8c03 weapon speed 2025-01-20 20:46:32 -06:00
FatBoy 5761e313fd weapon speed 2025-01-20 20:28:04 -06:00
FatBoy 441771839a new stat calculations 2025-01-20 20:02:47 -06:00
FatBoy ad6700974f new stat calculations 2025-01-20 19:56:10 -06:00
FatBoy 499aec2c61 new stat calculations 2025-01-20 18:55:41 -06:00
FatBoy ceed4c641a new stat calculations 2025-01-20 18:53:13 -06:00
FatBoy 669c0b4cd7 attack speed 2025-01-20 17:52:44 -06:00
FatBoy 7964de1045 attack speed 2025-01-20 17:52:08 -06:00
FatBoy 961e2915b4 attack speed 2025-01-20 17:43:06 -06:00
FatBoy 6c6a64fa98 mobs dont chase invisible players 2025-01-20 16:34:45 -06:00
FatBoy 7a8a751bca stealing/peeking fix 2025-01-20 16:30:48 -06:00
FatBoy 69bf6ef8cd combat formula and steal 2025-01-20 16:08:54 -06:00
FatBoy 05e542215d allow 5th disc at 70 2025-01-20 15:33:01 -06:00
FatBoy 868eaab5ed mantle of stone added to form break exception list 2025-01-20 15:30:36 -06:00
FatBoy e7d22717cd attack speed calculations 2025-01-20 15:24:48 -06:00
FatBoy bbabf814e1 attack speed calculations 2025-01-20 13:44:32 -06:00
FatBoy 938fcb1352 allow print bonuses 2025-01-19 19:51:54 -06:00
FatBoy 42a71396cd persist print commands for non-testmode 2025-01-19 19:50:50 -06:00
FatBoy 9ec95b974f mob work 2025-01-18 16:06:38 -06:00
FatBoy 49ea9e50cf mob work 2025-01-18 15:57:20 -06:00
FatBoy 456edce9fc mob work 2025-01-18 15:50:14 -06:00
FatBoy 537512ed5d mob work 2025-01-18 15:36:18 -06:00
FatBoy d0efd08a84 mobbase effect info command 2025-01-18 15:16:16 -06:00
FatBoy bb7ba9a6df mobbase effect info command 2025-01-18 15:07:35 -06:00
FatBoy 09695d97db mobbase effect info command 2025-01-18 15:04:27 -06:00
FatBoy 4fe4835c29 mobbase effects 2025-01-18 14:53:07 -06:00
FatBoy 86435a3563 respawn thread optimized 2025-01-18 03:35:35 -06:00
FatBoy bc84c7537b optimized regen client sync 2025-01-18 03:24:36 -06:00
FatBoy 29736f9c8f optimized regen client sync 2025-01-18 03:24:16 -06:00
FatBoy 99a9cd297c optimized mob ai thread 2025-01-18 03:19:08 -06:00
FatBoy e86749febd optimized bane thread 2025-01-18 03:15:48 -06:00
FatBoy 4b86fbb12c optimized regen 2025-01-18 03:11:45 -06:00
FatBoy 4c342c9b9a bard uses pathfinding 2025-01-15 19:39:15 -06:00
FatBoy d2e0b7b95c bard uses pathfinding 2025-01-15 19:25:37 -06:00
FatBoy 53fe763764 boxed characters dont get ding gold 2025-01-15 16:39:22 -06:00
FatBoy 86d7233aa4 remove console spam 2025-01-15 16:23:10 -06:00
FatBoy d19ea0968a allowed casts in form 2025-01-15 13:42:46 -06:00
FatBoy 7eb49446c1 correct use of proper stat for ATR calculation 2025-01-14 18:47:05 -06:00
FatBoy 01a88c85a6 correct use of proper stat for ATR calculation 2025-01-14 18:11:20 -06:00
FatBoy 5492374f2c saetor in who window, skin the beast double point value 2025-01-14 17:56:52 -06:00
FatBoy 9ca00be694 saetor in who window, skin the beast double point value 2025-01-14 16:19:46 -06:00
FatBoy 23d9807fe3 infastructure for exclusion to breaking form from powers 2025-01-14 15:50:54 -06:00
FatBoy 8a3e3ae866 special case weapon powers requiring hit rolls 2025-01-14 15:22:58 -06:00
FatBoy 117646cda4 limit spamming messages ot client for stat sync 2025-01-13 16:27:10 -06:00
FatBoy 6cf502c4bb mob drop aggro check 2025-01-13 16:06:36 -06:00
FatBoy 1bb99127c4 mob drop aggro check 2025-01-13 15:58:44 -06:00
FatBoy 8aeccd35c9 mob drop aggro check 2025-01-13 15:57:01 -06:00
FatBoy c90b94d1ec endless player guard combat cycle 2025-01-13 15:46:08 -06:00
FatBoy 031fd24842 PLayerCharacter.java Cleanup 2025-01-13 09:21:01 -06:00
FatBoy e1c07deb52 remove debug logs from stam/health consumption 2025-01-13 09:09:38 -06:00
FatBoy 5f10c24f03 health degregation for swimming 2025-01-12 20:08:07 -06:00
FatBoy f643caacbe health degregation for swimming 2025-01-12 19:45:30 -06:00
FatBoy cb5ab26924 recovery system fully synced to client 2025-01-12 19:37:24 -06:00
FatBoy 94c9e92553 mob loot system addressed 2025-01-12 17:09:27 -06:00
FatBoy 507638594d updated regen system 2025-01-12 16:56:13 -06:00
FatBoy e72c4886e8 updated regen system 2025-01-12 16:18:47 -06:00
FatBoy 5ba11a6238 updated regen system 2025-01-12 09:34:44 -06:00
FatBoy 2fc7671051 updated regen system 2025-01-12 00:59:02 -06:00
FatBoy d142097b0f updated regen system 2025-01-12 00:58:31 -06:00
FatBoy 4330bb3ecd updated regen system 2025-01-12 00:18:30 -06:00
FatBoy 2e1dd27332 updated regen system 2025-01-12 00:13:21 -06:00
FatBoy 4f08d7286e mob respawn issue resolved 2025-01-11 23:56:04 -06:00
FatBoy 7f8fb13552 mana regen change 2025-01-10 22:10:04 -06:00
FatBoy 93e0d119b0 mana regen change 2025-01-10 22:09:29 -06:00
FatBoy a9bc44f19b fifth disc for level 80 2025-01-10 21:18:17 -06:00
FatBoy 83bc09f34b fifth disc for level 80 2025-01-10 21:16:05 -06:00
FatBoy 4386e1c828 throttled xp for killing same person 2025-01-10 21:11:11 -06:00
FatBoy 72b2e54331 banes to set default times 2025-01-10 21:06:29 -06:00
FatBoy e912c24025 5th hireling in r8 ToL 2025-01-10 12:34:32 -06:00
FatBoy c9c1f6ba1c wall bonus HP 2025-01-10 09:52:34 -06:00
FatBoy abda30fc25 wall bonus HP 2025-01-10 09:47:39 -06:00
FatBoy 62c188c5c7 wall bonus HP 2025-01-10 09:45:51 -06:00
FatBoy 67f7b6f3f8 wall bonus HP 2025-01-10 09:40:15 -06:00
FatBoy f04ccb9403 wall bonus HP 2025-01-10 09:36:01 -06:00
FatBoy b71bb60669 allow 5th slot in r8 TOL + wall health upgrade for r8 trees 2025-01-10 09:28:08 -06:00
FatBoy 5eab1ad1c0 allow 5th slot in r8 TOL + wall health upgrade 2025-01-10 09:17:58 -06:00
FatBoy f96d0caf3c stun grounds 1 tier per 1.5 seconds of stunned 2025-01-09 18:22:57 -06:00
FatBoy 3e6655a199 cant change altitude while stunned 2025-01-09 18:02:04 -06:00
FatBoy 386cdc8c18 cant change altitude while stunned 2025-01-09 17:58:27 -06:00
FatBoy 63b40c27a5 fall slowly while stunned 2025-01-09 17:53:13 -06:00
FatBoy 6985dffda4 no more spamming console 2025-01-09 08:17:56 -06:00
FatBoy 88e16448a8 gold and conc on promotion 2025-01-07 19:11:41 -06:00
FatBoy 4cb428e993 noob island progression changes 2025-01-07 19:05:11 -06:00
FatBoy af9945f9db added null check for endEffect 2025-01-06 21:28:54 -06:00
FatBoy f0594fb1b2 sitting only toggle when casting spells not skills 2025-01-06 12:45:20 -06:00
FatBoy a155bc0308 modified ht chance 2025-01-06 07:14:40 -06:00
FatBoy dce7444483 modified ht chance 2025-01-06 06:54:26 -06:00
FatBoy 76eed79b0a repair cost formula fixed 2025-01-05 20:05:41 -06:00
FatBoy f73ed17c05 repair cost formula 2025-01-05 19:24:05 -06:00
FatBoy b049d21aff corpse timer 2025-01-05 18:53:00 -06:00
FatBoy f6cce5ee1f corpse timer 2025-01-05 18:52:53 -06:00
FatBoy 8038c2ebe2 arena que messages 2025-01-05 18:52:10 -06:00
FatBoy 9f51b9af57 arena que messages 2025-01-05 18:42:06 -06:00
FatBoy cbc75bf9d7 irekei healer blood prophet 2025-01-05 17:40:55 -06:00
FatBoy 0ecfa546cd SDR bind loc for errants 2025-01-05 16:43:38 -06:00
FatBoy b89fb0803d SDR bind loc for errants 2025-01-05 15:41:10 -06:00
FatBoy 11005d58a7 SDR bind loc for errants 2025-01-05 15:39:41 -06:00
FatBoy b0c6239314 SDR bind loc for errants 2025-01-05 15:36:30 -06:00
FatBoy 67f66155e9 SDR bind loc for errants 2025-01-05 15:28:51 -06:00
FatBoy 7fbae12e99 mob update 2025-01-05 14:53:05 -06:00
FatBoy 65580c0a47 mob update 2025-01-05 14:51:43 -06:00
FatBoy 236afe4cc6 mob update 2025-01-05 14:48:51 -06:00
FatBoy c23a6af28f mob update 2025-01-05 14:45:45 -06:00
FatBoy 2535106d2c player update sync 2025-01-05 14:38:07 -06:00
FatBoy d8379ae5a9 shades dont break hide when moving 2025-01-05 11:18:39 -06:00
FatBoy 9f13f5fc5d add sprint to shade stealth 2025-01-05 10:56:14 -06:00
FatBoy 884cb30ebd trade bug 2025-01-05 09:26:42 -06:00
115 changed files with 3625 additions and 1382 deletions

No files matched your search

+9 -17
View File
@@ -9,15 +9,13 @@
package engine;
import ch.claude_martin.enumbitset.EnumBitSetHelper;
import engine.gameManager.BuildingManager;
import engine.gameManager.ConfigManager;
import engine.gameManager.PowersManager;
import engine.gameManager.ZoneManager;
import engine.math.Vector2f;
import engine.math.Vector3fImmutable;
import engine.objects.AbstractCharacter;
import engine.objects.ItemBase;
import engine.objects.Shrine;
import engine.objects.Zone;
import engine.objects.*;
import engine.powers.EffectsBase;
import org.pmw.tinylog.Logger;
@@ -471,11 +469,14 @@ public class Enum {
// 14001 does not have a banestone to bind at
if (ruinZone.getLoadNum() == 14001)
if (ruinZone.getLoadNum() == 14001) {
spawnLocation = Vector3fImmutable.getRandomPointOnCircle(ruinZone.getLoc(), 30);
else
spawnLocation = Vector3fImmutable.getRandomPointOnCircle(ruinZone.getLoc()
.add(new Vector3fImmutable(-196.016f, 2.812f, 203.621f)), 30);
}else {
//spawnLocation = Vector3fImmutable.getRandomPointOnCircle(ruinZone.getLoc()
//.add(new Vector3fImmutable(-196.016f, 2.812f, 203.621f)), 30);
spawnLocation = Vector3fImmutable.getRandomPointOnCircle(BuildingManager.getBuilding(27977).loc,30f);
}
}
@@ -1090,15 +1091,6 @@ public class Enum {
DamageShield,
DeathShroud,
DefenseBuff,
DefenseBuffAss,
DefenseBuffChn,
DefenseBuffDsr,
DefenseBuffFur,
DefenseBuffNec,
DefenseBuffNsr,
DefenseBuffPrl,
DefenseBuffRng,
DefenseBuffWiz,
DefenseBuffGroup,
DefenseDebuff,
DetectInvis,
@@ -22,6 +22,7 @@ import java.util.HashMap;
public class dbItemBaseHandler extends dbHandlerBase {
public static final HashMap<Integer,Float> dexReductions = new HashMap<>();
public dbItemBaseHandler() {
}
@@ -45,6 +46,14 @@ public class dbItemBaseHandler extends dbHandlerBase {
}
}
public void LOAD_DEX_REDUCTION(ItemBase itemBase) {
if(dexReductions.containsKey(itemBase.getUUID())){
itemBase.dexReduction = dexReductions.get(itemBase.getUUID());
}else{
itemBase.dexReduction = 0.0f;
}
}
public void LOAD_ANIMATIONS(ItemBase itemBase) {
ArrayList<Integer> tempList = new ArrayList<>();
@@ -94,6 +103,21 @@ public class dbItemBaseHandler extends dbHandlerBase {
}
Logger.info("read: " + recordsRead + " cached: " + ItemBase.getUUIDCache().size());
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_item_dexpenalty`")) {
ResultSet rs = preparedStatement.executeQuery();
// Check if a result was found
if (rs.next()) {
int ID = rs.getInt("ID");
float factor = rs.getInt("item_bulk_factor");
dexReductions.put(ID,factor);
}
} catch (SQLException e) {
Logger.error(e);
}
}
public HashMap<Integer, ArrayList<Integer>> LOAD_RUNES_FOR_NPC_AND_MOBS() {
+7 -3
View File
@@ -134,9 +134,13 @@ public class dbItemHandler extends dbHandlerBase {
ResultSet rs = preparedStatement.executeQuery();
if (rs.next())
worked = rs.getBoolean("result");
if (rs.next()) {
try {
worked = rs.getBoolean("result");
}catch(Exception e){
worked = false;
}
}
} catch (SQLException e) {
Logger.error(e);
}
+22 -7
View File
@@ -15,9 +15,13 @@ import engine.Enum.GameObjectType;
import engine.Enum.TargetColor;
import engine.devcmd.AbstractDevCmd;
import engine.gameManager.BuildingManager;
import engine.gameManager.PowersManager;
import engine.gameManager.SessionManager;
import engine.math.Vector3fImmutable;
import engine.objects.*;
import engine.powers.EffectsBase;
import engine.powers.PowersBase;
import engine.server.MBServerStatics;
import engine.util.StringUtils;
import java.text.DecimalFormat;
@@ -338,7 +342,8 @@ public class InfoCmd extends AbstractDevCmd {
output += newline;
output += "isMoving : " + targetPC.isMoving();
output += newline;
output += "Zerg Multiplier : " + targetPC.ZergMultiplier;
output += "Zerg Multiplier : " + targetPC.ZergMultiplier+ newline;
output += "Hidden : " + targetPC.getHidden();
break;
case NPC:
@@ -493,13 +498,16 @@ public class InfoCmd extends AbstractDevCmd {
output += newline;
output += "No building found." + newline;
}
int max = (int)(4.882 * targetMob.level + 121.0);
if(max > 321){
max = 321;
output += "Damage: " + targetMob.mobBase.getDamageMin() + " - " + targetMob.mobBase.getDamageMax() + newline;
output += "ATR: " + targetMob.mobBase.getAttackRating() + newline;
output += "DEF: " + targetMob.defenseRating + newline;
output += "RANGE: " + targetMob.getRange() + newline;
output += "Effects:" + newline;
for(MobBaseEffects mbe : targetMob.mobBase.mobbaseEffects){
EffectsBase eb = PowersManager.getEffectByToken(mbe.getToken());
output += eb.getName() + newline;
}
int min = (int)(4.469 * targetMob.level - 3.469);
output += "Min Loot Roll = " + min;
output += "Max Loot Roll = " + max;
break;
case Item: //intentional passthrough
case MobLoot:
@@ -530,6 +538,13 @@ public class InfoCmd extends AbstractDevCmd {
}
break;
case Corpse:
Corpse corpse = (Corpse)target;
Long timeLeft = MBServerStatics.CORPSE_CLEANUP_TIMER_MS - (System.currentTimeMillis() - corpse.spawnedTime);
output += "Despawn in: " + timeLeft;
output += newline;
break;
}
throwbackInfo(pc, output);
@@ -49,6 +49,8 @@ public class PrintSkillsCmd extends AbstractDevCmd {
+ skill.getModifiedAmount() + '('
+ skill.getTotalSkillPercet() + " )");
}
//throwbackInfo(pc, "= = = = = NEW CALCULATIONS = = = = =");
// PlayerCombatStats.PrintSkillsToClient(pc);
} else
throwbackInfo(pc, "Skills not found for player");
}
+30 -21
View File
@@ -57,27 +57,36 @@ public class PrintStatsCmd extends AbstractDevCmd {
public void printStatsPlayer(PlayerCharacter pc, PlayerCharacter tar) {
String newline = "\r\n ";
String out = "Server stats for Player " + tar.getFirstName() + newline;
out += "Unused Stats: " + tar.getUnusedStatPoints() + newline;
out += "Stats Base (Modified)" + newline;
out += " Str: " + (int) tar.statStrBase + " (" + tar.getStatStrCurrent() + ')' + ", maxStr: " + tar.getStrMax() + newline;
out += " Dex: " + (int) tar.statDexBase + " (" + tar.getStatDexCurrent() + ')' + ", maxDex: " + tar.getDexMax() + newline;
out += " Con: " + (int) tar.statConBase + " (" + tar.getStatConCurrent() + ')' + ", maxCon: " + tar.getConMax() + newline;
out += " Int: " + (int) tar.statIntBase + " (" + tar.getStatIntCurrent() + ')' + ", maxInt: " + tar.getIntMax() + newline;
out += " Spi: " + (int) tar.statSpiBase + " (" + tar.getStatSpiCurrent() + ')' + ", maxSpi: " + tar.getSpiMax() + newline;
throwbackInfo(pc, out);
out = "Health: " + tar.getHealth() + ", maxHealth: " + tar.getHealthMax() + newline;
out += "Mana: " + tar.getMana() + ", maxMana: " + tar.getManaMax() + newline;
out += "Stamina: " + tar.getStamina() + ", maxStamina: " + tar.getStaminaMax() + newline;
out += "Defense: " + tar.getDefenseRating() + newline;
out += "Main Hand: atr: " + tar.getAtrHandOne() + ", damage: " + tar.getMinDamageHandOne() + " to " + tar.getMaxDamageHandOne() + ", speed: " + tar.getSpeedHandOne() + newline;
out += "Off Hand: atr: " + tar.getAtrHandTwo() + ", damage: " + tar.getMinDamageHandTwo() + " to " + tar.getMaxDamageHandTwo() + ", speed: " + tar.getSpeedHandTwo() + newline;
out += "isAlive: " + tar.isAlive() + ", Combat: " + tar.isCombat() + newline;
out += "Move Speed: " + tar.getSpeed() + newline;
out += "Health Regen: " + tar.getRegenModifier(Enum.ModType.HealthRecoverRate) + newline;
out += "Mana Regen: " + tar.getRegenModifier(Enum.ModType.ManaRecoverRate) + newline;
out += "Stamina Regen: " + tar.getRegenModifier(Enum.ModType.StaminaRecoverRate) + newline;
throwbackInfo(pc, out);
String newOut = "Server stats for Player " + tar.getFirstName() + newline;
newOut += "HEALTH: " + tar.getHealth() + " / " + tar.getHealthMax() + newline;
newOut += "MANA: " + tar.getMana() + " / " + tar.getManaMax() + newline;
newOut += "STAMINA: " + tar.getStamina() + " / " + tar.getStaminaMax() + newline;
newOut += "Unused Stats: " + tar.getUnusedStatPoints() + newline;
newOut += "Stats Base (Modified)" + newline;
newOut += " Str: " + (int) tar.statStrBase + " (" + tar.getStatStrCurrent() + ')' + ", maxStr: " + tar.getStrMax() + newline;
newOut += " Dex: " + (int) tar.statDexBase + " (" + tar.getStatDexCurrent() + ')' + ", maxDex: " + tar.getDexMax() + newline;
newOut += " Con: " + (int) tar.statConBase + " (" + tar.getStatConCurrent() + ')' + ", maxCon: " + tar.getConMax() + newline;
newOut += " Int: " + (int) tar.statIntBase + " (" + tar.getStatIntCurrent() + ')' + ", maxInt: " + tar.getIntMax() + newline;
newOut += " Spi: " + (int) tar.statSpiBase + " (" + tar.getStatSpiCurrent() + ')' + ", maxSpi: " + tar.getSpiMax() + newline;
newOut += "Move Speed: " + tar.getSpeed() + newline;
newOut += "Health Regen: " + tar.combatStats.healthRegen + newline;
newOut += "Mana Regen: " + tar.combatStats.manaRegen + newline;
newOut += "Stamina Regen: " + tar.combatStats.staminaRegen + newline;
newOut += "DEFENSE: " + tar.combatStats.defense + newline;
newOut += "HAND ONE" + newline;
newOut += "ATR: " + tar.combatStats.atrHandOne + newline;
newOut += "MIN: " + tar.combatStats.minDamageHandOne + newline;
newOut += "MAX: " + tar.combatStats.maxDamageHandOne + newline;
newOut += "RANGE: " + tar.combatStats.rangeHandOne + newline;
newOut += "ATTACK SPEED: " + tar.combatStats.attackSpeedHandOne + newline;
newOut += "HAND TWO" + newline;
newOut += "ATR: " + tar.combatStats.atrHandTwo + newline;
newOut += "MIN: " + tar.combatStats.minDamageHandTwo + newline;
newOut += "MAX: " + tar.combatStats.maxDamageHandTwo + newline;
newOut += "RANGE: " + tar.combatStats.rangeHandTwo + newline;
newOut += "ATTACK SPEED: " + tar.combatStats.attackSpeedHandTwo + newline;
throwbackInfo(pc, newOut);
}
public void printStatsMob(PlayerCharacter pc, Mob tar) {
@@ -1,5 +1,6 @@
package engine.devcmd.cmds;
import engine.Enum;
import engine.devcmd.AbstractDevCmd;
import engine.gameManager.LootManager;
import engine.gameManager.ZoneManager;
@@ -26,7 +27,52 @@ public class SimulateBootyCmd extends AbstractDevCmd {
String newline = "\r\n ";
String output;
if(target.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)){
int ATR = Integer.parseInt(words[0]);
int DEF = Integer.parseInt(words[1]);
int attacks = Integer.parseInt(words[2]);
int hits = 0;
int misses = 0;
int defaultHits = 0;
int defualtMisses = 0;
float chance = (ATR-((ATR+DEF) * 0.315f)) / ((DEF-((ATR+DEF) * 0.315f)) + (ATR-((ATR+DEF) * 0.315f)));
float convertedChance = chance * 100;
output = "" + newline;
output += "DEF VS ATR SIMULATION: " + attacks + " ATTACKS SIMULATED" + newline;
output += "DEF = " + DEF + newline;
output += "ATR = " + ATR + newline;
output += "CHANCE TO LAND HIT: " + convertedChance + "%" + newline;
if(convertedChance < 5){
output += "CHANCE ADJUSTED TO 5.0%" + newline;
convertedChance = 5.0f;
}
if(convertedChance > 95){
output += "CHANCE ADJUSTED TO 95.0%" + newline;
convertedChance = 95.0f;
}
for(int i = 0; i < attacks; i++){
int roll = ThreadLocalRandom.current().nextInt(101);
if(roll <= convertedChance){
hits += 1;
}else{
misses += 1;
}
}
float totalHits = defaultHits + hits;
float totalMisses = defualtMisses + misses;
float hitPercent = Math.round(totalHits / attacks * 100);
float missPercent = Math.round(totalMisses / attacks * 100);
output += "HITS LANDED: " + (defaultHits + hits) + "(" + Math.round(hitPercent) + "%)" + newline;
output += "HITS MISSED: " + (defualtMisses + misses) + "(" + Math.round(missPercent) + "%)";
throwbackInfo(playerCharacter,output);
return;
}
try
{
simCount = Integer.parseInt(words[0]);
+10
View File
@@ -49,10 +49,20 @@ public class ArenaManager {
if (!playerQueue.contains(player)) {
playerQueue.add(player);
}
for(PlayerCharacter pc : playerQueue){
if(pc.equals(player))
continue;
ChatManager.chatSystemInfo(pc, player.getName() + " has joined the arena que. There are now " + playerQueue.size() + " players queued.");
}
}
public static void leaveQueue(PlayerCharacter player) {
playerQueue.remove(player);
for(PlayerCharacter pc : playerQueue){
if(pc.equals(player))
continue;
ChatManager.chatSystemInfo(pc, player.getName() + " has left the arena que. There are now " + playerQueue.size() + " players queued.");
}
}
private static void createArena() {
+142 -58
View File
@@ -301,6 +301,17 @@ public enum CombatManager {
if (target == null)
return 0;
//pet to assist in attacking target
if(abstractCharacter.getObjectType().equals(GameObjectType.PlayerCharacter)){
PlayerCharacter attacker = (PlayerCharacter)abstractCharacter;
if(attacker.getPet() != null){
Mob pet = attacker.getPet();
if(pet.combatTarget == null && pet.assist)
pet.setCombatTarget(attacker.combatTarget);
}
}
//target must be valid type
if (AbstractWorldObject.IsAbstractCharacter(target)) {
@@ -483,16 +494,24 @@ public enum CombatManager {
createTimer(abstractCharacter, slot, 20, true); //2 second for no weapon
else {
int wepSpeed = (int) (wb.getSpeed());
if(abstractCharacter.getObjectType().equals(GameObjectType.PlayerCharacter)){
PlayerCharacter pc = (PlayerCharacter)abstractCharacter;
if(slot == 1){
wepSpeed = (int) pc.combatStats.attackSpeedHandOne;
}else{
wepSpeed = (int) pc.combatStats.attackSpeedHandTwo;
}
}else {
if (weapon != null && weapon.getBonusPercent(ModType.WeaponSpeed, SourceType.None) != 0f) //add weapon speed bonus
wepSpeed *= (1 + weapon.getBonus(ModType.WeaponSpeed, SourceType.None));
if (weapon != null && weapon.getBonusPercent(ModType.WeaponSpeed, SourceType.None) != 0f) //add weapon speed bonus
wepSpeed *= (1 + weapon.getBonus(ModType.WeaponSpeed, SourceType.None));
if (abstractCharacter.getBonuses() != null && abstractCharacter.getBonuses().getFloatPercentAll(ModType.AttackDelay, SourceType.None) != 0f) //add effects speed bonus
wepSpeed *= (1 + abstractCharacter.getBonuses().getFloatPercentAll(ModType.AttackDelay, SourceType.None));
if (wepSpeed < 10)
wepSpeed = 10; //Old was 10, but it can be reached lower with legit buffs,effects.
if (abstractCharacter.getBonuses() != null && abstractCharacter.getBonuses().getFloatPercentAll(ModType.AttackDelay, SourceType.None) != 0f) //add effects speed bonus
wepSpeed *= (1 + abstractCharacter.getBonuses().getFloatPercentAll(ModType.AttackDelay, SourceType.None));
if (wepSpeed < 10)
wepSpeed = 10; //Old was 10, but it can be reached lower with legit buffs,effects.
}
createTimer(abstractCharacter, slot, wepSpeed, true);
}
@@ -536,15 +555,29 @@ public enum CombatManager {
if (target == null)
return;
if (mainHand) {
atr = ac.getAtrHandOne();
minDamage = ac.getMinDamageHandOne();
maxDamage = ac.getMaxDamageHandOne();
} else {
atr = ac.getAtrHandTwo();
minDamage = ac.getMinDamageHandTwo();
maxDamage = ac.getMaxDamageHandTwo();
if(ac.getObjectType().equals(GameObjectType.PlayerCharacter)){
PlayerCharacter pc = (PlayerCharacter) ac;
pc.combatStats.calculateATR(true);
pc.combatStats.calculateATR(false);
if (mainHand) {
atr = pc.combatStats.atrHandOne;
minDamage = pc.combatStats.minDamageHandOne;
maxDamage = pc.combatStats.maxDamageHandOne;
} else {
atr = pc.combatStats.atrHandTwo;
minDamage = pc.combatStats.minDamageHandTwo;
maxDamage = pc.combatStats.maxDamageHandTwo;
}
}else {
if (mainHand) {
atr = ac.getAtrHandOne();
minDamage = ac.getMinDamageHandOne();
maxDamage = ac.getMaxDamageHandOne();
} else {
atr = ac.getAtrHandTwo();
minDamage = ac.getMinDamageHandTwo();
maxDamage = ac.getMaxDamageHandTwo();
}
}
boolean tarIsRat = false;
@@ -638,7 +671,12 @@ public enum CombatManager {
}
} else {
AbstractCharacter tar = (AbstractCharacter) target;
defense = tar.getDefenseRating();
if(tar.getObjectType().equals(GameObjectType.PlayerCharacter)){
((PlayerCharacter)tar).combatStats.calculateDefense();
defense = ((PlayerCharacter)tar).combatStats.defense;
}else {
defense = tar.getDefenseRating();
}
handleRetaliate(tar, ac); //Handle target attacking back if in combat and has no other target
}
@@ -647,7 +685,7 @@ public enum CombatManager {
//Get hit chance
//int chance;
float dif = atr - defense;
//float dif = atr - defense;
//if (dif > 100)
// chance = 94;
@@ -662,9 +700,8 @@ public enum CombatManager {
DeferredPowerJob dpj = null;
if (LandHit((int)atr,(int)defense)) {
boolean hitLanded = LandHit((int)atr,(int)defense);
if (hitLanded) {
if (ac.getObjectType().equals(GameObjectType.PlayerCharacter))
updateAttackTimers((PlayerCharacter) ac, target, true);
@@ -693,7 +730,13 @@ public enum CombatManager {
PlayerBonuses bonus = ac.getBonuses();
float attackRange = getWeaponRange(wb, bonus);
dpj.attack(target, attackRange);
if(specialCaseHitRoll(dpj.getPowerToken())) {
if(hitLanded) {
dpj.attack(target, attackRange);
}
}else{
dpj.attack(target, attackRange);
}
if (dpj.getPower() != null && (dpj.getPowerToken() == -1851459567 || dpj.getPowerToken() == -1851489518))
((PlayerCharacter) ac).setWeaponPower(dpj);
@@ -708,7 +751,13 @@ public enum CombatManager {
if (dpj != null && dpj.getPower() != null && (dpj.getPowerToken() == -1851459567 || dpj.getPowerToken() == -1851489518)) {
float attackRange = getWeaponRange(wb, bonuses);
dpj.attack(target, attackRange);
if(specialCaseHitRoll(dpj.getPowerToken())) {
if(hitLanded) {
dpj.attack(target, attackRange);
}
}else{
dpj.attack(target, attackRange);
}
}
}
@@ -815,6 +864,22 @@ public enum CombatManager {
else
damage = calculateDamage(ac, tarAc, minDamage, maxDamage, damageType, resists);
if(weapon != null && weapon.effects != null){
float armorPierce = 0;
for(Effect eff : weapon.effects.values()){
for(AbstractEffectModifier mod : eff.getEffectModifiers()){
if(mod.modType.equals(ModType.ArmorPiercing)){
armorPierce += mod.minMod * (mod.getRamp() * eff.getTrains());
}
}
}
if(armorPierce > 0){
damage *= 1 - armorPierce;
}
}
//Resists.handleFortitude(tarAc,damageType,damage);
float d = 0f;
errorTrack = 12;
@@ -867,27 +932,18 @@ public enum CombatManager {
if (weapon != null && tarAc != null && tarAc.isAlive()) {
ConcurrentHashMap<String, Effect> effects = weapon.getEffects();
for (Effect eff : effects.values()) {
if (eff == null)
continue;
HashSet<AbstractEffectModifier> aems = eff.getEffectModifiers();
if (aems != null) {
for (AbstractEffectModifier aem : aems) {
if (!tarAc.isAlive())
break;
if (aem instanceof WeaponProcEffectModifier) {
if(weapon.effects != null){
for (Effect eff : weapon.effects.values()){
for(AbstractEffectModifier mod : eff.getEffectModifiers()){
if(mod.modType.equals(ModType.WeaponProc)){
int procChance = ThreadLocalRandom.current().nextInt(100);
if (procChance < MBServerStatics.PROC_CHANCE)
((WeaponProcEffectModifier) aem).applyProc(ac, target);
if (procChance < MBServerStatics.PROC_CHANCE) {
try {
((WeaponProcEffectModifier) mod).applyProc(ac, target);
}catch(Exception e){
Logger.error(eff.getName() + " Failed To Cast Proc");
}
}
}
}
}
@@ -916,7 +972,13 @@ public enum CombatManager {
if (wp.requiresHitRoll() == false) {
PlayerBonuses bonus = ac.getBonuses();
float attackRange = getWeaponRange(wb, bonus);
dpj.attack(target, attackRange);
if(specialCaseHitRoll(dpj.getPowerToken())) {
if(hitLanded) {
dpj.attack(target, attackRange);
}
}else{
dpj.attack(target, attackRange);
}
} else
((PlayerCharacter) ac).setWeaponPower(null);
}
@@ -1023,10 +1085,12 @@ public enum CombatManager {
//calculate resists in if any
if (resists != null)
return resists.getResistedDamage(source, target, damageType, damage, 0);
else
return damage;
damage = resists.getResistedDamage(source, target, damageType, damage, 0);
return damage;
}
private static void sendPassiveDefenseMessage(AbstractCharacter source, ItemBase wb, AbstractWorldObject target, int passiveType, DeferredPowerJob dpj, boolean mainHand) {
@@ -1180,6 +1244,14 @@ public enum CombatManager {
private static boolean testPassive(AbstractCharacter source, AbstractCharacter target, String type) {
if(target.getBonuses() != null)
if(target.getBonuses().getBool(ModType.Stunned, SourceType.None))
return false;
if(source.getBonuses() != null)
if(source.getBonuses().getBool(ModType.IgnorePassiveDefense, SourceType.None))
return false;
float chance = target.getPassiveChance(type, source.getLevel(), true);
if (chance == 0f)
@@ -1190,7 +1262,7 @@ public enum CombatManager {
if (chance > 75f)
chance = 75f;
int roll = ThreadLocalRandom.current().nextInt(100);
int roll = ThreadLocalRandom.current().nextInt(1,100);
return roll < chance;
@@ -1368,9 +1440,9 @@ public enum CombatManager {
Resists resists = ac.getResists();
if (resists != null)
if (resists != null) {
amount = resists.getResistedDamage(target, ac, ds.getDamageType(), amount, 0);
}
total += amount;
}
@@ -1453,19 +1525,31 @@ public enum CombatManager {
((AbstractCharacter) awo).getCharItemManager().damageRandomArmor(1);
}
public static boolean LandHit(int atr, int defense){
public static boolean LandHit(int ATR, int DEF){
//float chance = (ATR-((ATR+DEF) * 0.315f)) / ((DEF-((ATR+DEF) * 0.315f)) + (ATR-((ATR+DEF) * 0.315f)));
//float convertedChance = chance * 100;
int roll = ThreadLocalRandom.current().nextInt(101);
float chance = (float)((atr-((atr+defense)*0.315))/((defense-((atr+defense)*0.315))+(atr-((atr+defense)*0.315))));
int connvertedChance = (int)(chance * 100);
//if(roll <= 5)//always 5% chance to miss
// return false;
if(connvertedChance < 5)
connvertedChance = 5;
//if(roll >= 95)//always 5% chance to hit
// return true;
if(connvertedChance > 95)
connvertedChance = 95;
float chance = PlayerCombatStats.getHitChance(ATR,DEF);
return chance >= roll;
}
return connvertedChance > roll;
public static boolean specialCaseHitRoll(int powerID){
switch(powerID) {
case 563200808: // Naargal's Bite
case 563205337: // Naargal's Dart
case 563205930: // Sword of Saint Malorn
return true;
default:
return false;
}
}
}
+2 -1
View File
@@ -98,7 +98,8 @@ public enum ConfigManager {
MB_MAGICBOT_FORTOFIX,
MB_MAGICBOT_RECRUIT,
MB_MAGICBOT_MAGICBOX,
MB_MAGICBOT_ADMINLOG;
MB_MAGICBOT_ADMINLOG,
MB_WORLD_BOXLIMIT;
// Map to hold our config pulled in from the environment
// We also use the config to point to the current message pump
+19
View File
@@ -177,6 +177,11 @@ public enum DevCmdManager {
return false;
}
if(!pcSender.getTimestamps().containsKey("DEVCOMMAND"))
pcSender.getTimestamps().put("DEVCOMMAND",System.currentTimeMillis() - 1500L);
else if(System.currentTimeMillis() - pcSender.getTimestamps().get("DEVCOMMAND") < 1000L)
return false;
//kill any commands not available to everyone on production server
//only admin level can run dev commands on production
boolean playerAllowed = false;
@@ -189,6 +194,20 @@ public enum DevCmdManager {
case "gimme":
case "goto":
case "teleportmode":
case "printbonuses":
playerAllowed = true;
if (!a.status.equals(Enum.AccountStatus.ADMIN))
target = pcSender;
break;
}
}else{
switch (adc.getMainCmdString()) {
case "printresists":
case "printstats":
case "printskills":
case "printpowers":
case "printbonuses":
//case "gimme":
playerAllowed = true;
if (!a.status.equals(Enum.AccountStatus.ADMIN))
target = pcSender;
+9 -2
View File
@@ -75,6 +75,11 @@ public enum LootManager {
}
public static void GenerateMobLoot(Mob mob) {
if(mob == null){
return;
}
//determine if mob is in hotzone
boolean inHotzone = false;
@@ -180,14 +185,16 @@ public enum LootManager {
// Iterate all entries in this bootySet and process accordingly
Zone zone = ZoneManager.findSmallestZone(mob.loc);
for (BootySetEntry bse : entries) {
switch (bse.bootyType) {
case "GOLD":
if (zone != null && zone.getSafeZone() == (byte)1)
return; // no loot to drop in safezones
GenerateGoldDrop(mob, bse, inHotzone);
break;
case "LOOT":
if (mob.getSafeZone())
if (zone != null && zone.getSafeZone() == (byte)1)
return; // no loot to drop in safezones
dropRate = LootManager.NORMAL_DROP_RATE;
+7 -3
View File
@@ -67,8 +67,10 @@ public enum MovementManager {
return;
if (toMove.getObjectType().equals(GameObjectType.PlayerCharacter)) {
if (((PlayerCharacter) toMove).isCasting())
((PlayerCharacter) toMove).update(false);
if (((PlayerCharacter) toMove).isCasting()) {
((PlayerCharacter) toMove).updateLocation();
((PlayerCharacter) toMove).updateMovementState();
}
}
@@ -408,7 +410,9 @@ public enum MovementManager {
if (bonus.getBool(ModType.Stunned, SourceType.None) || bonus.getBool(ModType.CannotMove, SourceType.None))
continue;
member.update(false);
//member.update(false);
member.updateLocation();
member.updateMovementState();
// All checks passed, let's move the player
+224 -32
View File
@@ -10,6 +10,7 @@ package engine.gameManager;
import engine.Enum.*;
import engine.InterestManagement.HeightMap;
import engine.InterestManagement.InterestManager;
import engine.InterestManagement.WorldGrid;
import engine.db.handlers.dbEffectsBaseHandler;
import engine.db.handlers.dbPowerHandler;
@@ -165,12 +166,20 @@ public enum PowersManager {
PlayerCharacter pc = SessionManager.getPlayerCharacter(origin);
if(!pc.isFlying()) //cant be sitting if flying
if(pc == null)
return;
if(!pc.isFlying() && powersBaseByToken.get(msg.getPowerUsedID()) != null && powersBaseByToken.get(msg.getPowerUsedID()).isSpell) //cant be sitting if flying
CombatManager.toggleSit(false,origin);
if(pc.isMoving())
pc.stopMovement(pc.getMovementLoc());
if(msg.getPowerUsedID() == 429429978){
applyPower(origin.getPlayerCharacter(),origin.getPlayerCharacter(),origin.getPlayerCharacter().getLoc(),429429978,msg.getNumTrains(),false);
return;
}
if (usePowerA(msg, origin, sendCastToSelf)) {
// Cast failed for some reason, reset timer
@@ -197,7 +206,8 @@ public enum PowersManager {
msg.setUnknown04(1);
if (useMobPowerA(msg, caster)) {
//sendMobPowerMsg(caster,2,msg); //Lol wtf was i thinking sending msg's to mobs... ZZZZ
if(pb.token == -1994153779)
InterestManager.setObjectDirty(caster);
}
}
@@ -216,16 +226,16 @@ public enum PowersManager {
City city = ZoneManager.getCityAtLocation(playerCharacter.loc);
if (city == null) {
failed = true;
}else{
Bane bane = city.getBane();
if (bane == null) {
failed = true;
}else{
if(!bane.getSiegePhase().equals(SiegePhase.WAR)){
failed = true;
}
}
}
}//else{
// Bane bane = city.getBane();
// if (bane == null) {
// failed = true;
// }else{
// if(!bane.getSiegePhase().equals(SiegePhase.WAR)){
// failed = true;
// }
// }
//}
if(failed){
//check to see if we are at an active mine
Zone zone = ZoneManager.findSmallestZone(playerCharacter.loc);
@@ -242,8 +252,15 @@ public enum PowersManager {
}
}
if(failed)
if(failed) {
playerCharacter.setIsCasting(false);
RecyclePowerMsg recyclePowerMsg = new RecyclePowerMsg(msg.getPowerUsedID());
Dispatch dispatch = Dispatch.borrow(playerCharacter, recyclePowerMsg);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY);
return false;
}
}
if (MBServerStatics.POWERS_DEBUG) {
@@ -329,17 +346,18 @@ public enum PowersManager {
// Check powers for normal users
if (playerCharacter.getPowers() == null || !playerCharacter.getPowers().containsKey(msg.getPowerUsedID()))
if (!playerCharacter.isCSR()) {
if (!MBServerStatics.POWERS_DEBUG) {
// ChatManager.chatSayInfo(pc, "You may not cast that spell!");
Logger.info("usePowerA(): Cheat attempted? '" + msg.getPowerUsedID() + "' was not associated with " + playerCharacter.getName());
return true;
}
} else
CSRCast = true;
if(msg.getPowerUsedID() != 421084024) {
if (playerCharacter.getPowers() == null || !playerCharacter.getPowers().containsKey(msg.getPowerUsedID()))
if (!playerCharacter.isCSR()) {
if (!MBServerStatics.POWERS_DEBUG) {
// ChatManager.chatSayInfo(pc, "You may not cast that spell!");
Logger.info("usePowerA(): Cheat attempted? '" + msg.getPowerUsedID() + "' was not associated with " + playerCharacter.getName());
return true;
}
} else
CSRCast = true;
}
// get numTrains for power
int trains = msg.getNumTrains();
@@ -349,8 +367,10 @@ public enum PowersManager {
msg.setNumTrains(trains);
}
//double stack point values for some useless disc spells
switch(pb.token){
case 429420458: // BH eyes
case 429601664: // huntsman skin the beast
msg.setNumTrains(msg.getNumTrains() * 2);
break;
}
@@ -490,6 +510,23 @@ public enum PowersManager {
}
}
if(!passed){
if (playerCharacter.getRace().getName().contains("Shade")) {
if(playerCharacter.getHidden() > 0){
switch(msg.getPowerUsedID()){
case -1851459567:
case 2094922127:
case -355707373:
case 246186475:
case 666419835:
case 1480354319:
passed = true;
break;
}
}
}
}
if (!passed)
return true;
}
@@ -602,12 +639,12 @@ public enum PowersManager {
}
// update cast (use skill) fail condition
if(pb.token != 429396028) {
if(pb.token != 429396028 && pb.breaksForm) {
playerCharacter.cancelOnCast();
}
// update castSpell (use spell) fail condition if spell
if (pb.isSpell())
if (pb.isSpell() && pb.breaksForm)
playerCharacter.cancelOnSpell();
// get cast time in ms.
@@ -748,10 +785,11 @@ public enum PowersManager {
// make person casting stand up if spell (unless they're casting a chant which does not make them stand up)
// update cast (use skill) fail condition
caster.cancelOnCast();
if(pb.breaksForm)
caster.cancelOnCast();
// update castSpell (use spell) fail condition if spell
if (pb.isSpell())
if (pb.isSpell() && pb.breaksForm)
caster.cancelOnSpell();
// get cast time in ms.
@@ -787,14 +825,36 @@ public enum PowersManager {
if (playerCharacter == null || msg == null)
return;
if((msg.getPowerUsedID() == 429495514 || msg.getPowerUsedID() == 429407306) && playerCharacter.getRace().getName().toLowerCase().contains("shade")){
//msg.setPowerUsedID(407015607);
applyPower(playerCharacter,playerCharacter,playerCharacter.loc,429397210,msg.getNumTrains(),false);
//handle sprint for bard sprint
if(msg.getPowerUsedID() == 429005674){
msg.setPowerUsedID(429611355);
}
if(msg.getPowerUsedID() == 429494441) {//wildkins chase
//handle root and snare break for wildkin's chase
if(msg.getPowerUsedID() == 429494441) {
playerCharacter.removeEffectBySource(EffectSourceType.Root,40,true);
playerCharacter.removeEffectBySource(EffectSourceType.Snare,40,true);
}
//handle power block portion for shade hide
if(playerCharacter.getRace().getName().contains("Shade")) {
if (msg.getPowerUsedID() == 429407306 || msg.getPowerUsedID() == 429495514) {
int trains = msg.getNumTrains() - 1;
if (trains < 1)
trains = 1;
applyPower(playerCharacter, playerCharacter, playerCharacter.loc, 429397210, trains, false);
playerCharacter.removeEffectBySource(EffectSourceType.Invisibility,40,true);
applyPower(playerCharacter, playerCharacter, playerCharacter.loc, msg.getPowerUsedID(), msg.getNumTrains(), false);
}
}
if(msg.getTargetType() == GameObjectType.PlayerCharacter.ordinal()) {
PlayerCharacter target = PlayerCharacter.getPlayerCharacter(msg.getTargetID());
if (msg.getPowerUsedID() == 429601664)
if(target.getPromotionClassID() != 2516)
PlayerCharacter.getPlayerCharacter(msg.getTargetID()).removeEffectBySource(EffectSourceType.Transform, msg.getNumTrains(), true);
}
if (playerCharacter.isCasting()) {
playerCharacter.update(false);
playerCharacter.updateStamRegen(-100);
@@ -2405,6 +2465,13 @@ public enum PowersManager {
dodgeMsg.setTargetID(awo.getObjectUUID());
sendPowerMsg(pc, 4, dodgeMsg);
return true;
} else if (testPassive(pc, tarAc, "Block")) {
// Dodge fired, send dodge message
PerformActionMsg dodgeMsg = new PerformActionMsg(msg);
dodgeMsg.setTargetType(awo.getObjectType().ordinal());
dodgeMsg.setTargetID(awo.getObjectUUID());
sendPowerMsg(pc, 4, dodgeMsg);
return true;
}
}
return false;
@@ -2452,7 +2519,12 @@ public enum PowersManager {
if (AbstractWorldObject.IsAbstractCharacter(awo)) {
AbstractCharacter tarAc = (AbstractCharacter) awo;
// Handle Dodge passive
return testPassive(caster, tarAc, "Dodge");
boolean passiveFired = false;
passiveFired = testPassive(caster, tarAc, "Dodge");
if(!passiveFired)
passiveFired = testPassive(caster, tarAc, "Block");
return passiveFired;
}
return false;
} else
@@ -2841,6 +2913,126 @@ public enum PowersManager {
}
}
public static boolean breakForm(int token) {
switch (token) {
case 429505865:
case 429407561:
case 429492073:
case 429644123:
case 429393769:
case 429545819:
case 429426537:
case 429590377:
case 429508425:
case 429541193:
case 429573961:
case 427924330:
case 429402918:
case 429545688:
case 429005674:
case 429637823:
case 429590426:
case 428066972:
case 429441862:
case 431611756:
case 431578988:
case 429502506:
case 429398191:
case 429447384:
case 428892191:
case 431579167:
case 430977067:
case 429409100:
case 429441868:
case 429594877:
case 427908971:
case 683741153:
case 429770569:
case 429452379:
case 429605055:
case 429086971:
case 429443230:
case 429505400:
case 429492122:
case 429643992:
case 550062236:
case 429498252:
case 429611224:
case 429441834:
case 428918940:
case 429633739:
case 429633579:
case 429568043:
case 429048646:
case 428392639:
case 428425407:
case 429054168:
case 429021400:
case 428955864:
case 429119704:
case 428890328:
case 428923096:
case 429218008:
case 429086936:
case 428988632:
case 428688204:
case 429514603:
case 428924959:
case 429393818:
case 429720966:
case 428982463:
case 427933887:
case 429572287:
case 429501222:
case 430694431:
case 429436131:
case 430006124:
case 429611355:
case 428005600:
case 427935608:
case 428949695:
case 427988218:
case 429414616:
case 429496495:
case 429428796:
case 563795754:
case 428988217:
case 429432716:
case 428955899:
case 429393286:
case 550062220:
case 429495557:
case 429401278:
case 428377478:
case 429409094:
case 428191947:
case 429434474:
case 429403363:
case 429512920:
case 429419611:
case 429645676:
case 429602895:
case 429605071:
case 429592428:
case 429500010:
case 429406602:
case 429426586:
case 429633898:
case 550062212:
case 429994027:
case 430813227:
case 429928491:
case 430026795:
case 429517915:
case 431854842:
case 429767544:
case 429502507:
case 428398816:
case 429446315:
return false;
}
return true;
}
}
@@ -93,13 +93,10 @@ public enum SimulationManager {
}
try {
if ((_updatePulseTime != 0)
&& (System.currentTimeMillis() > _updatePulseTime))
if ((_updatePulseTime != 0) && (System.currentTimeMillis() > _updatePulseTime))
pulseUpdate();
} catch (Exception e) {
Logger.error(
"Fatal error in Update Pulse: DISABLED");
// _runegatePulseTime = 0;
Logger.error("Fatal error in Update Pulse: DISABLED");
}
try {
@@ -160,7 +157,11 @@ public enum SimulationManager {
if (player == null)
continue;
player.update(false);
try {
player.update(false);
}catch(Exception e){
}
}
_updatePulseTime = System.currentTimeMillis() + 500;
+1 -1
View File
@@ -68,7 +68,7 @@ public abstract class AbstractJob implements Runnable {
this.markStopRunTime();
}
protected abstract void doJob();
public abstract void doJob();
public void executeJob(String threadName) {
this.workerID.set(threadName);
+1 -1
View File
@@ -17,7 +17,7 @@ public abstract class AbstractScheduleJob extends AbstractJob {
}
@Override
protected abstract void doJob();
public abstract void doJob();
public void cancelJob() {
JobScheduler.getInstance().cancelScheduledJob(this);
+1 -1
View File
@@ -16,7 +16,7 @@ public class JobContainer implements Comparable<JobContainer> {
final long timeOfExecution;
final boolean noTimer;
JobContainer(AbstractJob job, long timeOfExecution) {
public JobContainer(AbstractJob job, long timeOfExecution) {
if (job == null) {
throw new IllegalArgumentException("No 'null' jobs allowed.");
}
+75
View File
@@ -0,0 +1,75 @@
package engine.job;
import engine.server.world.WorldServer;
import org.pmw.tinylog.Logger;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
public class JobThread implements Runnable {
private final AbstractJob currentJob;
private final ReentrantLock lock = new ReentrantLock();
private static Long nextThreadPrint;
public JobThread(AbstractJob job){
this.currentJob = job;
}
@Override
public void run() {
try {
if (this.currentJob != null) {
if (lock.tryLock(5, TimeUnit.SECONDS)) { // Timeout to prevent deadlock
try {
this.currentJob.doJob();
} finally {
lock.unlock();
}
} else {
Logger.warn("JobThread could not acquire lock in time, skipping job.");
}
}
} catch (Exception e) {
Logger.error(e);
}
}
public static void startJobThread(AbstractJob job){
JobThread jobThread = new JobThread(job);
Thread thread = new Thread(jobThread);
thread.setName("JOB THREAD: " + job.getWorkerID());
thread.start();
if(JobThread.nextThreadPrint == null){
JobThread.nextThreadPrint = System.currentTimeMillis();
}else{
if(JobThread.nextThreadPrint < System.currentTimeMillis()){
JobThread.tryPrintThreads();
JobThread.nextThreadPrint = System.currentTimeMillis() + 10000L;
}
}
}
public static void tryPrintThreads(){
ThreadGroup rootGroup = Thread.currentThread().getThreadGroup();
while (rootGroup.getParent() != null) {
rootGroup = rootGroup.getParent();
}
// Estimate the number of threads
int activeThreads = rootGroup.activeCount();
// Create an array to hold the threads
Thread[] threads = new Thread[activeThreads];
// Get the active threads
rootGroup.enumerate(threads, true);
int availableThreads = Runtime.getRuntime().availableProcessors();
// Print the count
if(threads.length > 30)
Logger.info("Total threads in application: " + threads.length + " / " + availableThreads);
}
}
+6 -3
View File
@@ -58,10 +58,13 @@ public class JobWorker extends ControlledRunnable {
} else {
// execute the new job..
this.currentJob.executeJob(this.getThreadName());
this.currentJob = null;
//this.currentJob.executeJob(this.getThreadName());
if(this.currentJob != null) {
JobThread.startJobThread(this.currentJob);
this.currentJob = null;
}
}
Thread.yield();
}
return true;
}
+2 -2
View File
@@ -45,7 +45,7 @@ public abstract class AbstractEffectJob extends AbstractScheduleJob {
}
@Override
protected abstract void doJob();
public abstract void doJob();
@Override
protected abstract void _cancelJob();
@@ -117,7 +117,7 @@ public abstract class AbstractEffectJob extends AbstractScheduleJob {
}
public void endEffect() {
if (this.eb == null)
if (this.eb == null || this.power == null)
return;
this.eb.endEffect(this.source, this.target, this.trains, this.power, this);
}
+1 -1
View File
@@ -29,7 +29,7 @@ public class ActivateBaneJob extends AbstractScheduleJob {
}
@Override
protected void doJob() {
public void doJob() {
City city;
+1 -1
View File
@@ -27,7 +27,7 @@ public class AttackJob extends AbstractJob {
}
@Override
protected void doJob() {
public void doJob() {
CombatManager.doCombat(this.source, slot);
}
+1 -1
View File
@@ -24,7 +24,7 @@ public class BaneDefaultTimeJob extends AbstractScheduleJob {
}
@Override
protected void doJob() {
public void doJob() {
//bane already set.
if (this.bane.getLiveDate() != null) {
+1 -1
View File
@@ -97,7 +97,7 @@ public class BasicScheduledJob extends AbstractJob {
}
@Override
protected void doJob() {
public void doJob() {
if (execution == null) {
Logger.error("BasicScheduledJob executed with nothing to execute.");
return;
+1 -1
View File
@@ -22,7 +22,7 @@ public class BonusCalcJob extends AbstractJob {
}
@Override
protected void doJob() {
public void doJob() {
if (this.ac != null) {
this.ac.applyBonuses();
+1 -1
View File
@@ -22,7 +22,7 @@ public class CSessionCleanupJob extends AbstractJob {
}
@Override
protected void doJob() {
public void doJob() {
SessionManager.cSessionCleanup(secKey);
}
}
+1 -1
View File
@@ -27,7 +27,7 @@ public class ChangeAltitudeJob extends AbstractScheduleJob {
}
@Override
protected void doJob() {
public void doJob() {
if (this.ac != null)
MovementManager.finishChangeAltitude(ac, targetAlt);
}
+1 -1
View File
@@ -36,7 +36,7 @@ public class ChantJob extends AbstractEffectJob {
}
@Override
protected void doJob() {
public void doJob() {
if (this.aej == null || this.source == null || this.target == null || this.action == null || this.power == null || this.source == null || this.eb == null)
return;
PlayerBonuses bonuses = null;
+1 -1
View File
@@ -29,7 +29,7 @@ public class CloseGateJob extends AbstractScheduleJob {
}
@Override
protected void doJob() {
public void doJob() {
if (building == null) {
Logger.error("Rungate building was null");
+3 -1
View File
@@ -37,7 +37,7 @@ public class DamageOverTimeJob extends AbstractEffectJob {
}
@Override
protected void doJob() {
public void doJob() {
if (this.target.getObjectType().equals(GameObjectType.Building)
&& ((Building) this.target).isVulnerable() == false) {
_cancelJob();
@@ -60,6 +60,8 @@ public class DamageOverTimeJob extends AbstractEffectJob {
if (this.iteration < 0) {
PowersManager.finishEffectTime(this.source, this.target, this.action, this.trains);
if (AbstractWorldObject.IsAbstractCharacter(source))
eb.startEffect((AbstractCharacter) this.source, this.target, this.trains, this);
return;
}
this.skipSendEffect = true;
+1 -1
View File
@@ -28,7 +28,7 @@ public class DatabaseUpdateJob extends AbstractScheduleJob {
}
@Override
protected void doJob() {
public void doJob() {
if (this.ago == null)
return;
ago.removeDatabaseJob(this.type, false);
+1 -1
View File
@@ -29,7 +29,7 @@ public class DebugTimerJob extends AbstractScheduleJob {
}
@Override
protected void doJob() {
public void doJob() {
if (this.pc == null) {
return;
}
+1 -1
View File
@@ -37,7 +37,7 @@ public class DeferredPowerJob extends AbstractEffectJob {
}
@Override
protected void doJob() {
public void doJob() {
//Power ended with no attack, cancel weapon power boost
if (this.source != null && this.source instanceof PlayerCharacter) {
((PlayerCharacter) this.source).setWeaponPower(null);
+1 -1
View File
@@ -22,7 +22,7 @@ public class DisconnectJob extends AbstractScheduleJob {
}
@Override
protected void doJob() {
public void doJob() {
if (this.origin != null) {
this.origin.disconnect();
}
+1 -1
View File
@@ -28,7 +28,7 @@ public class DoorCloseJob extends AbstractScheduleJob {
}
@Override
protected void doJob() {
public void doJob() {
int doorNumber;
+1 -1
View File
@@ -22,7 +22,7 @@ public class EndFearJob extends AbstractEffectJob {
}
@Override
protected void doJob() {
public void doJob() {
//cancel fear for mob.
+1 -1
View File
@@ -26,7 +26,7 @@ public class FinishCooldownTimeJob extends AbstractJob {
}
@Override
protected void doJob() {
public void doJob() {
PowersManager.finishCooldownTime(this.msg, this.pc);
}
}
+1 -1
View File
@@ -22,7 +22,7 @@ public class FinishEffectTimeJob extends AbstractEffectJob {
}
@Override
protected void doJob() {
public void doJob() {
PowersManager.finishEffectTime(this.source, this.target, this.action, this.trains);
}
+1 -1
View File
@@ -26,7 +26,7 @@ public class FinishRecycleTimeJob extends AbstractScheduleJob {
}
@Override
protected void doJob() {
public void doJob() {
PowersManager.finishRecycleTime(this.msg, this.pc, false);
}
+1 -1
View File
@@ -20,7 +20,7 @@ public class FinishSpireEffectJob extends AbstractEffectJob {
}
@Override
protected void doJob() {
public void doJob() {
PlayerCharacter pc = (PlayerCharacter) target;
+1 -1
View File
@@ -31,7 +31,7 @@ public class FinishSummonsJob extends AbstractScheduleJob {
}
@Override
protected void doJob() {
public void doJob() {
if (this.target == null)
return;
+1 -1
View File
@@ -28,7 +28,7 @@ public class LoadEffectsJob extends AbstractJob {
}
@Override
protected void doJob() {
public void doJob() {
if (this.originToSend == null) {
return;
}
+1 -1
View File
@@ -25,7 +25,7 @@ public class LogoutCharacterJob extends AbstractScheduleJob {
}
@Override
protected void doJob() {
public void doJob() {
server.logoutCharacter(this.pc);
}
+1 -1
View File
@@ -19,7 +19,7 @@ public class NoTimeJob extends AbstractEffectJob {
}
@Override
protected void doJob() {
public void doJob() {
}
@Override
+1 -1
View File
@@ -40,7 +40,7 @@ public class PersistentAoeJob extends AbstractEffectJob {
}
@Override
protected void doJob() {
public void doJob() {
if (this.aej == null || this.source == null || this.action == null || this.power == null || this.source == null || this.eb == null)
return;
+1 -1
View File
@@ -45,7 +45,7 @@ public class RefreshGroupJob extends AbstractJob {
}
@Override
protected void doJob() {
public void doJob() {
if (this.pc == null || this.origin == null || grp == null) {
return;
+1 -1
View File
@@ -22,7 +22,7 @@ public class RemoveCorpseJob extends AbstractScheduleJob {
}
@Override
protected void doJob() {
public void doJob() {
if (this.corpse != null)
Corpse.removeCorpse(corpse, true);
+1 -1
View File
@@ -25,7 +25,7 @@ public class SiegeSpireWithdrawlJob extends AbstractScheduleJob {
}
@Override
protected void doJob() {
public void doJob() {
if (spire == null)
return;
+1 -1
View File
@@ -30,7 +30,7 @@ public class StuckJob extends AbstractScheduleJob {
}
@Override
protected void doJob() {
public void doJob() {
Vector3fImmutable stuckLoc;
Building building = null;
+1 -1
View File
@@ -27,7 +27,7 @@ public class SummonSendJob extends AbstractScheduleJob {
}
@Override
protected void doJob() {
public void doJob() {
if (this.source == null)
return;
+1 -1
View File
@@ -39,7 +39,7 @@ public class TeleportJob extends AbstractScheduleJob {
}
@Override
protected void doJob() {
public void doJob() {
if (this.pc == null || this.npc == null || this.origin == null)
return;
+1 -1
View File
@@ -35,7 +35,7 @@ public class TrackJob extends AbstractEffectJob {
}
@Override
protected void doJob() {
public void doJob() {
if (this.tpa == null || this.target == null || this.action == null || this.source == null || this.eb == null || !(this.source instanceof PlayerCharacter))
return;
+1 -1
View File
@@ -29,7 +29,7 @@ public class TransferStatOTJob extends AbstractEffectJob {
}
@Override
protected void doJob() {
public void doJob() {
if (this.dot == null || this.target == null || this.action == null || this.source == null || this.eb == null || this.action == null || this.power == null)
return;
if (!this.target.isAlive()) {
+1 -1
View File
@@ -26,7 +26,7 @@ public class UpdateGroupJob extends AbstractScheduleJob {
}
@Override
protected void doJob() {
public void doJob() {
if (this.group == null)
return;
+15 -1
View File
@@ -1,7 +1,9 @@
package engine.jobs;
import engine.gameManager.ZoneManager;
import engine.job.AbstractScheduleJob;
import engine.objects.Building;
import engine.objects.City;
import org.pmw.tinylog.Logger;
/*
@@ -20,7 +22,7 @@ public class UpgradeBuildingJob extends AbstractScheduleJob {
}
@Override
protected void doJob() {
public void doJob() {
// Must have a building to rank!
@@ -41,6 +43,18 @@ public class UpgradeBuildingJob extends AbstractScheduleJob {
rankingBuilding.setRank(rankingBuilding.getRank() + 1);
if(rankingBuilding.getBlueprint().isWallPiece()){
City cityObject = ZoneManager.getCityAtLocation(rankingBuilding.loc);
if(cityObject.getTOL().getRank() == 8) {
if (rankingBuilding.getBlueprint() != null && rankingBuilding.getBlueprint().getBuildingGroup() != null && rankingBuilding.getBlueprint().isWallPiece()) {
float currentHealthRatio = rankingBuilding.getCurrentHitpoints() / rankingBuilding.healthMax;
float newMax = rankingBuilding.healthMax * 1.1f;
rankingBuilding.setMaxHitPoints(newMax);
rankingBuilding.setHealth(rankingBuilding.healthMax * currentHealthRatio);
}
}
}
// Reload the object
+1 -1
View File
@@ -27,7 +27,7 @@ public class UpgradeNPCJob extends AbstractScheduleJob {
}
@Override
protected void doJob() {
public void doJob() {
int newRank;
+1 -1
View File
@@ -34,7 +34,7 @@ public class UseItemJob extends AbstractScheduleJob {
}
@Override
protected void doJob() {
public void doJob() {
PowersManager.finishApplyPower(ac, target, Vector3fImmutable.ZERO, pb, trains, liveCounter);
}
+1 -1
View File
@@ -35,7 +35,7 @@ public class UseMobPowerJob extends AbstractScheduleJob {
}
@Override
protected void doJob() {
public void doJob() {
PowersManager.finishUseMobPower(this.msg, this.caster, casterLiveCounter, targetLiveCounter);
}
+1 -1
View File
@@ -35,7 +35,7 @@ public class UsePowerJob extends AbstractScheduleJob {
}
@Override
protected void doJob() {
public void doJob() {
PowersManager.finishUsePower(this.msg, this.pc, casterLiveCounter, targetLiveCounter);
}
+98 -56
View File
@@ -9,7 +9,7 @@
package engine.mobileAI;
import engine.Enum;
import engine.Enum.DispatchChannel;
import engine.InterestManagement.InterestManager;
import engine.InterestManagement.WorldGrid;
import engine.gameManager.*;
import engine.math.Vector3f;
@@ -19,7 +19,7 @@ import engine.mobileAI.utilities.CombatUtilities;
import engine.mobileAI.utilities.MovementUtilities;
import engine.net.DispatchMessage;
import engine.net.client.msg.PerformActionMsg;
import engine.net.client.msg.PowerProjectileMsg;
import engine.net.client.msg.UpdateStateMsg;
import engine.objects.*;
import engine.powers.ActionsBase;
import engine.powers.PowersBase;
@@ -49,18 +49,19 @@ public class MobAI {
return;
}
if (target.getObjectType() == Enum.GameObjectType.PlayerCharacter && canCast(mob)) {
//mob casting disabled
//if (target.getObjectType() == Enum.GameObjectType.PlayerCharacter && canCast(mob)) {
if (mob.isPlayerGuard() == false && MobCast(mob)) {
mob.updateLocation();
return;
}
//if (mob.isPlayerGuard() == false && MobCast(mob)) {
// mob.updateLocation();
// return;
//}
if (mob.isPlayerGuard() == true && GuardCast(mob)) {
mob.updateLocation();
return;
}
}
//if (mob.isPlayerGuard() == true && GuardCast(mob)) {
// mob.updateLocation();
// return;
//}
//}
if (!CombatUtilities.inRangeToAttack(mob, target))
return;
@@ -106,10 +107,14 @@ public class MobAI {
return;
}
if(target.getPet() != null && target.getPet().isAlive()){
mob.setCombatTarget(target.getPet());
}
if (mob.BehaviourType.callsForHelp)
MobCallForHelp(mob);
if (!MovementUtilities.inRangeDropAggro(mob, target)) {
if (MovementUtilities.outOfAggroRange(mob, target)) {
mob.setCombatTarget(null);
return;
}
@@ -156,6 +161,12 @@ public class MobAI {
if (target.getPet().getCombatTarget() == null && target.getPet().assist == true)
target.getPet().setCombatTarget(mob);
try{
InterestManager.forceLoad(mob);
}catch(Exception e){
}
} catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: AttackPlayer" + " " + e.getMessage());
}
@@ -171,14 +182,14 @@ public class MobAI {
if (target.getRank() == -1 || !target.isVulnerable() || BuildingManager.getBuildingFromCache(target.getObjectUUID()) == null) {
mob.setCombatTarget(null);
return;
return;
}
City playercity = ZoneManager.getCityAtLocation(mob.getLoc());
if (playercity != null)
for (Mob guard : playercity.getParent().zoneMobSet)
if (guard.BehaviourType != null && guard.BehaviourType.ordinal() == Enum.MobBehaviourType.GuardCaptain.ordinal())
if (guard.BehaviourType != null && guard.BehaviourType.equals(Enum.MobBehaviourType.GuardCaptain))
if (guard.getCombatTarget() == null && guard.getGuild() != null && mob.getGuild() != null && !guard.getGuild().equals(mob.getGuild()))
guard.setCombatTarget(mob);
@@ -253,6 +264,9 @@ public class MobAI {
target.setCombatTarget(mob);
}
}
if(target.combatTarget == null)
target.setCombatTarget(mob);
} catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: AttackMob" + " " + e.getMessage());
}
@@ -321,28 +335,32 @@ public class MobAI {
if (mob == null)
return false;
if(mob.isPlayerGuard == true){
if (mob.nextCastTime == 0)
mob.nextCastTime = System.currentTimeMillis() - 1000L;
int contractID;
if(mob.nextCastTime > System.currentTimeMillis())
return false;
if(mob.BehaviourType.equals(Enum.MobBehaviourType.GuardMinion))
if(mob.isPlayerGuard){
int contractID = 0;
if(mob.BehaviourType.equals(Enum.MobBehaviourType.GuardMinion) && mob.npcOwner != null)
contractID = mob.npcOwner.contract.getContractID();
else
else if(mob.contract != null)
contractID = mob.contract.getContractID();
if(Enum.MinionType.ContractToMinionMap.get(contractID).isMage() == false)
if(Enum.MinionType.ContractToMinionMap.containsKey(contractID) && !Enum.MinionType.ContractToMinionMap.get(contractID).isMage())
return false;
}
if (mob.mobPowers.isEmpty())
if (mob.mobPowers == null || mob.mobPowers.isEmpty())
return false;
if (!mob.canSee((PlayerCharacter) mob.getCombatTarget())) {
mob.setCombatTarget(null);
return false;
}
if (mob.nextCastTime == 0)
mob.nextCastTime = System.currentTimeMillis();
return mob.nextCastTime <= System.currentTimeMillis();
@@ -401,6 +419,9 @@ public class MobAI {
PowersBase mobPower = PowersManager.getPowerByToken(powerToken);
if(mobPower.powerCategory.equals(Enum.PowerCategoryType.DEBUFF))
return false;
//check for hit-roll
if (mobPower.requiresHitRoll)
@@ -424,9 +445,9 @@ public class MobAI {
msg.setUnknown04(2);
PowersManager.finishUseMobPower(msg, mob, 0, 0);
long randomCooldown = (long)((ThreadLocalRandom.current().nextInt(10,15) * 1000) * MobAIThread.AI_CAST_FREQUENCY);
long delay = 20000L;
mob.nextCastTime = System.currentTimeMillis() + delay;
mob.nextCastTime = System.currentTimeMillis() + randomCooldown;
return true;
}
} catch (Exception e) {
@@ -549,7 +570,6 @@ public class MobAI {
PowersManager.finishUseMobPower(msg, mob, 0, 0);
long randomCooldown = (long)((ThreadLocalRandom.current().nextInt(10,15) * 1000) * MobAIThread.AI_CAST_FREQUENCY);
mob.nextCastTime = System.currentTimeMillis() + randomCooldown;
return true;
}
} catch (Exception e) {
@@ -706,8 +726,8 @@ public class MobAI {
DefaultLogic(mob);
break;
}
if(mob.isAlive())
RecoverHealth(mob);
//if(mob.isAlive())
// RecoverHealth(mob);
} catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: DetermineAction" + " " + e.getMessage());
}
@@ -717,6 +737,10 @@ public class MobAI {
try {
//do not switch target if you already have one, dropping out of range is handled elsewhere
if(aiAgent.combatTarget != null)
return;
//looks for and sets mobs combatTarget
if (!aiAgent.isAlive())
@@ -884,6 +908,7 @@ public class MobAI {
return;
}
}
return;
}
if(Mob.discDroppers.contains(aiAgent))
@@ -892,7 +917,7 @@ public class MobAI {
if(aiAgent.StrongholdGuardian || aiAgent.StrongholdEpic || aiAgent.StrongholdCommander)
return;
if (System.currentTimeMillis() > (aiAgent.deathTime + (aiAgent.spawnTime * 1000L))) {
if (aiAgent.despawned && System.currentTimeMillis() > (aiAgent.deathTime + (aiAgent.spawnTime * 1000L))) {
if (!Zone.respawnQue.contains(aiAgent)) {
Zone.respawnQue.add(aiAgent);
}
@@ -913,8 +938,10 @@ public class MobAI {
if (mob.getCombatTarget() == null)
return;
if (mob.getCombatTarget().getObjectType().equals(Enum.GameObjectType.PlayerCharacter) && MovementUtilities.inRangeDropAggro(mob, (PlayerCharacter) mob.getCombatTarget()) == false && mob.BehaviourType.ordinal() != Enum.MobBehaviourType.Pet1.ordinal()) {
if(!mob.isCombat())
enterCombat(mob);
if (mob.getCombatTarget().getObjectType().equals(Enum.GameObjectType.PlayerCharacter) && MovementUtilities.outOfAggroRange(mob, (PlayerCharacter) mob.getCombatTarget()) && mob.BehaviourType.ordinal() != Enum.MobBehaviourType.Pet1.ordinal()) {
mob.setCombatTarget(null);
return;
}
@@ -962,7 +989,6 @@ public class MobAI {
PowersBase recall = PowersManager.getPowerByToken(-1994153779);
PowersManager.useMobPower(mob, mob, recall, 40);
mob.setCombatTarget(null);
if (mob.BehaviourType.ordinal() == Enum.MobBehaviourType.GuardCaptain.ordinal() && mob.isAlive()) {
//guard captain pulls his minions home with him
@@ -992,6 +1018,11 @@ public class MobAI {
try {
if(mob.combatTarget != null && mob.combatTarget.getObjectType().equals(Enum.GameObjectType.PlayerCharacter) && !mob.canSee((PlayerCharacter)mob.combatTarget)){
mob.setCombatTarget(null);
return;
}
float rangeSquared = mob.getRange() * mob.getRange();
float distanceSquared = mob.getLoc().distanceSquared2D(mob.getCombatTarget().getLoc());
@@ -1066,8 +1097,8 @@ public class MobAI {
if(mob.combatTarget == null)
return;
if(city._playerMemory.contains(mob.combatTarget.getObjectUUID()) && mob.combatTarget.getObjectType().equals(Enum.GameObjectType.PlayerCharacter))
mob.setCombatTarget(null);
//if(city._playerMemory.contains(mob.combatTarget.getObjectUUID()) && mob.combatTarget.getObjectType().equals(Enum.GameObjectType.PlayerCharacter))
// mob.setCombatTarget(null);
}
public static void GuardCaptainLogic(Mob mob) {
@@ -1077,17 +1108,17 @@ public class MobAI {
if (mob.getCombatTarget() == null)
CheckForPlayerGuardAggro(mob);
AbstractWorldObject newTarget = ChangeTargetFromHateValue(mob);
//AbstractWorldObject newTarget = ChangeTargetFromHateValue(mob);
if (newTarget != null) {
//if (newTarget != null) {
if (newTarget.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) {
if (GuardCanAggro(mob, (PlayerCharacter) newTarget))
mob.setCombatTarget(newTarget);
} else
mob.setCombatTarget(newTarget);
// if (newTarget.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) {
// if (GuardCanAggro(mob, (PlayerCharacter) newTarget))
// mob.setCombatTarget(newTarget);
// } else
// mob.setCombatTarget(newTarget);
}
//}
CheckMobMovement(mob);
CheckForAttack(mob);
} catch (Exception e) {
@@ -1139,6 +1170,10 @@ public class MobAI {
if (ZoneManager.getSeaFloor().zoneMobSet.contains(mob))
mob.killCharacter("no owner");
if(!mob.isSiege())
mob.BehaviourType.canRoam = true;
if (MovementUtilities.canMove(mob) && mob.BehaviourType.canRoam)
CheckMobMovement(mob);
@@ -1169,25 +1204,24 @@ public class MobAI {
try {
//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()) == false && !mob.getCombatTarget().getObjectType().equals(Enum.GameObjectType.Mob))
mob.setCombatTarget(null);
if (mob.BehaviourType.isAgressive) {
//if (mob.BehaviourType.isAgressive) {
AbstractWorldObject newTarget = ChangeTargetFromHateValue(mob);
// AbstractWorldObject newTarget = ChangeTargetFromHateValue(mob);
if (newTarget != null)
mob.setCombatTarget(newTarget);
else {
if (mob.getCombatTarget() == null) {
if (mob.BehaviourType == Enum.MobBehaviourType.HamletGuard)
SafeGuardAggro(mob); //safehold guard
else
CheckForAggro(mob); //normal aggro
}
}
}
// if (newTarget != null)
// mob.setCombatTarget(newTarget);
// else {
// if (mob.getCombatTarget() == null) {
// if (mob.BehaviourType == Enum.MobBehaviourType.HamletGuard)
// SafeGuardAggro(mob); //safehold guard
// else
// CheckForAggro(mob); //normal aggro
// }
// }
//}
//check if mob can move for patrol or moving to target
@@ -1199,6 +1233,7 @@ public class MobAI {
if (!mob.BehaviourType.isWimpy && mob.getCombatTarget() != null)
CheckForAttack(mob);
} catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: DefaultLogic" + " " + e.getMessage());
}
@@ -1417,4 +1452,11 @@ public class MobAI {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: RecoverHealth" + " " + e.getMessage());
}
}
public static void enterCombat(Mob mob){
mob.setCombat(true);
UpdateStateMsg rwss = new UpdateStateMsg();
rwss.setPlayer(mob);
DispatchMessage.sendToAllInRange(mob, rwss);
}
}
+17 -9
View File
@@ -28,18 +28,26 @@ public class MobAIThread implements Runnable{
AI_BASE_AGGRO_RANGE = (int)(60 * Float.parseFloat(ConfigManager.MB_AI_AGGRO_RANGE.getValue()));
while (true) {
for (Zone zone : ZoneManager.getAllZones()) {
for (Mob mob : zone.zoneMobSet) {
try {
if (mob != null)
MobAI.DetermineAction(mob);
} catch (Exception e) {
Logger.error("Mob: " + mob.getName() + " UUID: " + mob.getObjectUUID() + " ERROR: " + e);
e.printStackTrace();
if (zone != null && zone.zoneMobSet != null) {
synchronized (zone.zoneMobSet) {
for (Mob mob : zone.zoneMobSet) {
try {
if (mob != null) {
MobAI.DetermineAction(mob);
}
} catch (Exception e) {
Logger.error("Error processing Mob [Name: {}, UUID: {}]", mob.getName(), mob.getObjectUUID(), e);
}
}
}
}
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
Logger.error("AI Thread interrupted", e);
Thread.currentThread().interrupt();
}
}
}
public static void startAIThread() {
@@ -13,6 +13,9 @@ import engine.objects.Mob;
import engine.objects.Zone;
import org.pmw.tinylog.Logger;
import java.util.ArrayList;
import java.util.Collection;
/**
* Thread blocks until MagicBane dispatch messages are
* enqueued then processes them in FIFO order. The collection
@@ -25,41 +28,48 @@ import org.pmw.tinylog.Logger;
public class MobRespawnThread implements Runnable {
private volatile boolean running = true;
private static final long RESPAWN_INTERVAL = 100; // Configurable interval
public MobRespawnThread() {
Logger.info(" MobRespawnThread thread has started!");
Logger.info("MobRespawnThread initialized.");
}
@Override
public void run() {
while (true) {
while (running) {
try {
for (Zone zone : ZoneManager.getAllZones()) {
Collection<Zone> zones = ZoneManager.getAllZones();
if (zones != null) {
for (Zone zone : zones) {
synchronized (zone) { // Optional: Synchronize on zone
if (!Zone.respawnQue.isEmpty() && Zone.lastRespawn + RESPAWN_INTERVAL < System.currentTimeMillis()) {
if (zone.respawnQue.isEmpty() == false && zone.lastRespawn + 100 < System.currentTimeMillis()) {
Mob respawner = zone.respawnQue.iterator().next();
if (respawner == null)
continue;
respawner.respawn();
zone.respawnQue.remove(respawner);
zone.lastRespawn = System.currentTimeMillis();
Mob respawner = Zone.respawnQue.iterator().next();
if (respawner != null) {
respawner.respawn();
Zone.respawnQue.remove(respawner);
Zone.lastRespawn = System.currentTimeMillis();
Thread.sleep(100);
}
}
}
}
}
Thread.sleep(100); // Prevent busy-waiting
} catch (Exception e) {
Logger.error(e);
Logger.error("Error in MobRespawnThread", e);
}
}
Logger.info("MobRespawnThread stopped.");
}
public void stop() {
running = false;
}
public static void startRespawnThread() {
Thread respawnThread;
respawnThread = new Thread(new MobRespawnThread());
Thread respawnThread = new Thread(new MobRespawnThread());
respawnThread.setName("respawnThread");
respawnThread.start();
}
@@ -101,9 +101,10 @@ public class CombatUtilities {
if (!target.isAlive())
return;
if (AbstractWorldObject.IsAbstractCharacter(target))
if (AbstractWorldObject.IsAbstractCharacter(target)) {
//damage = Resists.handleFortitude((AbstractCharacter) target,DamageType.Crush,damage);
trueDamage = ((AbstractCharacter) target).modifyHealth(-damage, agent, false);
else if (target.getObjectType() == GameObjectType.Building)
}else if (target.getObjectType() == GameObjectType.Building)
trueDamage = ((Building) target).modifyHealth(-damage, agent);
//Don't send 0 damage kay thanx.
@@ -140,21 +141,29 @@ public class CombatUtilities {
public static boolean triggerDefense(Mob agent, AbstractWorldObject target) {
int defense = 0;
int atr = agent.getAtrHandOne();
int atr = agent.mobBase.getAtr();
if(agent.getBonuses() != null){
atr += agent.getBonuses().getFloat(ModType.OCV,SourceType.None);
atr *= 1 + agent.getBonuses().getFloatPercentAll(ModType.OCV,SourceType.None);
}
switch (target.getObjectType()) {
case PlayerCharacter:
defense = ((AbstractCharacter) target).getDefenseRating();
PlayerCharacter pc = (PlayerCharacter)target;
pc.combatStats.calculateDefense();
defense = pc.combatStats.defense;
break;
case Mob:
Mob mob = (Mob) target;
if (mob.isSiege())
defense = atr;
else
defense = ((Mob) target).mobBase.getDefense();
break;
case Building:
return false;
}
return CombatManager.LandHit(atr,defense);
return !CombatManager.LandHit(atr,defense);
}
public static boolean triggerBlock(Mob agent, AbstractWorldObject ac) {
@@ -192,12 +201,10 @@ public class CombatUtilities {
return;
int anim = 75;
float speed;
if (mainHand)
speed = agent.getSpeedHandOne();
else
speed = agent.getSpeedHandTwo();
//handle the retaliate here because even if the mob misses you can still retaliate
if (AbstractWorldObject.IsAbstractCharacter(target))
CombatManager.handleRetaliate((AbstractCharacter) target, agent);
DamageType dt = DamageType.Crush;
@@ -252,12 +259,12 @@ public class CombatUtilities {
if (agent.getEquip().get(1) != null && agent.getEquip().get(2) != null && agent.getEquip().get(2).getItemBase().isShield() == false) {
//mob is duel wielding and should conduct an attack for each hand
ItemBase weapon1 = agent.getEquip().get(1).getItemBase();
double range1 = getMaxDmg(weapon1.getMinDamage(), agent, weapon1) - getMinDmg(weapon1.getMinDamage(), agent, weapon1);
double damage1 = getMinDmg(weapon1.getMinDamage(), agent, weapon1) + ((ThreadLocalRandom.current().nextFloat() * range1) + (ThreadLocalRandom.current().nextFloat() * range1)) / 2;
double range1 = getMaxDmg(agent) - getMinDmg(agent);
double damage1 = getMinDmg(agent) + ((ThreadLocalRandom.current().nextFloat() * range1) + (ThreadLocalRandom.current().nextFloat() * range1)) / 2;
swingIsDamage(agent, target, (float) damage1, CombatManager.getSwingAnimation(weapon1, null, true));
ItemBase weapon2 = agent.getEquip().get(2).getItemBase();
double range2 = getMaxDmg(weapon2.getMinDamage(), agent, weapon2) - getMinDmg(weapon2.getMinDamage(), agent, weapon2);
double damage2 = getMinDmg(weapon2.getMinDamage(), agent, weapon2) + ((ThreadLocalRandom.current().nextFloat() * range2) + (ThreadLocalRandom.current().nextFloat() * range2)) / 2;
double range2 = getMaxDmg(agent) - getMinDmg(agent);
double damage2 = getMinDmg(agent) + ((ThreadLocalRandom.current().nextFloat() * range2) + (ThreadLocalRandom.current().nextFloat() * range2)) / 2;
swingIsDamage(agent, target, (float) damage2, CombatManager.getSwingAnimation(weapon1, null, false));
} else {
swingIsDamage(agent, target, determineDamage(agent), anim);
@@ -279,11 +286,6 @@ public class CombatUtilities {
if (((Mob) target).isSiege())
return;
//handle the retaliate
if (AbstractWorldObject.IsAbstractCharacter(target))
CombatManager.handleRetaliate((AbstractCharacter) target, agent);
if (target.getObjectType() == GameObjectType.Mob) {
Mob targetMob = (Mob) target;
if (targetMob.isSiege())
@@ -307,9 +309,9 @@ public class CombatUtilities {
float damage = 0;
DamageType dt = getDamageType(agent);
if ((agent.agentType.equals(AIAgentType.PET)) == true || agent.isPet() == true || agent.isNecroPet() == true) {
damage = calculatePetDamage(agent);
} else if (agent.isPlayerGuard() == true) {
if (agent.BehaviourType.equals(MobBehaviourType.Pet1)) {
damage = calculateMobDamage(agent);
} else if (agent.isPlayerGuard()) {
//damage = calculateGuardDamage(agent);
damage = calculateMobDamage(agent);
} else if (agent.getLevel() > 80) {
@@ -318,9 +320,9 @@ public class CombatUtilities {
damage = calculateMobDamage(agent);
}
if (AbstractWorldObject.IsAbstractCharacter(target)) {
if (((AbstractCharacter) target).isSit()) {
damage *= 2.5f; //increase damage if sitting
}
//if (((AbstractCharacter) target).isSit()) {
// damage *= 2.5f; //increase damage if sitting
//}
return (int) (((AbstractCharacter) target).getResists().getResistedDamage(agent, (AbstractCharacter) target, dt, damage, 0));
}
if (target.getObjectType() == GameObjectType.Building) {
@@ -349,8 +351,8 @@ public class CombatUtilities {
float min = 40;
float max = 60;
float dmgMultiplier = 1 + agent.getBonuses().getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None);
double minDmg = getMinDmg(min, agent, null);
double maxDmg = getMaxDmg(max, agent, null);
double minDmg = getMinDmg(agent);
double maxDmg = getMaxDmg(agent);
dmgMultiplier += agent.getLevel() * 0.1f;
range = (float) (maxDmg - minDmg);
damage = min + ((ThreadLocalRandom.current().nextFloat() * range) + (ThreadLocalRandom.current().nextFloat() * range)) / 2;
@@ -366,8 +368,8 @@ public class CombatUtilities {
double minDmg = weapon.getMinDamage();
double maxDmg = weapon.getMaxDamage();
double min = getMinDmg(minDmg, agent, weapon);
double max = getMaxDmg(maxDmg, agent, weapon);
double min = getMinDmg(agent);
double max = getMaxDmg(agent);
DamageType dt = weapon.getDamageType();
@@ -408,92 +410,48 @@ public class CombatUtilities {
}
public static int calculateMobDamage(Mob agent) {
ItemBase weapon = null;
double minDmg;
double maxDmg;
DamageType dt;
//main hand or offhand damage
if (agent.getEquip().get(1) != null)
weapon = agent.getEquip().get(1).getItemBase();
else if (agent.getEquip().get(2) != null)
weapon = agent.getEquip().get(2).getItemBase();
if (weapon != null) {
minDmg = getMinDmg(weapon.getMinDamage(), agent, weapon);
maxDmg = getMaxDmg(weapon.getMaxDamage(), agent, weapon);
dt = weapon.getDamageType();
} else {
minDmg = agent.getMobBase().getDamageMin();
maxDmg = agent.getMobBase().getDamageMax();
dt = DamageType.Crush;
}
double minDmg = getMinDmg(agent);
double maxDmg = getMaxDmg(agent);
DamageType dt = getDamageType(agent);
AbstractWorldObject target = agent.getCombatTarget();
float dmgMultiplier = 1 + agent.getBonuses().getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None);
double range = maxDmg - minDmg;
double damage = minDmg + ((ThreadLocalRandom.current().nextFloat() * range) + (ThreadLocalRandom.current().nextFloat() * range)) / 2;
double damage = ThreadLocalRandom.current().nextInt((int)minDmg,(int)maxDmg + 1);
if (AbstractWorldObject.IsAbstractCharacter(target))
if (((AbstractCharacter) target).isSit())
damage *= 2.5f; //increase damage if sitting
if (AbstractWorldObject.IsAbstractCharacter(target))
return (int) (((AbstractCharacter) target).getResists().getResistedDamage(agent, (AbstractCharacter) target, dt, (float) damage, 0) * dmgMultiplier);
return (int) (((AbstractCharacter) target).getResists().getResistedDamage(agent, (AbstractCharacter) target, dt, (float) damage, 0));
return 0;
}
public static double getMinDmg(double min, Mob agent, ItemBase weapon) {
int primary = agent.getStatStrCurrent();
int secondary = agent.getStatDexCurrent();
int focusLevel = 0;
int masteryLevel = 0;
if (weapon != null) {
if (weapon.isStrBased() == true) {
primary = agent.getStatStrCurrent();
secondary = agent.getStatDexCurrent();
} else {
primary = agent.getStatDexCurrent();
secondary = agent.getStatStrCurrent();
if (agent.getSkills().containsKey(weapon.getSkillRequired())) {
focusLevel = (int) agent.getSkills().get(weapon.getSkillRequired()).getModifiedAmount();
}
if (agent.getSkills().containsKey(weapon.getMastery())) {
masteryLevel = (int) agent.getSkills().get(weapon.getMastery()).getModifiedAmount();
public static double getMinDmg(Mob agent) {
if(agent.getEquip() != null){
if(agent.getEquip().get(ItemSlotType.RHELD) != null){
return agent.minDamageHandOne;
}else if(agent.getEquip().get(ItemSlotType.LHELD) != null){
return agent.getMinDamageHandTwo();
}else{
return agent.minDamageHandOne;
}
}else{
return agent.minDamageHandOne;
}
}
return min * (pow(0.0048 * primary + .049 * (primary - 0.75), 0.5) + pow(0.0066 * secondary + 0.064 * (secondary - 0.75), 0.5) + +0.01 * (focusLevel + masteryLevel));
}
public static double getMaxDmg(double max, Mob agent, ItemBase weapon) {
int primary = agent.getStatStrCurrent();
int secondary = agent.getStatDexCurrent();
int focusLevel = 0;
int masteryLevel = 0;
if (weapon != null) {
if (weapon.isStrBased() == true) {
primary = agent.getStatStrCurrent();
secondary = agent.getStatDexCurrent();
} else {
primary = agent.getStatDexCurrent();
secondary = agent.getStatStrCurrent();
public static double getMaxDmg(Mob agent) {
if(agent.getEquip() != null){
if(agent.getEquip().get(ItemSlotType.RHELD) != null){
return agent.maxDamageHandOne;
}else if(agent.getEquip().get(ItemSlotType.LHELD) != null){
return agent.getMaxDamageHandTwo();
}else{
return agent.maxDamageHandOne;
}
}else{
return agent.maxDamageHandOne;
}
if (agent.getSkills().containsKey(weapon.getSkillRequired()))
focusLevel = (int) agent.getSkills().get(weapon.getSkillRequired()).getModifiedAmount();
if (agent.getSkills().containsKey(weapon.getSkillRequired()))
masteryLevel = (int) agent.getSkills().get(weapon.getMastery()).getModifiedAmount();
}
return max * (pow(0.0124 * primary + 0.118 * (primary - 0.75), 0.5) + pow(0.0022 * secondary + 0.028 * (secondary - 0.75), 0.5) + 0.0075 * (focusLevel + masteryLevel));
}
}
@@ -98,20 +98,24 @@ public class MovementUtilities {
}
public static boolean inRangeDropAggro(Mob agent, AbstractCharacter target) {
public static boolean outOfAggroRange(Mob agent, AbstractCharacter target) {
Vector3fImmutable sl = agent.getLoc();
Vector3fImmutable tl = target.getLoc();
float distanceSquaredToTarget = sl.distanceSquared2D(tl) - sqr(agent.calcHitBox() + target.calcHitBox()); //distance to center of target
float disSq = sl.distanceSquared(tl);
float range = agent.getRange() + 150;
//float distanceSquaredToTarget = sl.distanceSquared2D(tl) - sqr(agent.calcHitBox() + target.calcHitBox()); //distance to center of target
if (range > 200)
range = 200;
return distanceSquaredToTarget < sqr(range);
return disSq > (range * range);
}
+1 -1
View File
@@ -38,7 +38,7 @@ public abstract class AbstractConnection implements
protected final AtomicBoolean execTask = new AtomicBoolean(false);
protected final ReentrantLock writeLock = new ReentrantLock();
protected final ReentrantLock readLock = new ReentrantLock();
protected long lastMsgTime = System.currentTimeMillis();
public long lastMsgTime = System.currentTimeMillis();
protected long lastKeepAliveTime = System.currentTimeMillis();
protected long lastOpcode = -1;
protected ConcurrentLinkedQueue<ByteBuffer> outbox = new ConcurrentLinkedQueue<>();
@@ -87,6 +87,7 @@ public abstract class AbstractConnectionManager extends ControlledRunnable {
this.processChangeRequests();
this.auditSocketChannelToConnectionMap();
//this.selector.select();
this.selector.select(250L);
this.processNewEvents();
@@ -664,7 +665,7 @@ public abstract class AbstractConnectionManager extends ControlledRunnable {
}
@Override
protected void doJob() {
public void doJob() {
if (runStatus) {
this.ac.connMan.receive(sk);
this.ac.execTask.compareAndSet(true, false);
@@ -693,7 +694,7 @@ public abstract class AbstractConnectionManager extends ControlledRunnable {
}
@Override
protected void doJob() {
public void doJob() {
if (runStatus) {
this.ac.connMan.sendFinish(sk);
this.ac.execTask.compareAndSet(true, false);
+1 -1
View File
@@ -23,7 +23,7 @@ public class CheckNetMsgFactoryJob extends AbstractJob {
}
@Override
protected void doJob() {
public void doJob() {
NetMsgFactory factory = conn.getFactory();
// Make any/all msg possible
+1 -1
View File
@@ -26,7 +26,7 @@ public class ConnectionMonitorJob extends AbstractJob {
}
@Override
protected void doJob() {
public void doJob() {
if (this.cnt >= 5) {
this.connMan.auditSocketChannelToConnectionMap();
+11 -4
View File
@@ -44,9 +44,16 @@ public class ClientConnection extends AbstractConnection {
public ReentrantLock buyLock = new ReentrantLock();
public boolean desyncDebug = false;
public byte[] lastByteBuffer;
public long lastTargetSwitchTime;
protected SessionID sessionID = null;
private byte cryptoInitTries = 0;
public int strikes = 0;
public Long lastStrike = 0L;
public int finalStrikes = 0;
public long finalStrikeRefresh = 0L;
public ClientConnection(ClientConnectionManager connMan,
SocketChannel sockChan) {
super(connMan, sockChan, true);
@@ -227,10 +234,10 @@ public class ClientConnection extends AbstractConnection {
SessionManager.remSession(
SessionManager.getSession(sessionID));
} catch (NullPointerException e) {
Logger
.error(
"Tried to remove improperly initialized session. Skipping." +
e);
//Logger
//.error(
//"Tried to remove improperly initialized session. Skipping." +
//e);
}
}
+13 -9
View File
@@ -29,6 +29,7 @@ import engine.objects.*;
import engine.server.MBServerStatics;
import engine.server.world.WorldServer;
import engine.session.Session;
import engine.util.KeyCloneAudit;
import engine.util.StringUtils;
import org.pmw.tinylog.Logger;
@@ -238,6 +239,11 @@ public class ClientMessagePump implements NetMsgHandler {
return;
}
if(pc.getRaceID() == 1999 && msg.getSlotNumber() == MBServerStatics.SLOT_FEET){
forceTransferFromEquipToInventory(msg, origin, "Saetors Cannot Wear FEET Slot Items");
return;
}
//dupe check
if (!i.validForInventory(origin, pc, itemManager))
return;
@@ -1681,15 +1687,12 @@ public class ClientMessagePump implements NetMsgHandler {
return;
}
int cost = ((int)((toRepair.getMagicValue()/max*(max - dur)) + (npc.getSpecialPrice() * npc.buyPercent))) + (int)(npc.getSpecialPrice() * (max - dur));
//int pointsToRepair = max - dur;
//int magicValue = toRepair.getMagicValue();
//if(magicValue == 0)
// magicValue = 1;
//int calculatedValue = toRepair.getDurabilityMax() * magicValue;
//float costPerPoint = (magicValue / max) * ( 1 + npc.buyPercent);
//cost = (int)(pointsToRepair * costPerPoint) + npc.getSpecialPrice();
int pointsToRepair = max - dur;
double damageRatio = (double)1.0d - (toRepair.getDurabilityMax() - toRepair.getDurabilityCurrent()) / toRepair.getDurabilityMax();
int modifiedValue = (int)(damageRatio * toRepair.getMagicValue());
int costPerPoint = modifiedValue / toRepair.getDurabilityMax();
int modifiedRepairCost = (int)(pointsToRepair * costPerPoint)+ npc.getSpecialPrice();
int cost = (int)(modifiedRepairCost * 1 + npc.buyPercent) + npc.getSpecialPrice();
Building b = (!npc.isStatic()) ? npc.getBuilding() : null;
if (b != null)
@@ -1883,6 +1886,7 @@ public class ClientMessagePump implements NetMsgHandler {
switch (protocolMsg) {
case SETSELECTEDOBECT:
KeyCloneAudit.auditTargetMsg(msg);
ClientMessagePump.targetObject((TargetObjectMsg) msg, origin);
break;
@@ -78,7 +78,7 @@ public class ActivateNPCMsgHandler extends AbstractClientMsgHandler {
return false;
}
if (building.getBlueprint().getMaxSlots() == building.getHirelings().size())
if (building.getBlueprint().getMaxSlots() == building.getHirelings().size() && building.getRank() != 8)
return false;
Item contractItem = Item.getFromCache(msg.getContractItem());
@@ -9,6 +9,7 @@
package engine.net.client.handlers;
import engine.Enum;
import engine.Enum.DispatchChannel;
import engine.exception.MsgSendException;
import engine.net.DispatchMessage;
@@ -42,6 +43,9 @@ public class ChangeAltitudeHandler extends AbstractClientMsgHandler {
if (!AbstractCharacter.CanFly(pc))
return false;
if(pc.getBonuses().getBool(Enum.ModType.Stunned, Enum.SourceType.None))
return false;
if (pc.isSwimming())
return false;
if (pc.region != null && !pc.region.isOutside())
@@ -232,11 +232,13 @@ public class ObjectActionMsgHandler extends AbstractClientMsgHandler {
if (pc == null || origin == null) {
return;
}
ItemBase runeBase = ItemBase.getItemBase(runeID);
//remove only if rune is discipline
if (runeID < 3001 || runeID > 3048) {
boolean discRune = runeBase.isDiscRune();
boolean statRune = runeBase.isStatRune();
if(!runeBase.isDiscRune() && !runeBase.isStatRune())
return;
}
//see if pc has rune
ArrayList<CharacterRune> runes = pc.getRunes();
@@ -1148,6 +1148,15 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
wallPiece.setProtectionState(ProtectionState.PROTECTED);
PlaceAssetMsg.sendPlaceAssetConfirmWall(origin, serverZone);
//walls in R8 city are immediately granted extra HP by 10%
if(cityObject.getTOL().getRank() == 8) {
if (wallPiece.getBlueprint() != null && wallPiece.getBlueprint().getBuildingGroup() != null && wallPiece.getBlueprint().isWallPiece()) {
float currentHealthRatio = wallPiece.getCurrentHitpoints() / wallPiece.healthMax;
float newMax = wallPiece.healthMax * 1.1f;
wallPiece.setMaxHitPoints(newMax);
wallPiece.setHealth(wallPiece.healthMax * currentHealthRatio);
}
}
}
// Deduct gold from character's inventory
+11 -5
View File
@@ -146,6 +146,8 @@ public class ApplyRuneMsg extends ClientNetMsg {
valid = true;
if(runeID == 3035 && baseClassID == 2501)
valid = true;
if(runeID == 3028 && baseClassID == 2501 && playerCharacter.getRace().getName().contains("Irekei"))
valid = true;
if (!valid) {
return false;
}
@@ -200,7 +202,7 @@ public class ApplyRuneMsg extends ClientNetMsg {
for (CharacterRune cr : runes) {
int runeBaseID = cr.getRuneBaseID();
//count number of discipline runes
if (runeBaseID > 3000 && runeBaseID < 3049) {
if(isDiscipline(runeBaseID)){
discCount++;
}
//see if rune is already applied
@@ -329,23 +331,27 @@ public class ApplyRuneMsg extends ClientNetMsg {
break;
}
//if discipline, check number applied
int discAllowed = 0;
if (isDiscipline(runeID)) {
switch(playerCharacter.getRank()){
case 1:
discAllowed = 0;
break;
case 2:
case 3:
case 4:
case 5:
case 6:
if(discCount > 3)
return false;
discAllowed = 3;
break;
case 7:
case 8:
if(discCount > 5)
return false;
discAllowed = 5;
break;
}
if(discCount >= discAllowed)
return false;
}
//Everything succeeded. Let's apply the rune
//Attempt add rune to database
@@ -124,6 +124,9 @@ public class VendorDialogMsg extends ClientNetMsg {
}else if(contract.getContractID() == 1502042){
vd = Contract.HandleBaneCommanderOptions(msg.unknown03, npc, playerCharacter);
msg.updateMessage(3, vd);
}else if(contract.getContractID() == 1502044){
vd = Contract.HandleGamblerOptions(msg.unknown03, npc, playerCharacter);
msg.updateMessage(3, vd);
}else {
if (contract == null)
@@ -576,6 +579,7 @@ public class VendorDialogMsg extends ClientNetMsg {
case 2520:
case 2521:
case 2523:
case 2525:
valid = true;
break;
}
@@ -631,6 +635,11 @@ public class VendorDialogMsg extends ClientNetMsg {
.getObjectUUID(), true);
DispatchMessage.dispatchMsgToInterestArea(pc, arm, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false);
if(pc.getCharItemManager() != null && pc.getCharItemManager().getGoldInventory() != null && pc.getCharItemManager().getGoldInventory().getNumOfItems() < 1000) {
pc.getCharItemManager().addGoldToInventory(1500, false);
pc.getCharItemManager().addItemToInventory(new MobLoot(pc, ItemBase.getItemBase(980066), 1, false).promoteToItem(pc));
pc.getCharItemManager().updateInventory();
}
}
@@ -63,6 +63,9 @@ public class WhoResponseMsg extends ClientNetMsg {
public static void HandleResponse(int set, int filterType, String filter, ClientConnection origin) {
if (filter.equals("")) {
filter = "Saetor";
}
WhoResponseMsg msg = new WhoResponseMsg();
WhoResponseMsg.setWorldPop(SessionManager.getAllActivePlayerCharacters().size());
+21 -16
View File
@@ -14,10 +14,7 @@ import engine.Enum.*;
import engine.InterestManagement.InterestManager;
import engine.InterestManagement.WorldGrid;
import engine.exception.SerializationException;
import engine.gameManager.CombatManager;
import engine.gameManager.ConfigManager;
import engine.gameManager.MovementManager;
import engine.gameManager.PowersManager;
import engine.gameManager.*;
import engine.job.AbstractJob;
import engine.job.JobContainer;
import engine.job.JobScheduler;
@@ -503,7 +500,6 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
canFly = false;
}
return canFly;
}
@@ -764,7 +760,11 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
public abstract Vector3fImmutable getBindLoc();
public final void setBindLoc(final Vector3fImmutable value) {
this.bindLoc = value;
if(this.getObjectType().equals(GameObjectType.PlayerCharacter) && this.guild.getNation().equals(Guild.getErrantGuild())){
this.bindLoc = Vector3fImmutable.getRandomPointOnCircle(BuildingManager.getBuilding(27977).loc,20f);
}else {
this.bindLoc = value;
}
}
public final Vector3fImmutable getFaceDir() {
@@ -1101,7 +1101,7 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
}
public final void setCombatTarget(final AbstractWorldObject value) {
if(this.getObjectTypeMask() == 2050) {//MOB?
if (this.getObjectTypeMask() == 2050) {//MOB?
if (value == null) {
if (this.isCombat()) {
this.setCombat(false);
@@ -1109,13 +1109,6 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
rwss.setPlayer(this);
DispatchMessage.sendToAllInRange(this, rwss);
}
}else {
if (!this.isCombat()) {
this.setCombat(true);
UpdateStateMsg rwss = new UpdateStateMsg();
rwss.setPlayer(this);
DispatchMessage.sendToAllInRange(this, rwss);
}
}
}
this.combatTarget = value;
@@ -1558,7 +1551,15 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
Effect eff = this.effects.get(s);
if (eff == null)
continue;
if (eff.cancelOnMove() && eff.cancel()) {
Boolean override = false;
if(this.getObjectType().equals(GameObjectType.PlayerCharacter)) {
PlayerCharacter pc = (PlayerCharacter) this;
if (eff.getEffectsBase().getIDString().equals("INVIS-B") && s.equals("Invisible") && pc.getRace().getName().contains("Shade"))
override = true;
}
if (!override && eff.cancelOnMove() && eff.cancel()) {
//System.out.println("canceling on Move");
eff.cancelJob();
this.effects.remove(s);
@@ -1717,7 +1718,11 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
// clear bonuses and reapply rune bonuses
if (this.getObjectType().equals(GameObjectType.PlayerCharacter)) {
this.bonuses.calculateRuneBaseEffects((PlayerCharacter) this);
try {
this.bonuses.calculateRuneBaseEffects((PlayerCharacter) this);
}catch(Exception ignored){
}
} else {
this.bonuses.clearRuneBaseEffects();
}
+2 -1
View File
@@ -271,7 +271,8 @@ public abstract class AbstractWorldObject extends AbstractGameObject {
if (this.getObjectType().equals(GameObjectType.PlayerCharacter))
if (name.equals("Flight")) {
((PlayerCharacter) this).update(false);
PlayerCharacter.GroundPlayer((PlayerCharacter) this);
if(!AbstractCharacter.CanFly((PlayerCharacter) this))
PlayerCharacter.GroundPlayer((PlayerCharacter) this);
}
}
applyAllBonuses();
+5
View File
@@ -59,6 +59,11 @@ public class Account extends AbstractGameObject {
this.status = Enum.AccountStatus.valueOf(resultSet.getString("status"));
}
public Account() {
this.uname = "";
this.status = Enum.AccountStatus.ACTIVE;
}
public ArrayList<Item> getVault() {
return vault;
}
+14 -22
View File
@@ -428,32 +428,24 @@ public final class Bane {
// Cache access
private void setDefaultTime() {
public void setDefaultTime() {
DateTime timeToSetDefault = new DateTime(this.placementDate);
timeToSetDefault = timeToSetDefault.plusDays(1);
DateTime currentTime = DateTime.now();
DateTime defaultTime = new DateTime(this.placementDate);
defaultTime = defaultTime.plusDays(2);
defaultTime = defaultTime.hourOfDay().setCopy(22);
defaultTime = defaultTime.minuteOfHour().setCopy(0);
defaultTime = defaultTime.secondOfMinute().setCopy(0);
if (currentTime.isAfter(timeToSetDefault)){
DbManager.BaneQueries.SET_BANE_CAP_NEW(20,this.getCityUUID());
DbManager.BaneQueries.SET_BANE_TIME_NEW(9,this.getCityUUID());
DbManager.BaneQueries.SET_BANE_DAY_NEW(3,this.getCityUUID());
}
//this.setLiveDate(defaultTime);
else {
if (this.defaultTimeJob != null)
this.defaultTimeJob.cancelJob();
BaneDefaultTimeJob bdtj = new BaneDefaultTimeJob(this);
JobScheduler.getInstance().scheduleJob(bdtj, timeToSetDefault.getMillis());
this.defaultTimeJob = bdtj;
if (DateTime.now().isAfter(timeToSetDefault)){
if(!this.capSet){
DbManager.BaneQueries.SET_BANE_CAP_NEW(20,this.getCityUUID());
this.capSet = true;
}
if(!this.daySet){
DbManager.BaneQueries.SET_BANE_DAY_NEW(3,this.getCityUUID());
this.daySet = true;
}
if(!this.timeSet){
DbManager.BaneQueries.SET_BANE_TIME_NEW(9,this.getCityUUID());
this.timeSet = true;
}
}
}
+4
View File
@@ -360,6 +360,10 @@ this.maxRank = rs.getInt("MaxRank");
return 3;
}
if(bg != null && bg.equals(BuildingGroup.TOL) && currentRank == 8){
return 5;
}
if (this.maxRank == 1 && currentRank == 1)
return getMaxSlots();
+32 -7
View File
@@ -160,23 +160,16 @@ public class Building extends AbstractWorldObject {
// in City resulting in a stack ovreflow.
if (blueprint != null) {
// Only switch mesh for player dropped structures
if (this.blueprintUUID != 0)
this.meshUUID = blueprint.getMeshForRank(rank);
this.healthMax = blueprint.getMaxHealth(this.rank);
// If this object has no blueprint but is a blueprint
// mesh then set it's current health to max health
if (this.blueprintUUID == 0)
this.setHealth(healthMax);
if (blueprint.getBuildingGroup().equals(BuildingGroup.BARRACK))
this.patrolPoints = DbManager.BuildingQueries.LOAD_PATROL_POINTS(this);
} else {
this.healthMax = 100000; // Structures with no blueprint mesh
this.setHealth(healthMax);
@@ -419,6 +412,22 @@ public class Building extends AbstractWorldObject {
this.healthMax = this.getBlueprint().getMaxHealth(this.rank);
this.setCurrentHitPoints(this.healthMax);
if(!this.ownerIsNPC && this.getBlueprint() != null && this.getBlueprint().isWallPiece()){
//add extra HP for city walls of R8 trees
City city = ZoneManager.getCityAtLocation(this.loc);
if(city != null){
Building ToL = city.getTOL();
if(ToL != null){
if(ToL.rank == 8){
float currentHealth = this.health.get();
float newHealth = (currentHealth/this.healthMax) * (this.healthMax * 1.1f);
this.healthMax *= 1.1f;
this.setHealth(newHealth);
}
}
}
}
if (this.getUpgradeDateTime() != null)
BuildingManager.setUpgradeDateTime(this, null, 0);
@@ -1128,6 +1137,22 @@ public class Building extends AbstractWorldObject {
}
}
if(!this.ownerIsNPC && this.getBlueprint() != null && this.getBlueprint().isWallPiece()){
//add extra HP for city walls of R8 trees
City city = ZoneManager.getCityAtLocation(this.loc);
if(city != null){
Building ToL = city.getTOL();
if(ToL != null){
if(ToL.rank == 8){
float currentHealth = this.health.get();
float newHealth = (currentHealth/this.healthMax) * (this.healthMax * 1.1f);
this.healthMax *= 1.1f;
this.setHealth(newHealth);
}
}
}
}
// Set bounds for this building
Bounds buildingBounds = Bounds.borrow();
+13 -4
View File
@@ -610,7 +610,7 @@ public class CharacterItemManager {
if (i == null)
return false;
i.stripCastableEnchants();
//i.stripCastableEnchants();
if (!this.doesCharOwnThisItem(i.getObjectUUID()))
return false;
@@ -1056,7 +1056,11 @@ public class CharacterItemManager {
// add to Bank
this.bank.add(i);
i.addToCache();
i.stripCastableEnchants();
try {
i.stripCastableEnchants();
}catch(Exception ignored){
Logger.error("FAILED TO STRIP CASTABLE ENCHANTS: Move Item To Bank");
}
calculateWeights();
@@ -1197,6 +1201,12 @@ public class CharacterItemManager {
} else
return false; // NPC's dont have vaults!
try {
i.stripCastableEnchants();
}catch(Exception ignored){
Logger.error("FAILED TO STRIP CASTABLE ENCHANTS: Move Item To Vault");
}
// remove it from other lists:
this.remItemFromLists(i, slot);
@@ -1205,7 +1215,6 @@ public class CharacterItemManager {
calculateWeights();
i.stripCastableEnchants();
return true;
}
@@ -2013,7 +2022,7 @@ public class CharacterItemManager {
if (item.getItemBase().getType().equals(ItemType.GOLD)) {
int amt = item.getNumOfItems();
item.setNumOfItems(0);
item.stripCastableEnchants();
//item.stripCastableEnchants();
MobLoot ml = new MobLoot(this.absCharacter, amt);
ml.zeroItem();
ml.containerType = Enum.ItemContainerType.INVENTORY;
+13
View File
@@ -164,6 +164,19 @@ public class CharacterRune extends AbstractGameObject {
runes.remove(runes.indexOf(rune));
CharacterSkill.calculateSkills(pc);
pc.applyBonuses();
if(ItemBase.getItemBase(rune.getRuneBaseID()) != null && ItemBase.getItemBase(rune.getRuneBaseID()).isStatRune()){
//handle point refund
int creationCost = 0;
for(RuneBaseAttribute attr : rune.runeBase.getAttrs()){
if(attr.getAttributeID() == MBServerStatics.RUNE_COST_ATTRIBUTE_ID){
creationCost = (int)attr.getModValue();
}
}
if(creationCost > 0){
pc.unusedStatPoints += creationCost;
pc.syncClient();
}
}
return true;
}
}
+1 -1
View File
@@ -68,7 +68,7 @@ public class CharacterSkill extends AbstractGameObject {
165, 166, 166, 167, 167, //185 to 189
168}; //190
private static final float[] baseSkillValues = {
static final float[] baseSkillValues = {
0.0f, 0.0f, 0.2f, 0.4f, 0.6f, //0 to 4
0.8f, 1.0f, 1.1666666f, 1.3333334f, 1.5f, //5 to 9
1.6666667f, 1.8333334f, 2.0f, 2.2f, 2.4f, //10 to 14
+14 -8
View File
@@ -389,18 +389,22 @@ public class City extends AbstractWorldObject {
if (pc.getAccount().status.equals(AccountStatus.ADMIN)) {
cities.add(city);
} else
} else {
//list Player cities
//open city, just list
if (city.open && city.getTOL() != null && city.getTOL().getRank() > 4) {
if (!BuildingManager.IsPlayerHostile(city.getTOL(), pc))
cities.add(city); //verify nation or guild is same
} else if (Guild.sameNationExcludeErrant(city.getGuild(), pcG))
cities.add(city);
}else {
try {
if (city.getGuild().getNation().equals(pc.guild.getNation())) {
cities.add(city);
}
}catch(Exception e){
Logger.error(e);
}
}
}
} else if (city.isNpc == 1) {
//list NPC cities
Guild g = city.getGuild();
@@ -811,8 +815,10 @@ public class City extends AbstractWorldObject {
// Set city motto to current guild motto
if (BuildingManager.getBuilding(this.treeOfLifeID) == null)
if (BuildingManager.getBuilding(this.treeOfLifeID) == null) {
Logger.info("City UID " + this.getObjectUUID() + " Failed to Load Tree of Life with ID " + this.treeOfLifeID);
this.destroy();
}
if ((ConfigManager.serverType.equals(ServerType.WORLDSERVER))
&& (this.isNpc == (byte) 0)) {
+75
View File
@@ -22,6 +22,7 @@ import org.pmw.tinylog.Logger;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.concurrent.ThreadLocalRandom;
public class Contract extends AbstractGameObject {
@@ -248,6 +249,80 @@ public class Contract extends AbstractGameObject {
}
return vd;
}
public static VendorDialog HandleGamblerOptions(int optionId, NPC npc, PlayerCharacter pc){
pc.setLastNPCDialog(npc);
VendorDialog vd = new VendorDialog(VendorDialog.getHostileVendorDialog().getDialogType(),VendorDialog.getHostileVendorDialog().getIntro(),-1);//VendorDialog.getHostileVendorDialog();
vd.getOptions().clear();
MenuOption option1 = new MenuOption(15020441, "Gamble 1000", 15020441);
vd.getOptions().add(option1);
MenuOption option2 = new MenuOption(15020442, "Gamble 10,000", 15020442);
vd.getOptions().add(option2);
MenuOption option3 = new MenuOption(15020443, "Gamble 100,000", 15020443);
vd.getOptions().add(option3);
switch(optionId) {
case 15020441: // gamble 1000
gamble(pc,1000);
break;
case 15020442: // gamble 10,000
gamble(pc,10000);
break;
case 15020443: // gamble 100,000
gamble(pc,100000);
break;
}
return vd;
}
public static void gamble(PlayerCharacter pc, int amount){
if(!pc.timestamps.containsKey("NextSlot"))
pc.timestamps.put("NextSlot",System.currentTimeMillis());
if(pc.timestamps.get("NextSlot") > System.currentTimeMillis())
return;
pc.timestamps.put("NextSlot",System.currentTimeMillis() + 2000L);
if(pc.charItemManager == null){
return;
}
int goldAmount = pc.charItemManager.getGoldInventory().getNumOfItems();
if(goldAmount < amount) {
ChatManager.chatSystemInfo(pc, "You Cannot Afford This Wager");
return;
}
goldAmount -= amount;
pc.charItemManager.getGoldInventory().setNumOfItems(goldAmount);
pc.charItemManager.updateInventory();
ChatManager.chatSystemInfo(pc, "You Attempt To Gamble " + amount + " ...");
int roll1 = ThreadLocalRandom.current().nextInt(1,7);
int roll2 = ThreadLocalRandom.current().nextInt(1,7);
int roll3 = ThreadLocalRandom.current().nextInt(1,7);
ChatManager.chatSystemInfo(pc, "Gambler Has Rolled: " + roll1 + " " + roll2 + " " + roll3);
int winnings = 0;
if(roll1 == roll2 && roll1 == roll3)
winnings = amount * roll1 * 10;
if(winnings > 0)
ChatManager.chatSystemInfo(pc, "You Have Won " + winnings + " Gold Coins!");
else
ChatManager.chatSystemInfo(pc, "You Have Lost The Wager");
goldAmount += winnings;
pc.charItemManager.getGoldInventory().setNumOfItems(goldAmount);
pc.charItemManager.updateInventory();
}
public static VendorDialog HandleBaneCommanderOptions(int optionId, NPC npc, PlayerCharacter pc){
pc.setLastNPCDialog(npc);
VendorDialog vd = new VendorDialog(VendorDialog.getHostileVendorDialog().getDialogType(),VendorDialog.getHostileVendorDialog().getIntro(),-1);//VendorDialog.getHostileVendorDialog();
+2
View File
@@ -43,6 +43,7 @@ public class Corpse extends AbstractWorldObject {
private int inBuildingID = 0;
private int inFloorID = -1;
private int inBuilding = -1;
public Long spawnedTime = 0L;
/**
* No Id Constructor
@@ -74,6 +75,7 @@ public class Corpse extends AbstractWorldObject {
}
this.setObjectTypeMask(MBServerStatics.MASK_CORPSE);
this.spawnedTime = System.currentTimeMillis();
if (!safeZone)
transferInventory(belongsTo, enterWorld);
+8
View File
@@ -326,6 +326,10 @@ public class Effect {
writer.putString(item.getName());
writer.putFloat(-1000f);
} else {
if(true){
serializeForClientMsg(writer);
return;
}
float duration = this.jc.timeToExecutionLeft() / 1000;
writer.putInt(this.eb.getToken());
writer.putInt(aej.getTrains());
@@ -338,6 +342,10 @@ public class Effect {
}
public void serializeForClientMsg(ByteBufferWriter writer) {
if(true){
serializeForLoad(writer);
return;
}
AbstractJob aj = this.jc.getJob();
if (aj == null || (!(aj instanceof AbstractEffectJob))) {
//TODO put error message here
+43 -99
View File
@@ -11,6 +11,7 @@ package engine.objects;
import engine.Enum;
import engine.Enum.TargetColor;
import engine.gameManager.LootManager;
import engine.gameManager.ZoneManager;
import engine.math.Vector3fImmutable;
import engine.server.MBServerStatics;
@@ -349,129 +350,72 @@ public class Experience {
if(killer.equals(mob))
return;
double grantedExperience = 0.0;
if(killer.pvpKills.contains(mob.getObjectUUID()))
return;
if (g != null) { // Do group EXP stuff
double baseXP;
int leadership = 0;
int highestLevel = 0;
double penalty = 0.0;
if(g != null) {
//group experience
PlayerCharacter leader = g.getGroupLead();
float leadership = 0.0f;
if(leader.skills.containsKey("Leadership"))
leadership = leader.skills.get("Leadership").getModifiedAmount();
ArrayList<PlayerCharacter> giveEXPTo = new ArrayList<>();
for(PlayerCharacter member : g.members){
// Check if leader is within range of kill and then get leadership
// skill
Vector3fImmutable killLoc = mob.getLoc();
if (killLoc.distanceSquared2D(g.getGroupLead().getLoc()) < (MBServerStatics.EXP_RANGE * MBServerStatics.EXP_RANGE)) {
CharacterSkill leaderskill = g.getGroupLead().skills
.get("Leadership");
if (leaderskill != null)
leadership = leaderskill.getNumTrains();
if (leadership > 90)
leadership = 90; // leadership caps at 90%
}
// Check every group member for distance to see if they get xp
for (PlayerCharacter pc : g.getMembers()) {
if (pc.isAlive()) { // Skip if the player is dead.
// Check within range
if (killLoc.distanceSquared2D(pc.getLoc()) < (MBServerStatics.EXP_RANGE * MBServerStatics.EXP_RANGE)) {
giveEXPTo.add(pc);
// Track highest level character
if (pc.getLevel() > highestLevel)
highestLevel = pc.getLevel();
}
}
}
// Process every player in the group getting XP
for (PlayerCharacter playerCharacter : giveEXPTo) {
if (playerCharacter.getLevel() >= MBServerStatics.LEVELCAP)
if (member.getLevel() >= MBServerStatics.LEVELCAP)
continue;
if(playerCharacter.level >= 75 && !mob.getObjectType().equals(Enum.GameObjectType.PlayerCharacter))
if(!member.isAlive())
continue;
if(member.level >= 75 && !mob.getObjectType().equals(Enum.GameObjectType.PlayerCharacter))
continue; // cannot PVE higher than level 75
// Sets Max XP with server exp mod taken into account.
float range = member.loc.distanceSquared(killer.loc);
if(range <= (MBServerStatics.CHARACTER_LOAD_RANGE * MBServerStatics.CHARACTER_LOAD_RANGE)){
baseXP = LootManager.NORMAL_EXP_RATE * maxXPPerKill(member.getLevel());
double mod = getConMod(member, mob);
grantedExperience = (double) LOOTMANAGER.NORMAL_EXP_RATE * maxXPPerKill(playerCharacter.getLevel());
if(leadership > 0 && mod != 0)
mod += (leadership * 0.01f);
grantedExperience *= (1/ giveEXPTo.size()+0.9);
// Adjust XP for Mob Level
baseXP *= mod;
grantedExperience *= getConMod(playerCharacter, mob);
if(baseXP < 1)
baseXP = 1;
// Process XP for this member
baseXP *= (1.0f / g.members.size()+0.9f);
penalty = getGroupMemberPenalty(leadership, playerCharacter, giveEXPTo,
highestLevel);
// Leadership Penalty Reduction
if (leadership > 0)
penalty -= ((leadership) * 0.01) * penalty;
// Modify for hotzone
if (grantedExperience != 0)
if (ZoneManager.inHotZone(mob.getLoc()))
grantedExperience *= LOOTMANAGER.HOTZONE_EXP_RATE;
// Check for 0 XP due to white mob, otherwise subtract penalty
// xp
if (grantedExperience == 0)
grantedExperience = 1;
else {
grantedExperience -= (penalty * 0.01) * grantedExperience;
// Errant Penalty Calculation
if (playerCharacter.getGuild().isEmptyGuild())
grantedExperience *= 0.6;
member.grantXP((int) baseXP);
}
if (grantedExperience == 0)
grantedExperience = 1;
// Grant the player the EXP
playerCharacter.grantXP((int) Math.floor(grantedExperience));
}
} else { // Give EXP to a single character
//if (!killer.isAlive()) // Skip if the player is dead.
// return;
}else{
//solo no group
if (killer.getLevel() >= MBServerStatics.LEVELCAP)
return;
if(killer.level >= 75 && !mob.getObjectType().equals(Enum.GameObjectType.PlayerCharacter))
return;
return; // cannot PVE higher than level 75
// Get XP and adjust for Mob Level with world xp modifier taken into account
grantedExperience = (double) LOOTMANAGER.NORMAL_EXP_RATE * maxXPPerKill(killer.getLevel());
grantedExperience *= getConMod(killer, mob);
baseXP = LootManager.NORMAL_EXP_RATE * maxXPPerKill(killer.getLevel());
double mod = getConMod(killer, mob);
float leadership = 0.0f;
if(killer.skills.containsKey("Leadership"))
leadership = killer.skills.get("Leadership").getModifiedAmount();
if(leadership > 0 && mod != 0){
mod += (leadership * 0.01f);
}
// Modify for hotzone
if (ZoneManager.inHotZone(mob.getLoc()))
grantedExperience *= LOOTMANAGER.HOTZONE_EXP_RATE;
baseXP *= mod;
if(baseXP < 1)
baseXP = 1;
// Errant penalty
if (grantedExperience != 1)
if (killer.getGuild().isEmptyGuild())
grantedExperience *= .6;
baseXP *= 1.9f;
// Grant XP
killer.grantXP((int) Math.floor(grantedExperience));
killer.grantXP((int) baseXP);
}
}
}
+31 -20
View File
@@ -818,24 +818,15 @@ public class Item extends AbstractWorldObject {
}
public void stripCastableEnchants(){
ArrayList<String> keys =new ArrayList<>();
for(String eff : this.effects.keySet()){
for(AbstractEffectModifier mod : this.effects.get(eff).getEffectsBase().getModifiers()){
if(mod.modType.equals(ModType.WeaponProc)){
keys.add(eff);
}
}
}
for(String eff : keys){
try {
this.effects.get(eff).endEffect();
this.effects.remove(eff);
}catch(Exception e){
ArrayList<Effect> ToRemove = new ArrayList<>();
for(Effect eff : this.effects.values()){
if(eff.getJobContainer() != null && !eff.getJobContainer().noTimer()){
eff.endEffectNoPower();
eff.getJobContainer().cancelJob();
ToRemove.add(eff);
}
}
this.effects.values().removeAll(ToRemove);
}
//Only to be used for trading
public void setOwnerID(int ownerID) {
@@ -1085,7 +1076,7 @@ public class Item extends AbstractWorldObject {
this.ownerID = pc.getObjectUUID();
this.ownerType = OwnerType.PlayerCharacter;
this.containerType = ItemContainerType.INVENTORY;
this.stripCastableEnchants();
//this.stripCastableEnchants();
return true;
}
@@ -1106,7 +1097,7 @@ public class Item extends AbstractWorldObject {
this.ownerID = npc.getObjectUUID();
this.ownerType = OwnerType.Npc;
this.containerType = Enum.ItemContainerType.INVENTORY;
this.stripCastableEnchants();
//this.stripCastableEnchants();
return true;
}
@@ -1124,7 +1115,7 @@ public class Item extends AbstractWorldObject {
this.ownerID = 0;
this.ownerType = null;
this.containerType = Enum.ItemContainerType.INVENTORY;
this.stripCastableEnchants();
//this.stripCastableEnchants();
return true;
}
@@ -1227,7 +1218,10 @@ public class Item extends AbstractWorldObject {
}
public final int getMagicValue() {
return this.magicValue;
int val = this.calcMagicValue();
if(val == 0)
val = 1;
return val + this.getItemBase().getMagicValue();
}
public int getBaseValue() {
@@ -1489,4 +1483,21 @@ public class Item extends AbstractWorldObject {
return false;
return true;
}
public float getModifiedSpeed() {
float speed = this.getItemBase().getSpeed();
try {
for (Effect eff : this.effects.values()) {
for (AbstractEffectModifier mod : eff.getEffectModifiers()) {
if (mod.modType.equals(ModType.WeaponSpeed)) {
float modValue = 1 + mod.getPercentMod() * 0.01f;
speed *= modValue;
}
}
}
}catch(Exception e){
}
return speed;
}
}
+7 -1
View File
@@ -76,6 +76,8 @@ public class ItemBase {
private ArrayList<Integer> animations = new ArrayList<>();
private ArrayList<Integer> offHandAnimations = new ArrayList<>();
public float dexReduction = 0.0f;
/**
* ResultSet Constructor
*/
@@ -151,7 +153,7 @@ public class ItemBase {
}
initBakedInStats();
initializeHashes();
initDexReduction();
}
public static void addToCache(ItemBase itemBase) {
@@ -319,6 +321,10 @@ public class ItemBase {
DbManager.ItemBaseQueries.LOAD_BAKEDINSTATS(this);
}
private void initDexReduction(){
DbManager.ItemBaseQueries.LOAD_DEX_REDUCTION(this);
}
//TODO fix this later. Shouldn't be gotten from item base
public int getMagicValue() {
return this.value;
+1
View File
@@ -341,6 +341,7 @@ public class Mine extends AbstractGameObject {
if(!mine.isActive)
if(mine.getOwningGuild() != null)
if(mine.getOwningGuild().getNation().equals(player.getGuild().getNation()))
if(!mine.getOwningGuild().equals(Guild.getErrantGuild()))
mines.add(mine);
return mines;
+117 -225
View File
@@ -12,6 +12,7 @@ package engine.objects;
import ch.claude_martin.enumbitset.EnumBitSet;
import engine.Enum;
import engine.Enum.*;
import engine.InterestManagement.InterestManager;
import engine.InterestManagement.WorldGrid;
import engine.exception.SerializationException;
import engine.gameManager.*;
@@ -619,6 +620,7 @@ public class Mob extends AbstractIntelligenceAgent {
DbManager.addToCache(mob);
mob.setPet(owner, true);
mob.setWalkMode(false);
mob.level = level;
mob.runAfterLoad();
} catch (Exception e) {
@@ -627,8 +629,12 @@ public class Mob extends AbstractIntelligenceAgent {
createLock.writeLock().unlock();
}
parent.zoneMobSet.add(mob);
mob.level = level;
mob.healthMax = mob.getMobBase().getHealthMax() * (mob.level * 0.5f);
// mob.level = level;
float healthMax = mob.getMobBase().getHealthMax();
if(mob.bonuses != null){
healthMax += mob.bonuses.getFloat(ModType.HealthFull,SourceType.None);
}
mob.healthMax = healthMax;
mob.health.set(mob.healthMax);
return mob;
}
@@ -1326,8 +1332,6 @@ public class Mob extends AbstractIntelligenceAgent {
Dispatch dispatch;
try {
//resync corpses
//this.setLoc(this.getMovementLoc());
if (this.isSiege) {
this.deathTime = System.currentTimeMillis();
//this.state = STATE.Dead;
@@ -1407,6 +1411,8 @@ public class Mob extends AbstractIntelligenceAgent {
Logger.error(e);
}
this.updateLocation();
//resync corpses
InterestManager.setObjectDirty(this);
}
public void respawn() {
@@ -1441,6 +1447,9 @@ public class Mob extends AbstractIntelligenceAgent {
loadInventory();
this.updateLocation();
this.stopPatrolTime = 0;
this.lastPatrolPointIndex = 0;
InterestManager.setObjectDirty(this);
}
public void despawn() {
@@ -1635,67 +1644,67 @@ public class Mob extends AbstractIntelligenceAgent {
this.defenseRating = defense;
this.atrHandOne = atr;
return;
}else {
if (this.charItemManager == null || this.equip == null) {
Logger.error("Player " + currentID + " missing skills or equipment");
defaultAtrAndDamage(true);
defaultAtrAndDamage(false);
this.defenseRating = 0;
return;
}
try {
calculateAtrDamageForWeapon(this.equip.get(MBServerStatics.SLOT_MAINHAND), true);
} catch (Exception e) {
this.atrHandOne = GetAttackRating(this.mobBase.getAttackRating(), this);
this.minDamageHandOne = (short) this.mobBase.getDamageMin();
this.maxDamageHandOne = (short) this.mobBase.getDamageMax();
this.rangeHandOne = 6.5f;
this.speedHandOne = 20;
Logger.info("Mobbase ID " + this.getMobBaseID() + " returned an error. setting to default ATR and Damage." + e.getMessage());
}
try {
calculateAtrDamageForWeapon(this.equip.get(MBServerStatics.SLOT_OFFHAND), false);
} catch (Exception e) {
this.atrHandTwo = GetAttackRating(this.mobBase.getAttackRating(), this);
this.minDamageHandTwo = (short) this.mobBase.getDamageMin();
this.maxDamageHandTwo = (short) this.mobBase.getDamageMax();
this.rangeHandTwo = 6.5f;
this.speedHandTwo = 20;
Logger.info("Mobbase ID " + this.getMobBaseID() + " returned an error. setting to default ATR and Damage." + e.getMessage());
}
try {
float defense = this.mobBase.getDefenseRating();
defense += getShieldDefense(equip.get(MBServerStatics.SLOT_OFFHAND));
defense += getArmorDefense(equip.get(MBServerStatics.SLOT_HELMET));
defense += getArmorDefense(equip.get(MBServerStatics.SLOT_CHEST));
defense += getArmorDefense(equip.get(MBServerStatics.SLOT_ARMS));
defense += getArmorDefense(equip.get(MBServerStatics.SLOT_GLOVES));
defense += getArmorDefense(equip.get(MBServerStatics.SLOT_LEGGINGS));
defense += getArmorDefense(equip.get(MBServerStatics.SLOT_FEET));
defense += getWeaponDefense(equip);
// TODO add error log here
if (this.bonuses != null) {
defense = GetDefense((int) defense, this);
} else
Logger.error("Error: missing bonuses");
defense = (defense < 1) ? 1 : defense;
this.defenseRating = (short) (defense + 0.5f);
} catch (Exception e) {
Logger.info("Mobbase ID " + this.getMobBaseID() + " returned an error. Setting to Default Defense." + e.getMessage());
this.defenseRating = (short) this.mobBase.getDefense();
}
// calculate defense for equipment
}
if (this.charItemManager == null || this.equip == null) {
Logger.error("Player " + currentID + " missing skills or equipment");
defaultAtrAndDamage(true);
defaultAtrAndDamage(false);
this.defenseRating = 0;
return;
}
try {
calculateAtrDamageForWeapon(this.equip.get(MBServerStatics.SLOT_MAINHAND), true);
} catch (Exception e) {
this.atrHandOne = GetAttackRating(this.mobBase.getAttackRating(), this);
this.minDamageHandOne = (short) this.mobBase.getMinDmg();
this.maxDamageHandOne = (short) this.mobBase.getMaxDmg();
this.rangeHandOne = 6.5f;
this.speedHandOne = 20;
Logger.info("Mobbase ID " + this.getMobBaseID() + " returned an error. setting to default ATR and Damage." + e.getMessage());
}
try {
calculateAtrDamageForWeapon(this.equip.get(MBServerStatics.SLOT_OFFHAND), false);
} catch (Exception e) {
this.atrHandTwo = GetAttackRating(this.mobBase.getAttackRating(), this);
this.minDamageHandTwo = (short) this.mobBase.getMinDmg();
this.maxDamageHandTwo = (short) this.mobBase.getMaxDmg();
this.rangeHandTwo = 6.5f;
this.speedHandTwo = 20;
Logger.info("Mobbase ID " + this.getMobBaseID() + " returned an error. setting to default ATR and Damage." + e.getMessage());
}
try {
float defense = this.mobBase.getDefenseRating();
defense += getShieldDefense(equip.get(MBServerStatics.SLOT_OFFHAND));
defense += getArmorDefense(equip.get(MBServerStatics.SLOT_HELMET));
defense += getArmorDefense(equip.get(MBServerStatics.SLOT_CHEST));
defense += getArmorDefense(equip.get(MBServerStatics.SLOT_ARMS));
defense += getArmorDefense(equip.get(MBServerStatics.SLOT_GLOVES));
defense += getArmorDefense(equip.get(MBServerStatics.SLOT_LEGGINGS));
defense += getArmorDefense(equip.get(MBServerStatics.SLOT_FEET));
defense += getWeaponDefense(equip);
// TODO add error log here
if (this.bonuses != null) {
defense = GetDefense((int)defense, this);
} else
Logger.error("Error: missing bonuses");
defense = (defense < 1) ? 1 : defense;
this.defenseRating = (short) (defense + 0.5f);
} catch (Exception e) {
Logger.info("Mobbase ID " + this.getMobBaseID() + " returned an error. Setting to Default Defense." + e.getMessage());
this.defenseRating = (short) this.mobBase.getDefense();
}
// calculate defense for equipment
if(this.isDropper || Mob.discDroppers.contains(this)){
if((this.isDropper || Mob.discDroppers.contains(this)) && !this.mobBase.getFirstName().contains("Blood Mage")){
this.defenseRating *= 2;
this.atrHandOne *= 2;
this.atrHandTwo *= 2;
@@ -1839,168 +1848,46 @@ public class Mob extends AbstractIntelligenceAgent {
private void calculateAtrDamageForWeapon(MobEquipment weapon, boolean mainHand) {
int baseStrength = 0;
float skillPercentage, masteryPercentage;
float mastDam;
// make sure weapon exists
boolean noWeapon = false;
ItemBase wb = null;
if (weapon == null)
noWeapon = true;
else {
ItemBase ib = weapon.getItemBase();
if (ib == null)
noWeapon = true;
else if (ib.getType().equals(ItemType.WEAPON) == false) {
defaultAtrAndDamage(mainHand);
return;
} else
wb = ib;
}
float min, max;
float speed;
boolean strBased = false;
// get skill percentages and min and max damage for weapons
if (noWeapon) {
if (mainHand)
if(mainHand){
int min = (int)this.mobBase.getDamageMin();
int max = (int)this.mobBase.getDamageMax();
int atr = this.mobBase.getAtr();
if(this.bonuses != null){
min *= 1 + this.bonuses.getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None);
max *= 1 + this.bonuses.getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None);
atr *= 1 + this.bonuses.getFloatPercentAll(ModType.OCV,SourceType.None);
atr += this.bonuses.getFloat(ModType.OCV,SourceType.None);
}
this.minDamageHandOne = min;
this.maxDamageHandOne = max;
this.atrHandOne = atr;
if(weapon == null){
this.rangeHandOne = this.mobBase.getAttackRange();
else
this.rangeHandTwo = -1; // set to do not attack
skillPercentage = getModifiedAmount(this.skills.get("Unarmed Combat"));
masteryPercentage = getModifiedAmount(this.skills.get("Unarmed Combat Mastery"));
if (masteryPercentage == 0f)
mastDam = CharacterSkill.getQuickMastery(this, "Unarmed Combat Mastery");
else
mastDam = masteryPercentage;
// TODO Correct these
min = this.mobBase.getMinDmg();
max = this.mobBase.getMaxDmg();
} else {
if (mainHand)
this.rangeHandOne = weapon.getItemBase().getRange() * (1 + (baseStrength / 600.0f));
else
this.rangeHandTwo = weapon.getItemBase().getRange() * (1 + (baseStrength / 600.0f));
skillPercentage = getModifiedAmount(this.skills.get(wb.getSkillRequired()));
masteryPercentage = getModifiedAmount(this.skills.get(wb.getMastery()));
if (masteryPercentage == 0f)
mastDam = 0f;
else
mastDam = masteryPercentage;
min = wb.getMinDamage();
max = wb.getMaxDamage();
strBased = wb.isStrBased();
}
// calculate atr
float atr = this.mobBase.getAttackRating();
if (this.statStrCurrent > this.statDexCurrent)
atr += statStrCurrent * .5;
else
atr += statDexCurrent * .5;
// add in any bonuses to atr
if (this.bonuses != null) {
atr += this.bonuses.getFloat(ModType.OCV, SourceType.None);
// Finally use any multipliers. DO THIS LAST!
float pos_Bonus = 1 + this.bonuses.getFloatPercentPositive(ModType.OCV, SourceType.None);
atr *= pos_Bonus;
//and negative percent modifiers
//TODO DO DEBUFFS AFTER?? wILL TEst when finished
float neg_Bonus = this.bonuses.getFloatPercentNegative(ModType.OCV, SourceType.None);
atr *= (1 + neg_Bonus);
}
atr = (atr < 1) ? 1 : atr;
// set atr
if (mainHand)
this.atrHandOne = (short) (atr + 0.5f);
else
this.atrHandTwo = (short) (atr + 0.5f);
//calculate speed
if (wb != null)
speed = wb.getSpeed();
else
speed = 20f; //unarmed attack speed
if (this.bonuses != null && this.bonuses.getFloat(ModType.AttackDelay, SourceType.None) != 0f) //add effects speed bonus
speed *= (1 + this.bonuses.getFloatPercentAll(ModType.AttackDelay, SourceType.None));
if (speed < 10)
speed = 10;
//add min/max damage bonuses for weapon **REMOVED
//if duel wielding, cut damage by 30%
// calculate damage
float minDamage;
float maxDamage;
float pri = (strBased) ? (float) this.statStrCurrent : (float) this.statDexCurrent;
float sec = (strBased) ? (float) this.statDexCurrent : (float) this.statStrCurrent;
minDamage = (float) (min * ((0.0315f * Math.pow(pri, 0.75f)) + (0.042f * Math.pow(sec, 0.75f)) + (0.01f * ((int) skillPercentage + (int) mastDam))));
maxDamage = (float) (max * ((0.0785f * Math.pow(pri, 0.75f)) + (0.016f * Math.pow(sec, 0.75f)) + (0.0075f * ((int) skillPercentage + (int) mastDam))));
minDamage = (float) ((int) (minDamage + 0.5f)); //round to nearest decimal
maxDamage = (float) ((int) (maxDamage + 0.5f)); //round to nearest decimal
//add Base damage last.
float minDamageMod = this.mobBase.getDamageMin();
float maxDamageMod = this.mobBase.getDamageMax();
minDamage += minDamageMod;
maxDamage += maxDamageMod;
// add in any bonuses to damage
if (this.bonuses != null) {
// Add any base bonuses
minDamage += this.bonuses.getFloat(ModType.MinDamage, SourceType.None);
maxDamage += this.bonuses.getFloat(ModType.MaxDamage, SourceType.None);
// Finally use any multipliers. DO THIS LAST!
minDamage *= (1 + this.bonuses.getFloatPercentAll(ModType.MinDamage, SourceType.None));
maxDamage *= (1 + this.bonuses.getFloatPercentAll(ModType.MaxDamage, SourceType.None));
}
// set damages
if (mainHand) {
this.minDamageHandOne = (short) minDamage;
this.maxDamageHandOne = (short) maxDamage;
this.speedHandOne = 30;
} else {
this.minDamageHandTwo = (short) minDamage;
this.maxDamageHandTwo = (short) maxDamage;
this.speedHandTwo = 30;
this.speedHandTwo = 20.0f;
}else{
this.rangeHandOne = weapon.getItemBase().getRange();
this.speedHandTwo = weapon.getItemBase().getSpeed();
}
}else{
int min = (int)this.mobBase.getDamageMin();
int max = (int)this.mobBase.getDamageMax();
int atr = this.mobBase.getAtr();
if(this.bonuses != null){
min *= 1 + this.bonuses.getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None);
max *= 1 + this.bonuses.getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None);
atr *= 1 + this.bonuses.getFloatPercentAll(ModType.OCV,SourceType.None);
atr += this.bonuses.getFloat(ModType.OCV,SourceType.None);
}
this.minDamageHandTwo = min;
this.maxDamageHandTwo = max;
this.atrHandTwo = atr;
if(weapon == null){
this.rangeHandTwo = this.mobBase.getAttackRange();
this.speedHandTwo = 20.0f;
}else{
this.rangeHandTwo = weapon.getItemBase().getRange();
this.speedHandTwo = weapon.getItemBase().getSpeed();
}
}
}
@@ -2075,6 +1962,9 @@ public class Mob extends AbstractIntelligenceAgent {
}
try {
if(this.equipmentSetID == 6481) {
int i = 0;
}
if (this.equipmentSetID != 0)
this.equip = MobBase.loadEquipmentSet(this.equipmentSetID);
else
@@ -2114,6 +2004,7 @@ public class Mob extends AbstractIntelligenceAgent {
try {
NPCManager.applyRuneSetEffects(this);
MobBase.applyMobbaseEffects(this);
recalculateStats();
this.setHealth(this.healthMax);
@@ -2165,6 +2056,7 @@ public class Mob extends AbstractIntelligenceAgent {
}
this.deathTime = 0;
InterestManager.setObjectDirty(this);
} catch (Exception e) {
Logger.error(e.getMessage());
}
+40 -9
View File
@@ -13,8 +13,11 @@ import ch.claude_martin.enumbitset.EnumBitSet;
import engine.Enum;
import engine.gameManager.DbManager;
import engine.gameManager.LootManager;
import engine.gameManager.PowersManager;
import engine.loot.BootySetEntry;
import engine.powers.EffectsBase;
import engine.server.MBServerStatics;
import org.pmw.tinylog.Logger;
import java.sql.ResultSet;
import java.sql.SQLException;
@@ -54,6 +57,8 @@ public class MobBase extends AbstractGameObject {
private float walkCombat = 0;
private float runCombat = 0;
public ArrayList<MobBaseEffects> mobbaseEffects;
/**
* ResultSet Constructor
*/
@@ -108,6 +113,7 @@ public class MobBase extends AbstractGameObject {
this.mobBaseStats = DbManager.MobBaseQueries.LOAD_STATS(this.loadID);
DbManager.MobBaseQueries.LOAD_ALL_MOBBASE_SPEEDS(this);
this.mobbaseEffects = DbManager.MobBaseQueries.GET_RUNEBASE_EFFECTS(this.getObjectUUID());
}
@@ -125,16 +131,22 @@ public class MobBase extends AbstractGameObject {
return equip;
for (BootySetEntry equipmentSetEntry : equipList) {
try {
if(equipmentSetEntry.itemBase == 189500){
int i = 0;
}
MobEquipment mobEquipment = new MobEquipment(equipmentSetEntry.itemBase, equipmentSetEntry.dropChance);
ItemBase itemBase = mobEquipment.getItemBase();
MobEquipment mobEquipment = new MobEquipment(equipmentSetEntry.itemBase, equipmentSetEntry.dropChance);
ItemBase itemBase = mobEquipment.getItemBase();
if (itemBase != null) {
if (itemBase.getType().equals(Enum.ItemType.WEAPON))
if (mobEquipment.getSlot() == 1 && itemBase.getEquipFlag() == 2)
mobEquipment.setSlot(2);
if (itemBase != null) {
if (itemBase.getType().equals(Enum.ItemType.WEAPON))
if (mobEquipment.getSlot() == 1 && itemBase.getEquipFlag() == 2)
mobEquipment.setSlot(2);
equip.put(mobEquipment.getSlot(), mobEquipment);
equip.put(mobEquipment.getSlot(), mobEquipment);
}
}catch(Exception e){
Logger.error(e);
}
}
@@ -254,7 +266,7 @@ public class MobBase extends AbstractGameObject {
}
public int getAtr() {
return atr;
return attackRating;
}
public void setAtr(int atr) {
@@ -301,4 +313,23 @@ public class MobBase extends AbstractGameObject {
return runCombat;
}
public static void applyMobbaseEffects(Mob mob){
if(mob.getMobBaseID() == 12008)
mob.level = 65;
else if(mob.getMobBaseID() == 12019)
mob.level = 80;
for(MobBaseEffects mbe : mob.mobBase.mobbaseEffects){
if(mob.level >= mbe.getReqLvl()){
try {
//PowersManager.applyPower(mob, mob, mob.loc, mbe.getToken(), mbe.getRank(), false);
EffectsBase effectsBase = PowersManager.getEffectByToken(mbe.getToken());
if(effectsBase != null)
mob.addEffectNoTimer(Integer.toString(effectsBase.getUUID()), effectsBase, mbe.getRank(), true);
}catch(Exception e){
Logger.error("NULL POWER FOR MOB: " + mob.getObjectUUID() + ", POWER TOKEN: " + mbe.getToken());
}
}
}
}
}
+5 -1
View File
@@ -98,7 +98,11 @@ public class MobEquipment extends AbstractGameObject {
this.dropChance = dropChance;
this.parentID = 0;
setMagicValue();
try {
setMagicValue();
}catch(Exception e){
}
}
public static int getNewID() {
+1 -1
View File
@@ -27,7 +27,7 @@ import java.util.concurrent.ConcurrentHashMap;
public class PlayerBonuses {
//First bonus set
private ConcurrentHashMap<AbstractEffectModifier, Float> bonusFloats = new ConcurrentHashMap<>();
ConcurrentHashMap<AbstractEffectModifier, Float> bonusFloats = new ConcurrentHashMap<>();
private ConcurrentHashMap<AbstractEffectModifier, DamageShield> bonusDamageShields = new ConcurrentHashMap<>();
private ConcurrentHashMap<AbstractEffectModifier, String> bonusStrings = new ConcurrentHashMap<>();
private ConcurrentHashMap<ModType, HashSet<SourceType>> bonusLists = new ConcurrentHashMap<>();
File diff suppressed because it is too large. Load diff
Loaded 100 of 115 files, more files were not shown because too many files have changed in this diff. Show more