Compare commits

...

847 Commits

Author SHA1 Message Date
FatBoy-DOTC bbcbd6fc39 hot fix for regen 5 days ago
FatBoy-DOTC 123c488fc6 hot fix for regen 5 days ago
FatBoy-DOTC f5ebda9147 hot fix for regen 5 days ago
FatBoy-DOTC 1132f88b85 hot fix for powers failure 5 days ago
FatBoy-DOTC edc4aa5d07 recovering rates 5 days ago
FatBoy-DOTC 734b67be6d recovering rates 5 days ago
FatBoy-DOTC 53c8b28d2d audit chat messages for target ID 5 days ago
FatBoy-DOTC 017026fd03 audit chat messages for target ID 6 days ago
FatBoy-DOTC 4e9b1927f2 fix mob target aggro issue 6 days ago
FatBoy-DOTC 56ce5b5a3c fix track power range 6 days ago
FatBoy-DOTC afd1b4e760 uptime to show boxed and active players 6 days ago
FatBoy-DOTC 1975e60f36 pet aggro fix 6 days ago
FatBoy-DOTC fbdca5b917 xp range fix 6 days ago
FatBoy-DOTC 78dfa0c68c invis mob solution 6 days ago
FatBoy-DOTC a04ad2f382 break point 6 days ago
FatBoy-DOTC 257a8aff15 break point 6 days ago
FatBoy-DOTC 291a20c4d0 break point 6 days ago
FatBoy-DOTC eec08ce962 break point 6 days ago
FatBoy-DOTC 99183dc248 break point 6 days ago
FatBoy-DOTC 6c7f01dc72 mobs will attack player pets 6 days ago
FatBoy-DOTC 6ebeb9cadf must be in safezone to switch boxes 6 days ago
FatBoy-DOTC 8e0f1090d9 fix white XP 6 days ago
FatBoy-DOTC bc0bc577ea fix white XP 6 days ago
FatBoy-DOTC 3b5c0e6210 must be in safezone to gain level up gold 6 days ago
FatBoy-DOTC d6fa7dba9d fix XP range 6 days ago
FatBoy-DOTC b5fbc8478d new Regen 1 week ago
FatBoy-DOTC b79c827d81 new Regen 1 week ago
FatBoy-DOTC b9b254f8e8 new Regen 1 week ago
FatBoy-DOTC 6834146eb2 new Regen 1 week ago
FatBoy-DOTC e9f1711120 pet assistance 1 week ago
FatBoy-DOTC 29f054e192 retaliate handled properly 1 week ago
FatBoy-DOTC 7d9c5d3498 huntress pets properly granted modifiers 1 week ago
FatBoy-DOTC 618353c088 set mob level earlier in routine 1 week ago
FatBoy-DOTC 24656b1030 expereince system rework 1 week ago
FatBoy-DOTC 27cb704837 expereince system rework 1 week ago
FatBoy-DOTC 6961b186a9 disable gimme command 1 week ago
FatBoy-DOTC bee91a6aa7 catch weird city null error 1 week ago
FatBoy-DOTC 8c5b1d56c2 proper XP group scaling 1 week ago
FatBoy-DOTC f21e8c130b stam ticks 1 week ago
FatBoy-DOTC 345c451ac8 stam ticks 1 week ago
FatBoy-DOTC c3a7262a7f logging for failed to move item to vault or bank 1 week ago
FatBoy-DOTC d1c6d9edec reveal thyself castable by all 1 week ago
FatBoy-DOTC 1e865eecbc increase starting gold to 1500 1 week ago
FatBoy-DOTC 5f735a49c1 mobs no longer double multiply for sitting target 1 week ago
FatBoy-DOTC e609c015b9 Dwarvish Wrath added to exception list 1 week ago
FatBoy-DOTC 5a198669b9 quick targeting check cleanup 1 week ago
FatBoy-DOTC fe399664f3 targeting object checks only count when targeting players 1 week ago
FatBoy-DOTC 3bc62e9baa 10 seconds for 7 stamina ticks in travel stance 2 weeks ago
FatBoy-DOTC cf23266f31 10 seconds for 7 stamina ticks in travel stance 2 weeks ago
FatBoy-DOTC b097472402 delete AI Players 2 weeks ago
FatBoy-DOTC 57b18c2d15 AI Players as mobs 2 weeks ago
FatBoy-DOTC 040eef576e disable AI Players 2 weeks ago
FatBoy-DOTC d76403a0c8 Ai Players 2 weeks ago
FatBoy-DOTC 8ce1054599 Ai Players 2 weeks ago
FatBoy-DOTC 0daf8cfe4c Ai Players 2 weeks ago
FatBoy-DOTC 898c4c2fa0 Ai Players 2 weeks ago
FatBoy-DOTC ecba693105 Ai Players 2 weeks ago
FatBoy-DOTC dbc0da20df pets issues fixed 2 weeks ago
FatBoy-DOTC 354d0ab283 pets issues 2 weeks ago
FatBoy-DOTC c1b66269bb new regen system 2 weeks ago
FatBoy-DOTC 7981acb582 new regen system 2 weeks ago
FatBoy-DOTC 03448397ee strike counter trash logging 2 weeks ago
FatBoy-DOTC 685dc572e8 strike counter 2 weeks ago
FatBoy-DOTC 5a161a0808 strike counter 2 weeks ago
FatBoy-DOTC 3e4aad9db9 aimbot detection 2 weeks ago
FatBoy-DOTC 47981872be network message validation 2 weeks ago
FatBoy-DOTC daea835613 network message validation 2 weeks ago
FatBoy-DOTC 55923559cd group tele allowe don all city zones 2 weeks ago
FatBoy-DOTC 9efde874f3 remove level difference form passive chance 2 weeks ago
FatBoy-DOTC 9b2b0073a5 gambler NPC 2 weeks ago
FatBoy-DOTC 33328f74db gambler NPC 2 weeks ago
FatBoy-DOTC 41023fb890 gambler NPC 2 weeks ago
FatBoy-DOTC 54a279c3e6 track threads being used 2 weeks ago
FatBoy-DOTC 29aea83217 track threads being used 2 weeks ago
FatBoy-DOTC 30d27f8a68 job worker thread to prevent deadlocks 2 weeks ago
FatBoy-DOTC 17e54ea4aa job worker thread 2 weeks ago
FatBoy-DOTC 86c0bbb065 passives 2 weeks ago
FatBoy-DOTC ec4cad5e19 added 250L wait to network selector 2 weeks ago
FatBoy-DOTC b674625f7b reduced admin command spam 2 weeks ago
FatBoy-DOTC d57b45ef9c fix event processing in network code 2 weeks ago
FatBoy-DOTC 2a38c60a67 Revert "fix event processing in network code" 2 weeks ago
FatBoy-DOTC cd1e38b184 fix event processing in network code 2 weeks ago
FatBoy-DOTC 69457d5f7e new curved map for hit chances 2 weeks ago
FatBoy-DOTC 7728a800d9 new hit chance scaling 2 weeks ago
FatBoy-DOTC 8b2c018103 mana can be recovered while casting - to match client 2 weeks ago
FatBoy-DOTC 76d39f5cc3 mana can be recovered while casting - to match client 2 weeks ago
FatBoy-DOTC 826457fb25 mana and stamina regen resynced 2 weeks ago
FatBoy-DOTC 0681d3d116 tears of saedron remove stat runes 2 weeks ago
FatBoy-DOTC ccdea6f970 players can teleport to their own cities 2 weeks ago
FatBoy-DOTC ab00fd7a85 limit dev commands 2 weeks ago
FatBoy-DOTC 70d67a2b7f update thread optimized 2 weeks ago
FatBoy-DOTC f5b27e0c5b no reverse KoS 2 weeks ago
FatBoy-DOTC 3c26df5f86 last tick on over time applies 2 weeks ago
FatBoy-DOTC 9ed43b5891 combatstats cleanup 2 weeks ago
FatBoy-DOTC 4814404f1c combatstats cleanup 2 weeks ago
FatBoy-DOTC b1d41e8e85 update delay removed 2 weeks ago
FatBoy-DOTC cc5aa4c140 ATR completed 2 weeks ago
FatBoy-DOTC 934c0a98f8 atr buff/debuffs 2 weeks ago
FatBoy-DOTC 91c2cd47fb def buff/debuffs 2 weeks ago
FatBoy-DOTC 22f14fb8f1 treb spam 2 weeks ago
FatBoy-DOTC 93a975dd42 optimized run time 2 weeks ago
FatBoy-DOTC 7d1570fdca group tele limit recyle power properly 3 weeks ago
FatBoy-DOTC 76db3e1f96 disable mob casting 3 weeks ago
FatBoy-DOTC afbe23fc03 use calculated value son PC for combat stats 3 weeks ago
FatBoy-DOTC 4e417c8810 audit hit/miss chances 3 weeks ago
FatBoy-DOTC d79c69658a parry chance removed 10x 3 weeks ago
FatBoy-DOTC 0d125e2640 hit chance 3 weeks ago
FatBoy-DOTC e4a3405032 location sync and def formula 3 weeks ago
FatBoy-DOTC c391272e5b can block spells 3 weeks ago
FatBoy-DOTC 0d3423d51b can block spells 3 weeks ago
FatBoy-DOTC 549ca25483 can block spells 3 weeks ago
FatBoy-DOTC 603d4ca3a8 reconstructed passive chance formulas 3 weeks ago
FatBoy-DOTC fababd3e42 reconstructed passive chance formulas 3 weeks ago
FatBoy-DOTC bec6230a06 box limiter 3 weeks ago
FatBoy-DOTC 773b6253b9 def formula 3 weeks ago
FatBoy-DOTC 1ffcc1086b def formula 3 weeks ago
FatBoy-DOTC 992d52a389 always allow parry on saetor 3 weeks ago
FatBoy-DOTC 61088d0b59 box limiter 3 weeks ago
FatBoy-DOTC 601e97eaca Revert "box limited config entry" 3 weeks ago
FatBoy-DOTC eae4675f85 box limited config entry 3 weeks ago
FatBoy-DOTC 84410114e7 mob casting time fixed 3 weeks ago
FatBoy-DOTC 70855acbcf mob casting time 3 weeks ago
FatBoy-DOTC 2a8e0dea73 mob casting time 3 weeks ago
FatBoy-DOTC 6c4f18218c atr calculations 3 weeks ago
FatBoy-DOTC 0b5f469b13 no footwear on saetors 3 weeks ago
FatBoy-DOTC 68a43388ff saetor can only parry naturally 3 weeks ago
FatBoy-DOTC 5fe12df436 mobs cannot cast debuffs 3 weeks ago
FatBoy-DOTC caa0aa5172 AI cast frequency 3 weeks ago
FatBoy-DOTC 37a81ed53e ATR system 3 weeks ago
FatBoy-DOTC 39afb33186 old regen system 3 weeks ago
FatBoy-DOTC 228152596c spell dodge chance resolved 3 weeks ago
FatBoy-DOTC d75a052bd3 non siege pets can always roam as a flag 3 weeks ago
FatBoy-DOTC 81d6a55096 stop bonus calc spam 3 weeks ago
FatBoy-DOTC 55d9cf6d26 calculate base skill 3 weeks ago
FatBoy-DOTC 9cf69ec73f calculate base skill 3 weeks ago
FatBoy-DOTC 4595582def calculate base skill 3 weeks ago
FatBoy-DOTC 0b2d598261 print new skill calculations to client 3 weeks ago
FatBoy-DOTC cf342cd1a6 print new skill calculations to client 3 weeks ago
FatBoy-DOTC 05bb323c0c print new skill calculations to client 3 weeks ago
FatBoy-DOTC c415bb15e2 use new skill level calculations 3 weeks ago
FatBoy-DOTC eac58b086b limiter for client syncing 3 weeks ago
FatBoy-DOTC fea39ffa85 calculate modified and base skill values 3 weeks ago
FatBoy-DOTC fb8971ce86 calculate modified and base skill values 3 weeks ago
FatBoy-DOTC e44dd5e2cc properly sync client for regen 3 weeks ago
FatBoy-DOTC 3ed303bec4 calculate combat stats spam fix 3 weeks ago
FatBoy-DOTC f4267c3c92 calculate combat stats spam fix 3 weeks ago
FatBoy-DOTC c5f678ea0e join heavens host allowed for prelates 3 weeks ago
FatBoy-DOTC 4fe3d92b3f optimize PlayerCombatStats calling 3 weeks ago
FatBoy-DOTC 284fc7e37e remove error logging spam 3 weeks ago
FatBoy-DOTC 402d69312c use new regen calculations 3 weeks ago
FatBoy-DOTC 198648d3db use new regen calculations 3 weeks ago
FatBoy-DOTC 3a01dbf5f6 shade hide power block 3 weeks ago
FatBoy-DOTC 0ec505e37f player lock fix 3 weeks ago
FatBoy-DOTC 1e26d7f38c player lock fix 3 weeks ago
FatBoy-DOTC 64f9f4d4b9 player lock fix 3 weeks ago
FatBoy-DOTC 89c06f714f player lock fix 3 weeks ago
FatBoy-DOTC 157d116626 player lock fix 3 weeks ago
FatBoy-DOTC de229ddde5 dont load cities without ToL 3 weeks ago
FatBoy-DOTC 8b456f66ef healers dont get ATR from def stance 3 weeks ago
FatBoy-DOTC 2e35e35a6e fury no longer grounded at end of flight chant 3 weeks ago
FatBoy-DOTC cca078f017 strip castable enchanst when moving to vault 3 weeks ago
FatBoy-DOTC f658a30132 atr % bonus accounted for 3 weeks ago
FatBoy-DOTC 0a827d2404 proper duel wield attack speed calc 3 weeks ago
FatBoy-DOTC 806adee3de fortitude fix 3 weeks ago
FatBoy-DOTC bdd108065b apply powerBlock on shade hide 3 weeks ago
FatBoy-DOTC 8d41c5475c unfuck fortitude 4 weeks ago
FatBoy-DOTC 99ad461a82 skin the beast work son all but templar 4 weeks ago
FatBoy-DOTC 9da56b4226 3 second power block for hide 4 weeks ago
FatBoy-DOTC beeca529cd fortitudes handled last 4 weeks ago
FatBoy-DOTC ebb765ae82 use total skill percent when calculating ATR 4 weeks ago
FatBoy-DOTC 65e391f6f7 Revert "use total skill instea dof modified for ATR" 4 weeks ago
FatBoy-DOTC ab45d92bd1 use total skill instea dof modified for ATR 4 weeks ago
FatBoy-DOTC a366c95941 can't TP to errant mines 4 weeks ago
FatBoy-DOTC f2d9eb003c temporary enchant timers 4 weeks ago
FatBoy-DOTC bb1a99912c temporary enchant stripping 4 weeks ago
FatBoy-DOTC fd30e52741 temporary enchant stripping 4 weeks ago
FatBoy-DOTC 58a0b6150f aI delay 4 weeks ago
FatBoy-DOTC 9aa053beb6 aI delay 4 weeks ago
FatBoy-DOTC 7eb084efaa aI delay 4 weeks ago
FatBoy-DOTC 1568377725 dex reductions 4 weeks ago
FatBoy-DOTC 7b32cfe235 shade backstabs 4 weeks ago
FatBoy-DOTC 7ef3efafd3 shade backstabs 4 weeks ago
FatBoy-DOTC ffdd79c497 blood mage fix 4 weeks ago
FatBoy-DOTC b156da7ded AP applies only to mele damage 4 weeks ago
FatBoy-DOTC 9278954f2f saetor can parry 4 weeks ago
FatBoy-DOTC 4324ebe855 Phaedra's Fury added to exception list for form break 4 weeks ago
FatBoy-DOTC 4a69dca5cc allow gimme 4 weeks ago
FatBoy-DOTC 2cc54b4002 100 ms delay between mob spawns 4 weeks ago
FatBoy-DOTC eac0aebd59 defense calc completed 4 weeks ago
FatBoy-DOTC 172dcfb6d8 defense calc completed 4 weeks ago
FatBoy-DOTC d320d83c22 defense calc completed 4 weeks ago
FatBoy-DOTC af2dd004e4 defense calc 4 weeks ago
FatBoy-DOTC dfbace76db defense calc 4 weeks ago
FatBoy-DOTC 119f762492 defense calc 4 weeks ago
FatBoy-DOTC e586c442c1 PlayerCombatStats dex penalty applied correctly 4 weeks ago
FatBoy-DOTC c01e87ee8b PlayerCombatStats dex penalty applied correctly 4 weeks ago
FatBoy-DOTC af4025d948 PlayerCombatStats dex penalty applied correctly 4 weeks ago
FatBoy-DOTC b7c2b7a0d5 PlayerCombatStats dex penalty applied correctly 4 weeks ago
FatBoy-DOTC f073a93d47 PlayerCombatStats dex penalty applied correctly 4 weeks ago
FatBoy-DOTC 47914838f5 PlayerCombatStats dex penalty applied correctly 4 weeks ago
FatBoy-DOTC 69e2630d77 PlayerCombatStats dex penalty applied correctly 4 weeks ago
FatBoy-DOTC 08148c058c PlayerCombatStats defense formula 4 weeks ago
FatBoy-DOTC a7ee8f553b PlayerCombatStats proc chances 4 weeks ago
FatBoy-DOTC 8395bb80f1 PlayerCombatStats use in combat 4 weeks ago
FatBoy-DOTC becd3cbf65 PlayerCombatStats use in combat 4 weeks ago
FatBoy-DOTC 80ec681a2c PlayerCombatStats 30% damage reduction for duel wielding 4 weeks ago
FatBoy-DOTC 96a80ce1b6 PlayerCombatStats attack delay 4 weeks ago
FatBoy-DOTC f18cf5c8a6 PlayerCombatStats modified skills 4 weeks ago
FatBoy-DOTC 4c21159553 PlayerCombatStats modified skills 4 weeks ago
FatBoy-DOTC 475c0a9b09 PlayerCombatStats modified skills 4 weeks ago
FatBoy-DOTC f80ad61179 PlayerCombatStats weapon speed enchants applied separately 4 weeks ago
FatBoy-DOTC 10ccfb1086 PlayerCombatStats weapon speed enchants applied separately 4 weeks ago
FatBoy-DOTC 44197fd83c PlayerCombatStats revision 4 weeks ago
FatBoy-DOTC 0d9e03f848 PlayerCombatStats weapon speed calculations complete 4 weeks ago
FatBoy-DOTC 810812d06b PlayerCombatStats weapon speed calculations 4 weeks ago
FatBoy-DOTC 539d7f6e79 PlayerCombatStats def calculations completed 4 weeks ago
FatBoy-DOTC 3358d9e943 PlayerCombatStats def calculations 4 weeks ago
FatBoy-DOTC eeffd9b357 PlayerCombatStats atr calculations completed 4 weeks ago
FatBoy-DOTC b33f41200e PlayerCombatStats atr 4 weeks ago
FatBoy-DOTC 030d1110b9 PlayerCombatStats proper delays 4 weeks ago
FatBoy-DOTC 09af8084b9 PlayerCombatStats final 1 month ago
FatBoy-DOTC 0cff9524c2 PlayerCombatStats final 1 month ago
FatBoy-DOTC f6299f5b97 PlayerCombatStats final 1 month ago
FatBoy-DOTC b1250ae4e4 PlayerCombatStats proper stance calculations 1 month ago
FatBoy-DOTC a9144471b1 PlayerCombatStats defense proper rounding 1 month ago
FatBoy-DOTC 9f924da18b PlayerCombatStats min/max rounding final 1 month ago
FatBoy-DOTC aac92f1760 PlayerCombatStats defense final 1 month ago
FatBoy-DOTC fdf42bd913 PlayerCombatStats defense 1 month ago
FatBoy-DOTC ecee2f2e8c PlayerCombatStats damage calc final 1 month ago
FatBoy-DOTC 1b487fdbb6 PlayerCombatStats damage calc 1 month ago
FatBoy-DOTC bb7bd6d71b PlayerCombatStats atr final 1 month ago
FatBoy-DOTC 34178906a3 PlayerCombatStats attack speed final 1 month ago
FatBoy-DOTC c689722459 PlayerCombatStats object 1 month ago
FatBoy-DOTC 8e4ff8c67f PlayerCombatStats object 1 month ago
FatBoy-DOTC 4ff22d1d20 PlayerCombatStats object 1 month ago
FatBoy-DOTC 5ed7712aed PlayerCombatStats object 1 month ago
FatBoy-DOTC a6fcb5ea00 weapon speed 1 month ago
FatBoy-DOTC 8f402c8c03 weapon speed 1 month ago
FatBoy-DOTC 5761e313fd weapon speed 1 month ago
FatBoy-DOTC 441771839a new stat calculations 1 month ago
FatBoy-DOTC ad6700974f new stat calculations 1 month ago
FatBoy-DOTC 499aec2c61 new stat calculations 1 month ago
FatBoy-DOTC ceed4c641a new stat calculations 1 month ago
FatBoy-DOTC 669c0b4cd7 attack speed 1 month ago
FatBoy-DOTC 7964de1045 attack speed 1 month ago
FatBoy-DOTC 961e2915b4 attack speed 1 month ago
FatBoy-DOTC 6c6a64fa98 mobs dont chase invisible players 1 month ago
FatBoy-DOTC 7a8a751bca stealing/peeking fix 1 month ago
FatBoy-DOTC 69bf6ef8cd combat formula and steal 1 month ago
FatBoy-DOTC 05e542215d allow 5th disc at 70 1 month ago
FatBoy-DOTC 868eaab5ed mantle of stone added to form break exception list 1 month ago
FatBoy-DOTC e7d22717cd attack speed calculations 1 month ago
FatBoy-DOTC bbabf814e1 attack speed calculations 1 month ago
FatBoy-DOTC 938fcb1352 allow print bonuses 1 month ago
FatBoy-DOTC 42a71396cd persist print commands for non-testmode 1 month ago
FatBoy-DOTC 9ec95b974f mob work 1 month ago
FatBoy-DOTC 49ea9e50cf mob work 1 month ago
FatBoy-DOTC 456edce9fc mob work 1 month ago
FatBoy-DOTC 537512ed5d mob work 1 month ago
FatBoy-DOTC d0efd08a84 mobbase effect info command 1 month ago
FatBoy-DOTC bb7ba9a6df mobbase effect info command 1 month ago
FatBoy-DOTC 09695d97db mobbase effect info command 1 month ago
FatBoy-DOTC 4fe4835c29 mobbase effects 1 month ago
FatBoy-DOTC 86435a3563 respawn thread optimized 1 month ago
FatBoy-DOTC bc84c7537b optimized regen client sync 1 month ago
FatBoy-DOTC 29736f9c8f optimized regen client sync 1 month ago
FatBoy-DOTC 99a9cd297c optimized mob ai thread 1 month ago
FatBoy-DOTC e86749febd optimized bane thread 1 month ago
FatBoy-DOTC 4b86fbb12c optimized regen 1 month ago
FatBoy-DOTC 4c342c9b9a bard uses pathfinding 1 month ago
FatBoy-DOTC d2e0b7b95c bard uses pathfinding 1 month ago
FatBoy-DOTC 53fe763764 boxed characters dont get ding gold 1 month ago
FatBoy-DOTC 86d7233aa4 remove console spam 1 month ago
FatBoy-DOTC d19ea0968a allowed casts in form 1 month ago
FatBoy-DOTC 7eb49446c1 correct use of proper stat for ATR calculation 1 month ago
FatBoy-DOTC 01a88c85a6 correct use of proper stat for ATR calculation 1 month ago
FatBoy-DOTC 5492374f2c saetor in who window, skin the beast double point value 1 month ago
FatBoy-DOTC 9ca00be694 saetor in who window, skin the beast double point value 1 month ago
FatBoy-DOTC 23d9807fe3 infastructure for exclusion to breaking form from powers 1 month ago
FatBoy-DOTC 8a3e3ae866 special case weapon powers requiring hit rolls 1 month ago
FatBoy-DOTC 117646cda4 limit spamming messages ot client for stat sync 1 month ago
FatBoy-DOTC 6cf502c4bb mob drop aggro check 1 month ago
FatBoy-DOTC 1bb99127c4 mob drop aggro check 1 month ago
FatBoy-DOTC 8aeccd35c9 mob drop aggro check 1 month ago
FatBoy-DOTC c90b94d1ec endless player guard combat cycle 1 month ago
FatBoy-DOTC 031fd24842 PLayerCharacter.java Cleanup 1 month ago
FatBoy-DOTC e1c07deb52 remove debug logs from stam/health consumption 1 month ago
FatBoy-DOTC 5f10c24f03 health degregation for swimming 1 month ago
FatBoy-DOTC f643caacbe health degregation for swimming 1 month ago
FatBoy-DOTC cb5ab26924 recovery system fully synced to client 1 month ago
FatBoy-DOTC 94c9e92553 mob loot system addressed 1 month ago
FatBoy-DOTC 507638594d updated regen system 1 month ago
FatBoy-DOTC e72c4886e8 updated regen system 1 month ago
FatBoy-DOTC 5ba11a6238 updated regen system 1 month ago
FatBoy-DOTC 2fc7671051 updated regen system 1 month ago
FatBoy-DOTC d142097b0f updated regen system 1 month ago
FatBoy-DOTC 4330bb3ecd updated regen system 1 month ago
FatBoy-DOTC 2e1dd27332 updated regen system 1 month ago
FatBoy-DOTC 4f08d7286e mob respawn issue resolved 1 month ago
FatBoy-DOTC 7f8fb13552 mana regen change 1 month ago
FatBoy-DOTC 93e0d119b0 mana regen change 1 month ago
FatBoy-DOTC a9bc44f19b fifth disc for level 80 1 month ago
FatBoy-DOTC 83bc09f34b fifth disc for level 80 1 month ago
FatBoy-DOTC 4386e1c828 throttled xp for killing same person 1 month ago
FatBoy-DOTC 72b2e54331 banes to set default times 1 month ago
FatBoy-DOTC e912c24025 5th hireling in r8 ToL 1 month ago
FatBoy-DOTC c9c1f6ba1c wall bonus HP 1 month ago
FatBoy-DOTC abda30fc25 wall bonus HP 1 month ago
FatBoy-DOTC 62c188c5c7 wall bonus HP 1 month ago
FatBoy-DOTC 67f7b6f3f8 wall bonus HP 1 month ago
FatBoy-DOTC f04ccb9403 wall bonus HP 1 month ago
FatBoy-DOTC b71bb60669 allow 5th slot in r8 TOL + wall health upgrade for r8 trees 1 month ago
FatBoy-DOTC 5eab1ad1c0 allow 5th slot in r8 TOL + wall health upgrade 1 month ago
FatBoy-DOTC f96d0caf3c stun grounds 1 tier per 1.5 seconds of stunned 1 month ago
FatBoy-DOTC 3e6655a199 cant change altitude while stunned 1 month ago
FatBoy-DOTC 386cdc8c18 cant change altitude while stunned 1 month ago
FatBoy-DOTC 63b40c27a5 fall slowly while stunned 1 month ago
FatBoy-DOTC 6985dffda4 no more spamming console 1 month ago
FatBoy-DOTC 88e16448a8 gold and conc on promotion 1 month ago
FatBoy-DOTC 4cb428e993 noob island progression changes 1 month ago
FatBoy-DOTC af9945f9db added null check for endEffect 2 months ago
FatBoy-DOTC f0594fb1b2 sitting only toggle when casting spells not skills 2 months ago
FatBoy-DOTC a155bc0308 modified ht chance 2 months ago
FatBoy-DOTC dce7444483 modified ht chance 2 months ago
FatBoy-DOTC 76eed79b0a repair cost formula fixed 2 months ago
FatBoy-DOTC f73ed17c05 repair cost formula 2 months ago
FatBoy-DOTC b049d21aff corpse timer 2 months ago
FatBoy-DOTC f6cce5ee1f corpse timer 2 months ago
FatBoy-DOTC 8038c2ebe2 arena que messages 2 months ago
FatBoy-DOTC 9f51b9af57 arena que messages 2 months ago
FatBoy-DOTC cbc75bf9d7 irekei healer blood prophet 2 months ago
FatBoy-DOTC 0ecfa546cd SDR bind loc for errants 2 months ago
FatBoy-DOTC b89fb0803d SDR bind loc for errants 2 months ago
FatBoy-DOTC 11005d58a7 SDR bind loc for errants 2 months ago
FatBoy-DOTC b0c6239314 SDR bind loc for errants 2 months ago
FatBoy-DOTC 67f66155e9 SDR bind loc for errants 2 months ago
FatBoy-DOTC 7fbae12e99 mob update 2 months ago
FatBoy-DOTC 65580c0a47 mob update 2 months ago
FatBoy-DOTC 236afe4cc6 mob update 2 months ago
FatBoy-DOTC c23a6af28f mob update 2 months ago
FatBoy-DOTC 2535106d2c player update sync 2 months ago
FatBoy-DOTC d8379ae5a9 shades dont break hide when moving 2 months ago
FatBoy-DOTC 9f13f5fc5d add sprint to shade stealth 2 months ago
FatBoy-DOTC 884cb30ebd trade bug 2 months ago
FatBoy-DOTC 30488e5da6 maintenance bug 2 months ago
FatBoy-DOTC b7e798a950 spire effect extension 2 months ago
FatBoy-DOTC e999ca3f68 spire effect extension 2 months ago
FatBoy-DOTC 039638c0d8 stackable enum types 2 months ago
FatBoy-DOTC f282504896 irekei movepseed 2 months ago
FatBoy-DOTC 0062936ac6 irekei movepseed 2 months ago
FatBoy-DOTC 19c41daa86 irekei movepseed 2 months ago
FatBoy-DOTC d860b16cfd irekei movepseed 2 months ago
FatBoy-DOTC e3b42a8ad9 irekei movepseed 2 months ago
FatBoy-DOTC 20bd7a82af proper flying check for speed calculation 2 months ago
FatBoy-DOTC e607eb8220 irekei movespeed sync 2 months ago
FatBoy-DOTC 38ca49d1a5 errants bind loc to tree in SDR 2 months ago
FatBoy-DOTC a21bdfe031 blood prophet for all irekei mage/healers 2 months ago
FatBoy-DOTC f95832b87c xp modifiers 2 months ago
FatBoy-DOTC feff9b3540 cant get XP for suicide 2 months ago
FatBoy-DOTC 78118aa08c update inventory when getting conc and gold at start 2 months ago
FatBoy-DOTC 3539372437 powers manager fixes 2 months ago
FatBoy-DOTC 7c498625bd bounds error 2 months ago
FatBoy-DOTC e379016123 bane mechanic complete - working 2 months ago
FatBoy-DOTC afa68b840c bane mechanic complete - working 2 months ago
FatBoy-DOTC 1926deb7f9 bane mechanic complete - working 2 months ago
FatBoy-DOTC 25c1f34c23 bane mechanic 2 months ago
FatBoy-DOTC d0e04e53ad bane mechanic 2 months ago
FatBoy-DOTC e475fb5cc9 wildkins chase removes snare 2 months ago
FatBoy-DOTC f72f632cd8 login crash bug 2 months ago
FatBoy-DOTC 02ea27fc6f login crash bug 2 months ago
FatBoy-DOTC 5d338bb87c login crash bug 2 months ago
FatBoy-DOTC f9f08c2886 login crash bug 2 months ago
FatBoy-DOTC dcc139043d stop movement on cast 2 months ago
FatBoy-DOTC 520219404c NPC special price option 2 months ago
FatBoy-DOTC f97991f00d NPC special price option 2 months ago
FatBoy-DOTC 7b7e1c5337 NPC special price option 2 months ago
FatBoy-DOTC 6e66659940 NPC special price option 2 months ago
FatBoy-DOTC 3d83baed78 all sages can repair everything 2 months ago
FatBoy-DOTC 049b27da96 all sages can repair everything 2 months ago
FatBoy-DOTC 6bcbe0f633 all sages can repair everything 2 months ago
FatBoy-DOTC 8c44e39275 all sages can repair everything 2 months ago
FatBoy-DOTC e36ab1f5d2 corspe timer reduced to 10 minutes(from 15) 2 months ago
FatBoy-DOTC 865c775f41 Arena death message 2 months ago
FatBoy-DOTC 198778ba2d arena circle addition 2 months ago
FatBoy-DOTC 215aabdc5f arena circle addition 2 months ago
FatBoy-DOTC 8d92c8be37 Arena System complete feature 2 months ago
FatBoy-DOTC 93b3ce07f0 Arena System prize 2 months ago
FatBoy-DOTC f9b7c8b851 Arena System 2 months ago
FatBoy-DOTC b3cf72abdc Arena System 2 months ago
FatBoy-DOTC 65fddd06a9 Arena System 2 months ago
FatBoy-DOTC 41f4a8ff58 Arena System 2 months ago
FatBoy-DOTC a13d5018b9 Arena System 2 months ago
FatBoy-DOTC 2ac3ce5bc8 Arena System 2 months ago
FatBoy-DOTC 85514987e7 Arena Manager NPC 2 months ago
FatBoy-DOTC c9eb07b5ba Enrollment officer dialog option added 2 months ago
FatBoy-DOTC 7201b61498 Enrollment officer dialog option added 2 months ago
FatBoy-DOTC 55b3161900 Enrollment officer dialog 2 months ago
FatBoy-DOTC 9d5c4424a1 Arena Infrastructure 2 months ago
FatBoy-DOTC d507ba2339 force to stand when casting 2 months ago
FatBoy-DOTC 4ec5103454 saetor doomsayers 2 months ago
FatBoy-DOTC 3e09cd415e thread count on boot 2 months ago
FatBoy-DOTC 1098265145 player update handled in new thread 2 months ago
FatBoy-DOTC df7a106237 bane commander dialog reset options 2 months ago
FatBoy-DOTC 00b38970a1 bane commander dialog reset options 2 months ago
FatBoy-DOTC c1004e5817 bane commander dialog options 2 months ago
FatBoy-DOTC 13e9738345 bane commander dialog options 2 months ago
FatBoy-DOTC 1a7c1e2544 mine load error 2 months ago
FatBoy-DOTC ff082487b5 mine load error 2 months ago
FatBoy-DOTC 14cac0d892 mine load error 2 months ago
FatBoy-DOTC a8347e0b53 npc manager error spam 2 months ago
FatBoy-DOTC a73c3453ea npc manager error spam 2 months ago
FatBoy-DOTC a64932b2c9 Revert "npc manager error spam" 2 months ago
FatBoy-DOTC 685297171c npc manager error spam 2 months ago
FatBoy-DOTC 2e3e403165 trouble shooting mine bug 2 months ago
FatBoy-DOTC fbd910ef50 fix for flying bug 2 months ago
FatBoy-DOTC 30129d161f force respawn of dead players throwing error 2 months ago
FatBoy-DOTC a6510af56d force respawn of dead players throwing error 2 months ago
FatBoy-DOTC 9830920635 bane mechanic thread finalized 2 months ago
FatBoy-DOTC 93025b72cd bane mechanic thread finalized 2 months ago
FatBoy-DOTC 22639baa4c bane mechanic thread 2 months ago
FatBoy-DOTC 1aba8dfb11 bane mechanic thread 2 months ago
FatBoy-DOTC 8b4eb96262 bane mechanic thread 2 months ago
FatBoy-DOTC cafe6cd2fe bane mechanic thread 2 months ago
FatBoy-DOTC da6140f6f4 bane mechanic thread 2 months ago
FatBoy-DOTC 3fc68ce2ff bane mechanic thread 2 months ago
FatBoy-DOTC 5e8927245b bane mechanic thread 2 months ago
FatBoy-DOTC 75de1b3ae8 initiate baneAtendees 2 months ago
FatBoy-DOTC 6743114d19 update bane time first try 2 months ago
FatBoy-DOTC 28cca67cb3 Revert "update bane time first try" 2 months ago
FatBoy-DOTC bad7c6e798 update bane time first try 2 months ago
FatBoy-DOTC ecd3b38d3a update map when bane set 2 months ago
FatBoy-DOTC 8f09f16603 update map when bane set 2 months ago
FatBoy-DOTC 80812cb402 update map when bane set 2 months ago
FatBoy-DOTC 66fbf7aee6 update map when bane set 2 months ago
FatBoy-DOTC a92c603ab2 update map when bane set 2 months ago
FatBoy-DOTC 365438370d update map when bane set 2 months ago
FatBoy-DOTC a40b8fc915 update map when bane set 2 months ago
FatBoy-DOTC 5d92c1c86d bane system work 2 months ago
FatBoy-DOTC c526fd8847 bane system work 2 months ago
FatBoy-DOTC cd767dc68c bane system work 2 months ago
FatBoy-DOTC e21ebc75ee pets dont get sent home 2 months ago
FatBoy-DOTC 931eaaae4a city bane status update fix 2 months ago
FatBoy-DOTC 4d487e6bf0 city bane status update fix 2 months ago
FatBoy-DOTC 6c45a6573a null checks 2 months ago
FatBoy-DOTC 45b0dda7d9 remove duplicated gold and conc grants at character creation 2 months ago
FatBoy-DOTC caf3bc7470 remove option for 10 and 20 man banes based on trees in nation 2 months ago
FatBoy-DOTC 5259b801f7 bane ZergMultiplier value sfor 20-unlimited banes 2 months ago
FatBoy-DOTC 77e6d0db75 player guards to drop aggro once player leaves city 2 months ago
FatBoy-DOTC b2d7e5ec1e bane commander NPC work 2 months ago
FatBoy-DOTC 15bc99d216 bane commander NPC work 2 months ago
FatBoy-DOTC 63c6e2abd7 bane zerg mechanics enabled 2 months ago
FatBoy-DOTC 8ab97a1b36 bane zerg mechanics enabled 2 months ago
FatBoy-DOTC d1aa581879 players coutn towards Siege Cap at banes for 3 minutes after leaving bane area 2 months ago
FatBoy-DOTC 5f56143c5e fixed bug with negative xp when setting level to 10 2 months ago
FatBoy-DOTC 1a2b558ac3 fixed bug with negative xp when setting level to 10 2 months ago
FatBoy-DOTC 4f4ff74bf1 fixed bug with negative xp when setting level to 10 2 months ago
FatBoy-DOTC ded3b08080 fixed random rune drop chance 2 months ago
FatBoy-DOTC 14a29c8612 fixed NPC interaction 2 months ago
FatBoy-DOTC e66e430d30 fixed NPC interaction 2 months ago
FatBoy-DOTC c833f560c1 guard minion retaliation 2 months ago
FatBoy-DOTC 454c721842 zerg mechanic values adjusted 2 months ago
FatBoy-DOTC 26eda324dc adjusted global drop rates 2 months ago
FatBoy-DOTC 16951d36a2 bane commander NPC 2 months ago
FatBoy-DOTC e1d36125d2 bane commander NPC 2 months ago
FatBoy-DOTC 7a3c259d2f bane commander NPC 2 months ago
FatBoy-DOTC aa5fb2a2c5 bane commander NPC 2 months ago
FatBoy-DOTC a92cc6506c bane commander NPC 2 months ago
FatBoy-DOTC 3971548142 bane commander NPC 2 months ago
FatBoy-DOTC d94de771bf bane commander NPC 2 months ago
FatBoy-DOTC c5f47ffcd4 bane commander NPC 2 months ago
FatBoy-DOTC b336235ad7 bane commander NPC 2 months ago
FatBoy-DOTC eea07309aa bane commander NPC 2 months ago
FatBoy-DOTC 5529170036 bane commander NPC 2 months ago
FatBoy-DOTC 3d745e93b6 bane commander NPC 2 months ago
FatBoy-DOTC 019082bec7 bane commander NPC 2 months ago
FatBoy-DOTC 855cceea70 bane commander NPC 2 months ago
FatBoy-DOTC 487eae85e1 bane commander NPC 2 months ago
FatBoy-DOTC 5d188e61c0 bane commander NPC 2 months ago
FatBoy-DOTC 546c335198 bane commander NPC 2 months ago
FatBoy-DOTC aaecc5eda2 bane commander NPC 2 months ago
FatBoy-DOTC d13e939ddd bane commander NPC 2 months ago
FatBoy-DOTC afea79474e bane commander NPC 2 months ago
FatBoy-DOTC 05f555b5b5 bane commander NPC 2 months ago
FatBoy-DOTC 85931b6dc2 bane commander NPC 2 months ago
FatBoy-DOTC 9f0c7f6a76 bane commander NPC 2 months ago
FatBoy-DOTC 022c06c803 bane commander NPC 2 months ago
FatBoy-DOTC 1b72e7d6b7 bane commander NPC 2 months ago
FatBoy-DOTC 666ac6df5b bane commander NPC 2 months ago
FatBoy-DOTC 36481a53d9 bane commander NPC 2 months ago
FatBoy-DOTC 5a9901d775 bane commander NPC 2 months ago
FatBoy-DOTC b3a24d0158 fixed bug with trebs spamming console 2 months ago
FatBoy-DOTC 8890826070 fixed bug with trebs spamming console 2 months ago
FatBoy-DOTC daa84a1fef added MB_WORLD_TESTMODE to config manager and file 2 months ago
FatBoy-DOTC a4bd47f001 audit command for drop rates 2 months ago
FatBoy-DOTC d031f1be01 audit command for drop rates 2 months ago
FatBoy-DOTC a48abc59ce audit command for drop rates 2 months ago
FatBoy-DOTC 878f05c323 audit command for drop rates 2 months ago
FatBoy-DOTC d462711d25 audit command for drop rates 2 months ago
FatBoy-DOTC 40a0120a28 +1% drop disp[arity for mobs unde rlevel 50 AND introduce guard drops 2 months ago
FatBoy-DOTC ac812eaeae allow goto and teleportmode for players 2 months ago
FatBoy-DOTC 9965223d9b revert steward and builder sell inventory 5 months ago
FatBoy-DOTC 08b99d0d3a revert steward and builder sell inventory 5 months ago
FatBoy-DOTC 519a6a2b1e revert steward and builder sell inventory 5 months ago
FatBoy-DOTC 524f5d470b protocol error logging 5 months ago
FatBoy-DOTC 6631c6a5d7 protocol error logging 5 months ago
FatBoy-DOTC 10f95fb0d9 fixed banestone roll times 5 months ago
FatBoy-DOTC a315366026 disconnect after 10 minutes dead 5 months ago
FatBoy-DOTC 1901c9a679 disconnect after 10 minutes dead 5 months ago
FatBoy-DOTC 415ad5402f disconnect after 10 minutes dead 5 months ago
FatBoy-DOTC 9a40e12dbc castable enchants removed when item leaves players immediate posession 5 months ago
FatBoy-DOTC a1af663796 irekei healers get blood prophet 5 months ago
FatBoy-DOTC 78b7ddb32a saetor trains undone 5 months ago
FatBoy-DOTC 5e5ee4fed1 saetor trains 5 months ago
FatBoy-DOTC 84c022a39b saetor trains 5 months ago
FatBoy-DOTC 300741b05a saetor trains 5 months ago
FatBoy-DOTC dc685a01c6 remove roots form wildkins chase 5 months ago
FatBoy-DOTC 752f897a34 juiced up droppers 5 months ago
FatBoy-DOTC 722cb6b1fd Revert "high str NPCs" 5 months ago
FatBoy-DOTC 50c095cd09 high str NPCs 5 months ago
FatBoy-DOTC c23546eb46 10% cost for magical random rolls removed 5 months ago
FatBoy-DOTC 36340c4e52 fixed production bug for mines 5 months ago
FatBoy-DOTC a7ab38f40c can teleport to owned mines 5 months ago
FatBoy-DOTC 0901c03b74 can teleport to owned mines 5 months ago
FatBoy-DOTC 50817352c1 teleport to mines 5 months ago
FatBoy-DOTC ee4a7447bc teleport to mines 5 months ago
FatBoy-DOTC a6d3c827ad teleport to mines 5 months ago
FatBoy-DOTC d4ea31b91f teleport to mines 5 months ago
FatBoy-DOTC 210faaec6d refund gold for cancelled rolled items 5 months ago
FatBoy-DOTC 16be9b9dae refund gold for cancelled rolled items 5 months ago
FatBoy-DOTC 2b8f709182 stun grounds 5 months ago
FatBoy-DOTC aec22d8563 disable keyclone audit 5 months ago
FatBoy-DOTC 1996d042f0 fly speed changes finished 5 months ago
FatBoy-DOTC 27b6665717 fly speed changes 5 months ago
FatBoy-DOTC ce20045611 Merge remote-tracking branch 'origin/lakebane-strongholds' into lakebane-strongholds 5 months ago
FatBoy-DOTC 277f8bfd69 fly speed changes 5 months ago
FatBoy-DOTC 1da2db856f fly speed completed 5 months ago
FatBoy-DOTC 33dfe1389c move buff grounding 5 months ago
FatBoy-DOTC 013b69405a move buff grounding 5 months ago
FatBoy-DOTC ca07a53835 cast while flying 5 months ago
FatBoy-DOTC bbdb6ae1f6 cast while flying 5 months ago
FatBoy-DOTC 4a63222318 cast while flying 5 months ago
FatBoy-DOTC 1a1c552964 cast while flying 5 months ago
FatBoy-DOTC 3587dc2d75 builders sell things at proper ranks 5 months ago
FatBoy-DOTC 96eb9a3ad0 builders sell things at proper ranks 5 months ago
FatBoy-DOTC eaa70f43c0 stewards sell things at proper ranks 5 months ago
FatBoy-DOTC a426b773d3 sage on TOL 5 months ago
FatBoy-DOTC 84841edda9 r8 gets extra hireling slot 5 months ago
FatBoy-DOTC d416dbe47b shade hide 5 months ago
FatBoy-DOTC 7052da7e54 shade hide 5 months ago
FatBoy-DOTC 8f2a2f0ba6 Rogue Druids 6 months ago
FatBoy-DOTC d575ba663d displayed maintenance for r8 tree no longer shows resource required 6 months ago
FatBoy-DOTC 964fe7f335 city serilizing bug 6 months ago
FatBoy-DOTC d3e92d6576 city serilizing bug 6 months ago
FatBoy-DOTC 9dbd6069f1 force respawn after 10 minutes dead 6 months ago
FatBoy-DOTC 7ae25c9a1b can now summon in combat 6 months ago
FatBoy-DOTC 689969a005 r* tree buildings acquire 10% more HP 6 months ago
FatBoy-DOTC b270e1ac8d r8 maintenance flat 3 mil 6 months ago
FatBoy-DOTC 95d38cea44 rogue can promote to druid 6 months ago
FatBoy-DOTC 3ed0765fe5 flying while having move buff fix 6 months ago
FatBoy-DOTC 0c90164c24 shade invis bug 6 months ago
FatBoy-DOTC a45fa39afc random roll magic extra cost removed 6 months ago
FatBoy-DOTC 8959f5e1c5 r7 votary grants PR40 boon 6 months ago
FatBoy-DOTC df338ab00e fix resource vendor pricing 6 months ago
FatBoy-DOTC ac7a2452d6 disable strongholds 6 months ago
FatBoy-DOTC 80104e6d07 fixed login bug 6 months ago
FatBoy-DOTC 8f394cd01d fixed login bug 6 months ago
FatBoy-DOTC e5a32c83c5 Revert "mine production values adjusted" 6 months ago
FatBoy-DOTC 8dce20e69f Revert "adjusted hit chance formula" 6 months ago
FatBoy-DOTC 3428a06bb8 adjusted hit chance formula 6 months ago
FatBoy-DOTC 177f9a1ff6 mine production values adjusted 6 months ago
FatBoy-DOTC 9d93944dd1 mob roll levels 6 months ago
FatBoy-DOTC a4cba1a352 better roll chance for high level vendors 6 months ago
FatBoy-DOTC 17b4232d80 better roll chance for high level vendors 6 months ago
FatBoy-DOTC 2eb58eb719 custom hit chance formula 6 months ago
FatBoy-DOTC db5a4195ad custom hit chance formula 6 months ago
FatBoy-DOTC 3fb29f8e2b custom hit chance formula 6 months ago
FatBoy-DOTC dacdb2cf35 stronghold mobs 6 months ago
FatBoy-DOTC c8473cbe03 stronghold mobs 6 months ago
FatBoy-DOTC e9edf8a7ea increase number of strongholds 6 months ago
FatBoy-DOTC 5a73aa3d90 increase number of strongholds 6 months ago
FatBoy-DOTC 04101c1c3e additional 60 second logout timer for players who have enemies nearby and aren't in safezone 6 months ago
FatBoy-DOTC 0c9343f24d additional 60 second logout timer for players who have enemies nearby and aren't in safezone 6 months ago
FatBoy-DOTC b71710871c track list construction 6 months ago
FatBoy-DOTC f6df6db17b level cap increased to 80 6 months ago
FatBoy-DOTC 3f8b3bc6cb PVP xp enabled 6 months ago
FatBoy-DOTC 383ef27128 can use abilities while flying 6 months ago
FatBoy-DOTC d8189768ae mine production cut in half 6 months ago
FatBoy-DOTC a5eb2fce75 mine management to show correct production amount 6 months ago
FatBoy-DOTC 1fe242a284 strip temporary item enchants when transfered 6 months ago
FatBoy-DOTC a4b83ca9a0 increase resists of the droppers 6 months ago
FatBoy-DOTC 2365b26c1c trainer buildinsg capped at r1 with 3 slots 6 months ago
FatBoy-DOTC 8fb044f71b trainer buildinsg capped at r1 with 3 slots 6 months ago
FatBoy-DOTC 5ce42475c4 force respawn after 10 minutes of unreleased corpse 6 months ago
FatBoy-DOTC 57b9d31fff dropper resists 6 months ago
FatBoy-DOTC 7671586cb0 terraform issue 6 months ago
FatBoy-DOTC a1997e31a8 terraform issue 6 months ago
FatBoy-DOTC f5478e9f64 terraform issue 6 months ago
FatBoy-DOTC 06abea3576 terraform issue 6 months ago
FatBoy-DOTC ae6b584a5f DS immunity fixed 6 months ago
FatBoy-DOTC 9e27c69906 trainer buildings get 3 slots at r1 6 months ago
FatBoy-DOTC 00afe27900 stealing from mobs works again 6 months ago
FatBoy-DOTC 4e5c1a32d3 stronghold mob equipsets 6 months ago
FatBoy-DOTC d4f5043a25 toughness sync issue 6 months ago
FatBoy-DOTC 03a5a55974 remove NPC slot error spam onboot 6 months ago
FatBoy-DOTC dbab4c1212 baked in stats null check 6 months ago
FatBoy-DOTC d186a96796 non vorg droppers cannot drop vorg items 6 months ago
FatBoy-DOTC 6880d014c3 elan vendor price increased to 1,000,000 6 months ago
FatBoy-DOTC 6542dec358 saetors can take disc runes 6 months ago
FatBoy-DOTC 1a2738c3a9 saetors can take disc runes 6 months ago
FatBoy-DOTC 12118ff125 fixed saetor promotions 6 months ago
FatBoy-DOTC c3a00186ff saetors allowed to take creation runes 6 months ago
FatBoy-DOTC fafa777e98 saetor creation fixed 6 months ago
FatBoy-DOTC d4da99f61c NPC sell% in safezone = 0 6 months ago
FatBoy-DOTC bb293c0c02 BH eyes get double value for points in skill (20 points = PR40) 6 months ago
FatBoy-DOTC 1e29971b3c safe NPC profits 6 months ago
FatBoy-DOTC 25d70cca4f error message for flying with movement buff 6 months ago
FatBoy-DOTC 362832a196 NPC safezone sell% = 0 6 months ago
FatBoy-DOTC ed150a5ccd gimme command bumps level to 75 6 months ago
FatBoy-DOTC d2247b66f1 safezone NPCs have 0% profit 6 months ago
FatBoy-DOTC 3b58ea716c custom range for booty sim command 6 months ago
FatBoy-DOTC 368e548e46 special case rolls for contracts, glass, resources and runes 6 months ago
FatBoy-DOTC 6f3612d196 Elf Blood Runes Free 6 months ago
FatBoy-DOTC 0f38146fcc extra stats on printstats 6 months ago
FatBoy-DOTC 1a13f3f096 hit roll formula fixed 6 months ago
FatBoy-DOTC 9cc102ca2a scrolls removed from form breaking 6 months ago
FatBoy-DOTC 50ff4b89bf granted concnc pot fixed 6 months ago
FatBoy-DOTC 9b898825ab no move buff while flying 6 months ago
FatBoy-DOTC 5be9033c40 no move buff while flying 6 months ago
FatBoy-DOTC 67e55ab0a0 no move buff while flying 6 months ago
FatBoy-DOTC 227549bf22 no move buff while flying 6 months ago
FatBoy-DOTC 19707d10a3 no move buff while flying 6 months ago
FatBoy-DOTC 91565ced89 no move buff while flying 6 months ago
FatBoy-DOTC 2383b00c8c mobs recall when out of range of their bind loc 6 months ago
FatBoy-DOTC 405063f036 guilds MOTD now persist 6 months ago
FatBoy-DOTC d2f3c6a879 potions and scrolls no longer count as casting a spell 6 months ago
FatBoy-DOTC 4f759c1bd2 shade sneak 6 months ago
FatBoy-DOTC 9d7f9ce7b3 no movement buffs while flying, cannot fly if you have a movement buff applied 6 months ago
FatBoy-DOTC 56f3dfce92 no movement buffs while flying, cannot fly if you have a movement buff applied 6 months ago
FatBoy-DOTC 9a66f18edb extra 60 seconds added to summon if enemies near and not in safezone 6 months ago
FatBoy-DOTC d7270ffb84 group teleport restricted to active banes and active mines 6 months ago
FatBoy-DOTC dd834a3104 cant delete buildings when baned 6 months ago
FatBoy-DOTC e28ed1b882 fortitude handled after resists 6 months ago
FatBoy-DOTC 2370123c72 hit roll formula added 6 months ago
FatBoy-DOTC 8a5133f04b character starts with 1000 gold and a conc pot 6 months ago
FatBoy-DOTC a0f874b319 cannot tax cities in realm 6 months ago
FatBoy-DOTC 415d11ae33 Vorg droppers increased level and resists 6 months ago
FatBoy-DOTC f93b1ce30e teleport to runegate power action fix for closest gate 6 months ago
FatBoy-DOTC 9fb2e4ff1b apply rune message work 6 months ago
FatBoy-DOTC 601d0f4324 special case drop rate for contracts runes and resources completed 6 months ago
FatBoy-DOTC cbf7db3347 mine production issue resolved 6 months ago
FatBoy-DOTC 217be1d234 Special Case rune contract and resource drops 6 months ago
FatBoy-DOTC 7fabd6554d glass chance is 10/100,000 6 months ago
FatBoy-DOTC d673819796 gimme command 6 months ago
FatBoy-DOTC a963a331a2 mobs that spawn with no loot respawn again 6 months ago
FatBoy-DOTC eda5b8995f stronghold mobs power sets 6 months ago
FatBoy-DOTC d5e95eedf3 stronghold loot adjustment 6 months ago
FatBoy-DOTC 032e703704 gimme command for testing 6 months ago
FatBoy-DOTC ad1444f5ba level 70+ is allowed to apply a fifth disc rune 6 months ago
FatBoy-DOTC a4b30b8620 level cap increased to 80 6 months ago
FatBoy-DOTC 9c002c7bff updated stronghold mobs 7 months ago
FatBoy-DOTC 90495a27d9 blood rune dropper issue resolved 7 months ago
FatBoy-DOTC 1246fa699a blood rune boot issue 7 months ago
FatBoy-DOTC 511d37f5e0 blood rune droppers moved to DB with client patch 7 months ago
FatBoy-DOTC 7a03a0eaa9 noob conc pots 7 months ago
FatBoy-DOTC 2f57cb613e noob conc pots 7 months ago
FatBoy-DOTC e386c3078a noob conc pots 7 months ago
FatBoy-DOTC 3802889834 allow applying blood runes 7 months ago
FatBoy-DOTC f825b2baba negate stronghold mobs from dropping equipment 7 months ago
FatBoy-DOTC 6c92abd083 present drops restricted to strongholds 7 months ago
FatBoy-DOTC c652379a5f mob region lookup 7 months ago
FatBoy-DOTC 61d34ab4ad hotfixes 7 months ago
FatBoy-DOTC d511641410 hotfixes 7 months ago
FatBoy-DOTC c8430625bf mob resists fix 7 months ago
FatBoy-DOTC a418224bbb start random roll at 0 to avoid illegal argument 7 months ago
FatBoy-DOTC 9e3c13dea3 generic resists added for mobs to stop crashing AI 7 months ago
FatBoy-DOTC 335850f7ff stronghold epics target playe rnot self 8 months ago
FatBoy-DOTC f6baf8fe83 resistance modifiers for mobs 8 months ago
FatBoy-DOTC 4c9b82b649 def and ATR cuts for stronghold mobs 8 months ago
FatBoy-DOTC f2570992e5 completed custom strongholds 8 months ago
FatBoy-DOTC 6911d6314d epic encounter naming convention 8 months ago
FatBoy-DOTC eaeea9730c epic encounter naming convention 8 months ago
FatBoy-DOTC fb0790a733 epic encounter after clearing a stronghold 8 months ago
FatBoy-DOTC 3230cd53e1 epic encounter after clearing a stronghold 8 months ago
FatBoy-DOTC edbce067b8 epic encounter after clearing a stronghold 8 months ago
FatBoy-DOTC 83877e5107 epic encounter after clearing a stronghold 8 months ago
FatBoy-DOTC 3a67540212 stronghold attack messages 8 months ago
FatBoy-DOTC 1a5db96023 stronghold mobs spawn 2x mines cap size 8 months ago
FatBoy-DOTC ef82f9ab5b stronghold mobs no longer lose bonuses from weapon powers 8 months ago
FatBoy-DOTC bf7e5c6333 stronghold guardian fix 8 months ago
FatBoy-DOTC 443f0f5450 stronghold guardian fix 8 months ago
FatBoy-DOTC cb1dccd630 stronghold guardian fix 8 months ago
FatBoy-DOTC 2e558acbee stronghold guardian fix 8 months ago
FatBoy-DOTC 74162ea54c stronghold guardian fix 8 months ago
FatBoy-DOTC ccbe4fba04 stronghold guardian fix 8 months ago
FatBoy-DOTC 5aeddb6166 stronghold guardian fix 8 months ago
FatBoy-DOTC 49df5203ae stronghold guardian fix 8 months ago
FatBoy-DOTC 0cfe801d18 stronghold guardian fix 8 months ago
FatBoy-DOTC 89c01e8244 random item generation fix 8 months ago
FatBoy-DOTC 6605e4dd61 update regions when changing mesh 8 months ago
FatBoy-DOTC d6239de6fd delete stronghold mobs form DB when finished 8 months ago
FatBoy-DOTC 99ad6f3712 delete stronghold mobs form DB when finished 8 months ago
FatBoy-DOTC f3041e7549 SetLoc for stronghold mobs 8 months ago
FatBoy-DOTC 1269031be3 SetLoc for stronghold mobs 8 months ago
FatBoy-DOTC ce96274f28 SetLoc for stronghold mobs 8 months ago
FatBoy-DOTC a9a9bd0a3d Stronghold variations 8 months ago
FatBoy-DOTC 33789adadc final strongholds update 8 months ago
FatBoy-DOTC 15b50a75c4 commander stats update 8 months ago
FatBoy-DOTC ead34dbb1f commander powers 8 months ago
FatBoy-DOTC a9b1356efa new stronghold mesh 8 months ago
FatBoy-DOTC 33e105bc7b naming convention 8 months ago
FatBoy-DOTC e5041147f4 added disc and rune to commander drops 8 months ago
FatBoy-DOTC 576e627ad1 fixed loot generation array size bug 8 months ago
FatBoy-DOTC 4059664354 stronghold loot 8 months ago
FatBoy-DOTC 974c0ca7e8 force load changes meshes 8 months ago
FatBoy-DOTC 8e7a7b8b6d stronghold scale set 8 months ago
FatBoy-DOTC 1e3b1db905 commander location set 8 months ago
FatBoy-DOTC 51c98746c4 make stronghold mobs aggro 8 months ago
FatBoy-DOTC 4c21439847 serialize the stronghold mine 8 months ago
FatBoy-DOTC 31385ee533 SCALING DOWN THE STRONGHOLD BUILDING 8 months ago
FatBoy-DOTC bd4e34e0e1 SCALING DOWN THE STRONGHOLD BUILDING 8 months ago
FatBoy-DOTC 9f591b166b Initial Stronghold Push 8 months ago
FatBoy-DOTC 7e457fa17b all items form "Noob Helper" cost 2 gold 8 months ago
FatBoy-DOTC 926b9d2bae R8 ToL can have 4 shrines 8 months ago
FatBoy-DOTC c5822b5acf dropper resists and level increase 8 months ago
FatBoy-DOTC 516b66a50a reintroduce blood rune droppers on 3 hour disc cycle 8 months ago
FatBoy-DOTC 39305d63c7 noob island gear 8 months ago
FatBoy-DOTC c0cb856961 noob island gear 8 months ago
FatBoy-DOTC 2fb97a676f allow some dev commands for players (print) 8 months ago
FatBoy-DOTC cbff151dc3 allow some dev commands for players (print) 8 months ago
FatBoy-DOTC eed75fd2fd repair costs calculated properly 8 months ago
FatBoy-DOTC 6374390b34 repair cost synced with server values 8 months ago
FatBoy-DOTC 2185d3ef7c rune merchants pricing adjusts 8 months ago
FatBoy-DOTC 4aaa96e36c resourc emerchant pricing adjust 8 months ago
FatBoy-DOTC bf86680547 higher present drop chance 8 months ago
FatBoy-DOTC 960307e262 rune pricing fix 8 months ago
FatBoy-DOTC eedf96cc31 resource pricing fix 8 months ago
FatBoy-DOTC 6fb5fce4d3 fixed profit error for NPCs 8 months ago
FatBoy-DOTC 7688d21fe6 boons refreshable, boon level determined by votary rank, shrines should work for all, boons nation friendly again 8 months ago
FatBoy-DOTC 23e60b36b4 General Cleanup and drop rates 8 months ago
FatBoy-DOTC ab8fc8e0a0 random vorg droppers, max durability repairable 8 months ago
FatBoy-DOTC b30f04046d uniform disc dropper times 8 months ago
FatBoy-DOTC 9bd03c7d43 pricing corrected for rune vendors 8 months ago
FatBoy-DOTC 78118a1ac1 fix for rune application 8 months ago
FatBoy-DOTC 1f863d0cce resource pricing fix 8 months ago
FatBoy-DOTC c49204aeeb NPC have 0 maint, fix for resource merchant 8 months ago
FatBoy-DOTC b1de3755fd display correct maintenance costs 8 months ago
FatBoy-DOTC 83a1cc5aba maintenance display on buildings 8 months ago
FatBoy-DOTC 9b0b15c31e remove refund for deranked building due to maintenance 8 months ago
FatBoy-DOTC 802651d2d4 rune application error fixed 8 months ago
FatBoy-DOTC 52a48e5618 rune application checks 8 months ago
FatBoy-DOTC 14fe248e19 mine serializing 8 months ago
FatBoy-DOTC 5b81be371e mine serializing 8 months ago
FatBoy-DOTC 82d67f2850 mine serializing 8 months ago
FatBoy-DOTC 1c342bd566 server pop on creation displays amount of realms captured 8 months ago
FatBoy-DOTC bb8ad3c971 character creation population message 8 months ago
FatBoy-DOTC e9fef85b72 set maintenance dates correctly 8 months ago
FatBoy-DOTC c0d1a4f274 mines produce once a day, maintenance system for TOL only 8 months ago
FatBoy-DOTC 94be3335a0 mine production change error tracking 8 months ago
FatBoy-DOTC 7d03f78546 rune application require/restrict actually use values 8 months ago
FatBoy-DOTC 023f933d0b rune application require/restrict actually use values 8 months ago
FatBoy-DOTC 9995cc01b7 rune application require/restrict actually use values 8 months ago
FatBoy-DOTC fd03b263d1 pets follow owners through teleporting 8 months ago
FatBoy-DOTC 6a09a3fd44 pets follow owners through teleporting 8 months ago
FatBoy-DOTC 1322f8610c safe guards dont kill pets anymore 8 months ago
FatBoy-DOTC 90ab6175b5 extra ToL slots 8 months ago
FatBoy-DOTC 2e3e9ee882 extra ToL slots 8 months ago
FatBoy-DOTC 5158329785 Saetor can take Chaos Shrine boon 8 months ago
FatBoy-DOTC b8e0165da2 allowed siege engineer alchemist and banker on ToL 8 months ago
FatBoy-DOTC 0fa6ebc136 fix pets 8 months ago
FatBoy-DOTC 4e5e362197 attempt to fix mine serialization 8 months ago
FatBoy-DOTC 61514fef2b attempt to fix mine serialization 8 months ago
FatBoy-DOTC 59e593ab0d attempt to fix mine serialization 8 months ago
FatBoy-DOTC 2c6ea98ef9 revert instant respawns 8 months ago
FatBoy-DOTC bd3ea16b57 faster respawns 8 months ago
FatBoy-DOTC 45165332f6 faster respawns 8 months ago
FatBoy-DOTC d764a66e55 logging 8 months ago
FatBoy-DOTC ac41e64429 logging 8 months ago
FatBoy-DOTC 462beb30b3 logging 8 months ago
FatBoy-DOTC 3a89e9c087 logging 8 months ago
FatBoy-DOTC e71863cbd2 logging 8 months ago
FatBoy-DOTC 5ec0ff0598 logging 8 months ago
FatBoy-DOTC 2ca9b77cfb logging 8 months ago
FatBoy-DOTC 4f535ef5fe loot manager for glass runes and contracts 8 months ago
FatBoy-DOTC a46ad71bb0 loot manager for glass runes and contracts 8 months ago
FatBoy-DOTC 90d6911d41 loot manager for glass runes and contracts 8 months ago
FatBoy-DOTC e13ebae0df loot manager for glass runes and contracts 8 months ago
FatBoy-DOTC 3e15fc8206 bootysim command work 8 months ago
FatBoy-DOTC 6a400467dd drop rate work 8 months ago
FatBoy-DOTC 488188e9c3 glass chance work 8 months ago
FatBoy-DOTC 0d31bc4280 contract and rune drop work 8 months ago
FatBoy-DOTC 6375b4431c box check 8 months ago
FatBoy-DOTC 683422f8a4 auto identify all items 8 months ago
FatBoy-DOTC e4dbad2669 generic loot system in place 8 months ago
FatBoy-DOTC 34721fdee8 generic loot system in place 8 months ago
FatBoy-DOTC f27668552c corrected pricing for +10 runes 8 months ago
FatBoy-DOTC 306fdf4235 permanent open runegates 8 months ago
FatBoy-DOTC 553b09d827 rune pricing corrected 8 months ago
FatBoy-DOTC 8ee17f0c64 fix resource merchant elan stones pricing 8 months ago
FatBoy-DOTC 7e5ad644d3 fix resource merchant elan stones 8 months ago
FatBoy-DOTC 846b8a7cde fix resource merchant margins 8 months ago
FatBoy-DOTC f27a4f174b error popup when trying to flag unboxed too frequently 8 months ago
FatBoy-DOTC c6d4375aa8 error popup when trying to flag unboxed too frequently 8 months ago
FatBoy-DOTC b9ec54c76a enrollment office removes DS effect 8 months ago
FatBoy-DOTC b351d7c1ae enrollment officer system 8 months ago
FatBoy-DOTC 729ebe7cd0 box checker 8 months ago
FatBoy-DOTC f51c28e708 revert boxing enforcement 8 months ago
FatBoy-DOTC 9fbf55127d sourcetype lookup fix 8 months ago
FatBoy-DOTC f9fd61dc6b revert sourcetype lookup fix 8 months ago
FatBoy-DOTC 4f198e1f53 Merge remote-tracking branch 'origin/lakebane-new' into lakebane-new 8 months ago
FatBoy-DOTC 24c85a5140 revert sourcetype lookup fix 8 months ago
FatBoy-DOTC 3e1a5f4ccd SpurceType lookup fixes for Piercing Crushing and Slashing 8 months ago
FatBoy-DOTC 34e5a3878c SpurceType lookup fixes for Piercing Crushing and Slashing 8 months ago
FatBoy-DOTC 663e285091 Deathshroud applied ot all boxed characters 8 months ago
FatBoy-DOTC d87c03bb79 fixed combat message to reflect proper zerg multiplier values 8 months ago
FatBoy-DOTC abc57688d3 reset zerg multipliers when window closes 8 months ago
FatBoy-DOTC 29671d56fc display zerg multiplier in ./info 8 months ago
FatBoy-DOTC e8cf6a722b remove hotzone form the game 8 months ago
FatBoy-DOTC 2793ec331b mines revert to claimable at 1am CST 8 months ago
FatBoy-DOTC 1a0b91b068 buying larger stacks of resources form resource vendor 8 months ago
FatBoy-DOTC bec6cbe6e6 implement stat modifications for the ZergMultiplier 8 months ago
FatBoy-DOTC f7ab10ff07 altered mine production values 8 months ago
FatBoy-DOTC 9671cbdc1a unlimited sub guilds 8 months ago
FatBoy-DOTC e0af1f5932 no caps on claimable mines for nations 8 months ago
FatBoy-DOTC 8cb52c6142 zerg multiplier resets for players after mine closes 8 months ago
FatBoy-DOTC e5133211a9 Zerg Mechanic for Mines 8 months ago
FatBoy-DOTC 8548612a80 items auto ID 8 months ago
FatBoy-DOTC 41c3193275 irekei movespeed fix 8 months ago
FatBoy-DOTC 15771d2802 new characters start at level 10 8 months ago
FatBoy-DOTC b4a62e5f3e update inventory when junking for gold 8 months ago
FatBoy-DOTC fc7e6735a1 mine tower health scales with cap size 8 months ago
FatBoy-DOTC aeb21c328e max slots for rank adjustments 8 months ago
FatBoy-DOTC 9a34b13c2e junk from inventory 8 months ago
FatBoy-DOTC 231feef7fe mines open during a reboot time frame now open correctly 8 months ago
FatBoy-DOTC 0e6b68139f refactor mine processing to HalfHourlyJob 8 months ago
FatBoy-DOTC ef62c2bb39 mines open and close 8 months ago
FatBoy-DOTC 8f68997f3c terraform size correction 8 months ago
FatBoy-DOTC aebe2698c3 terraform size correction 8 months ago
FatBoy-DOTC 54e7a8fc7f display mine times correctly 8 months ago
FatBoy-DOTC 8b4d37c53c fix for mines loading 8 months ago
FatBoy-DOTC fbfca46d2f fix for mines loading 8 months ago
FatBoy-DOTC 3228f473de fix for mines loading 8 months ago
FatBoy-DOTC 17fcf0ee40 duplicated zone loading disabled 8 months ago
FatBoy-DOTC 395fe31e02 duplicated zone loading disabled 8 months ago
FatBoy-DOTC e98f9cf1f7 duplicated zone loading disabled 8 months ago
FatBoy-DOTC fe0c0f97a5 duplicated zone loading disabled 8 months ago
FatBoy-DOTC 7e27838818 mine changes 8 months ago
FatBoy-DOTC bc8094c20c saetor race as minotaurs 8 months ago
  1. 48
      src/engine/Enum.java
  2. 7
      src/engine/InterestManagement/InterestManager.java
  3. 166
      src/engine/db/handlers/dbBaneHandler.java
  4. 14
      src/engine/db/handlers/dbCityHandler.java
  5. 56
      src/engine/db/handlers/dbContractHandler.java
  6. 17
      src/engine/db/handlers/dbHandlerBase.java
  7. 24
      src/engine/db/handlers/dbItemBaseHandler.java
  8. 24
      src/engine/db/handlers/dbItemHandler.java
  9. 38
      src/engine/db/handlers/dbNPCHandler.java
  10. 47
      src/engine/devcmd/cmds/AddNPCCmd.java
  11. 63
      src/engine/devcmd/cmds/GimmeCmd.java
  12. 77
      src/engine/devcmd/cmds/HotzoneCmd.java
  13. 30
      src/engine/devcmd/cmds/InfoCmd.java
  14. 5
      src/engine/devcmd/cmds/MineActiveCmd.java
  15. 2
      src/engine/devcmd/cmds/PrintSkillsCmd.java
  16. 48
      src/engine/devcmd/cmds/PrintStatsCmd.java
  17. 4
      src/engine/devcmd/cmds/SetLevelCmd.java
  18. 74
      src/engine/devcmd/cmds/SimulateBootyCmd.java
  19. 168
      src/engine/gameManager/ArenaManager.java
  20. 37
      src/engine/gameManager/BuildingManager.java
  21. 5
      src/engine/gameManager/ChatManager.java
  22. 230
      src/engine/gameManager/CombatManager.java
  23. 4
      src/engine/gameManager/ConfigManager.java
  24. 40
      src/engine/gameManager/DevCmdManager.java
  25. 661
      src/engine/gameManager/LootManager.java
  26. 123
      src/engine/gameManager/MaintenanceManager.java
  27. 14
      src/engine/gameManager/MovementManager.java
  28. 4
      src/engine/gameManager/NPCManager.java
  29. 446
      src/engine/gameManager/PowersManager.java
  30. 45
      src/engine/gameManager/SimulationManager.java
  31. 347
      src/engine/gameManager/StrongholdManager.java
  32. 195
      src/engine/gameManager/ZergManager.java
  33. 73
      src/engine/gameManager/ZoneManager.java
  34. 2
      src/engine/job/AbstractJob.java
  35. 2
      src/engine/job/AbstractScheduleJob.java
  36. 2
      src/engine/job/JobContainer.java
  37. 75
      src/engine/job/JobThread.java
  38. 9
      src/engine/job/JobWorker.java
  39. 4
      src/engine/jobs/AbstractEffectJob.java
  40. 2
      src/engine/jobs/ActivateBaneJob.java
  41. 2
      src/engine/jobs/AttackJob.java
  42. 2
      src/engine/jobs/BaneDefaultTimeJob.java
  43. 2
      src/engine/jobs/BasicScheduledJob.java
  44. 2
      src/engine/jobs/BonusCalcJob.java
  45. 2
      src/engine/jobs/CSessionCleanupJob.java
  46. 2
      src/engine/jobs/ChangeAltitudeJob.java
  47. 2
      src/engine/jobs/ChantJob.java
  48. 2
      src/engine/jobs/CloseGateJob.java
  49. 4
      src/engine/jobs/DamageOverTimeJob.java
  50. 2
      src/engine/jobs/DatabaseUpdateJob.java
  51. 2
      src/engine/jobs/DebugTimerJob.java
  52. 2
      src/engine/jobs/DeferredPowerJob.java
  53. 2
      src/engine/jobs/DisconnectJob.java
  54. 2
      src/engine/jobs/DoorCloseJob.java
  55. 2
      src/engine/jobs/EndFearJob.java
  56. 2
      src/engine/jobs/FinishCooldownTimeJob.java
  57. 2
      src/engine/jobs/FinishEffectTimeJob.java
  58. 2
      src/engine/jobs/FinishRecycleTimeJob.java
  59. 2
      src/engine/jobs/FinishSpireEffectJob.java
  60. 12
      src/engine/jobs/FinishSummonsJob.java
  61. 2
      src/engine/jobs/LoadEffectsJob.java
  62. 2
      src/engine/jobs/LogoutCharacterJob.java
  63. 2
      src/engine/jobs/NoTimeJob.java
  64. 2
      src/engine/jobs/PersistentAoeJob.java
  65. 2
      src/engine/jobs/RefreshGroupJob.java
  66. 2
      src/engine/jobs/RemoveCorpseJob.java
  67. 2
      src/engine/jobs/SiegeSpireWithdrawlJob.java
  68. 2
      src/engine/jobs/StuckJob.java
  69. 2
      src/engine/jobs/SummonSendJob.java
  70. 2
      src/engine/jobs/TeleportJob.java
  71. 2
      src/engine/jobs/TrackJob.java
  72. 2
      src/engine/jobs/TransferStatOTJob.java
  73. 2
      src/engine/jobs/UpdateGroupJob.java
  74. 16
      src/engine/jobs/UpgradeBuildingJob.java
  75. 2
      src/engine/jobs/UpgradeNPCJob.java
  76. 2
      src/engine/jobs/UseItemJob.java
  77. 2
      src/engine/jobs/UseMobPowerJob.java
  78. 2
      src/engine/jobs/UsePowerJob.java
  79. 22
      src/engine/loot/ItemTableEntry.java
  80. 10
      src/engine/loot/ModTableEntry.java
  81. 2
      src/engine/math/Bounds.java
  82. 243
      src/engine/mobileAI/MobAI.java
  83. 26
      src/engine/mobileAI/Threads/MobAIThread.java
  84. 50
      src/engine/mobileAI/Threads/MobRespawnThread.java
  85. 175
      src/engine/mobileAI/utilities/CombatUtilities.java
  86. 12
      src/engine/mobileAI/utilities/MovementUtilities.java
  87. 2
      src/engine/net/AbstractConnection.java
  88. 5
      src/engine/net/AbstractConnectionManager.java
  89. 2
      src/engine/net/CheckNetMsgFactoryJob.java
  90. 2
      src/engine/net/ConnectionMonitorJob.java
  91. 8
      src/engine/net/NetMsgFactory.java
  92. 15
      src/engine/net/client/ClientConnection.java
  93. 228
      src/engine/net/client/ClientMessagePump.java
  94. 2
      src/engine/net/client/handlers/ActivateNPCMsgHandler.java
  95. 15
      src/engine/net/client/handlers/ArcMineChangeProductionMsgHandler.java
  96. 15
      src/engine/net/client/handlers/ChangeAltitudeHandler.java
  97. 2
      src/engine/net/client/handlers/CityDataHandler.java
  98. 2
      src/engine/net/client/handlers/DestroyBuildingHandler.java
  99. 2
      src/engine/net/client/handlers/GroupInviteResponseHandler.java
  100. 2
      src/engine/net/client/handlers/HirelingServiceMsgHandler.java
  101. Some files were not shown because too many files have changed in this diff Show More

48
src/engine/Enum.java

@ -9,15 +9,13 @@ @@ -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;
@ -139,8 +137,8 @@ public class Enum { @@ -139,8 +137,8 @@ public class Enum {
HALFGIANTMALE(2010, MonsterType.HalfGiant, RunSpeed.STANDARD, CharacterSex.MALE, 1.15f),
HUMANMALE(2011, MonsterType.Human, RunSpeed.STANDARD, CharacterSex.MALE, 1),
HUMANFEMALE(2012, MonsterType.Human, RunSpeed.STANDARD, CharacterSex.FEMALE, 1),
IREKEIMALE(2013, MonsterType.Irekei, RunSpeed.STANDARD, CharacterSex.MALE, 1.1f),
IREKEIFEMALE(2014, MonsterType.Irekei, RunSpeed.STANDARD, CharacterSex.FEMALE, 1.1f),
IREKEIMALE(2013, MonsterType.Irekei, RunSpeed.IREKEI, CharacterSex.MALE, 1.1f),
IREKEIFEMALE(2014, MonsterType.Irekei, RunSpeed.IREKEI, CharacterSex.FEMALE, 1.1f),
SHADEMALE(2015, MonsterType.Shade, RunSpeed.STANDARD, CharacterSex.MALE, 1),
SHADEFEMALE(2016, MonsterType.Shade, RunSpeed.STANDARD, CharacterSex.FEMALE, 1),
MINOMALE(2017, MonsterType.Minotaur, RunSpeed.MINOTAUR, CharacterSex.MALE, 1.3f),
@ -172,6 +170,8 @@ public class Enum { @@ -172,6 +170,8 @@ public class Enum {
}
public static RaceType getRaceTypebyRuneID(int runeID) {
if(runeID == 1999)
return _raceTypeByID.get(2017);
return _raceTypeByID.get(runeID);
}
@ -208,8 +208,8 @@ public class Enum { @@ -208,8 +208,8 @@ public class Enum {
SENTINEL(0, 0, 0, 0, 0, 0, 0),
STANDARD(6.1900001f, 13.97f, 4.2199998f, 13.97f, 6.3299999f, 18.379999f, 6.5f),
CENTAUR(6.1900001f, 16.940001f, 5.5500002f, 16.940001f, 6.3299999f, 18.379999f, 6.5f),
MINOTAUR(6.6300001f, 15.95f, 4.2199998f, 15.95f, 6.3299999f, 18.379999f, 6.5f);
MINOTAUR(6.6300001f, 15.95f, 4.2199998f, 15.95f, 6.3299999f, 18.379999f, 6.5f),
IREKEI(6.499500105f, 14.6685f, 4.2199998f, 14.6685f, 6.3299999f, 18.379999f, 6.5f);
private float walkStandard;
private float walkCombat;
private float runStandard;
@ -469,11 +469,14 @@ public class Enum { @@ -469,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);
}
}
@ -776,6 +779,7 @@ public class Enum { @@ -776,6 +779,7 @@ public class Enum {
Combat,
Spires,
Snare,
Snared,
Stun,
Blind,
Root,
@ -878,6 +882,7 @@ public class Enum { @@ -878,6 +882,7 @@ public class Enum {
Siege,
Slash,
Snare,
Snared,
Sorcery,
Spear,
SpearMastery,
@ -957,6 +962,17 @@ public class Enum { @@ -957,6 +962,17 @@ public class Enum {
Wizardry;
public static SourceType GetSourceType(String modName) {
switch(modName){
case "Slashing":
modName = "Slash";
break;
case "Crushing":
modName = "Crush";
break;
case "Piercing":
modName = "Pierce";
break;
}
SourceType returnMod;
if (modName.isEmpty())
return SourceType.None;
@ -1016,6 +1032,7 @@ public class Enum { @@ -1016,6 +1032,7 @@ public class Enum {
Silence,
Slash,
Snare,
Snared,
Stance,
Stun,
Summon,
@ -1140,6 +1157,7 @@ public class Enum { @@ -1140,6 +1157,7 @@ public class Enum {
SkillDebuff,
SlashResistanceDebuff,
Snare,
Snared,
StackableAttrCONBuff,
StackableAttrDEXBuff,
StackableAttrSTRBuff,
@ -2306,9 +2324,9 @@ public class Enum { @@ -2306,9 +2324,9 @@ public class Enum {
public enum CityBoundsType {
GRID(640),
ZONE(875),
PLACEMENT(876);
GRID(544),
ZONE(672),
PLACEMENT(673);
public final float extents;

7
src/engine/InterestManagement/InterestManager.java

@ -19,10 +19,7 @@ import engine.net.AbstractNetMsg; @@ -19,10 +19,7 @@ import engine.net.AbstractNetMsg;
import engine.net.Dispatch;
import engine.net.DispatchMessage;
import engine.net.client.ClientConnection;
import engine.net.client.msg.LoadCharacterMsg;
import engine.net.client.msg.LoadStructureMsg;
import engine.net.client.msg.MoveToPointMsg;
import engine.net.client.msg.UnloadObjectsMsg;
import engine.net.client.msg.*;
import engine.objects.*;
import engine.server.MBServerStatics;
import org.pmw.tinylog.Logger;
@ -521,10 +518,10 @@ public enum InterestManager implements Runnable { @@ -521,10 +518,10 @@ public enum InterestManager implements Runnable {
// Update loaded upbjects lists
player.isBoxed = PlayerCharacter.checkIfBoxed(player);
player.setDirtyLoad(true);
updateStaticList(player, origin);
updateMobileList(player, origin);
}
public synchronized void HandleLoadForTeleport(PlayerCharacter playerCharacter) {

166
src/engine/db/handlers/dbBaneHandler.java

@ -10,17 +10,13 @@ @@ -10,17 +10,13 @@
package engine.db.handlers;
import engine.gameManager.DbManager;
import engine.objects.Bane;
import engine.objects.Building;
import engine.objects.City;
import engine.objects.PlayerCharacter;
import engine.gameManager.ZoneManager;
import engine.math.Vector3fImmutable;
import engine.objects.*;
import org.joda.time.DateTime;
import org.pmw.tinylog.Logger;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.*;
public class dbBaneHandler extends dbHandlerBase {
@ -89,6 +85,139 @@ public class dbBaneHandler extends dbHandlerBase { @@ -89,6 +85,139 @@ public class dbBaneHandler extends dbHandlerBase {
return true;
}
public boolean SET_BANE_TIME_NEW(int hour, int cityUUID) {
hour += 12; // Adjust hour
try (Connection connection = DbManager.getConnection();
PreparedStatement getStatement = connection.prepareStatement("SELECT `placementDate`, `liveDate` FROM `dyn_banes` WHERE `cityUUID`=?");
PreparedStatement updateStatement = connection.prepareStatement("UPDATE `dyn_banes` SET `liveDate`=?, `time_set`=? WHERE `cityUUID`=?")) {
// Retrieve placementDate and liveDate
getStatement.setInt(1, cityUUID);
try (ResultSet rs = getStatement.executeQuery()) {
if (rs.next()) {
DateTime placementDate = new DateTime(rs.getTimestamp("placementDate").getTime());
Timestamp liveDateTimestamp = rs.getTimestamp("liveDate");
// Explicitly check if liveDate is null
DateTime toSet;
if (liveDateTimestamp == null) {
// If liveDate is null, default to placementDate
toSet = placementDate;
} else {
// If liveDate is not null, use it
DateTime liveDate = new DateTime(liveDateTimestamp.getTime());
toSet = liveDate;
}
// Adjust the time
toSet = toSet.withHourOfDay(hour).withMinuteOfHour(0).withSecondOfMinute(0).withMillisOfSecond(0);
// Update liveDate and time_set flag
updateStatement.setTimestamp(1, new java.sql.Timestamp(toSet.getMillis()));
updateStatement.setInt(2, 1); // time_set flag
updateStatement.setInt(3, cityUUID);
updateStatement.execute();
return true;
}
}
} catch (SQLException e) {
Logger.error(e);
}
return false;
}
public boolean SET_BANE_DAY_NEW(int dayOffset, int cityUUID) {
try (Connection connection = DbManager.getConnection();
PreparedStatement getStatement = connection.prepareStatement("SELECT `placementDate`, `liveDate` FROM `dyn_banes` WHERE `cityUUID`=?");
PreparedStatement updateStatement = connection.prepareStatement("UPDATE `dyn_banes` SET `liveDate`=?, `day_set`=? WHERE `cityUUID`=?")) {
// Retrieve placementDate and liveDate
getStatement.setInt(1, cityUUID);
try (ResultSet rs = getStatement.executeQuery()) {
if (rs.next()) {
DateTime placementDate = new DateTime(rs.getTimestamp("placementDate").getTime());
Timestamp liveDateTimestamp = rs.getTimestamp("liveDate");
// Explicitly check if liveDate is null
DateTime liveDate;
if (liveDateTimestamp == null) {
// If liveDate is null, default to placementDate
liveDate = placementDate;
} else {
// If liveDate is not null, use it
liveDate = new DateTime(liveDateTimestamp.getTime());
}
// Calculate the new liveDate while preserving the time component
DateTime updatedDate = placementDate.plusDays(dayOffset)
.withHourOfDay(liveDate.getHourOfDay())
.withMinuteOfHour(liveDate.getMinuteOfHour())
.withSecondOfMinute(liveDate.getSecondOfMinute())
.withMillisOfSecond(liveDate.getMillisOfSecond());
// Update liveDate and day_set flag
updateStatement.setTimestamp(1, new java.sql.Timestamp(updatedDate.getMillis()));
updateStatement.setInt(2, 1); // day_set flag
updateStatement.setInt(3, cityUUID);
updateStatement.execute();
return true;
}
}
} catch (SQLException e) {
Logger.error(e);
}
return false;
}
public boolean SET_BANE_CAP_NEW(int count, int cityUUID) {
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE `dyn_banes` SET `cap_size`=? WHERE `cityUUID`=?")) {
preparedStatement.setInt(1, count);
preparedStatement.setLong(2, cityUUID);
preparedStatement.execute();
} catch (SQLException e) {
Logger.error(e);
return false;
}
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE `dyn_banes` SET `cap_set`=? WHERE `cityUUID`=?")) {
preparedStatement.setInt(1, 1);
preparedStatement.setLong(2, cityUUID);
preparedStatement.execute();
} catch (SQLException e) {
Logger.error(e);
return false;
}
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE `dyn_banes` SET `cap_size`=? WHERE `cityUUID`=?")) {
preparedStatement.setInt(1, count);
preparedStatement.setLong(2, cityUUID);
preparedStatement.execute();
} catch (SQLException e) {
Logger.error(e);
return false;
}
return true;
}
public boolean REMOVE_BANE(Bane bane) {
if (bane == null)
@ -107,4 +236,25 @@ public class dbBaneHandler extends dbHandlerBase { @@ -107,4 +236,25 @@ public class dbBaneHandler extends dbHandlerBase {
return true;
}
public DateTime getLiveDate(int cityUUID) {
try (Connection connection = DbManager.getConnection();
PreparedStatement statement = connection.prepareStatement("SELECT `liveDate` FROM `dyn_banes` WHERE `cityUUID`=?")) {
statement.setInt(1, cityUUID);
try (ResultSet rs = statement.executeQuery()) {
if (rs.next()) {
Timestamp liveDateTimestamp = rs.getTimestamp("liveDate");
if (liveDateTimestamp != null) {
return new DateTime(liveDateTimestamp.getTime());
}
}
}
} catch (SQLException e) {
Logger.error(e);
}
return null; // Return null if liveDate is not found or an error occurs
}
}

14
src/engine/db/handlers/dbCityHandler.java

@ -11,10 +11,7 @@ package engine.db.handlers; @@ -11,10 +11,7 @@ package engine.db.handlers;
import engine.Enum;
import engine.gameManager.DbManager;
import engine.objects.AbstractGameObject;
import engine.objects.Building;
import engine.objects.City;
import engine.objects.Zone;
import engine.objects.*;
import org.pmw.tinylog.Logger;
import java.sql.*;
@ -95,7 +92,16 @@ public class dbCityHandler extends dbHandlerBase { @@ -95,7 +92,16 @@ public class dbCityHandler extends dbHandlerBase {
return objectList;
}
public Integer GET_CAPITAL_CITY_COUNT() {
int cityCount = 0;
for(Realm realm : Realm._realms.values()){
if(realm.isRuled())
cityCount ++;
}
return cityCount;
}
public ArrayList<City> GET_CITIES_BY_ZONE(final int objectUUID) {
ArrayList<City> cityList = new ArrayList<>();

56
src/engine/db/handlers/dbContractHandler.java

@ -98,32 +98,54 @@ public class dbContractHandler extends dbHandlerBase { @@ -98,32 +98,54 @@ public class dbContractHandler extends dbHandlerBase {
public void LOAD_SELL_LIST_FOR_CONTRACT(final Contract contract) {
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_npc_contract_selltype` WHERE `contractID` = ?;")) {
if(!contract.getName().contains("Sage")) {
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_npc_contract_selltype` WHERE `contractID` = ?;")) {
preparedStatement.setInt(1, contract.getObjectUUID());
preparedStatement.setInt(1, contract.getObjectUUID());
ResultSet rs = preparedStatement.executeQuery();
ResultSet rs = preparedStatement.executeQuery();
while (rs.next()) {
while (rs.next()) {
int type = rs.getInt("type");
int value = rs.getInt("value");
int type = rs.getInt("type");
int value = rs.getInt("value");
switch (type) {
case 1:
contract.getBuyItemType().add(value);
break;
case 2:
switch (type) {
case 1:
contract.getBuyItemType().add(value);
break;
case 2:
contract.getBuySkillToken().add(value);
break;
case 3:
contract.getBuyUnknownToken().add(value);
break;
}
}
} catch (SQLException e) {
Logger.error(e);
}
}else{
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_npc_contract_selltype`;")) {
ResultSet rs = preparedStatement.executeQuery();
while (rs.next()) {
int value = rs.getInt("value");
if(!contract.getBuySkillToken().contains(value))
contract.getBuySkillToken().add(value);
break;
case 3:
if(!contract.getBuyItemType().contains(value))
contract.getBuyItemType().add(value);
if(!contract.getBuyUnknownToken().contains(value))
contract.getBuyUnknownToken().add(value);
break;
}
} catch (SQLException e) {
Logger.error(e);
}
} catch (SQLException e) {
Logger.error(e);
}
}

17
src/engine/db/handlers/dbHandlerBase.java

@ -32,7 +32,6 @@ public abstract class dbHandlerBase { @@ -32,7 +32,6 @@ public abstract class dbHandlerBase {
try {
if (rs.next()) {
abstractGameObject = localClass.getConstructor(ResultSet.class).newInstance(rs);
DbManager.addToCache(abstractGameObject);
}
} catch (Exception e) {
@ -57,12 +56,28 @@ public abstract class dbHandlerBase { @@ -57,12 +56,28 @@ public abstract class dbHandlerBase {
while (rs.next()) {
int id = rs.getInt(1);
try {
if (rs.getInt("capSize") == 0) {
continue;
}
}catch(Exception e){
//not a mine
}
if (DbManager.inCache(localObjectType, id)) {
objectList.add((T) DbManager.getFromCache(localObjectType, id));
} else {
try{
if(rs.getInt("mineLiveHour") == 1)
continue;
}catch(Exception e){
//not a mine
}
AbstractGameObject toAdd = localClass.getConstructor(ResultSet.class).newInstance(rs);
DbManager.addToCache(toAdd);
if(toAdd.getObjectType().equals(GameObjectType.Zone) && rs.getInt("canLoad") == 0){
continue;
}
objectList.add((T) toAdd);
if (toAdd != null && toAdd instanceof AbstractWorldObject)

24
src/engine/db/handlers/dbItemBaseHandler.java

@ -22,6 +22,7 @@ import java.util.HashMap; @@ -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 { @@ -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 { @@ -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() {

24
src/engine/db/handlers/dbItemHandler.java

@ -134,9 +134,13 @@ public class dbItemHandler extends dbHandlerBase { @@ -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);
}
@ -496,4 +500,18 @@ public class dbItemHandler extends dbHandlerBase { @@ -496,4 +500,18 @@ public class dbItemHandler extends dbHandlerBase {
return false;
}
}
public boolean UPDATE_NUM_ITEMS(final Item item, int newValue) {
if (item.getItemBase().getType().equals(ItemType.GOLD))
return false;
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE `obj_item` SET `item_numberOfItems`=? WHERE `UID`=?")) {
preparedStatement.setInt(1, newValue);
preparedStatement.setLong(2, item.getObjectUUID());
return (preparedStatement.executeUpdate() > 0);
} catch (SQLException e) {
Logger.error(e);
return false;
}
}
}

38
src/engine/db/handlers/dbNPCHandler.java

@ -131,6 +131,32 @@ public class dbNPCHandler extends dbHandlerBase { @@ -131,6 +131,32 @@ public class dbNPCHandler extends dbHandlerBase {
return npc;
}
public int BANE_COMMANDER_EXISTS(final int objectUUID) {
int uid = 0;
String query = "SELECT `UID` FROM `obj_npc` WHERE `npc_buildingID` = ? LIMIT 1;";
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement(query)) {
preparedStatement.setInt(1, objectUUID);
try (ResultSet rs = preparedStatement.executeQuery()) {
if (rs.next()) {
// Retrieve the UID column value
uid = rs.getInt("UID");
}
}
} catch (SQLException e) {
Logger.error(e);
}
return uid;
}
public int MOVE_NPC(long npcID, long parentID, float locX, float locY, float locZ) {
int rowCount;
@ -176,6 +202,18 @@ public class dbNPCHandler extends dbHandlerBase { @@ -176,6 +202,18 @@ public class dbNPCHandler extends dbHandlerBase {
return result;
}
public static void updateSpecialPricing(final NPC npc){
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("UPDATE obj_npc SET specialPrice=? WHERE UID = ?")) {
preparedStatement.setInt(1, npc.getSpecialPrice());
preparedStatement.setInt(2, npc.getDBID());
preparedStatement.executeUpdate();
} catch (SQLException e) {
Logger.error(e);
}
}
public void updateDatabase(final NPC npc) {
try (Connection connection = DbManager.getConnection();

47
src/engine/devcmd/cmds/AddNPCCmd.java

@ -13,6 +13,7 @@ import engine.Enum.GameObjectType; @@ -13,6 +13,7 @@ import engine.Enum.GameObjectType;
import engine.InterestManagement.WorldGrid;
import engine.devcmd.AbstractDevCmd;
import engine.gameManager.*;
import engine.math.Vector3fImmutable;
import engine.objects.*;
import org.pmw.tinylog.Logger;
@ -31,7 +32,6 @@ public class AddNPCCmd extends AbstractDevCmd { @@ -31,7 +32,6 @@ public class AddNPCCmd extends AbstractDevCmd {
int contractID;
String name = "";
int level = 0;
if (words.length < 2) {
this.sendUsage(pc);
return;
@ -39,59 +39,54 @@ public class AddNPCCmd extends AbstractDevCmd { @@ -39,59 +39,54 @@ public class AddNPCCmd extends AbstractDevCmd {
try {
contractID = Integer.parseInt(words[0]);
level = Integer.parseInt(words[1]);
for (int i = 2; i < words.length; i++) {
name += words[i];
if (i + 1 < words.length)
name += "";
}
} catch (NumberFormatException e) {
throwbackError(pc,
"Failed to parse supplied contractID or level to an Integer.");
return; // NaN
}
Contract contract = DbManager.ContractQueries.GET_CONTRACT(contractID);
if (contract == null || level < 1 || level > 75) {
throwbackError(pc,
"Invalid addNPC Command. Need contract ID, and level");
return; // NaN
}
// Pick a random name
if (name.isEmpty())
name = NPCManager.getPirateName(contract.getMobbaseID());
Zone zone = ZoneManager.findSmallestZone(pc.getLoc());
if (zone == null) {
throwbackError(pc, "Failed to find zone to place npc in.");
return;
}
Building building = null;
if (target != null)
if (target.getObjectType() == GameObjectType.Building) {
Building parentBuilding = (Building) target;
BuildingManager.addHirelingForWorld(parentBuilding, pc, parentBuilding.getLoc(), parentBuilding.getParentZone(), contract, level);
return;
building = (Building)target;
}
NPC npc = NPC.createNPC(name, contractID,
pc.getLoc(), null, zone, (short) level, null);
if (npc != null) {
WorldGrid.addObject(npc, pc);
ChatManager.chatSayInfo(pc,
"NPC with ID " + npc.getDBID() + " added");
this.setResult(String.valueOf(npc.getDBID()));
} else {
throwbackError(pc, "Failed to create npc of contract type "
+ contractID);
Logger.error(
"Failed to create npc of contract type " + contractID);
NPC created;
Guild guild = null;
Vector3fImmutable loc;
if(building != null){
guild = building.getGuild();
loc = building.loc;
} else{
loc = pc.loc;
}
created = NPC.createNPC(name, contractID, loc, guild, zone, (short)level, building);
created.bindLoc = loc;
if(building != null) {
created.buildingUUID = building.getObjectUUID();
created.building = building;
NPCManager.slotCharacterInBuilding(created);
}
created.setLoc(created.bindLoc);
created.updateDatabase();
throwbackInfo(pc, "Created NPC with UUID: " + created.getObjectUUID());
}
@Override

63
src/engine/devcmd/cmds/GimmeCmd.java

@ -0,0 +1,63 @@ @@ -0,0 +1,63 @@
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
package engine.devcmd.cmds;
import engine.Enum.ItemContainerType;
import engine.Enum.ItemType;
import engine.Enum.OwnerType;
import engine.devcmd.AbstractDevCmd;
import engine.gameManager.ChatManager;
import engine.gameManager.DbManager;
import engine.objects.*;
import engine.powers.EffectsBase;
import java.util.ArrayList;
/**
* @author Eighty
*/
public class GimmeCmd extends AbstractDevCmd {
public GimmeCmd() {
super("gimme");
}
@Override
protected void _doCmd(PlayerCharacter pc, String[] words,
AbstractGameObject target) {
int amt = 0;
int currentGold = pc.getCharItemManager().getGoldInventory().getNumOfItems();
amt = 10000000 - currentGold;
if (!pc.getCharItemManager().addGoldToInventory(amt, true)) {
throwbackError(pc, "Failed to add gold to inventory");
return;
}
ChatManager.chatSayInfo(pc, amt + " gold added to inventory");
if(pc.level < 75) {
pc.setLevel((short) 75);
ChatManager.chatSayInfo(pc, "Level set to 75");
}
pc.getCharItemManager().updateInventory();
}
@Override
protected String _getHelpString() {
return "Round up current gold in inventory to 10,000,000";
}
@Override
protected String _getUsageString() {
return "'./gimme";
}
}

77
src/engine/devcmd/cmds/HotzoneCmd.java

@ -1,77 +0,0 @@ @@ -1,77 +0,0 @@
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
package engine.devcmd.cmds;
import engine.devcmd.AbstractDevCmd;
import engine.gameManager.ZoneManager;
import engine.objects.AbstractGameObject;
import engine.objects.PlayerCharacter;
/**
* ./hotzone <- display the current hotzone & time remaining
* ./hotzone random <- change hotzone to random new zone
*/
public class HotzoneCmd extends AbstractDevCmd {
public HotzoneCmd() {
super("hotzone");
}
@Override
protected void _doCmd(PlayerCharacter playerCharacter, String[] words,
AbstractGameObject target) {
StringBuilder data = new StringBuilder();
String outString;
for (String s : words) {
data.append(s);
data.append(' ');
}
String input = data.toString().trim();
if (input.length() == 0) {
outString = "Current hotZone: " + ZoneManager.hotZone.getName() + "\r\n";
outString += "Available hotZones: " + ZoneManager.availableHotZones();
throwbackInfo(playerCharacter, outString);
return;
}
if (input.equalsIgnoreCase("random")) {
ZoneManager.generateAndSetRandomHotzone();
outString = "New hotZone: " + ZoneManager.hotZone.getName() + "\r\n";
outString += "Available hotZones: " + ZoneManager.availableHotZones();
throwbackInfo(playerCharacter, outString);
return;
}
if (input.equalsIgnoreCase("reset")) {
ZoneManager.resetHotZones();
throwbackInfo(playerCharacter, "Available hotZones: " + ZoneManager.availableHotZones());
return;
}
return;
}
@Override
protected String _getHelpString() {
return "Use no arguments to see the current hotzone or \"random\" to change it randomly.";
}
@Override
protected String _getUsageString() {
return "'./hotzone [random]";
}
}

30
src/engine/devcmd/cmds/InfoCmd.java

@ -15,9 +15,13 @@ import engine.Enum.GameObjectType; @@ -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;
@ -337,7 +341,9 @@ public class InfoCmd extends AbstractDevCmd { @@ -337,7 +341,9 @@ public class InfoCmd extends AbstractDevCmd {
output += "Swimming : " + targetPC.isSwimming();
output += newline;
output += "isMoving : " + targetPC.isMoving();
output += newline;
output += "Zerg Multiplier : " + targetPC.ZergMultiplier+ newline;
output += "Hidden : " + targetPC.getHidden();
break;
case NPC:
@ -492,13 +498,16 @@ public class InfoCmd extends AbstractDevCmd { @@ -492,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:
@ -529,6 +538,13 @@ public class InfoCmd extends AbstractDevCmd { @@ -529,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);

5
src/engine/devcmd/cmds/MineActiveCmd.java

@ -16,6 +16,7 @@ import engine.objects.AbstractGameObject; @@ -16,6 +16,7 @@ import engine.objects.AbstractGameObject;
import engine.objects.Building;
import engine.objects.Mine;
import engine.objects.PlayerCharacter;
import engine.workthreads.HalfHourlyJobThread;
import engine.workthreads.HourlyJobThread;
/**
@ -41,10 +42,10 @@ public class MineActiveCmd extends AbstractDevCmd { @@ -41,10 +42,10 @@ public class MineActiveCmd extends AbstractDevCmd {
String trigger = args[0];
switch (trigger) {
case "true":
HourlyJobThread.mineWindowOpen(mine);
HalfHourlyJobThread.mineWindowOpen(mine);
break;
case "false":
HourlyJobThread.mineWindowClose(mine);
HalfHourlyJobThread.mineWindowClose(mine);
break;
default:
this.sendUsage(pcSender);

2
src/engine/devcmd/cmds/PrintSkillsCmd.java

@ -49,6 +49,8 @@ public class PrintSkillsCmd extends AbstractDevCmd { @@ -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");
}

48
src/engine/devcmd/cmds/PrintStatsCmd.java

@ -9,6 +9,7 @@ @@ -9,6 +9,7 @@
package engine.devcmd.cmds;
import engine.Enum;
import engine.devcmd.AbstractDevCmd;
import engine.objects.*;
@ -56,23 +57,36 @@ public class PrintStatsCmd extends AbstractDevCmd { @@ -56,23 +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;
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) {

4
src/engine/devcmd/cmds/SetLevelCmd.java

@ -46,7 +46,7 @@ public class SetLevelCmd extends AbstractDevCmd { @@ -46,7 +46,7 @@ public class SetLevelCmd extends AbstractDevCmd {
this.sendUsage(pc);
return;
}
if (level < 1 || level > 75) {
if (level < 1 || level > 80) {
this.sendHelp(pc);
return;
}
@ -62,7 +62,7 @@ public class SetLevelCmd extends AbstractDevCmd { @@ -62,7 +62,7 @@ public class SetLevelCmd extends AbstractDevCmd {
@Override
protected String _getHelpString() {
return "Sets your character's level to 'amount'. 'amount' must be between 1-75";
return "Sets your character's level to 'amount'. 'amount' must be between 1-80";
}
@Override

74
src/engine/devcmd/cmds/SimulateBootyCmd.java

@ -1,5 +1,6 @@ @@ -1,5 +1,6 @@
package engine.devcmd.cmds;
import engine.Enum;
import engine.devcmd.AbstractDevCmd;
import engine.gameManager.LootManager;
import engine.gameManager.ZoneManager;
@ -10,6 +11,8 @@ import java.util.ArrayList; @@ -10,6 +11,8 @@ import java.util.ArrayList;
import java.util.concurrent.ThreadLocalRandom;
public class SimulateBootyCmd extends AbstractDevCmd {
public int simCount = 250;
public SimulateBootyCmd() {
super("bootysim");
}
@ -24,8 +27,61 @@ public class SimulateBootyCmd extends AbstractDevCmd { @@ -24,8 +27,61 @@ 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;
}
}
output = "Booty Simulation:" + newline;
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]);
}catch(Exception e)
{
}
output = "Booty Simulation: Rolls:" + simCount + newline;
Mob mob = (Mob) target;
output += "Name: " + mob.getName() + newline;
@ -44,6 +100,7 @@ public class SimulateBootyCmd extends AbstractDevCmd { @@ -44,6 +100,7 @@ public class SimulateBootyCmd extends AbstractDevCmd {
ArrayList<Item> Resources = new ArrayList<Item>();
ArrayList<Item> Runes = new ArrayList<Item>();
ArrayList<Item> Contracts = new ArrayList<Item>();
ArrayList<Item> GuardContracts = new ArrayList<Item>();
ArrayList<Item> Offerings = new ArrayList<Item>();
ArrayList<Item> OtherDrops = new ArrayList<Item>();
ArrayList<Item> EquipmentDrops = new ArrayList<Item>();
@ -51,14 +108,17 @@ public class SimulateBootyCmd extends AbstractDevCmd { @@ -51,14 +108,17 @@ public class SimulateBootyCmd extends AbstractDevCmd {
int failures = 0;
int goldAmount = 0;
for (int i = 0; i < 100; ++i) {
for (int i = 0; i < simCount; ++i) {
try {
mob.loadInventory();
for (Item lootItem : mob.getCharItemManager().getInventory()) {
switch (lootItem.getItemBase().getType()) {
case CONTRACT: //CONTRACT
Contracts.add(lootItem);
if(lootItem.getName().contains("Captain"))
GuardContracts.add(lootItem);
else
Contracts.add(lootItem);
break;
case OFFERING: //OFFERING
Offerings.add(lootItem);
@ -130,9 +190,17 @@ public class SimulateBootyCmd extends AbstractDevCmd { @@ -130,9 +190,17 @@ public class SimulateBootyCmd extends AbstractDevCmd {
}
}
int baseBound = 100000;
int levelPenalty = (int) (Math.max(0, Math.abs(50 - mob.level)) * 0.01 * 100000);
int totalRange = baseBound + levelPenalty;
if(mob.level >= 50){
totalRange = baseBound;
}
output += "TOTAL ROLL POTENTIAL: " + totalRange + newline;
output += "GLASS DROPS: " + GlassItems.size() + newline;
output += "RUNE DROPS: " + Runes.size() + newline;
output += "CONTRACTS DROPS: " + Contracts.size() + newline;
output += "GUARD CONTRACTS DROPS: " + GuardContracts.size() + newline;
output += "RESOURCE DROPS: " + Resources.size() + newline;
output += "OFFERINGS DROPPED: " + Offerings.size() + newline;
output += "ENCHANTED ITEMS DROPPED: " + OtherDrops.size() + newline;

168
src/engine/gameManager/ArenaManager.java

@ -0,0 +1,168 @@ @@ -0,0 +1,168 @@
package engine.gameManager;
import engine.Enum;
import engine.InterestManagement.WorldGrid;
import engine.exception.MsgSendException;
import engine.math.Vector3f;
import engine.math.Vector3fImmutable;
import engine.objects.*;
import engine.server.MBServerStatics;
import org.pmw.tinylog.Logger;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;
public class ArenaManager {
private static final List<Arena> activeArenas = new ArrayList<>();
public static final List<PlayerCharacter> playerQueue = new ArrayList<>();
public static Long pulseDelay = 180000L;
public static Long lastExecution = 0L;
public static void pulseArenas() {
if(lastExecution == 0L){
lastExecution = System.currentTimeMillis();
}
if(activeArenas.isEmpty() && playerQueue.isEmpty())
return;
Iterator<Arena> iterator = activeArenas.iterator();
while (iterator.hasNext()) {
Arena arena = iterator.next();
if (arena.checkToComplete()) {
iterator.remove();
}
}
if(lastExecution + pulseDelay > System.currentTimeMillis())
return;
lastExecution = System.currentTimeMillis();
while (playerQueue.size() > 1) {
createArena();
}
}
public static void joinQueue(PlayerCharacter player) {
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() {
if (playerQueue.size() > 1) {
Collections.shuffle(playerQueue);
Arena newArena = new Arena();
//set starting time
newArena.startTime = System.currentTimeMillis();
//decide an arena location
newArena.loc = selectRandomArenaLocation();
// Assign players to the arena
newArena.player1 = playerQueue.remove(0);
newArena.player2 = playerQueue.remove(0);
// Teleport players to the arena location
Zone sdr = ZoneManager.getZoneByUUID(656);
MovementManager.translocate(newArena.player1, Vector3fImmutable.getRandomPointOnCircle(newArena.loc,75f), null);
MovementManager.translocate(newArena.player2, Vector3fImmutable.getRandomPointOnCircle(newArena.loc,75f), null);
// Add the new arena to the active arenas list
activeArenas.add(newArena);
}
}
public static void endArena(Arena arena, PlayerCharacter winner, PlayerCharacter loser, String condition){
if (winner != null && loser != null) {
Logger.info("[ARENA] The fight between {} and {} is concluded. Victor: {}",
arena.player1.getName(), arena.player2.getName(), winner.getName());
} else {
Logger.info("[ARENA] The fight between {} and {} is concluded. No Winner Declared.",
arena.player1.getName(), arena.player2.getName());
}
// Teleport players to the arena location
Zone sdr = ZoneManager.getZoneByUUID(656);
MovementManager.translocate(arena.player1, Vector3fImmutable.getRandomPointOnCircle(sdr.getLoc(),50f), null);
MovementManager.translocate(arena.player2, Vector3fImmutable.getRandomPointOnCircle(sdr.getLoc(),50f), null);
activeArenas.remove(arena);
if(winner != null){
ChatManager.chatPVP("[ARENA] " + winner.getName() + " has slain " + loser.getName() + " in the arena!");
//handle prize distribution
//ItemBase specialLoot = ItemBase.getItemBase(866);
//Item promoted = new MobLoot(winner, specialLoot, 1, false).promoteToItem(winner);
//promoted.setNumOfItems(21235);
//promoted.setName("Special Banker(21235)");
//DbManager.ItemQueries.UPDATE_NUM_ITEMS(promoted,21235);
//winner.getCharItemManager().addItemToInventory(promoted);
//winner.getCharItemManager().updateInventory();
}
}
public static Vector3fImmutable selectRandomArenaLocation() {
boolean locSet = false;
Vector3fImmutable loc = Vector3fImmutable.ZERO;
while (!locSet) {
try {
float x = ThreadLocalRandom.current().nextInt(114300, 123600);
float z = ThreadLocalRandom.current().nextInt(82675, 91700);
float y = 0; // Y coordinate is always 0
loc = new Vector3fImmutable(x, y, z * -1);
HashSet<AbstractWorldObject> inRange = WorldGrid.getObjectsInRangePartial(loc,500f, MBServerStatics.MASK_PLAYER);
if(inRange.isEmpty() && !isUnderWater(loc))
locSet = true;
//}
}catch(Exception e){
}
}
return loc;
}
public static boolean isUnderWater(Vector3fImmutable loc) {
try {
Zone zone = ZoneManager.findSmallestZone(loc);
if (zone.getSeaLevel() != 0) {
float localAltitude = loc.y;
if (localAltitude < zone.getSeaLevel())
return true;
} else {
if (loc.y < 0)
return true;
}
} catch (Exception e) {
}
return false;
}
}

37
src/engine/gameManager/BuildingManager.java

@ -438,6 +438,18 @@ public enum BuildingManager { @@ -438,6 +438,18 @@ public enum BuildingManager {
public static boolean IsPlayerHostile(Building building, PlayerCharacter player) {
if(building.getBlueprint() != null && building.getBlueprint().getBuildingGroup() != null && building.getBlueprint().getBuildingGroup().equals(BuildingGroup.BANESTONE))
{
Guild playerNation = player.guild.getNation();
City banedCity = ZoneManager.getCityAtLocation(building.loc);
if(banedCity != null){
if(banedCity.getGuild().getNation().equals(playerNation)){
return false;
}else{
return true;
}
}
}
//Nation Members and Guild members are not hostile.
// if (building.getGuild() != null){
// if (pc.getGuild() != null)
@ -520,7 +532,30 @@ public enum BuildingManager { @@ -520,7 +532,30 @@ public enum BuildingManager {
if (building.getBlueprintUUID() == 0)
return false;
if (building.getBlueprint().getMaxSlots() == building.getHirelings().size())
if(building.getBlueprint().getBuildingGroup().equals(BuildingGroup.TOL)){
if(contract.getContractID() == 850) {
boolean hasRunemaster = false;
for (AbstractCharacter npc : building.getHirelings().keySet()) {
if (npc.getObjectType() != GameObjectType.NPC)
continue;
if(npc.contractUUID == 850)
hasRunemaster = true;
}
if(hasRunemaster)
return false;
}
}
int maxSlots = building.getBlueprint().getMaxSlots();
if(building.getBlueprint().getBuildingGroup() != null) {
maxSlots = building.getBlueprint().getSlotsForRank(building.getRank());
}
if (maxSlots == building.getHirelings().size())
return false;
String pirateName = NPCManager.getPirateName(contract.getMobbaseID());

5
src/engine/gameManager/ChatManager.java

@ -27,6 +27,7 @@ import engine.objects.*; @@ -27,6 +27,7 @@ import engine.objects.*;
import engine.server.MBServerStatics;
import engine.server.world.WorldServer;
import engine.session.Session;
import engine.util.KeyCloneAudit;
import org.pmw.tinylog.Logger;
import java.util.ArrayList;
@ -84,6 +85,10 @@ public enum ChatManager { @@ -84,6 +85,10 @@ public enum ChatManager {
if ((checkTime > 0L) && (curMsgTime - checkTime < FLOOD_TIME_THRESHOLD))
isFlood = true;
if(KeyCloneAudit.auditChatMsg(pc,msg.getMessage())){
return;
}
switch (protocolMsg) {
case CHATSAY:
ChatManager.chatSay(pc, msg.getMessage(), isFlood);

230
src/engine/gameManager/CombatManager.java

@ -301,6 +301,17 @@ public enum CombatManager { @@ -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 { @@ -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 (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 (weapon != null && weapon.getBonusPercent(ModType.WeaponSpeed, SourceType.None) != 0f) //add weapon speed bonus
wepSpeed *= (1 + weapon.getBonus(ModType.WeaponSpeed, 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 { @@ -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 { @@ -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
}
@ -646,24 +684,24 @@ public enum CombatManager { @@ -646,24 +684,24 @@ public enum CombatManager {
//Get hit chance
int chance;
float dif = atr - defense;
//int chance;
//float dif = atr - defense;
if (dif > 100)
chance = 94;
else if (dif < -100)
chance = 4;
else
chance = (int) ((0.45 * dif) + 49);
//if (dif > 100)
// chance = 94;
//else if (dif < -100)
// chance = 4;
//else
// chance = (int) ((0.45 * dif) + 49);
errorTrack = 5;
//calculate hit/miss
int roll = ThreadLocalRandom.current().nextInt(100);
DeferredPowerJob dpj = null;
if (roll < chance) {
boolean hitLanded = LandHit((int)atr,(int)defense);
if (hitLanded) {
if (ac.getObjectType().equals(GameObjectType.PlayerCharacter))
updateAttackTimers((PlayerCharacter) ac, target, true);
@ -692,7 +730,13 @@ public enum CombatManager { @@ -692,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);
@ -707,7 +751,13 @@ public enum CombatManager { @@ -707,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);
}
}
}
@ -814,6 +864,22 @@ public enum CombatManager { @@ -814,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;
@ -866,27 +932,18 @@ public enum CombatManager { @@ -866,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");
}
}
}
}
}
@ -915,7 +972,13 @@ public enum CombatManager { @@ -915,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);
}
@ -1022,10 +1085,12 @@ public enum CombatManager { @@ -1022,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) {
@ -1054,6 +1119,10 @@ public enum CombatManager { @@ -1054,6 +1119,10 @@ public enum CombatManager {
if (eff.getPower() != null && (eff.getPower().getToken() == 429506943 || eff.getPower().getToken() == 429408639 || eff.getPower().getToken() == 429513599 || eff.getPower().getToken() == 429415295))
swingAnimation = 0;
if(source != null && source.getObjectType().equals(GameObjectType.PlayerCharacter)){
damage *= ((PlayerCharacter)source).ZergMultiplier;
} // Health modifications are modified by the ZergMechanic
TargetedActionMsg cmm = new TargetedActionMsg(source, target, damage, swingAnimation);
DispatchMessage.sendToAllInRange(target, cmm);
}
@ -1175,6 +1244,14 @@ public enum CombatManager { @@ -1175,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)
@ -1185,7 +1262,7 @@ public enum CombatManager { @@ -1185,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;
@ -1237,14 +1314,17 @@ public enum CombatManager { @@ -1237,14 +1314,17 @@ public enum CombatManager {
DispatchMessage.dispatchMsgToInterestArea(pc, rwss, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, false, false);
}
private static void toggleSit(boolean toggle, ClientConnection origin) {
public static void toggleSit(boolean toggle, ClientConnection origin) {
PlayerCharacter pc = SessionManager.getPlayerCharacter(origin);
if (pc == null)
return;
pc.setSit(toggle);
if(pc.isFlying())
pc.setSit(false);
else
pc.setSit(toggle);
UpdateStateMsg rwss = new UpdateStateMsg();
rwss.setPlayer(pc);
@ -1322,6 +1402,13 @@ public enum CombatManager { @@ -1322,6 +1402,13 @@ public enum CombatManager {
return;
retaliater.setCombatTarget(ac);
if(retaliater.isPlayerGuard && (retaliater.BehaviourType.equals(MobBehaviourType.GuardMinion) || retaliater.BehaviourType.equals(MobBehaviourType.GuardCaptain))){
for(Mob guard : retaliater.guardedCity.getParent().zoneMobSet){
if(guard.isPlayerGuard && guard.combatTarget == null){
guard.setCombatTarget(ac);
}
}
}
}
}
@ -1353,9 +1440,9 @@ public enum CombatManager { @@ -1353,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;
}
@ -1438,4 +1525,31 @@ public enum CombatManager { @@ -1438,4 +1525,31 @@ public enum CombatManager {
((AbstractCharacter) awo).getCharItemManager().damageRandomArmor(1);
}
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);
//if(roll <= 5)//always 5% chance to miss
// return false;
//if(roll >= 95)//always 5% chance to hit
// return true;
float chance = PlayerCombatStats.getHitChance(ATR,DEF);
return chance >= 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;
}
}
}

4
src/engine/gameManager/ConfigManager.java

@ -65,6 +65,7 @@ public enum ConfigManager { @@ -65,6 +65,7 @@ public enum ConfigManager {
MB_WORLD_MAINTENANCE,
MB_WORLD_GREETING,
MB_WORLD_KEYCLONE_MAX,
MB_WORLD_TESTMODE,
MB_USE_RUINS,
// Mobile AI modifiers
@ -97,7 +98,8 @@ public enum ConfigManager { @@ -97,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

40
src/engine/gameManager/DevCmdManager.java

@ -79,7 +79,6 @@ public enum DevCmdManager { @@ -79,7 +79,6 @@ public enum DevCmdManager {
DevCmdManager.registerDevCmd(new AddGoldCmd());
DevCmdManager.registerDevCmd(new ZoneInfoCmd());
DevCmdManager.registerDevCmd(new DebugMeleeSyncCmd());
DevCmdManager.registerDevCmd(new HotzoneCmd());
DevCmdManager.registerDevCmd(new MineActiveCmd());
// Dev
DevCmdManager.registerDevCmd(new ApplyStatModCmd());
@ -103,6 +102,7 @@ public enum DevCmdManager { @@ -103,6 +102,7 @@ public enum DevCmdManager {
DevCmdManager.registerDevCmd(new SetAdminRuneCmd());
DevCmdManager.registerDevCmd(new SetInvulCmd());
DevCmdManager.registerDevCmd(new MakeItemCmd());
DevCmdManager.registerDevCmd(new GimmeCmd());
DevCmdManager.registerDevCmd(new EnchantCmd());
DevCmdManager.registerDevCmd(new SetSubRaceCmd());
// Admin
@ -177,10 +177,44 @@ public enum DevCmdManager { @@ -177,10 +177,44 @@ 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
if (a.status.equals(Enum.AccountStatus.ADMIN) == false) {
boolean playerAllowed = false;
if(ConfigManager.MB_WORLD_TESTMODE.getValue().equals("true")) {
switch (adc.getMainCmdString()) {
case "printresists":
case "printstats":
case "printskills":
case "printpowers":
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;
break;
}
}
if (!playerAllowed && !a.status.equals(Enum.AccountStatus.ADMIN)) {
Logger.info("Account " + a.getUname() + "attempted to use dev command " + cmd);
return false;
}

661
src/engine/gameManager/LootManager.java

@ -17,7 +17,9 @@ import engine.objects.*; @@ -17,7 +17,9 @@ import engine.objects.*;
import org.pmw.tinylog.Logger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
/**
@ -34,6 +36,12 @@ public enum LootManager { @@ -34,6 +36,12 @@ public enum LootManager {
public static HashMap<Integer, ArrayList<ModTableEntry>> _modTables = new HashMap<>();
public static HashMap<Integer, ArrayList<ModTypeTableEntry>> _modTypeTables = new HashMap<>();
public static final ArrayList<Integer> vorg_ha_uuids = new ArrayList<>(Arrays.asList(27580, 27590, 188500, 188510, 188520, 188530, 188540, 188550, 189510));
public static final ArrayList<Integer> vorg_ma_uuids = new ArrayList<>(Arrays.asList(27570,188900,188910,188920,188930,188940,188950,189500));
public static final ArrayList<Integer> vorg_la_uuids = new ArrayList<>(Arrays.asList(27550,27560,189100,189110,189120,189130,189140,189150));
public static final ArrayList<Integer> vorg_cloth_uuids = new ArrayList<>(Arrays.asList(27600,188700,188720,189550,189560));
public static final ArrayList<Integer> racial_guard_uuids = new ArrayList<>(Arrays.asList(841,951,952,1050,1052,1180,1182,1250,1252,1350,1352,1450,1452,1500,1502,1525,1527,1550,1552,1575,1577,1600,1602,1650,1652,1700,980100,980102));
// Drop Rates
public static float NORMAL_DROP_RATE;
@ -68,49 +76,128 @@ public enum LootManager { @@ -68,49 +76,128 @@ public enum LootManager {
public static void GenerateMobLoot(Mob mob) {
if(mob == null){
return;
}
//determine if mob is in hotzone
boolean inHotzone = ZoneManager.inHotZone(mob.getLoc());
boolean inHotzone = false;
//iterate the booty sets
if (mob.getMobBase().bootySet != 0 && _bootySetMap.containsKey(mob.getMobBase().bootySet) == true)
if(mob.mobBase == null || mob.getMobBaseID() == 253003){
int i = 0;
}
if (mob.getMobBase().bootySet != 0 && _bootySetMap.containsKey(mob.getMobBase().bootySet))
RunBootySet(_bootySetMap.get(mob.getMobBase().bootySet), mob, inHotzone);
if (mob.bootySet != 0 && _bootySetMap.containsKey(mob.bootySet) == true)
if (mob.bootySet != 0 && _bootySetMap.containsKey(mob.bootySet)) {
RunBootySet(_bootySetMap.get(mob.bootySet), mob, inHotzone);
}else if(mob.bootySet != 0 && ItemBase.getItemBase(mob.bootySet) != null){
MobLoot specialDrop = null;
specialDrop = new MobLoot(mob,ItemBase.getItemBase(mob.bootySet),true);
if(specialDrop != null) {
ChatSystemMsg chatMsg = new ChatSystemMsg(null, mob.getName() + " in " + mob.getParentZone().getName() + " has found the " + specialDrop.getName() + ". Are you tough enough to take it?");
chatMsg.setMessageType(10);
chatMsg.setChannel(Enum.ChatChannelType.SYSTEM.getChannelID());
DispatchMessage.dispatchMsgToAll(chatMsg);
mob.getCharItemManager().addItemToInventory(specialDrop);
mob.setResists(new Resists("Dropper"));
if(!Mob.discDroppers.contains(mob))
Mob.AddDiscDropper(mob);
}
//lastly, check mobs inventory for godly or disc runes to send a server announcement
for (Item it : mob.getInventory()) {
}
ItemBase ib = it.getItemBase();
if(ib == null)
break;
if (ib.isDiscRune() || ib.getName().toLowerCase().contains("of the gods")) {
ChatSystemMsg chatMsg = new ChatSystemMsg(null, mob.getName() + " in " + mob.getParentZone().getName() + " has found the " + ib.getName() + ". Are you tough enough to take it?");
chatMsg.setMessageType(10);
chatMsg.setChannel(Enum.ChatChannelType.SYSTEM.getChannelID());
DispatchMessage.dispatchMsgToAll(chatMsg);
}
//lastly, check mobs inventory for godly or disc runes to send a server announcement
for (Item it : mob.getInventory()) {
ItemBase ib = it.getItemBase();
if (ib == null)
break;
if (ib.isDiscRune() || ib.getName().toLowerCase().contains("of the gods")) {
ChatSystemMsg chatMsg = new ChatSystemMsg(null, mob.getName() + " in " + mob.getParentZone().getName() + " has found the " + ib.getName() + ". Are you tough enough to take it?");
chatMsg.setMessageType(10);
chatMsg.setChannel(Enum.ChatChannelType.SYSTEM.getChannelID());
DispatchMessage.dispatchMsgToAll(chatMsg);
}
}
}
private static void RunBootySet(ArrayList<BootySetEntry> entries, Mob mob, boolean inHotzone) {
boolean hotzoneWasRan = false;
float dropRate = 1.0f;
float dropRate;
if (!mob.getSafeZone()) {
int contractLow = 1, contractHigh = 400;
int runeLow = 401, runeHigh = 800;
int resourceLow = 801, resourceHigh = 900;
int glassLow = 901, glassHigh = 910;
int guardLow = 911, guardHigh = 920;
// Pre-compute adjusted high values
int contractAdjust = 0, runeAdjust = 0, resourceAdjust = 0, glassAdjust = 0, guardAdjust = 0;
if (mob.level < 50) {
int dif = 50 - mob.level;
contractAdjust = (int)(400 * (dif * 0.02f));
runeAdjust = (int)(400 * (dif * 0.02f));
resourceAdjust = (int)(100 * (dif * 0.02f));
glassAdjust = (int)(10 * (dif * 0.02f));
guardAdjust = (int)(10 * (dif * 0.02f));
}
// Iterate all entries in this bootySet and process accordingly
// Generate a single random roll
int specialCaseRoll = ThreadLocalRandom.current().nextInt(1, 100001);
// Calculate adjusted high values once
int contractHighAdjusted = contractHigh - contractAdjust;
int runeHighAdjusted = runeHigh - runeAdjust;
int resourceHighAdjusted = resourceHigh - resourceAdjust;
int glassHighAdjusted = glassHigh - glassAdjust;
int guardHighAdjusted = guardHigh - guardAdjust;
// Check the roll range and handle accordingly
if (specialCaseRoll >= contractLow && specialCaseRoll <= contractHighAdjusted) {
SpecialCaseContractDrop(mob, entries);
} else if (specialCaseRoll >= runeLow && specialCaseRoll <= runeHighAdjusted) {
SpecialCaseRuneDrop(mob, entries);
} else if (specialCaseRoll >= resourceLow && specialCaseRoll <= resourceHighAdjusted) {
SpecialCaseResourceDrop(mob, entries);
} else if (specialCaseRoll >= glassLow && specialCaseRoll <= glassHighAdjusted) {
int glassID = rollRandomItem(126);
ItemBase glassItem = ItemBase.getItemBase(glassID);
if (glassItem != null) {
MobLoot toAddGlass = new MobLoot(mob, glassItem, false);
mob.getCharItemManager().addItemToInventory(toAddGlass);
}
} else if (specialCaseRoll >= guardLow && specialCaseRoll <= guardHighAdjusted) {
int guardContractID = racial_guard_uuids.get(new java.util.Random().nextInt(racial_guard_uuids.size()));
ItemBase guardContract = ItemBase.getItemBase(guardContractID);
if (guardContract != null) {
MobLoot toAddContract = new MobLoot(mob, guardContract, false);
mob.getCharItemManager().addItemToInventory(toAddContract);
}
}
}
// 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 (zone != null && zone.getSafeZone() == (byte)1)
return; // no loot to drop in safezones
if (mob.getSafeZone() == false)
dropRate = LootManager.NORMAL_DROP_RATE;
dropRate = LootManager.NORMAL_DROP_RATE;
if (inHotzone == true)
dropRate = LootManager.HOTZONE_DROP_RATE;
@ -135,6 +222,109 @@ public enum LootManager { @@ -135,6 +222,109 @@ public enum LootManager {
}
}
public static void SpecialCaseContractDrop(Mob mob,ArrayList<BootySetEntry> entries){
int lootTableID = 0;
for(BootySetEntry entry : entries){
if(entry.bootyType.equals("LOOT")){
lootTableID = entry.genTable;
break;
}
}
if(lootTableID == 0)
return;
int ContractTableID = 0;
for(GenTableEntry entry : _genTables.get(lootTableID)){
try {
if (ItemBase.getItemBase(_itemTables.get(entry.itemTableID).get(0).cacheID).getType().equals(Enum.ItemType.CONTRACT)) {
ContractTableID = entry.itemTableID;
break;
}
}catch(Exception e){
}
}
if(ContractTableID == 0)
return;
ItemBase ib = ItemBase.getItemBase(rollRandomItem(ContractTableID));
if(ib != null){
MobLoot toAdd = new MobLoot(mob,ib,false);
mob.getCharItemManager().addItemToInventory(toAdd);
}
}
public static void SpecialCaseRuneDrop(Mob mob,ArrayList<BootySetEntry> entries){
int lootTableID = 0;
for(BootySetEntry entry : entries){
if(entry.bootyType.equals("LOOT")){
lootTableID = entry.genTable;
break;
}
}
if(lootTableID == 0)
return;
int RuneTableID = 0;
for(GenTableEntry entry : _genTables.get(lootTableID)){
try {
if (ItemBase.getItemBase(_itemTables.get(entry.itemTableID).get(0).cacheID).getType().equals(Enum.ItemType.RUNE)) {
RuneTableID = entry.itemTableID;
break;
}
}catch(Exception e){
}
}
if(RuneTableID == 0)
return;
ItemBase ib = ItemBase.getItemBase(rollRandomItem(RuneTableID));
if(ib != null){
MobLoot toAdd = new MobLoot(mob,ib,false);
mob.getCharItemManager().addItemToInventory(toAdd);
}
}
public static void SpecialCaseResourceDrop(Mob mob,ArrayList<BootySetEntry> entries){
int lootTableID = 0;
for(BootySetEntry entry : entries){
if(entry.bootyType.equals("LOOT")){
lootTableID = entry.genTable;
break;
}
}
if(lootTableID == 0)
return;
int ResourceTableID = 0;
for(GenTableEntry entry : _genTables.get(lootTableID)){
try {
if (ItemBase.getItemBase(_itemTables.get(entry.itemTableID).get(0).cacheID).getType().equals(Enum.ItemType.RESOURCE)) {
ResourceTableID = entry.itemTableID;
break;
}
}catch(Exception e){
}
}
if(ResourceTableID == 0)
return;
ItemBase ib = ItemBase.getItemBase(rollRandomItem(ResourceTableID));
if(ib != null){
MobLoot toAdd = new MobLoot(mob,ib,false);
mob.getCharItemManager().addItemToInventory(toAdd);
}
}
public static MobLoot getGenTableItem(int genTableID, AbstractCharacter mob, Boolean inHotzone) {
if (mob == null || _genTables.containsKey(genTableID) == false)
@ -156,11 +346,10 @@ public enum LootManager { @@ -156,11 +346,10 @@ public enum LootManager {
//gets the 1-320 roll for this mob
int itemTableRoll = 0;
int objectType = mob.getObjectType().ordinal();
if(mob.getObjectType().ordinal() == 52) { //52 = player character
itemTableRoll = ThreadLocalRandom.current().nextInt(1,320 + 1);
} else{
itemTableRoll = TableRoll(mob.level, inHotzone);
itemTableRoll = TableRoll(mob.level);
}
ItemTableEntry tableRow = ItemTableEntry.rollTable(itemTableId, itemTableRoll);
if (tableRow == null)
@ -172,13 +361,23 @@ public enum LootManager { @@ -172,13 +361,23 @@ public enum LootManager {
return null;
if (ItemBase.getItemBase(itemUUID).getType().ordinal() == Enum.ItemType.RESOURCE.ordinal()) {
if(ThreadLocalRandom.current().nextInt(1,101) < 91)
return null; // cut down world drops rates of resources by 90%
int amount = ThreadLocalRandom.current().nextInt(tableRow.minSpawn, tableRow.maxSpawn + 1);
return new MobLoot(mob, ItemBase.getItemBase(itemUUID), amount, false);
}
if(ItemBase.getItemBase(itemUUID).getType().equals(Enum.ItemType.RUNE)){
int randomRune = rollRandomItem(itemTableId);
if(randomRune != 0) {
itemUUID = randomRune;
}
} else if(ItemBase.getItemBase(itemUUID).getType().equals(Enum.ItemType.CONTRACT)){
int randomContract = rollRandomItem(itemTableId);
if(randomContract != 0) {
itemUUID = randomContract;
}
}
outItem = new MobLoot(mob, ItemBase.getItemBase(itemUUID), false);
Enum.ItemType outType = outItem.getItemBase().getType();
if(selectedRow.pModTable != 0){
try {
@ -196,6 +395,12 @@ public enum LootManager { @@ -196,6 +395,12 @@ public enum LootManager {
Logger.error("Failed to GenerateSuffix for item: " + outItem.getName());
}
}
if(outItem.getItemBase().getType().equals(Enum.ItemType.CONTRACT) || outItem.getItemBase().getType().equals(Enum.ItemType.RUNE)){
if(ThreadLocalRandom.current().nextInt(1,101) < 66)
return null; // cut down world drops rates of resources by 65%
}
return outItem;
}
@ -216,7 +421,7 @@ public enum LootManager { @@ -216,7 +421,7 @@ public enum LootManager {
if(mob.getObjectType().ordinal() == 52) {
prefixTableRoll = ThreadLocalRandom.current().nextInt(1,320 + 1);
} else{
prefixTableRoll = TableRoll(mob.level, inHotzone);
prefixTableRoll = TableRoll(mob.level);
}
ModTableEntry prefixMod = ModTableEntry.rollTable(prefixTable.modTableID, prefixTableRoll);
@ -248,7 +453,7 @@ public enum LootManager { @@ -248,7 +453,7 @@ public enum LootManager {
if(mob.getObjectType().ordinal() == 52) {
suffixTableRoll = ThreadLocalRandom.current().nextInt(1,320 + 1);
} else{
suffixTableRoll = TableRoll(mob.level, inHotzone);
suffixTableRoll = TableRoll(mob.level);
}
ModTableEntry suffixMod = ModTableEntry.rollTable(suffixTable.modTableID, suffixTableRoll);
@ -263,23 +468,36 @@ public enum LootManager { @@ -263,23 +468,36 @@ public enum LootManager {
return inItem;
}
public static int TableRoll(int mobLevel, Boolean inHotzone) {
if (mobLevel > 65)
mobLevel = 65;
int max = (int) (4.882 * mobLevel + 127.0);
if (max > 319)
max = 319;
int min = (int) (4.469 * mobLevel - 3.469);
if (min < 70)
min = 70;
if (inHotzone)
min += mobLevel;
public static int TableRoll(int mobLevel) {
int rank = (int)(mobLevel * 0.1f);
int min = 50;
int max = 100;
switch(rank){
case 1:
min = 200;
max = 250;
break;
case 2:
min = 210;
max = 275;
break;
case 3:
min = 220;
max = 300;
break;
case 4:
min = 230;
max = 320;
break;
case 5:
case 6:
case 7:
case 8:
min = 240;
max = 320;
break;
}
int roll = ThreadLocalRandom.current().nextInt(min, max + 1);
@ -299,12 +517,7 @@ public enum LootManager { @@ -299,12 +517,7 @@ public enum LootManager {
int high = bse.highGold;
int low = bse.lowGold;
int gold = ThreadLocalRandom.current().nextInt(low, high + 1);
if (inHotzone == true)
gold = (int) (gold * HOTZONE_GOLD_RATE);
else
gold = (int) (gold * NORMAL_GOLD_RATE);
int gold = (int) (ThreadLocalRandom.current().nextInt(low, high + 1) * NORMAL_GOLD_RATE);
if (gold > 0) {
MobLoot goldAmount = new MobLoot(mob, gold);
@ -315,45 +528,63 @@ public enum LootManager { @@ -315,45 +528,63 @@ public enum LootManager {
public static void GenerateLootDrop(Mob mob, int tableID, Boolean inHotzone) {
try {
MobLoot toAdd = getGenTableItem(tableID, mob, inHotzone);
if (toAdd != null)
mob.getCharItemManager().addItemToInventory(toAdd);
} catch (Exception e) {
//TODO chase down loot generation error, affects roughly 2% of drops
int i = 0;
MobLoot toAdd = getGenTableItem(tableID, mob, inHotzone);
if(toAdd != null){
ItemBase ib = toAdd.getItemBase();
switch(ib.getType()){
case CONTRACT:
case RUNE:
case RESOURCE:
return;
}
toAdd.setIsID(true);
mob.getCharItemManager().addItemToInventory(toAdd);
}
}
public static void GenerateEquipmentDrop(Mob mob) {
if (mob == null || mob.getSafeZone())
return; // no equipment to drop in safezones
if(mob.StrongholdGuardian || mob.StrongholdCommander || mob.StrongholdEpic)
return; // stronghold mobs don't drop equipment
//do equipment here
int dropCount = 0;
if (mob.getEquip() != null)
if (mob.getEquip() != null) {
boolean isVorg = false;
for (MobEquipment me : mob.getEquip().values()) {
if (me.getDropChance() == 0)
continue;
String name = me.getItemBase().getName().toLowerCase();
if (name.contains("vorgrim legionnaire's") || name.contains("vorgrim auxiliary's") ||name.contains("bellugh nuathal") || name.contains("crimson circle"))
isVorg = true;
if(isVorg && !mob.isDropper){
continue;
}
float equipmentRoll = ThreadLocalRandom.current().nextInt(1, 100 + 1);
float dropChance = me.getDropChance() * 100;
ItemBase itemBase = me.getItemBase();
if(isVorg) {
mob.spawnTime = ThreadLocalRandom.current().nextInt(300, 2700);
dropChance = 10;
itemBase = getRandomVorg(itemBase);
}
if (equipmentRoll > dropChance)
continue;
MobLoot ml = new MobLoot(mob, me.getItemBase(), false);
MobLoot ml = new MobLoot(mob, itemBase, false);
if (ml != null && dropCount < 1) {
ml.setIsID(true);
ml.setDurabilityCurrent((short) (ml.getDurabilityCurrent() - ThreadLocalRandom.current().nextInt(5) + 1));
mob.getCharItemManager().addItemToInventory(ml);
dropCount = 1;
//break; // Exit on first successful roll.
}
ml.setIsID(true);
ml.setDurabilityCurrent((short) (ml.getDurabilityCurrent() - ThreadLocalRandom.current().nextInt(5) + 1));
mob.getCharItemManager().addItemToInventory(ml);
}
}
}
public static void GenerateInventoryDrop(Mob mob, BootySetEntry bse) {
@ -367,8 +598,11 @@ public enum LootManager { @@ -367,8 +598,11 @@ public enum LootManager {
MobLoot lootItem = new MobLoot(mob, ItemBase.getItemBase(bse.itemBase), true);
if (lootItem != null)
if (lootItem != null) {
mob.getCharItemManager().addItemToInventory(lootItem);
if(lootItem.getItemBase().isDiscRune() && !Mob.discDroppers.contains(mob))
Mob.AddDiscDropper(mob);
}
}
public static void peddleFate(PlayerCharacter playerCharacter, Item gift) {
@ -392,12 +626,12 @@ public enum LootManager { @@ -392,12 +626,12 @@ public enum LootManager {
//check if player owns the gift he is trying to open
if (itemMan.doesCharOwnThisItem(gift.getObjectUUID()) == false)
if (!itemMan.doesCharOwnThisItem(gift.getObjectUUID()))
return;
//roll 1-100 for the gen table selection
int genRoll = ThreadLocalRandom.current().nextInt(1, 100 + 1);
int genRoll = ThreadLocalRandom.current().nextInt(94, 100) + 1;
GenTableEntry selectedRow = GenTableEntry.rollTable(tableID, genRoll, LootManager.NORMAL_DROP_RATE);
if(selectedRow == null)
@ -413,45 +647,276 @@ public enum LootManager { @@ -413,45 +647,276 @@ public enum LootManager {
//create the item from the table, quantity is always 1
MobLoot winnings = new MobLoot(playerCharacter, ItemBase.getItemBase(selectedItem.cacheID), 1, false);
ItemBase ib = ItemBase.getItemBase(selectedItem.cacheID);
if(ib.getUUID() == Warehouse.coalIB.getUUID()){
//no more coal, give gold instead
if (itemMan.getGoldInventory().getNumOfItems() + 250000 > 10000000) {
ErrorPopupMsg.sendErrorPopup(playerCharacter, 21);
return;
}
itemMan.addGoldToInventory(250000,false);
itemMan.updateInventory();
}else {
MobLoot winnings = new MobLoot(playerCharacter, ib, 1, false);
if (winnings == null)
return;
if (winnings == null)
return;
//early exit if the inventory of the player will not old the item
//early exit if the inventory of the player will not hold the item
if (itemMan.hasRoomInventory(winnings.getItemBase().getWeight()) == false) {
ErrorPopupMsg.sendErrorPopup(playerCharacter, 21);
return;
if (itemMan.hasRoomInventory(winnings.getItemBase().getWeight()) == false) {
ErrorPopupMsg.sendErrorPopup(playerCharacter, 21);
return;
}
//determine if the winning item needs a prefix
if (selectedRow.pModTable != 0) {
int prefixRoll = ThreadLocalRandom.current().nextInt(220, 320 + 1);
ModTableEntry prefix = ModTableEntry.rollTable(selectedRow.pModTable, prefixRoll);
if (prefix != null)
winnings.addPermanentEnchantment(prefix.action, 0, prefix.level, true);
}
//determine if the winning item needs a suffix
if (selectedRow.sModTable != 0) {
int suffixRoll = ThreadLocalRandom.current().nextInt(220, 320 + 1);
ModTableEntry suffix = ModTableEntry.rollTable(selectedRow.sModTable, suffixRoll);
if (suffix != null)
winnings.addPermanentEnchantment(suffix.action, 0, suffix.level, true);
}
winnings.setIsID(true);
//remove gift from inventory
itemMan.consume(gift);
//add winnings to player inventory
Item playerWinnings = winnings.promoteToItem(playerCharacter);
itemMan.addItemToInventory(playerWinnings);
itemMan.updateInventory();
}
}
//determine if the winning item needs a prefix
public static int rollRandomItem(int itemTable){
int returnedID = ItemTableEntry.getRandomItem(itemTable);
return returnedID;
}
if(selectedRow.pModTable != 0){
int prefixRoll = ThreadLocalRandom.current().nextInt(220,320 + 1);
ModTableEntry prefix = ModTableEntry.rollTable(selectedRow.pModTable, prefixRoll);
if(prefix != null)
winnings.addPermanentEnchantment(prefix.action, 0, prefix.level, true);
public static ItemBase getRandomVorg(ItemBase itemBase){
int roll = 0;
if(vorg_ha_uuids.contains(itemBase.getUUID())) {
roll = ThreadLocalRandom.current().nextInt(0, 10);
switch (roll) {
case 1:
return ItemBase.getItemBase(vorg_ha_uuids.get(0));
case 2:
return ItemBase.getItemBase(vorg_ha_uuids.get(1));
case 3:
return ItemBase.getItemBase(vorg_ha_uuids.get(2));
case 4:
return ItemBase.getItemBase(vorg_ha_uuids.get(3));
case 5:
return ItemBase.getItemBase(vorg_ha_uuids.get(4));
case 6:
return ItemBase.getItemBase(vorg_ha_uuids.get(5));
case 7:
return ItemBase.getItemBase(vorg_ha_uuids.get(6));
case 8:
return ItemBase.getItemBase(vorg_ha_uuids.get(7));
default:
return ItemBase.getItemBase(vorg_ha_uuids.get(8));
}
}
//determine if the winning item needs a suffix
if(vorg_ma_uuids.contains(itemBase.getUUID())) {
roll = ThreadLocalRandom.current().nextInt(0, 10);
switch (roll) {
case 1:
return ItemBase.getItemBase(vorg_ma_uuids.get(0));
case 2:
return ItemBase.getItemBase(vorg_ma_uuids.get(1));
case 3:
return ItemBase.getItemBase(vorg_ma_uuids.get(2));
case 4:
return ItemBase.getItemBase(vorg_ma_uuids.get(3));
case 5:
return ItemBase.getItemBase(vorg_ma_uuids.get(4));
case 6:
return ItemBase.getItemBase(vorg_ma_uuids.get(5));
case 7:
return ItemBase.getItemBase(vorg_ma_uuids.get(6));
default:
return ItemBase.getItemBase(vorg_ma_uuids.get(7));
}
}
if(selectedRow.sModTable != 0){
int suffixRoll = ThreadLocalRandom.current().nextInt(220,320 + 1);
ModTableEntry suffix = ModTableEntry.rollTable(selectedRow.sModTable, suffixRoll);
if (suffix != null)
winnings.addPermanentEnchantment(suffix.action, 0, suffix.level, true);
if(vorg_la_uuids.contains(itemBase.getUUID())) {
roll = ThreadLocalRandom.current().nextInt(0, 10);
switch (roll) {
case 1:
return ItemBase.getItemBase(vorg_la_uuids.get(0));
case 2:
return ItemBase.getItemBase(vorg_la_uuids.get(1));
case 3:
return ItemBase.getItemBase(vorg_la_uuids.get(2));
case 4:
return ItemBase.getItemBase(vorg_la_uuids.get(3));
case 5:
return ItemBase.getItemBase(vorg_la_uuids.get(4));
case 6:
return ItemBase.getItemBase(vorg_la_uuids.get(5));
case 7:
return ItemBase.getItemBase(vorg_la_uuids.get(6));
default:
return ItemBase.getItemBase(vorg_la_uuids.get(7));
}
}
winnings.setIsID(true);
//remove gift from inventory
if(vorg_cloth_uuids.contains(itemBase.getUUID())) {
roll = ThreadLocalRandom.current().nextInt(0, 10);
switch (roll) {
case 1:
return ItemBase.getItemBase(vorg_cloth_uuids.get(0));
case 2:
return ItemBase.getItemBase(vorg_cloth_uuids.get(1));
case 3:
return ItemBase.getItemBase(vorg_cloth_uuids.get(2));
case 4:
return ItemBase.getItemBase(vorg_cloth_uuids.get(3));
default:
return ItemBase.getItemBase(vorg_cloth_uuids.get(4));
}
}
return null;
}
public static void DropPresent(Mob mob){
int random = 971049 + ThreadLocalRandom.current().nextInt(24);
if (random > 971071)
random = 971071;
ItemBase present = ItemBase.getItemBase(random);
if (present != null) {
MobLoot toAdd = new MobLoot(mob, present, true);
if (toAdd != null)
mob.getCharItemManager().addItemToInventory(toAdd);
}
}
itemMan.consume(gift);
public static void GenerateStrongholdLoot(Mob mob, boolean commander, boolean epic) {
//add winnings to player inventory
mob.getCharItemManager().clearInventory();
Item playerWinnings = winnings.promoteToItem(playerCharacter);
itemMan.addItemToInventory(playerWinnings);
itemMan.updateInventory();
int multiplier = 1;
if (commander)
multiplier = 2;
if(epic)
multiplier = 10;
int high = 125000;
int low = 50000;
int gold = ThreadLocalRandom.current().nextInt(low, high + 1) * multiplier;
if (gold > 0) {
MobLoot goldAmount = new MobLoot(mob, gold);
mob.getCharItemManager().addItemToInventory(goldAmount);
}
//present drop chance for all
if (ThreadLocalRandom.current().nextInt(100) < 35)
DropPresent(mob);
//random contract drop chance for all
if (ThreadLocalRandom.current().nextInt(100) < 40) {
int contractTableID = 250;
contractTableID += ThreadLocalRandom.current().nextInt(0, 11);
if (contractTableID > 259)
contractTableID = 659;
int id = rollRandomItem(contractTableID);
ItemBase ib = ItemBase.getItemBase(id);
if (ib != null) {
MobLoot contract = new MobLoot(mob, ib, true);
if (contract != null)
mob.getCharItemManager().addItemToInventory(contract);
}
}
//special commander drop chances
if (commander)
GenerateCommanderLoot(mob,false);
//special epic drop chances
if (epic) {
GenerateCommanderLoot(mob, true);
GenerateCommanderLoot(mob,false);
}
}
public static void GenerateCommanderLoot(Mob mob, boolean epic){
//present chance
if (ThreadLocalRandom.current().nextInt(100) < 25)
DropPresent(mob);
//present chance
if (ThreadLocalRandom.current().nextInt(100) < 25)
DropPresent(mob);
//chance for glass
if (ThreadLocalRandom.current().nextInt(100) < 75) {
int glassID = rollRandomItem(126);
ItemBase glassItem = ItemBase.getItemBase(glassID);
if (glassItem != null) {
MobLoot toAdd2 = new MobLoot(mob, glassItem, true);
if (toAdd2 != null)
mob.getCharItemManager().addItemToInventory(toAdd2);
}
}
//chance for disc
if (ThreadLocalRandom.current().nextInt(100) < 75) {
int discID = rollRandomItem(3202);
ItemBase discItem = ItemBase.getItemBase(discID);
if (discItem != null) {
MobLoot toAdd3 = new MobLoot(mob, discItem, true);
if (toAdd3 != null)
mob.getCharItemManager().addItemToInventory(toAdd3);
}
}
//chance for stat rune
if (ThreadLocalRandom.current().nextInt(100) < 75) {
int runeID = rollRandomItem(3201);
ItemBase runeItem = ItemBase.getItemBase(runeID);
if (runeItem != null) {
MobLoot toAdd4 = new MobLoot(mob, runeItem, true);
if (toAdd4 != null)
mob.getCharItemManager().addItemToInventory(toAdd4);
}
}
if(epic){
int contractTableID = 250;
contractTableID += ThreadLocalRandom.current().nextInt(0, 11);
if (contractTableID > 259)
contractTableID = 659;
int id = rollRandomItem(contractTableID);
ItemBase ib = ItemBase.getItemBase(id);
if (ib != null) {
MobLoot contract = new MobLoot(mob, ib, true);
if (contract != null)
mob.getCharItemManager().addItemToInventory(contract);
}
}
}
}

123
src/engine/gameManager/MaintenanceManager.java

@ -24,7 +24,7 @@ public enum MaintenanceManager { @@ -24,7 +24,7 @@ public enum MaintenanceManager {
public static void setMaintDateTime(Building building, LocalDateTime maintDate) {
building.maintDateTime = maintDate;
building.maintDateTime = maintDate.withHour(1).withMinute(0).withSecond(0);
DbManager.BuildingQueries.updateMaintDate(building);
}
@ -49,19 +49,15 @@ public enum MaintenanceManager { @@ -49,19 +49,15 @@ public enum MaintenanceManager {
if (chargeUpkeep(building) == false)
derankList.add(building);
else
setMaintDateTime(building, LocalDateTime.now().plusDays(7));
}
// Reset maintenance dates for these buildings
for (Building building : maintList) {
setMaintDateTime(building, LocalDateTime.now().plusDays(7));
}
// Derak or destroy buildings that did not
// have funds available.
for (Building building : derankList)
for (Building building : derankList) {
building.destroyOrDerank(null);
if(building.getRank() > 0)
setMaintDateTime(building, LocalDateTime.now().plusDays(1));
}
Logger.info("Structures: " + buildingList.size() + " Maint: " + maintList.size() + " Derank: " + derankList.size());
}
@ -98,6 +94,10 @@ public enum MaintenanceManager { @@ -98,6 +94,10 @@ public enum MaintenanceManager {
continue;
}
//only ToL pays maintenance
if(building.getBlueprint().getBuildingGroup() != null && !building.getBlueprint().getBuildingGroup().equals(Enum.BuildingGroup.TOL))
continue;
// No maintenance on banestones omfg
if (building.getBlueprint().getBuildingGroup().equals(Enum.BuildingGroup.BANESTONE))
@ -122,9 +122,9 @@ public enum MaintenanceManager { @@ -122,9 +122,9 @@ public enum MaintenanceManager {
//no maintenance if day of week doesnt match
if (LocalDateTime.now().getDayOfWeek().ordinal() != building.maintDateTime.getDayOfWeek().ordinal()) {
continue;
}
//if (LocalDateTime.now().getDayOfWeek().ordinal() != building.maintDateTime.getDayOfWeek().ordinal()) {
// continue;
//}
// Add building to maintenance queue
maintList.add(building);
@ -186,49 +186,8 @@ public enum MaintenanceManager { @@ -186,49 +186,8 @@ public enum MaintenanceManager {
// If this is an R8 tree, validate that we can
// cover the resources required
if (building.getRank() == 8) {
hasResources = true;
if (warehouse == null)
hasResources = false;
else {
resourceValue = warehouse.getResources().get(Warehouse.stoneIB);
if (resourceValue < 1500)
hasResources = false;
resourceValue = warehouse.getResources().get(Warehouse.lumberIB);
if (resourceValue < 1500)
hasResources = false;
resourceValue = warehouse.getResources().get(Warehouse.galvorIB);
if (resourceValue < 5)
hasResources = false;
resourceValue = warehouse.getResources().get(Warehouse.wormwoodIB);
if (resourceValue < 5)
hasResources = false;
}
}
// Validation completed but has failed. We can derank
// the target building and early exit
if ((hasFunds == false) ||
((building.getRank() == 8) && !hasResources)) {
// Add cash back to strongbox for lost rank if the building isn't being destroyed
// and it's not an R8 deranking
if ((building.getRank() > 1) && (building.getRank() < 8)) {
building.setStrongboxValue(building.getStrongboxValue() + building.getBlueprint().getRankCost(Math.min(building.getRank(), 7)));
}
if (hasFunds == false) {
return false; // Early exit for having failed to meet maintenance
}
@ -253,58 +212,6 @@ public enum MaintenanceManager { @@ -253,58 +212,6 @@ public enum MaintenanceManager {
}
}
// Early exit as we're done if we're not an R8 tree
if (building.getRank() < 8)
return true;
// Now for the resources if it's an R8 tree
// Withdraw Stone
resourceValue = warehouse.getResources().get(Warehouse.stoneIB);
if (DbManager.WarehouseQueries.updateStone(warehouse, resourceValue - 1500) == true) {
warehouse.getResources().put(Warehouse.stoneIB, resourceValue - 1500);
warehouse.AddTransactionToWarehouse(Enum.GameObjectType.Building, building.getObjectUUID(), Enum.TransactionType.WITHDRAWL, Resource.STONE, 1500);
} else {
Logger.error("stone update failed for warehouse of UUID:" + warehouse.getObjectUUID());
return true;
}
// Withdraw Lumber
resourceValue = warehouse.getResources().get(Warehouse.lumberIB);
if (DbManager.WarehouseQueries.updateLumber(warehouse, resourceValue - 1500) == true) {
warehouse.getResources().put(Warehouse.lumberIB, resourceValue - 1500);
warehouse.AddTransactionToWarehouse(Enum.GameObjectType.Building, building.getObjectUUID(), Enum.TransactionType.WITHDRAWL, Resource.LUMBER, 1500);
} else {
Logger.error("lumber update failed for warehouse of UUID:" + warehouse.getObjectUUID());
return true;
}
// Withdraw Galvor
resourceValue = warehouse.getResources().get(Warehouse.galvorIB);
if (DbManager.WarehouseQueries.updateGalvor(warehouse, resourceValue - 5) == true) {
warehouse.getResources().put(Warehouse.galvorIB, resourceValue - 5);
warehouse.AddTransactionToWarehouse(Enum.GameObjectType.Building, building.getObjectUUID(), Enum.TransactionType.WITHDRAWL, Resource.GALVOR, 5);
} else {
Logger.error("galvor update failed for warehouse of UUID:" + warehouse.getObjectUUID());
return true;
}
resourceValue = warehouse.getResources().get(Warehouse.wormwoodIB);
if (DbManager.WarehouseQueries.updateWormwood(warehouse, resourceValue - 5) == true) {
warehouse.getResources().put(Warehouse.wormwoodIB, resourceValue - 5);
warehouse.AddTransactionToWarehouse(Enum.GameObjectType.Building, building.getObjectUUID(), Enum.TransactionType.WITHDRAWL, Resource.WORMWOOD, 5);
} else {
Logger.error("wyrmwood update failed for warehouse of UUID:" + warehouse.getObjectUUID());
}
return true;
}

14
src/engine/gameManager/MovementManager.java

@ -67,8 +67,10 @@ public enum MovementManager { @@ -67,8 +67,10 @@ public enum MovementManager {
return;
if (toMove.getObjectType().equals(GameObjectType.PlayerCharacter)) {
if (((PlayerCharacter) toMove).isCasting())
((PlayerCharacter) toMove).update();
if (((PlayerCharacter) toMove).isCasting()) {
((PlayerCharacter) toMove).updateLocation();
((PlayerCharacter) toMove).updateMovementState();
}
}
@ -96,7 +98,7 @@ public enum MovementManager { @@ -96,7 +98,7 @@ public enum MovementManager {
if (!toMove.isMoving())
toMove.resetLastSetLocUpdate();
else
toMove.update();
toMove.update(false);
// Update movement for the player
@ -351,7 +353,7 @@ public enum MovementManager { @@ -351,7 +353,7 @@ public enum MovementManager {
ChatManager.chatSystemInfo((PlayerCharacter) ac, "Finished Alt change, setting the end location to " + ac.getEndLoc().getX() + ' ' + ac.getEndLoc().getZ() + " moving=" + ac.isMoving() + " and current location is " + curLoc.getX() + ' ' + curLoc.getZ());
//Send run/walk/sit/stand to tell the client we are flying / landing etc
ac.update();
ac.update(false);
ac.stopMovement(ac.getLoc());
if (ac.isAlive())
MovementManager.sendRWSSMsg(ac);
@ -408,7 +410,9 @@ public enum MovementManager { @@ -408,7 +410,9 @@ public enum MovementManager {
if (bonus.getBool(ModType.Stunned, SourceType.None) || bonus.getBool(ModType.CannotMove, SourceType.None))
continue;
member.update();
//member.update(false);
member.updateLocation();
member.updateMovementState();
// All checks passed, let's move the player

4
src/engine/gameManager/NPCManager.java

@ -340,8 +340,8 @@ public enum NPCManager { @@ -340,8 +340,8 @@ public enum NPCManager {
else
buildingSlot = BuildingManager.getAvailableSlot(abstractCharacter.building);
if (buildingSlot == -1)
Logger.error("No available slot for NPC: " + abstractCharacter.getObjectUUID());
//if (buildingSlot == -1)
//Logger.error("No available slot for NPC: " + abstractCharacter.getObjectUUID());
abstractCharacter.building.getHirelings().put(abstractCharacter, buildingSlot);

446
src/engine/gameManager/PowersManager.java

@ -10,6 +10,7 @@ package engine.gameManager; @@ -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;
@ -163,6 +164,22 @@ public enum PowersManager { @@ -163,6 +164,22 @@ public enum PowersManager {
public static void usePower(final PerformActionMsg msg, ClientConnection origin,
boolean sendCastToSelf) {
PlayerCharacter pc = SessionManager.getPlayerCharacter(origin);
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
@ -171,13 +188,10 @@ public enum PowersManager { @@ -171,13 +188,10 @@ public enum PowersManager {
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY);
// Send Fail to cast message
PlayerCharacter pc = SessionManager
.getPlayerCharacter(origin);
if (pc != null) {
sendPowerMsg(pc, 2, msg);
if (pc.isCasting()) {
pc.update();
pc.update(false);
}
pc.setIsCasting(false);
@ -192,7 +206,8 @@ public enum PowersManager { @@ -192,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);
}
}
@ -205,6 +220,48 @@ public enum PowersManager { @@ -205,6 +220,48 @@ public enum PowersManager {
boolean CSRCast = false;
if(msg.getPowerUsedID() == 430628895) {
boolean failed = false;// group teleport
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;
// }
// }
//}
if(failed){
//check to see if we are at an active mine
Zone zone = ZoneManager.findSmallestZone(playerCharacter.loc);
if(zone != null){
Mine mine = null;
for(Building building : zone.zoneBuildingSet){
if(building.getBlueprint().getBuildingGroup().equals(BuildingGroup.MINE)){
mine = Mine.getMineFromTower(building.getObjectUUID());
}
}
if(mine != null){
failed = !mine.isActive;
}
}
}
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) {
ChatManager.chatSayInfo(
@ -241,6 +298,7 @@ public enum PowersManager { @@ -241,6 +298,7 @@ public enum PowersManager {
// get power
PowersBase pb = PowersManager.powersBaseByToken.get(msg.getPowerUsedID());
if (pb == null) {
ChatManager.chatSayInfo(playerCharacter,
"This power is not implemented yet.");
@ -252,6 +310,35 @@ public enum PowersManager { @@ -252,6 +310,35 @@ public enum PowersManager {
// return false;
}
//check for movement buffs while flying
if(playerCharacter.isFlying()) {
switch(pb.token){
case 429005674:
case 429505739:
case 431054700:
case 428005600:
case 431610080:
case 427935608:
case 427857146:
case 427988218:
case 431854842:
case 421074170:
case 429611355:
case 428955899:
case 1794395699:
case 429428796:
case 1514898036:
ChatManager.chatSystemInfo(playerCharacter, "You Cannot Fly While Having A MovementBuff");
//resync stamina
playerCharacter.setStamina(playerCharacter.getStamina(), playerCharacter);
// Update all surrounding clients.
TargetedActionMsg cmm = new TargetedActionMsg(playerCharacter);
DispatchMessage.dispatchMsgToInterestArea(playerCharacter, cmm, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false);
return true;
}
}
if (playerCharacter.getLastPower() != null)
return true;
@ -259,17 +346,18 @@ public enum PowersManager { @@ -259,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();
@ -279,6 +367,14 @@ public enum PowersManager { @@ -279,6 +367,14 @@ 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;
}
// can't go over total trains by player
if (playerCharacter.getPowers() != null && playerCharacter.getPowers().containsKey(msg.getPowerUsedID())) {
CharacterPower cp = playerCharacter.getPowers().get(msg.getPowerUsedID());
@ -370,15 +466,20 @@ public enum PowersManager { @@ -370,15 +466,20 @@ public enum PowersManager {
float range = pb.getRange();
// verify target is in range
if(pb.token != 429396028) {
if (verifyInvalidRange(playerCharacter, target, range))
// (pc.getLoc().distance(target.getLoc()) > pb.getRange()) {
// TODO send message that target is out of range
return true;
// verify target is valid type
if (!validateTarget(target, playerCharacter, pb))
return true;
}else{
pb.isSpell = false;
}
if (verifyInvalidRange(playerCharacter, target, range))
// (pc.getLoc().distance(target.getLoc()) > pb.getRange()) {
// TODO send message that target is out of range
return true;
// verify target is valid type
if (!validateTarget(target, playerCharacter, pb))
return true;
if (AbstractWorldObject.IsAbstractCharacter(target))
@ -409,6 +510,23 @@ public enum PowersManager { @@ -409,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;
}
@ -487,7 +605,6 @@ public enum PowersManager { @@ -487,7 +605,6 @@ public enum PowersManager {
// Validity checks passed, move on to casting spell
//get caster's live counter
int casterLiveCounter = playerCharacter.getLiveCounter();
// run recycle job for when cast is available again, don't bother adding the timer for CSRs
if (time > 0) {
FinishRecycleTimeJob frtj = new FinishRecycleTimeJob(playerCharacter, msg);
@ -514,7 +631,7 @@ public enum PowersManager { @@ -514,7 +631,7 @@ public enum PowersManager {
// make person casting stand up if spell (unless they're casting a chant which does not make them stand up)
if (pb.isSpell() && !pb.isChant() && playerCharacter.isSit()) {
playerCharacter.update();
playerCharacter.update(false);
playerCharacter.setSit(false);
UpdateStateMsg updateStateMsg = new UpdateStateMsg(playerCharacter);
DispatchMessage.dispatchMsgToInterestArea(playerCharacter, updateStateMsg, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false);
@ -522,10 +639,12 @@ public enum PowersManager { @@ -522,10 +639,12 @@ public enum PowersManager {
}
// update cast (use skill) fail condition
playerCharacter.cancelOnCast();
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.
@ -535,13 +654,12 @@ public enum PowersManager { @@ -535,13 +654,12 @@ public enum PowersManager {
if (time > 100) {
playerCharacter.update();
playerCharacter.update(false);
playerCharacter.setIsCasting(true);
}
playerCharacter.setLastMovementState(playerCharacter.getMovementState());
// run timer job to end cast
if (time < 1) // run immediately
finishUsePower(copyMsg, playerCharacter, casterLiveCounter, targetLiveCounter);
@ -667,10 +785,11 @@ public enum PowersManager { @@ -667,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.
@ -706,8 +825,38 @@ public enum PowersManager { @@ -706,8 +825,38 @@ public enum PowersManager {
if (playerCharacter == null || msg == null)
return;
//handle sprint for bard sprint
if(msg.getPowerUsedID() == 429005674){
msg.setPowerUsedID(429611355);
}
//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();
playerCharacter.update(false);
playerCharacter.updateStamRegen(-100);
}
@ -809,15 +958,16 @@ public enum PowersManager { @@ -809,15 +958,16 @@ public enum PowersManager {
}
float range = pb.getRange() + speedRange;
if(pb.token != 429396028) {
if (verifyInvalidRange(playerCharacter, mainTarget, range)) {
if (verifyInvalidRange(playerCharacter, mainTarget, range)) {
sendPowerMsg(playerCharacter, 8, msg);
return;
sendPowerMsg(playerCharacter, 8, msg);
return;
}
// (pc.getLoc().distance(target.getLoc()) > pb.getRange()) {
// TODO send message that target is out of range
}
// (pc.getLoc().distance(target.getLoc()) > pb.getRange()) {
// TODO send message that target is out of range
}
@ -1233,7 +1383,7 @@ public enum PowersManager { @@ -1233,7 +1383,7 @@ public enum PowersManager {
PlayerCharacter target = SessionManager
.getPlayerCharacterByLowerCaseName(msg.getTargetName());
if (target == null || target.equals(pc) || target.isCombat()) {
if (target == null || target.equals(pc)) {
if (target == null) // Player not found. Send not found message
ChatManager.chatInfoError(pc,
@ -1337,6 +1487,16 @@ public enum PowersManager { @@ -1337,6 +1487,16 @@ public enum PowersManager {
else
duration = 45000; // Belgosh Summons, 45 seconds
boolean enemiesNear = false;
for(AbstractWorldObject awo : WorldGrid.getObjectsInRangePartial(pc.loc,MBServerStatics.CHARACTER_LOAD_RANGE, MBServerStatics.MASK_PLAYER)){
PlayerCharacter playerCharacter = (PlayerCharacter)awo;
if(!playerCharacter.guild.getNation().equals(pc.guild.getNation())){
enemiesNear = true;
}
}
if(enemiesNear && !pc.isInSafeZone())
duration += 60000;
// Teleport to summoners location
FinishSummonsJob fsj = new FinishSummonsJob(source, pc);
@ -1462,8 +1622,18 @@ public enum PowersManager { @@ -1462,8 +1622,18 @@ public enum PowersManager {
}
// create list of characters
HashSet<AbstractCharacter> trackChars = RangeBasedAwo.getTrackList(
allTargets, playerCharacter, maxTargets);
HashSet<AbstractCharacter> trackChars;
switch(msg.getPowerToken()){
case 431511776:
case 429578587:
case 429503360:
case 44106356:
trackChars = getTrackList(playerCharacter);
break;
default:
trackChars = RangeBasedAwo.getTrackList(allTargets, playerCharacter, maxTargets);
break;
}
TrackWindowMsg trackWindowMsg = new TrackWindowMsg(msg);
@ -1476,6 +1646,30 @@ public enum PowersManager { @@ -1476,6 +1646,30 @@ public enum PowersManager {
}
public static HashSet<AbstractCharacter> getTrackList(PlayerCharacter tracker){
HashSet<AbstractCharacter> list = new HashSet<AbstractCharacter>();
HashSet<AbstractWorldObject> shortList = WorldGrid.getObjectsInRangePartial(tracker.loc,MBServerStatics.CHARACTER_LOAD_RANGE, MBServerStatics.MASK_PLAYER);
HashSet<AbstractWorldObject> fullList = WorldGrid.getObjectsInRangePartial(tracker.loc,1408, MBServerStatics.MASK_PLAYER);
ArrayList<Guild> guildsPresent = new ArrayList<>();
for(AbstractWorldObject awo : shortList){
PlayerCharacter pc = (PlayerCharacter)awo;
if(!guildsPresent.contains(pc.guild.getNation())){
guildsPresent.add(pc.guild.getNation());
}
}
for(AbstractWorldObject awo : fullList){
if(awo.equals(tracker))
continue;
PlayerCharacter pc = (PlayerCharacter)awo;
if(!pc.isAlive())
continue;
if(guildsPresent.contains(pc.guild.getNation()))
list.add(pc);
}
return list;
}
private static void sendRecyclePower(int token, ClientConnection origin) {
RecyclePowerMsg recyclePowerMsg = new RecyclePowerMsg(token);
@ -2189,7 +2383,7 @@ public enum PowersManager { @@ -2189,7 +2383,7 @@ public enum PowersManager {
// set player is not casting for regens
if (pc.isCasting()) {
pc.update();
pc.update(false);
}
pc.setIsCasting(false);
@ -2241,28 +2435,26 @@ public enum PowersManager { @@ -2241,28 +2435,26 @@ public enum PowersManager {
defense = 0f;
// Get hit chance
if (pc.getDebug(16)) {
String smsg = "ATR: " + atr + ", Defense: " + defense;
ChatManager.chatSystemInfo(pc, smsg);
}
//if (pc.getDebug(16)) {
// String smsg = "ATR: " + atr + ", Defense: " + defense;
// ChatManager.chatSystemInfo(pc, smsg);
//}
int chance;
//int chance;
if (atr > defense || defense == 0)
chance = 94;
else {
float dif = atr / defense;
if (dif <= 0.8f)
chance = 4;
else
chance = ((int) (450 * (dif - 0.8f)) + 4);
}
//if (atr > defense || defense == 0)
// chance = 94;
//else {
// float dif = atr / defense;
// if (dif <= 0.8f)
// chance = 4;
// else
// chance = ((int) (450 * (dif - 0.8f)) + 4);
//}
// calculate hit/miss
int roll = ThreadLocalRandom.current().nextInt(100);
boolean disable = true;
if (roll < chance) {
if (CombatManager.LandHit((int)atr,(int)defense)) {
// Hit, check if dodge kicked in
if (awo instanceof AbstractCharacter) {
AbstractCharacter tarAc = (AbstractCharacter) awo;
@ -2274,6 +2466,13 @@ public enum PowersManager { @@ -2274,6 +2466,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;
@ -2321,7 +2520,12 @@ public enum PowersManager { @@ -2321,7 +2520,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
@ -2562,7 +2766,9 @@ public enum PowersManager { @@ -2562,7 +2766,9 @@ public enum PowersManager {
}
public static void cancelOnStun(AbstractCharacter ac) {
if(ac.getObjectType().equals(GameObjectType.PlayerCharacter)){
//PlayerCharacter.GroundPlayer((PlayerCharacter)ac);
}
}
private static PowersBase getLastPower(AbstractCharacter ac) {
@ -2708,6 +2914,126 @@ public enum PowersManager { @@ -2708,6 +2914,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;
}
}

45
src/engine/gameManager/SimulationManager.java

@ -10,10 +10,7 @@ package engine.gameManager; @@ -10,10 +10,7 @@ package engine.gameManager;
import engine.Enum;
import engine.Enum.GameObjectType;
import engine.objects.AbstractGameObject;
import engine.objects.City;
import engine.objects.PlayerCharacter;
import engine.objects.Runegate;
import engine.objects.*;
import org.pmw.tinylog.Logger;
import java.sql.Connection;
@ -33,7 +30,7 @@ public enum SimulationManager { @@ -33,7 +30,7 @@ public enum SimulationManager {
SERVERHEARTBEAT;
private static final long CITY_PULSE = 2000;
private static final long RUNEGATE_PULSE = 3000;
private static final long RUNEGATE_PULSE = 1000;
private static final long UPDATE_PULSE = 1000;
private static final long FlIGHT_PULSE = 100;
public static Duration executionTime = Duration.ofNanos(1);
@ -96,13 +93,10 @@ public enum SimulationManager { @@ -96,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 {
@ -116,9 +110,18 @@ public enum SimulationManager { @@ -116,9 +110,18 @@ public enum SimulationManager {
}
try {
if ((_cityPulseTime != 0)
&& (System.currentTimeMillis() > _cityPulseTime))
pulseCities();
if ((_cityPulseTime != 0) && (System.currentTimeMillis() > _cityPulseTime)) {
try {
pulseCities();
}catch(Exception e){
}
try {
ArenaManager.pulseArenas();
}catch(Exception e){
}
}
} catch (Exception e) {
Logger.error(
"Fatal error in City Pulse: DISABLED. Error Message : "
@ -154,7 +157,11 @@ public enum SimulationManager { @@ -154,7 +157,11 @@ public enum SimulationManager {
if (player == null)
continue;
player.update();
try {
player.update(false);
}catch(Exception e){
}
}
_updatePulseTime = System.currentTimeMillis() + 500;
@ -203,8 +210,12 @@ public enum SimulationManager { @@ -203,8 +210,12 @@ public enum SimulationManager {
city = (City) cityObject;
city.onEnter();
}
for(Mine mine : Mine.getMines()){
if(mine != null && mine.isActive)
mine.onEnter();
}
_cityPulseTime = System.currentTimeMillis() + CITY_PULSE;
}
/*
@ -214,6 +225,10 @@ public enum SimulationManager { @@ -214,6 +225,10 @@ public enum SimulationManager {
private void pulseRunegates() {
for (Runegate runegate : Runegate._runegates.values()) {
for(Portal portal : runegate._portals)
if(!portal.isActive())
portal.activate(false);
runegate.collidePortals();
}

347
src/engine/gameManager/StrongholdManager.java

@ -0,0 +1,347 @@ @@ -0,0 +1,347 @@
package engine.gameManager;
import engine.Enum;
import engine.InterestManagement.InterestManager;
import engine.InterestManagement.WorldGrid;
import engine.math.Vector3f;
import engine.math.Vector3fImmutable;
import engine.objects.*;
import org.pmw.tinylog.Logger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.concurrent.ThreadLocalRandom;
public class StrongholdManager {
public static void processStrongholds() {
ArrayList<Mine> mines = Mine.getMines();
//process strongholds selecting 3 randomly to become active
int count = 0;
while (count < 3) {
int random = ThreadLocalRandom.current().nextInt(1, mines.size()) - 1;
Mine mine = mines.get(random);
if (mine != null) {
if (!mine.isActive && !mine.isStronghold) {
StartStronghold(mine);
count++;
}
}
}
}
public static void StartStronghold(Mine mine){
//remove buildings
Building tower = BuildingManager.getBuilding(mine.getBuildingID());
if(tower == null)
return;
mine.isStronghold = true;
mine.strongholdMobs = new ArrayList<>();
mine.oldBuildings = new HashMap<>();
Zone mineZone = ZoneManager.findSmallestZone(tower.loc);
for(Building building : mineZone.zoneBuildingSet){
mine.oldBuildings.put(building.getObjectUUID(),building.meshUUID);
building.setMeshUUID(407650);
building.setMeshScale(new Vector3f(0,0,0));
InterestManager.setObjectDirty(building);
WorldGrid.updateObject(building);
}
//update tower to become stronghold mesh
tower.setMeshUUID(getStrongholdMeshID(mine.getParentZone()));
tower.setMeshScale(new Vector3f(1,1,1));
InterestManager.setObjectDirty(tower);
WorldGrid.updateObject(tower);
//create elite mobs
for(int i = 0; i < mine.capSize * 2; i++){
Vector3fImmutable loc = Vector3fImmutable.getRandomPointOnCircle(tower.loc,30);
MobBase guardBase = MobBase.getMobBase(getStrongholdGuardianID(tower.meshUUID));
Mob guard = Mob.createStrongholdMob(guardBase.getLoadID(), loc, Guild.getErrantGuild(),true,mineZone,null,0, guardBase.getFirstName(),65);
if(guard != null){
guard.parentZone = mine.getParentZone();
guard.bindLoc = loc;
guard.setLoc(loc);
guard.StrongholdGuardian = true;
guard.equipmentSetID = getStrongholdMobEquipSetID(guard);
guard.runAfterLoad();
guard.setLevel((short)65);
guard.setResists(new Resists("Elite"));
guard.spawnTime = 1000000000;
guard.BehaviourType = Enum.MobBehaviourType.Aggro;
mine.strongholdMobs.add(guard);
LootManager.GenerateStrongholdLoot(guard,false,false);
guard.healthMax = 12500;
guard.setHealth(guard.healthMax);
guard.maxDamageHandOne = 1550;
guard.minDamageHandOne = 750;
guard.atrHandOne = 1800;
guard.defenseRating = 2200;
guard.setFirstName("Elite Guardian");
InterestManager.setObjectDirty(guard);
WorldGrid.addObject(guard,loc.x,loc.z);
WorldGrid.updateObject(guard);
guard.stronghold = mine;
guard.mobPowers.clear();
guard.mobPowers.put(429399948,20); // find weakness
}
}
//create stronghold commander
Vector3fImmutable loc = tower.loc;
MobBase commanderBase = MobBase.getMobBase(getStrongholdCommanderID(tower.meshUUID));
Mob commander = Mob.createStrongholdMob(commanderBase.getLoadID(), loc,Guild.getErrantGuild(),true,mineZone,null,0, commanderBase.getFirstName(),75);
if(commander != null){
commander.parentZone = mine.getParentZone();
commander.bindLoc = loc;
commander.setLoc(loc);
commander.StrongholdCommander = true;
commander.equipmentSetID = getStrongholdMobEquipSetID(commander);
commander.runAfterLoad();
commander.setLevel((short)75);
commander.setResists(new Resists("Elite"));
commander.spawnTime = 1000000000;
commander.BehaviourType = Enum.MobBehaviourType.Aggro;
commander.mobPowers.clear();
commander.mobPowers.put(429032838, 40); // gravechill
commander.mobPowers.put(429757701,20); // magebolt
commander.mobPowers.put(429121388,20); // blight
commander.mobPowers.put(431566891,20); // lightning bolt
commander.mobPowers.put(428716075,20); // fire bolt
commander.mobPowers.put(429010987,20); // ice bolt
mine.strongholdMobs.add(commander);
LootManager.GenerateStrongholdLoot(commander,true, false);
commander.healthMax = 50000;
commander.setHealth(commander.healthMax);
commander.maxDamageHandOne = 3500;
commander.minDamageHandOne = 1500;
commander.atrHandOne = 3500;
commander.defenseRating = 3500;
commander.setFirstName("Guardian Commander");
InterestManager.setObjectDirty(commander);
WorldGrid.addObject(commander,loc.x,loc.z);
WorldGrid.updateObject(commander);
commander.stronghold = mine;
}
mine.isActive = true;
tower.setProtectionState(Enum.ProtectionState.PROTECTED);
tower.getBounds().setRegions(tower);
InterestManager.setObjectDirty(tower);
WorldGrid.updateObject(tower);
ChatManager.chatSystemChannel(mine.getZoneName() + "'s Stronghold Has Begun!");
Logger.info(mine.getZoneName() + "'s Stronghold Has Begun!");
}
public static void EndStronghold(Mine mine){
//restore the buildings
Building tower = BuildingManager.getBuilding(mine.getBuildingID());
if(tower == null)
return;
mine.isStronghold = false;
//get rid of the mobs
for(Mob mob : mine.strongholdMobs) {
mob.despawn();
mob.removeFromCache();
DbManager.MobQueries.DELETE_MOB(mob);
}
//restore the buildings
Zone mineZone = ZoneManager.findSmallestZone(tower.loc);
for(Building building : mineZone.zoneBuildingSet){
if(mine.oldBuildings.containsKey(building.getObjectUUID())) {
building.setMeshUUID(mine.oldBuildings.get(building.getObjectUUID()));
building.setMeshScale(new Vector3f(1, 1, 1));
InterestManager.setObjectDirty(building);
WorldGrid.updateObject(building);
}
}
//update tower to become Mine Tower again
tower.setMeshUUID(1500100);
mine.isActive = false;
tower.setProtectionState(Enum.ProtectionState.NPC);
tower.getBounds().setRegions(tower);
InterestManager.setObjectDirty(tower);
WorldGrid.updateObject(tower);
ChatManager.chatSystemChannel(mine.getZoneName() + "'s Stronghold Has Concluded!");
Logger.info(mine.getZoneName() + "'s Stronghold Has Concluded!");
}
public static int getStrongholdMeshID(Zone parent){
while(!parent.isMacroZone()){
parent = parent.getParent();
if(parent.getName().equalsIgnoreCase("seafloor")){
return 0;
}
}
switch(parent.getObjectUUID()){
case 197:
case 234:
case 178:
case 122:
return 814000; //Frost Giant Hall (ICE)
case 968:
case 951:
case 313:
case 331:
return 5001500; // Lich Queens Keep (UNDEAD)
case 785:
case 761:
case 717:
case 737:
return 1306600; // Temple of the Dragon (DESERT)
case 353:
case 371:
case 388:
case 532:
return 564600; // Undead Lord's Keep (SWAMP)
case 550:
case 508:
case 475:
case 418:
return 1326600; // elven hall
case 437:
case 491:
case 590:
case 569:
return 602400;
case 824:
case 842:
case 632:
return 1600000; // chaos temple
}
return 456100; // small stockade
}
public static int getStrongholdGuardianID(int ID){
switch(ID){
case 814000:
return 253004; // Mountain Giant Raider Axe
case 5001500:
return 253008; // Vampire Spear Warrior
case 1306600:
return 253007; // Desert Orc Warrior
case 564600:
return 253010; // Kolthoss Warrior
case 1326600:
return 253005; //elven warrior
case 602400:
return 253009; // templar missionary
case 1600000:
return 253006; // scourger
}
return 13434; // human sword and board warrior
}
public static int getStrongholdEpicID(int ID){
switch(ID){
case 814000:
return 253023; // Mountain Giant Raider Axe
case 5001500:
return 253022; // Vampire Spear Warrior
case 1306600:
return 253021; // Desert Orc Warrior
case 564600:
return 253018; // Kolthoss Warrior
case 1326600:
return 253019; //elven warrior
case 602400:
return 253024; // templar missionary
case 1600000:
return 253020; // scourger
}
return 13434; // human sword and board warrior
}
public static int getStrongholdCommanderID(int ID){
switch(ID){
case 814000:
return 253017;
case 5001500:
return 253012;
case 1306600:
return 253016; // Desert Orc Xbow
case 564600:
return 253011; // xbow kolthoss
case 1326600:
return 253013; //elven bow warrior
case 602400:
return 253015; // dune giant with xbow
case 1600000:
return 253014; // barbator
}
return 13433;
}
public static int getStrongholdMobEquipSetID(Mob mob) {
if(mob.StrongholdGuardian){
return 6327;
}else{
return 10790;
}
}
public static void CheckToEndStronghold(Mine mine) {
boolean stillAlive = false;
for (Mob mob : mine.strongholdMobs)
if (mob.isAlive())
stillAlive = true;
if (!stillAlive) {
// Epic encounter
Building tower = BuildingManager.getBuilding(mine.getBuildingID());
if (tower == null)
return;
Zone mineZone = ZoneManager.findSmallestZone(tower.loc);
Vector3fImmutable loc = tower.loc;
MobBase commanderBase = MobBase.getMobBase(getStrongholdEpicID(tower.meshUUID));
Mob commander = Mob.createStrongholdMob(commanderBase.getLoadID(), loc, Guild.getErrantGuild(), true, mineZone, null, 0, commanderBase.getFirstName(), 75);
if (commander != null) {
commander.parentZone = mine.getParentZone();
commander.bindLoc = loc;
commander.setLoc(loc);
commander.StrongholdEpic = true;
commander.equipmentSetID = getStrongholdMobEquipSetID(commander);
commander.runAfterLoad();
commander.setLevel((short) 85);
commander.setResists(new Resists("Elite"));
commander.spawnTime = 1000000000;
commander.BehaviourType = Enum.MobBehaviourType.Aggro;
commander.mobPowers.clear();
commander.mobPowers.put(429032838, 40); // gravechill
commander.mobPowers.put(429757701,40); // magebolt
commander.mobPowers.put(429121388,40); // blight
commander.mobPowers.put(431566891,40); // lightning bolt
commander.mobPowers.put(428716075,40); // fire bolt
commander.mobPowers.put(429010987,40); // ice bolt
mine.strongholdMobs.add(commander);
LootManager.GenerateStrongholdLoot(commander, true, true);
commander.healthMax = 250000;
commander.setHealth(commander.healthMax);
commander.maxDamageHandOne = 5000;
commander.minDamageHandOne = 2500;
commander.atrHandOne = 5000;
commander.defenseRating = 3500;
commander.setFirstName("Defender of " + mine.getParentZone().getParent().getName());
InterestManager.setObjectDirty(commander);
WorldGrid.addObject(commander,loc.x,loc.z);
WorldGrid.updateObject(commander);
commander.stronghold = mine;
}
}
}
}

195
src/engine/gameManager/ZergManager.java

@ -0,0 +1,195 @@ @@ -0,0 +1,195 @@
package engine.gameManager;
import engine.objects.Guild;
public class ZergManager {
public static float getCurrentMultiplier(int count, int maxCount){
switch(maxCount) {
case 3: return getMultiplier3Man(count);
case 5: return getMultiplier5Man(count);
case 10: return getMultiplier10Man(count);
case 20: return getMultiplier20Man(count);
case 30: return getMultiplier30Man(count);
case 40: return getMultiplier40Man(count);
default: return 1.0f; //unlimited
}
}
public static float getMultiplier3Man(int count) {
if(count < 4)
return 1.0f;
if(count > 6)
return 0.0f;
switch(count){
case 4: return 0.63f;
case 5: return 0.40f;
case 6: return 0.25f;
default: return 1.0f;
}
}
public static float getMultiplier5Man(int count) {
if(count < 6)
return 1.0f;
if(count > 10)
return 0.0f;
switch(count){
case 6: return 0.75f;
case 7: return 0.57f;
case 8: return 0.44f;
case 9: return 0.33f;
case 10: return 0.25f;
default: return 1.0f;
}
}
public static float getMultiplier10Man(int count) {
if(count < 11)
return 1.0f;
if(count > 20)
return 0.0f;
switch(count){
case 11: return 0.86f;
case 12: return 0.75f;
case 13: return 0.65f;
case 14: return 0.57f;
case 15: return 0.50f;
case 16: return 0.44f;
case 17: return 0.38f;
case 18: return 0.33f;
case 19: return 0.29f;
case 20: return 0.25f;
default: return 1.0f;
}
}
public static float getMultiplier20Man(int count) {
if(count < 21)
return 1.0f;
if(count > 40)
return 0.0f;
switch (count)
{
case 21: return 0.93f;
case 22: return 0.86f;
case 23: return 0.80f;
case 24: return 0.75f;
case 25: return 0.70f;
case 26: return 0.65f;
case 27: return 0.61f;
case 28: return 0.57f;
case 29: return 0.53f;
case 30: return 0.50f;
case 31: return 0.47f;
case 32: return 0.44f;
case 33: return 0.41f;
case 34: return 0.38f;
case 35: return 0.36f;
case 36: return 0.33f;
case 37: return 0.31f;
case 38: return 0.29f;
case 39: return 0.27f;
case 40: return 0.25f;
default: return 1.0f;
}
}
public static float getMultiplier30Man(int count) {
if(count < 31)
return 1.0f;
if(count > 60)
return 0.0f;
switch (count)
{
case 31: return 0.95f;
case 32: return 0.91f;
case 33: return 0.86f;
case 34: return 0.82f;
case 35: return 0.79f;
case 36: return 0.75f;
case 37: return 0.72f;
case 38: return 0.68f;
case 39: return 0.65f;
case 40: return 0.63f;
case 41: return 0.60f;
case 42: return 0.57f;
case 43: return 0.55f;
case 44: return 0.52f;
case 45: return 0.50f;
case 46: return 0.48f;
case 47: return 0.46f;
case 48: return 0.44f;
case 49: return 0.42f;
case 50: return 0.40f;
case 51: return 0.38f;
case 52: return 0.37f;
case 53: return 0.35f;
case 54: return 0.33f;
case 55: return 0.32f;
case 56: return 0.30f;
case 57: return 0.29f;
case 58: return 0.28f;
case 59: return 0.26f;
case 60: return 0.25f;
default: return 1.0f;
}
}
public static float getMultiplier40Man(int count) {
if(count < 41)
return 1.0f;
if(count > 80)
return 0.0f;
switch (count)
{
case 41: return 0.96f;
case 42: return 0.93f;
case 43: return 0.90f;
case 44: return 0.86f;
case 45: return 0.83f;
case 46: return 0.80f;
case 47: return 0.78f;
case 48: return 0.75f;
case 49: return 0.72f;
case 50: return 0.70f;
case 51: return 0.68f;
case 52: return 0.65f;
case 53: return 0.63f;
case 54: return 0.61f;
case 55: return 0.59f;
case 56: return 0.57f;
case 57: return 0.55f;
case 58: return 0.53f;
case 59: return 0.52f;
case 60: return 0.50f;
case 61: return 0.48f;
case 62: return 0.47f;
case 63: return 0.45f;
case 64: return 0.44f;
case 65: return 0.42f;
case 66: return 0.41f;
case 67: return 0.40f;
case 68: return 0.38f;
case 69: return 0.37f;
case 70: return 0.36f;
case 71: return 0.35f;
case 72: return 0.33f;
case 73: return 0.32f;
case 74: return 0.31f;
case 75: return 0.30f;
case 76: return 0.29f;
case 77: return 0.28f;
case 78: return 0.27f;
case 79: return 0.26f;
case 80: return 0.25f;
default: return 1.0f;
}
}
}

73
src/engine/gameManager/ZoneManager.java

@ -19,14 +19,12 @@ import engine.objects.Building; @@ -19,14 +19,12 @@ import engine.objects.Building;
import engine.objects.City;
import engine.objects.Zone;
import engine.server.MBServerStatics;
import org.pmw.tinylog.Logger;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ThreadLocalRandom;
/*
* Class contains methods and structures which
@ -109,20 +107,6 @@ public enum ZoneManager { @@ -109,20 +107,6 @@ public enum ZoneManager {
}
// Returns the number of available hotZones
// remaining in this cycle (1am)
public static int availableHotZones() {
int count = 0;
for (Zone zone : ZoneManager.macroZones)
if (ZoneManager.validHotZone(zone))
count = count + 1;
return count;
}
// Resets the availability of hotZones
// for this cycle
@ -217,63 +201,6 @@ public enum ZoneManager { @@ -217,63 +201,6 @@ public enum ZoneManager {
ZoneManager.playerCityZones.add(zone);
}
public static final void generateAndSetRandomHotzone() {
Zone hotZone;
ArrayList<Integer> zoneArray = new ArrayList<>();
if (ZoneManager.macroZones.isEmpty())
return;
// Reset hotZone availability if none are left.
if (ZoneManager.availableHotZones() == 0)
ZoneManager.resetHotZones();
for (Zone zone : ZoneManager.macroZones)
if (validHotZone(zone))
zoneArray.add(zone.getObjectUUID());
int entryIndex = ThreadLocalRandom.current().nextInt(zoneArray.size());
hotZone = ZoneManager.getZoneByUUID(zoneArray.get(entryIndex));
if (hotZone == null) {
Logger.error("Hotzone is null");
return;
}
ZoneManager.setHotZone(hotZone);
}
public static final boolean validHotZone(Zone zone) {
if (zone.getSafeZone() == (byte) 1)
return false; // no safe zone hotzones// if (this.hotzone == null)
if (zone.getNodes().isEmpty())
return false;
if (zone.equals(ZoneManager.seaFloor))
return false;
//no duplicate hotZones
if (zone.hasBeenHotzone == true)
return false;
// Enforce min level
if (zone.minLvl < Integer.parseInt(ConfigManager.MB_HOTZONE_MIN_LEVEL.getValue()))
return false;
if (ZoneManager.hotZone != null)
return ZoneManager.hotZone.getObjectUUID() != zone.getObjectUUID();
return true;
}
// Converts world coordinates to coordinates local to a given zone.
public static Vector3fImmutable worldToLocal(Vector3fImmutable worldVector,

2
src/engine/job/AbstractJob.java

@ -68,7 +68,7 @@ public abstract class AbstractJob implements Runnable { @@ -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);

2
src/engine/job/AbstractScheduleJob.java

@ -17,7 +17,7 @@ public abstract class AbstractScheduleJob extends AbstractJob { @@ -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);

2
src/engine/job/JobContainer.java

@ -16,7 +16,7 @@ public class JobContainer implements Comparable<JobContainer> { @@ -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
src/engine/job/JobThread.java

@ -0,0 +1,75 @@ @@ -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);
}
}

9
src/engine/job/JobWorker.java

@ -58,10 +58,13 @@ public class JobWorker extends ControlledRunnable { @@ -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;
}

4
src/engine/jobs/AbstractEffectJob.java

@ -45,7 +45,7 @@ public abstract class AbstractEffectJob extends AbstractScheduleJob { @@ -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 { @@ -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);
}

2
src/engine/jobs/ActivateBaneJob.java

@ -29,7 +29,7 @@ public class ActivateBaneJob extends AbstractScheduleJob { @@ -29,7 +29,7 @@ public class ActivateBaneJob extends AbstractScheduleJob {
}
@Override
protected void doJob() {
public void doJob() {
City city;

2
src/engine/jobs/AttackJob.java

@ -27,7 +27,7 @@ public class AttackJob extends AbstractJob { @@ -27,7 +27,7 @@ public class AttackJob extends AbstractJob {
}
@Override
protected void doJob() {
public void doJob() {
CombatManager.doCombat(this.source, slot);
}

2
src/engine/jobs/BaneDefaultTimeJob.java

@ -24,7 +24,7 @@ public class BaneDefaultTimeJob extends AbstractScheduleJob { @@ -24,7 +24,7 @@ public class BaneDefaultTimeJob extends AbstractScheduleJob {
}
@Override
protected void doJob() {
public void doJob() {
//bane already set.
if (this.bane.getLiveDate() != null) {

2
src/engine/jobs/BasicScheduledJob.java

@ -97,7 +97,7 @@ public class BasicScheduledJob extends AbstractJob { @@ -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;

2
src/engine/jobs/BonusCalcJob.java

@ -22,7 +22,7 @@ public class BonusCalcJob extends AbstractJob { @@ -22,7 +22,7 @@ public class BonusCalcJob extends AbstractJob {
}
@Override
protected void doJob() {
public void doJob() {
if (this.ac != null) {
this.ac.applyBonuses();

2
src/engine/jobs/CSessionCleanupJob.java

@ -22,7 +22,7 @@ public class CSessionCleanupJob extends AbstractJob { @@ -22,7 +22,7 @@ public class CSessionCleanupJob extends AbstractJob {
}
@Override
protected void doJob() {
public void doJob() {
SessionManager.cSessionCleanup(secKey);
}
}

2
src/engine/jobs/ChangeAltitudeJob.java

@ -27,7 +27,7 @@ public class ChangeAltitudeJob extends AbstractScheduleJob { @@ -27,7 +27,7 @@ public class ChangeAltitudeJob extends AbstractScheduleJob {
}
@Override
protected void doJob() {
public void doJob() {
if (this.ac != null)
MovementManager.finishChangeAltitude(ac, targetAlt);
}

2
src/engine/jobs/ChantJob.java

@ -36,7 +36,7 @@ public class ChantJob extends AbstractEffectJob { @@ -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;

2
src/engine/jobs/CloseGateJob.java

@ -29,7 +29,7 @@ public class CloseGateJob extends AbstractScheduleJob { @@ -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");

4
src/engine/jobs/DamageOverTimeJob.java

@ -37,7 +37,7 @@ public class DamageOverTimeJob extends AbstractEffectJob { @@ -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 { @@ -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;

2
src/engine/jobs/DatabaseUpdateJob.java

@ -28,7 +28,7 @@ public class DatabaseUpdateJob extends AbstractScheduleJob { @@ -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);

2
src/engine/jobs/DebugTimerJob.java

@ -29,7 +29,7 @@ public class DebugTimerJob extends AbstractScheduleJob { @@ -29,7 +29,7 @@ public class DebugTimerJob extends AbstractScheduleJob {
}
@Override
protected void doJob() {
public void doJob() {
if (this.pc == null) {
return;
}

2
src/engine/jobs/DeferredPowerJob.java

@ -37,7 +37,7 @@ public class DeferredPowerJob extends AbstractEffectJob { @@ -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);

2
src/engine/jobs/DisconnectJob.java

@ -22,7 +22,7 @@ public class DisconnectJob extends AbstractScheduleJob { @@ -22,7 +22,7 @@ public class DisconnectJob extends AbstractScheduleJob {
}
@Override
protected void doJob() {
public void doJob() {
if (this.origin != null) {
this.origin.disconnect();
}

2
src/engine/jobs/DoorCloseJob.java

@ -28,7 +28,7 @@ public class DoorCloseJob extends AbstractScheduleJob { @@ -28,7 +28,7 @@ public class DoorCloseJob extends AbstractScheduleJob {
}
@Override
protected void doJob() {
public void doJob() {
int doorNumber;

2
src/engine/jobs/EndFearJob.java

@ -22,7 +22,7 @@ public class EndFearJob extends AbstractEffectJob { @@ -22,7 +22,7 @@ public class EndFearJob extends AbstractEffectJob {
}
@Override
protected void doJob() {
public void doJob() {
//cancel fear for mob.

2
src/engine/jobs/FinishCooldownTimeJob.java

@ -26,7 +26,7 @@ public class FinishCooldownTimeJob extends AbstractJob { @@ -26,7 +26,7 @@ public class FinishCooldownTimeJob extends AbstractJob {
}
@Override
protected void doJob() {
public void doJob() {
PowersManager.finishCooldownTime(this.msg, this.pc);
}
}

2
src/engine/jobs/FinishEffectTimeJob.java

@ -22,7 +22,7 @@ public class FinishEffectTimeJob extends AbstractEffectJob { @@ -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);
}

2
src/engine/jobs/FinishRecycleTimeJob.java

@ -26,7 +26,7 @@ public class FinishRecycleTimeJob extends AbstractScheduleJob { @@ -26,7 +26,7 @@ public class FinishRecycleTimeJob extends AbstractScheduleJob {
}
@Override
protected void doJob() {
public void doJob() {
PowersManager.finishRecycleTime(this.msg, this.pc, false);
}

2
src/engine/jobs/FinishSpireEffectJob.java

@ -20,7 +20,7 @@ public class FinishSpireEffectJob extends AbstractEffectJob { @@ -20,7 +20,7 @@ public class FinishSpireEffectJob extends AbstractEffectJob {
}
@Override
protected void doJob() {
public void doJob() {
PlayerCharacter pc = (PlayerCharacter) target;

12
src/engine/jobs/FinishSummonsJob.java

@ -31,7 +31,7 @@ public class FinishSummonsJob extends AbstractScheduleJob { @@ -31,7 +31,7 @@ public class FinishSummonsJob extends AbstractScheduleJob {
}
@Override
protected void doJob() {
public void doJob() {
if (this.target == null)
return;
@ -47,13 +47,13 @@ public class FinishSummonsJob extends AbstractScheduleJob { @@ -47,13 +47,13 @@ public class FinishSummonsJob extends AbstractScheduleJob {
return;
// cannot summon a player in combat
if (this.target.isCombat()) {
//if (this.target.isCombat()) {
ErrorPopupMsg.sendErrorMsg(this.source, "Cannot summon player in combat.");
// ErrorPopupMsg.sendErrorMsg(this.source, "Cannot summon player in combat.");
PowersManager.finishRecycleTime(428523680, this.source, false);
return;
}
// PowersManager.finishRecycleTime(428523680, this.source, false);
// return;
//}
if (this.target.getBonuses() != null && this.target.getBonuses().getBool(ModType.BlockedPowerType, SourceType.SUMMON)) {
ErrorPopupMsg.sendErrorMsg(this.target, "You have been blocked from receiving summons!");

2
src/engine/jobs/LoadEffectsJob.java

@ -28,7 +28,7 @@ public class LoadEffectsJob extends AbstractJob { @@ -28,7 +28,7 @@ public class LoadEffectsJob extends AbstractJob {
}
@Override
protected void doJob() {
public void doJob() {
if (this.originToSend == null) {
return;
}

2
src/engine/jobs/LogoutCharacterJob.java

@ -25,7 +25,7 @@ public class LogoutCharacterJob extends AbstractScheduleJob { @@ -25,7 +25,7 @@ public class LogoutCharacterJob extends AbstractScheduleJob {
}
@Override
protected void doJob() {
public void doJob() {
server.logoutCharacter(this.pc);
}

2
src/engine/jobs/NoTimeJob.java

@ -19,7 +19,7 @@ public class NoTimeJob extends AbstractEffectJob { @@ -19,7 +19,7 @@ public class NoTimeJob extends AbstractEffectJob {
}
@Override
protected void doJob() {
public void doJob() {
}
@Override

2
src/engine/jobs/PersistentAoeJob.java

@ -40,7 +40,7 @@ public class PersistentAoeJob extends AbstractEffectJob { @@ -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;

2
src/engine/jobs/RefreshGroupJob.java

@ -45,7 +45,7 @@ public class RefreshGroupJob extends AbstractJob { @@ -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;

2
src/engine/jobs/RemoveCorpseJob.java

@ -22,7 +22,7 @@ public class RemoveCorpseJob extends AbstractScheduleJob { @@ -22,7 +22,7 @@ public class RemoveCorpseJob extends AbstractScheduleJob {
}
@Override
protected void doJob() {
public void doJob() {
if (this.corpse != null)
Corpse.removeCorpse(corpse, true);

2
src/engine/jobs/SiegeSpireWithdrawlJob.java

@ -25,7 +25,7 @@ public class SiegeSpireWithdrawlJob extends AbstractScheduleJob { @@ -25,7 +25,7 @@ public class SiegeSpireWithdrawlJob extends AbstractScheduleJob {
}
@Override
protected void doJob() {
public void doJob() {
if (spire == null)
return;

2
src/engine/jobs/StuckJob.java

@ -30,7 +30,7 @@ public class StuckJob extends AbstractScheduleJob { @@ -30,7 +30,7 @@ public class StuckJob extends AbstractScheduleJob {
}
@Override
protected void doJob() {
public void doJob() {
Vector3fImmutable stuckLoc;
Building building = null;

2
src/engine/jobs/SummonSendJob.java

@ -27,7 +27,7 @@ public class SummonSendJob extends AbstractScheduleJob { @@ -27,7 +27,7 @@ public class SummonSendJob extends AbstractScheduleJob {
}
@Override
protected void doJob() {
public void doJob() {
if (this.source == null)
return;

2
src/engine/jobs/TeleportJob.java

@ -39,7 +39,7 @@ public class TeleportJob extends AbstractScheduleJob { @@ -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;

2
src/engine/jobs/TrackJob.java

@ -35,7 +35,7 @@ public class TrackJob extends AbstractEffectJob { @@ -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;

2
src/engine/jobs/TransferStatOTJob.java

@ -29,7 +29,7 @@ public class TransferStatOTJob extends AbstractEffectJob { @@ -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()) {

2
src/engine/jobs/UpdateGroupJob.java

@ -26,7 +26,7 @@ public class UpdateGroupJob extends AbstractScheduleJob { @@ -26,7 +26,7 @@ public class UpdateGroupJob extends AbstractScheduleJob {
}
@Override
protected void doJob() {
public void doJob() {
if (this.group == null)
return;

16
src/engine/jobs/UpgradeBuildingJob.java

@ -1,7 +1,9 @@ @@ -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 { @@ -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 { @@ -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

2
src/engine/jobs/UpgradeNPCJob.java

@ -27,7 +27,7 @@ public class UpgradeNPCJob extends AbstractScheduleJob { @@ -27,7 +27,7 @@ public class UpgradeNPCJob extends AbstractScheduleJob {
}
@Override
protected void doJob() {
public void doJob() {
int newRank;

2
src/engine/jobs/UseItemJob.java

@ -34,7 +34,7 @@ public class UseItemJob extends AbstractScheduleJob { @@ -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);
}

2
src/engine/jobs/UseMobPowerJob.java

@ -35,7 +35,7 @@ public class UseMobPowerJob extends AbstractScheduleJob { @@ -35,7 +35,7 @@ public class UseMobPowerJob extends AbstractScheduleJob {
}
@Override
protected void doJob() {
public void doJob() {
PowersManager.finishUseMobPower(this.msg, this.caster, casterLiveCounter, targetLiveCounter);
}

2
src/engine/jobs/UsePowerJob.java

@ -35,7 +35,7 @@ public class UsePowerJob extends AbstractScheduleJob { @@ -35,7 +35,7 @@ public class UsePowerJob extends AbstractScheduleJob {
}
@Override
protected void doJob() {
public void doJob() {
PowersManager.finishUsePower(this.msg, this.pc, casterLiveCounter, targetLiveCounter);
}

22
src/engine/loot/ItemTableEntry.java

@ -9,10 +9,12 @@ @@ -9,10 +9,12 @@
package engine.loot;
import engine.gameManager.LootManager;
import org.pmw.tinylog.Logger;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
public class ItemTableEntry {
public int minRoll;
@ -35,11 +37,23 @@ public class ItemTableEntry { @@ -35,11 +37,23 @@ public class ItemTableEntry {
List<ItemTableEntry> itemTableEntryList;
itemTableEntryList = LootManager._itemTables.get(itemTable);
if(itemTableEntryList != null) {
for (ItemTableEntry iteration : itemTableEntryList)
if (roll >= iteration.minRoll && roll <= iteration.maxRoll)
itemTableEntry = iteration;
}
return itemTableEntry;
}
public static Integer getRandomItem(int itemTable) {
int id = 0;
List<ItemTableEntry> itemTableEntryList;
for (ItemTableEntry iteration : itemTableEntryList)
if (roll >= iteration.minRoll && roll <= iteration.maxRoll)
itemTableEntry = iteration;
itemTableEntryList = LootManager._itemTables.get(itemTable);
return itemTableEntry;
if(itemTableEntryList != null && itemTableEntryList.size() > 1){
id = itemTableEntryList.get(ThreadLocalRandom.current().nextInt(0, itemTableEntryList.size())).cacheID;
}
return id;
}
}

10
src/engine/loot/ModTableEntry.java

@ -33,11 +33,11 @@ public class ModTableEntry { @@ -33,11 +33,11 @@ public class ModTableEntry {
List<ModTableEntry> itemTableEntryList;
itemTableEntryList = LootManager._modTables.get(modTablwe);
for (ModTableEntry iteration : itemTableEntryList)
if (roll >= iteration.minRoll && roll <= iteration.maxRoll)
modTableEntry = iteration;
if(itemTableEntryList != null) {
for (ModTableEntry iteration : itemTableEntryList)
if (roll >= iteration.minRoll && roll <= iteration.maxRoll)
modTableEntry = iteration;
}
return modTableEntry;
}
}

2
src/engine/math/Bounds.java

@ -220,7 +220,7 @@ public class Bounds { @@ -220,7 +220,7 @@ public class Bounds {
//player is inside building region, skip collision check. we only do collision from the outside.
if (player.region != null && player.region.parentBuildingID == building.getObjectUUID())
continue;
if (building.getBounds().colliders == null)
if (building.getBounds() == null || building.getBounds().colliders == null)
continue;
for (Colliders collider : building.getBounds().colliders) {

243
src/engine/mobileAI/MobAI.java

@ -9,7 +9,7 @@ @@ -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; @@ -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 { @@ -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;
@ -82,6 +83,16 @@ public class MobAI { @@ -82,6 +83,16 @@ public class MobAI {
mob.updateLocation();
if(mob.StrongholdGuardian || mob.StrongholdEpic){
// attempt to ground all players in attack range
for(int i : mob.playerAgroMap.keySet()){
PlayerCharacter tar = PlayerCharacter.getFromCache(i);
if(tar != null && tar.loc.distanceSquared(mob.loc) < 80){
PowersManager.applyPower(mob,tar,tar.loc, 111111,40,false);
}
}
}
} catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: AttackTarget" + " " + e.getMessage());
}
@ -96,10 +107,16 @@ public class MobAI { @@ -96,10 +107,16 @@ public class MobAI {
return;
}
if(target.getPet() != null && target.getPet().isAlive() && !target.getPet().isSiege()){
mob.setCombatTarget(target.getPet());
AttackTarget(mob,mob.combatTarget);
return;
}
if (mob.BehaviourType.callsForHelp)
MobCallForHelp(mob);
if (!MovementUtilities.inRangeDropAggro(mob, target)) {
if (MovementUtilities.outOfAggroRange(mob, target)) {
mob.setCombatTarget(null);
return;
}
@ -146,6 +163,12 @@ public class MobAI { @@ -146,6 +163,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());
}
@ -156,6 +179,9 @@ public class MobAI { @@ -156,6 +179,9 @@ public class MobAI {
try {
if(mob == null || target == null)
return;
if (target.getRank() == -1 || !target.isVulnerable() || BuildingManager.getBuildingFromCache(target.getObjectUUID()) == null) {
mob.setCombatTarget(null);
return;
@ -165,8 +191,8 @@ public class MobAI { @@ -165,8 +191,8 @@ public class MobAI {
if (playercity != null)
for (Mob guard : playercity.getParent().zoneMobSet)
if (guard.BehaviourType != null && guard.BehaviourType.ordinal() == Enum.MobBehaviourType.GuardCaptain.ordinal())
if (guard.getCombatTarget() == null && !guard.getGuild().equals(mob.getGuild()))
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);
if (mob.isSiege())
@ -195,11 +221,11 @@ public class MobAI { @@ -195,11 +221,11 @@ public class MobAI {
mob.setLastAttackTime(System.currentTimeMillis() + attackDelay);
}
if (mob.isSiege()) {
PowerProjectileMsg ppm = new PowerProjectileMsg(mob, target);
ppm.setRange(50);
DispatchMessage.dispatchMsgToInterestArea(mob, ppm, DispatchChannel.SECONDARY, MBServerStatics.CHARACTER_LOAD_RANGE, false, false);
}
//if (mob.isSiege()) {
// PowerProjectileMsg ppm = new PowerProjectileMsg(mob, target);
// ppm.setRange(50);
// DispatchMessage.dispatchMsgToInterestArea(mob, ppm, DispatchChannel.SECONDARY, MBServerStatics.CHARACTER_LOAD_RANGE, false, false);
//}
} catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: AttackBuilding" + " " + e.getMessage());
@ -308,28 +334,32 @@ public class MobAI { @@ -308,28 +334,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();
@ -388,6 +418,9 @@ public class MobAI { @@ -388,6 +418,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)
@ -400,7 +433,7 @@ public class MobAI { @@ -400,7 +433,7 @@ public class MobAI {
PerformActionMsg msg;
if (!mobPower.isHarmful() || mobPower.targetSelf) {
if (!mob.StrongholdCommander && !mob.StrongholdEpic && (!mobPower.isHarmful() || mobPower.targetSelf)) {
PowersManager.useMobPower(mob, mob, mobPower, powerRank);
msg = PowersManager.createPowerMsg(mobPower, powerRank, mob, mob);
} else {
@ -411,9 +444,9 @@ public class MobAI { @@ -411,9 +444,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) {
@ -536,7 +569,6 @@ public class MobAI { @@ -536,7 +569,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) {
@ -588,6 +620,9 @@ public class MobAI { @@ -588,6 +620,9 @@ public class MobAI {
if (mob == null)
return;
if(mob.isAlive())
if(!mob.getMovementLoc().equals(Vector3fImmutable.ZERO))
mob.setLoc(mob.getMovementLoc());
if (mob.getTimestamps().containsKey("lastExecution") == false)
mob.getTimestamps().put("lastExecution", System.currentTimeMillis());
@ -625,9 +660,6 @@ public class MobAI { @@ -625,9 +660,6 @@ public class MobAI {
//check to send mob home for player guards to prevent exploit of dragging guards away and then teleporting
if (mob.BehaviourType.ordinal() != Enum.MobBehaviourType.Pet1.ordinal())
CheckToSendMobHome(mob);
return;
}
@ -646,7 +678,7 @@ public class MobAI { @@ -646,7 +678,7 @@ public class MobAI {
return;
}
if (mob.BehaviourType.ordinal() != Enum.MobBehaviourType.Pet1.ordinal())
if(mob.isPet() == false && mob.isPlayerGuard == false)
CheckToSendMobHome(mob);
if (mob.getCombatTarget() != null) {
@ -857,26 +889,31 @@ public class MobAI { @@ -857,26 +889,31 @@ public class MobAI {
return;
}
//No items in inventory.
} else if (aiAgent.isHasLoot()) {
if (System.currentTimeMillis() > aiAgent.deathTime + MBServerStatics.DESPAWN_TIMER_ONCE_LOOTED) {
aiAgent.despawn();
aiAgent.deathTime = System.currentTimeMillis();
return;
}
//Mob never had Loot.
} else {
//Mob's Loot has been looted.
if (aiAgent.isHasLoot()) {
if (System.currentTimeMillis() > aiAgent.deathTime + MBServerStatics.DESPAWN_TIMER_ONCE_LOOTED) {
aiAgent.despawn();
aiAgent.deathTime = System.currentTimeMillis();
return;
}
//Mob never had Loot.
} else {
if (System.currentTimeMillis() > aiAgent.deathTime + MBServerStatics.DESPAWN_TIMER) {
aiAgent.despawn();
aiAgent.deathTime = System.currentTimeMillis();
return;
}
}
return;
}
} else if (System.currentTimeMillis() > (aiAgent.deathTime + (aiAgent.spawnTime * 1000))) {
if (Zone.respawnQue.contains(aiAgent) == false) {
if(Mob.discDroppers.contains(aiAgent))
return;
if(aiAgent.StrongholdGuardian || aiAgent.StrongholdEpic || aiAgent.StrongholdCommander)
return;
if (aiAgent.despawned && System.currentTimeMillis() > (aiAgent.deathTime + (aiAgent.spawnTime * 1000L))) {
if (!Zone.respawnQue.contains(aiAgent)) {
Zone.respawnQue.add(aiAgent);
}
}
@ -896,8 +933,10 @@ public class MobAI { @@ -896,8 +933,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;
}
@ -911,7 +950,21 @@ public class MobAI { @@ -911,7 +950,21 @@ public class MobAI {
private static void CheckToSendMobHome(Mob mob) {
if(mob.isNecroPet())
return;
try {
//trebs dont recall
if(mob.isSiege())
return;
if(mob.BehaviourType.equals(Enum.MobBehaviourType.Pet1)){
if(mob.loc.distanceSquared(mob.getOwner().loc) > 60 * 60)
mob.teleport(mob.getOwner().loc);
return;
}
if (mob.BehaviourType.isAgressive) {
if (mob.isPlayerGuard()) {
@ -922,9 +975,6 @@ public class MobAI { @@ -922,9 +975,6 @@ public class MobAI {
}
}
if (mob.getCombatTarget() != null && CombatUtilities.inRange2D(mob, mob.getCombatTarget(), MobAIThread.AI_BASE_AGGRO_RANGE * 0.5f))
return;
if (mob.isPlayerGuard() && !mob.despawned) {
City current = ZoneManager.getCityAtLocation(mob.getLoc());
@ -934,7 +984,6 @@ public class MobAI { @@ -934,7 +984,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
@ -945,7 +994,7 @@ public class MobAI { @@ -945,7 +994,7 @@ public class MobAI {
}
}
}
} else if (MovementUtilities.inRangeOfBindLocation(mob) == false) {
} else if (!MovementUtilities.inRangeOfBindLocation(mob)) {
PowersBase recall = PowersManager.getPowerByToken(-1994153779);
PowersManager.useMobPower(mob, mob, recall, 40);
@ -953,6 +1002,7 @@ public class MobAI { @@ -953,6 +1002,7 @@ public class MobAI {
for (Entry playerEntry : mob.playerAgroMap.entrySet())
PlayerCharacter.getFromCache((int) playerEntry.getKey()).setHateValue(0);
mob.setCombatTarget(null);
}
} catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: CheckToSendMobHome" + " " + e.getMessage());
@ -963,6 +1013,11 @@ public class MobAI { @@ -963,6 +1013,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());
@ -1006,7 +1061,7 @@ public class MobAI { @@ -1006,7 +1061,7 @@ public class MobAI {
//dont scan self.
if (mob.equals(awoMob) || (mob.agentType.equals(Enum.AIAgentType.GUARD)) == true)
if (mob.equals(awoMob) || (mob.agentType.equals(Enum.AIAgentType.GUARD)) || (mob.agentType.equals(Enum.AIAgentType.PET)))
continue;
Mob aggroMob = (Mob) awoMob;
@ -1029,23 +1084,36 @@ public class MobAI { @@ -1029,23 +1084,36 @@ public class MobAI {
}
}
public static void checkToDropGuardAggro(Mob mob){
City city = mob.guardedCity;
if(city == null)
return;
if(mob.combatTarget == null)
return;
//if(city._playerMemory.contains(mob.combatTarget.getObjectUUID()) && mob.combatTarget.getObjectType().equals(Enum.GameObjectType.PlayerCharacter))
// mob.setCombatTarget(null);
}
public static void GuardCaptainLogic(Mob mob) {
try {
checkToDropGuardAggro(mob);
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) {
@ -1056,6 +1124,8 @@ public class MobAI { @@ -1056,6 +1124,8 @@ public class MobAI {
public static void GuardMinionLogic(Mob mob) {
try {
checkToDropGuardAggro(mob);
boolean isComanded = mob.npcOwner.isAlive();
if (!isComanded) {
GuardCaptainLogic(mob);
@ -1076,6 +1146,8 @@ public class MobAI { @@ -1076,6 +1146,8 @@ public class MobAI {
public static void GuardWallArcherLogic(Mob mob) {
try {
checkToDropGuardAggro(mob);
if (mob.getCombatTarget() == null)
CheckForPlayerGuardAggro(mob);
else
@ -1093,6 +1165,10 @@ public class MobAI { @@ -1093,6 +1165,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);
@ -1129,17 +1205,17 @@ public class MobAI { @@ -1129,17 +1205,17 @@ public class MobAI {
if (mob.BehaviourType.isAgressive) {
AbstractWorldObject newTarget = ChangeTargetFromHateValue(mob);
//AbstractWorldObject newTarget = ChangeTargetFromHateValue(mob);
if (newTarget != null)
mob.setCombatTarget(newTarget);
else {
//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
}
// }
}
}
@ -1153,6 +1229,7 @@ public class MobAI { @@ -1153,6 +1229,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());
}
@ -1351,21 +1428,31 @@ public class MobAI { @@ -1351,21 +1428,31 @@ public class MobAI {
return null;
}
public static void RecoverHealth(Mob mob){
public static void RecoverHealth(Mob mob) {
//recover health
try {
if (mob.getTimestamps().containsKey("HEALTHRECOVERED") == false)
mob.getTimestamps().put("HEALTHRECOVERED", System.currentTimeMillis());
if (mob.getTimestamps().containsKey("HEALTHRECOVERED") == false)
mob.getTimestamps().put("HEALTHRECOVERED", System.currentTimeMillis());
if (mob.isSit() && mob.getTimeStamp("HEALTHRECOVERED") < System.currentTimeMillis() + 3000)
if (mob.getHealth() < mob.getHealthMax()) {
if (mob.isSit() && mob.getTimeStamp("HEALTHRECOVERED") < System.currentTimeMillis() + 3000)
if (mob.getHealth() < mob.getHealthMax()) {
float recoveredHealth = mob.getHealthMax() * ((1 + mob.getBonuses().getFloatPercentAll(Enum.ModType.HealthRecoverRate, Enum.SourceType.None)) * 0.01f);
mob.setHealth(mob.getHealth() + recoveredHealth);
mob.getTimestamps().put("HEALTHRECOVERED", System.currentTimeMillis());
float recoveredHealth = mob.getHealthMax() * ((1 + mob.getBonuses().getFloatPercentAll(Enum.ModType.HealthRecoverRate, Enum.SourceType.None)) * 0.01f);
mob.setHealth(mob.getHealth() + recoveredHealth);
mob.getTimestamps().put("HEALTHRECOVERED", System.currentTimeMillis());
if (mob.getHealth() > mob.getHealthMax())
mob.setHealth(mob.getHealthMax());
}
} catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: RecoverHealth" + " " + e.getMessage());
}
}
if (mob.getHealth() > mob.getHealthMax())
mob.setHealth(mob.getHealthMax());
}
public static void enterCombat(Mob mob){
mob.setCombat(true);
UpdateStateMsg rwss = new UpdateStateMsg();
rwss.setPlayer(mob);
DispatchMessage.sendToAllInRange(mob, rwss);
}
}

26
src/engine/mobileAI/Threads/MobAIThread.java

@ -28,18 +28,26 @@ public class MobAIThread implements Runnable{ @@ -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() {

50
src/engine/mobileAI/Threads/MobRespawnThread.java

@ -13,6 +13,9 @@ import engine.objects.Mob; @@ -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; @@ -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()) {
if (zone.respawnQue.isEmpty() == false && zone.lastRespawn + 100 < System.currentTimeMillis()) {
Mob respawner = zone.respawnQue.iterator().next();
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 (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();
}

175
src/engine/mobileAI/utilities/CombatUtilities.java

@ -101,9 +101,10 @@ public class CombatUtilities { @@ -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.
@ -139,37 +140,30 @@ public class CombatUtilities { @@ -139,37 +140,30 @@ public class CombatUtilities {
}
public static boolean triggerDefense(Mob agent, AbstractWorldObject target) {
int defenseScore = 0;
int attackScore = agent.getAtrHandOne();
int defense = 0;
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:
defenseScore = ((AbstractCharacter) target).getDefenseRating();
PlayerCharacter pc = (PlayerCharacter)target;
pc.combatStats.calculateDefense();
defense = pc.combatStats.defense;
break;
case Mob:
Mob mob = (Mob) target;
if (mob.isSiege())
defenseScore = attackScore;
defense = atr;
else
defense = ((Mob) target).mobBase.getDefense();
break;
case Building:
return false;
}
int hitChance;
if (attackScore > defenseScore || defenseScore == 0)
hitChance = 94;
else if (attackScore == defenseScore && target.getObjectType() == GameObjectType.Mob)
hitChance = 10;
else {
float dif = attackScore / defenseScore;
if (dif <= 0.8f)
hitChance = 4;
else
hitChance = ((int) (450 * (dif - 0.8f)) + 4);
if (target.getObjectType() == GameObjectType.Building)
hitChance = 100;
}
return ThreadLocalRandom.current().nextInt(100) > hitChance;
return !CombatManager.LandHit(atr,defense);
}
public static boolean triggerBlock(Mob agent, AbstractWorldObject ac) {
@ -207,12 +201,10 @@ public class CombatUtilities { @@ -207,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;
@ -267,12 +259,12 @@ public class CombatUtilities { @@ -267,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);
@ -294,11 +286,6 @@ public class CombatUtilities { @@ -294,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())
@ -322,9 +309,9 @@ public class CombatUtilities { @@ -322,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) {
@ -333,9 +320,9 @@ public class CombatUtilities { @@ -333,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) {
@ -364,8 +351,8 @@ public class CombatUtilities { @@ -364,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;
@ -381,8 +368,8 @@ public class CombatUtilities { @@ -381,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();
@ -423,92 +410,48 @@ public class CombatUtilities { @@ -423,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));
}
}

12
src/engine/mobileAI/utilities/MovementUtilities.java

@ -98,20 +98,24 @@ public class MovementUtilities { @@ -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);
}

2
src/engine/net/AbstractConnection.java

@ -38,7 +38,7 @@ public abstract class AbstractConnection implements @@ -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<>();

5
src/engine/net/AbstractConnectionManager.java

@ -87,6 +87,7 @@ public abstract class AbstractConnectionManager extends ControlledRunnable { @@ -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 { @@ -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 { @@ -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);

2
src/engine/net/CheckNetMsgFactoryJob.java

@ -23,7 +23,7 @@ public class CheckNetMsgFactoryJob extends AbstractJob { @@ -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

2
src/engine/net/ConnectionMonitorJob.java

@ -26,7 +26,7 @@ public class ConnectionMonitorJob extends AbstractJob { @@ -26,7 +26,7 @@ public class ConnectionMonitorJob extends AbstractJob {
}
@Override
protected void doJob() {
public void doJob() {
if (this.cnt >= 5) {
this.connMan.auditSocketChannelToConnectionMap();

8
src/engine/net/NetMsgFactory.java

@ -13,6 +13,8 @@ import engine.exception.FactoryBuildException; @@ -13,6 +13,8 @@ import engine.exception.FactoryBuildException;
import engine.gameManager.ChatManager;
import engine.net.client.ClientConnection;
import engine.net.client.Protocol;
import engine.net.client.msg.ErrorPopupMsg;
import engine.net.client.msg.PlaceAssetMsg;
import engine.objects.PlayerCharacter;
import engine.server.MBServerStatics;
import org.joda.time.DateTime;
@ -94,11 +96,9 @@ public class NetMsgFactory { @@ -94,11 +96,9 @@ public class NetMsgFactory {
if (origin instanceof ClientConnection) {
PlayerCharacter player = ((ClientConnection) origin).getPlayerCharacter();
if (player != null) {
// if (MBServerStatics.worldServerName.equals("Grief"))
Logger.error("Invalid protocol msg for player " + player.getFirstName() + " : " + opcode + " lastopcode: " + origin.lastProtocol.name() + " Error Code : " + errorCode);
} else
Logger.error("Invalid protocol msg : " + opcode + " lastopcode: " + origin.lastProtocol.name() + " Error Code : " + errorCode);
PlaceAssetMsg.sendPlaceAssetError(player.getClientConnection(), 1, "Please Report What You Just Did. Ref Code: " + opcode);
}
}
return null;

15
src/engine/net/client/ClientConnection.java

@ -44,9 +44,16 @@ public class ClientConnection extends AbstractConnection { @@ -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 { @@ -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);
}
}

228
src/engine/net/client/ClientMessagePump.java

@ -29,6 +29,7 @@ import engine.objects.*; @@ -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;
@ -85,7 +86,7 @@ public class ClientMessagePump implements NetMsgHandler { @@ -85,7 +86,7 @@ public class ClientMessagePump implements NetMsgHandler {
if (pc == null)
return;
pc.update();
pc.update(false);
if (msg.getSpeed() == 2)
pc.setWalkMode(false);
else
@ -114,7 +115,7 @@ public class ClientMessagePump implements NetMsgHandler { @@ -114,7 +115,7 @@ public class ClientMessagePump implements NetMsgHandler {
if (pc == null)
return;
pc.update();
pc.update(false);
pc.setSit(msg.toggleSitStand());
@ -238,6 +239,11 @@ public class ClientMessagePump implements NetMsgHandler { @@ -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;
@ -560,12 +566,30 @@ public class ClientMessagePump implements NetMsgHandler { @@ -560,12 +566,30 @@ public class ClientMessagePump implements NetMsgHandler {
if (!itemManager.inventoryContains(i))
return;
if (i.isCanDestroy())
if (itemManager.delete(i) == true) {
//cannot delete gold
if(i.getItemBaseID() == 7)
return;
if (i.isCanDestroy()) {
int goldValue = i.getBaseValue();
if (i.getItemBase().isRune())
goldValue = 500000;
if (i.getItemBaseID() == 980066)
goldValue = 0;
if(itemManager.getGoldInventory().getNumOfItems() + goldValue > 10000000)
return;
if (itemManager.delete(i)) {
if (goldValue > 0)
itemManager.addGoldToInventory(goldValue, false);
itemManager.updateInventory();
Dispatch dispatch = Dispatch.borrow(sourcePlayer, msg);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
}
}
}
private static void ackBankWindowOpened(AckBankWindowOpenedMsg msg, ClientConnection origin) {
@ -654,6 +678,8 @@ public class ClientMessagePump implements NetMsgHandler { @@ -654,6 +678,8 @@ public class ClientMessagePump implements NetMsgHandler {
JobScheduler.getInstance().scheduleJob(new RefreshGroupJob(sourcePlayer), MBServerStatics.LOAD_OBJECT_DELAY);
}
private static void lootWindowRequest(LootWindowRequestMsg msg, ClientConnection origin) throws MsgSendException {
PlayerCharacter pc = SessionManager.getPlayerCharacter(origin);
@ -1243,6 +1269,8 @@ public class ClientMessagePump implements NetMsgHandler { @@ -1243,6 +1269,8 @@ public class ClientMessagePump implements NetMsgHandler {
cost = sell.getBaseValue();
if(sell.getItemBaseID() == 980066)
cost = 0;
//apply damaged value reduction
float durabilityCurrent = sell.getDurabilityCurrent();
@ -1347,6 +1375,8 @@ public class ClientMessagePump implements NetMsgHandler { @@ -1347,6 +1375,8 @@ public class ClientMessagePump implements NetMsgHandler {
return;
// test within talking range
if(npc.isInSafeZone())
npc.sellPercent = 0;
if (sourcePlayer.getLoc().distanceSquared2D(npc.getLoc()) > MBServerStatics.NPC_TALK_RANGE * MBServerStatics.NPC_TALK_RANGE) {
ErrorPopupMsg.sendErrorPopup(sourcePlayer, 14);
@ -1358,219 +1388,192 @@ public class ClientMessagePump implements NetMsgHandler { @@ -1358,219 +1388,192 @@ public class ClientMessagePump implements NetMsgHandler {
}
private static void buyFromNPC(BuyFromNPCMsg msg, ClientConnection origin) {
PlayerCharacter sourcePlayer = SessionManager.getPlayerCharacter(origin);
if (sourcePlayer == null)
return;
if (origin.buyLock.tryLock()) {
try {
CharacterItemManager itemMan = sourcePlayer.getCharItemManager();
if (itemMan == null)
if (itemMan == null) {
return;
}
NPC npc = NPC.getFromCache(msg.getNPCID());
if (npc == null)
if (npc == null) {
return;
}
Item gold = itemMan.getGoldInventory();
if (gold == null)
if (gold == null) {
return;
}
Item buy = null;
if (msg.getItemType() == GameObjectType.MobEquipment.ordinal()) {
ArrayList<MobEquipment> sellInventory = npc.getContract().getSellInventory();
if (sellInventory == null)
//if(npc.contract.getObjectUUID() == 890){ // default steward
// sellInventory = npc.getSellInventorySteward();
//}
//if(npc.contract.getObjectUUID() == 889){ // default builder
// sellInventory = npc.getSellInventoryBuilder();
//}
if (sellInventory == null) {
return;
}
for (MobEquipment me : sellInventory) {
if (me.getObjectUUID() == msg.getItemID()) {
ItemBase ib = me.getItemBase();
if (ib == null)
if (ib == null) {
return;
}
//test room available for item
if (!itemMan.hasRoomInventory(ib.getWeight()))
if (!itemMan.hasRoomInventory(ib.getWeight())) {
return;
}
int cost = me.getMagicValue();
float bargain = sourcePlayer.getBargain();
switch(npc.getContractID()){
case 1201:
cost = ItemBase.getDiscPrice(ib.getUUID());
bargain = 0;
break;
case 1202:
cost = ItemBase.getStatPrice(ib.getUUID());
bargain = 0;
break;
case 900:
cost = Warehouse.getCostForResource(ib.getUUID()) * Warehouse.getSellStackSize(ib.getUUID());
bargain = 0;
break;
}
float profit;
float profit = npc.getSellPercent(sourcePlayer) - bargain;
if (profit < 1)
profit = 1;
if(npc.isInSafeZone())
profit = 0;
else
profit = npc.getSellPercent(sourcePlayer) - bargain;
cost *= profit;
if(profit > 0)
cost *= profit;
if (gold.getNumOfItems() - cost < 0) {
//dont' have enough goldItem exit!
// chatMan.chatSystemInfo(pc, "" + "You dont have enough gold.");
return;
}
Building b = (!npc.isStatic()) ? npc.getBuilding() : null;
if (b != null && b.getProtectionState().equals(ProtectionState.NPC))
b = null;
int buildingDeposit = cost - me.getMagicValue();
if (b != null && (b.getStrongboxValue() + buildingDeposit) > b.getMaxGold()) {
if (b != null && (b.getStrongboxValue() + buildingDeposit) > b.getMaxGold() && !b.isOwnerIsNPC()) {
ErrorPopupMsg.sendErrorPopup(sourcePlayer, 206);
return;
}
if (!itemMan.buyFromNPC(b, cost, buildingDeposit)) {
}if(npc.getContractID() == 1502041){
me.fromNoob = true;
} else if (!itemMan.buyFromNPC(b, cost, buildingDeposit)) {
// chatMan.chatSystemInfo(pc, "" + "You Failed to buy the item.");
ChatManager.chatSystemError(sourcePlayer, "Failed To Buy Item");
return;
}
buy = Item.createItemForPlayer(sourcePlayer, ib);
if (buy != null) {
me.transferEnchants(buy);
itemMan.addItemToInventory(buy);
//itemMan.updateInventory();
if(me.getItemBase().getType().equals(ItemType.RESOURCE) && npc.getContractID() == 900){
handleResourcePurchase(me,itemMan,sourcePlayer,ib);
}else {
buy = Item.createItemForPlayer(sourcePlayer, ib, me.fromNoob);
if (buy != null) {
me.transferEnchants(buy);
itemMan.addItemToInventory(buy);
if(npc.contractUUID == 900 && buy.getItemBaseID() == 1705032){
buy.setNumOfItems(10);
DbManager.ItemQueries.UPDATE_NUM_ITEMS(buy,buy.getNumOfItems());
}
//itemMan.updateInventory();
}
}
}
}
} else if (msg.getItemType() == GameObjectType.Item.ordinal()) {
CharacterItemManager npcCim = npc.getCharItemManager();
if (npcCim == null)
return;
buy = Item.getFromCache(msg.getItemID());
if (buy == null)
return;
ItemBase ib = buy.getItemBase();
if (ib == null)
return;
if (!npcCim.inventoryContains(buy))
return;
//test room available for item
if (!itemMan.hasRoomInventory(ib.getWeight()))
return;
//TODO test cost and subtract goldItem
//TODO CHnage this if we ever put NPc city npcs in buildings.
int cost = buy.getBaseValue();
if (buy.isID() || buy.isCustomValue())
cost = buy.getMagicValue();
float bargain = sourcePlayer.getBargain();
float profit = npc.getSellPercent(sourcePlayer) - bargain;
if (profit < 1)
profit = 1;
if (!buy.isCustomValue())
cost *= profit;
else
cost = buy.getValue();
if (gold.getNumOfItems() - cost < 0) {
ErrorPopupMsg.sendErrorPopup(sourcePlayer, 128); // Insufficient Gold
return;
}
Building b = (!npc.isStatic()) ? npc.getBuilding() : null;
if (b != null)
if (b.getProtectionState().equals(ProtectionState.NPC))
b = null;
int buildingDeposit = cost;
if (b != null && (b.getStrongboxValue() + buildingDeposit) > b.getMaxGold()) {
if (b != null && (b.getStrongboxValue() + buildingDeposit) > b.getMaxGold() && !b.isOwnerIsNPC()) {
ErrorPopupMsg.sendErrorPopup(sourcePlayer, 206);
return;
}
if (!itemMan.buyFromNPC(b, cost, buildingDeposit)) {
ErrorPopupMsg.sendErrorPopup(sourcePlayer, 110);
return;
}
if (buy != null)
itemMan.buyFromNPC(buy, npc);
} else if (msg.getItemType() == GameObjectType.MobLoot.ordinal()) {
CharacterItemManager npcCim = npc.getCharItemManager();
if (npcCim == null)
return;
buy = MobLoot.getFromCache(msg.getItemID());
if (buy == null)
return;
ItemBase ib = buy.getItemBase();
if (ib == null)
return;
if (!npcCim.inventoryContains(buy))
return;
//test room available for item
if (!itemMan.hasRoomInventory(ib.getWeight()))
return;
//TODO test cost and subtract goldItem
//TODO CHnage this if we ever put NPc city npcs in buildings.
int cost = buy.getMagicValue();
cost *= npc.getSellPercent(sourcePlayer);
if (gold.getNumOfItems() - cost < 0) {
ErrorPopupMsg.sendErrorPopup(sourcePlayer, 128); // Insufficient Gold
return;
}
Building b = (!npc.isStatic()) ? npc.getBuilding() : null;
if (b != null && b.getProtectionState().equals(ProtectionState.NPC))
b = null;
int buildingDeposit = cost;
if (b != null && (b.getStrongboxValue() + buildingDeposit) > b.getMaxGold()) {
if (b != null && (b.getStrongboxValue() + buildingDeposit) > b.getMaxGold() && !b.isOwnerIsNPC()) {
ErrorPopupMsg.sendErrorPopup(sourcePlayer, 206);
return;
}
if (!itemMan.buyFromNPC(b, cost, buildingDeposit))
return;
if (buy != null)
itemMan.buyFromNPC(buy, npc);
} else
return;
if (buy != null) {
msg.setItem(buy);
//send the buy message back to update player
// msg.setItemType(buy.getObjectType().ordinal());
@ -1579,14 +1582,43 @@ public class ClientMessagePump implements NetMsgHandler { @@ -1579,14 +1582,43 @@ public class ClientMessagePump implements NetMsgHandler {
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
itemMan.updateInventory();
}
} finally {
origin.buyLock.unlock();
}
} else {
ErrorPopupMsg.sendErrorPopup(origin.getPlayerCharacter(), 12); // All production slots taken
}
}
public static void handleResourcePurchase(MobEquipment me, CharacterItemManager itemMan, PlayerCharacter sourcePlayer, ItemBase ib){
boolean stacked = false;
int buystack = Warehouse.getSellStackSize(me.getItemBase().getUUID());
for(Item item : itemMan.getInventory()){
int itemID = item.getItemBaseID();
int meID = me.getItemBase().getUUID();
if(itemID == meID){
if(Warehouse.maxResources.isEmpty())
Warehouse.getMaxResources();
int maxStack = Warehouse.maxResources.get(itemID);
if(maxStack > item.getNumOfItems() + buystack){
item.setNumOfItems(item.getNumOfItems() + buystack);
stacked = true;
itemMan.updateInventory();
DbManager.ItemQueries.UPDATE_NUM_ITEMS(item,item.getNumOfItems());
break;
}
}
}
if(!stacked){
Item buy = Item.createItemForPlayer(sourcePlayer, ib, false);
if (buy != null) {
me.transferEnchants(buy);
itemMan.addItemToInventory(buy);
buy.setNumOfItems(buystack);
DbManager.ItemQueries.UPDATE_NUM_ITEMS(buy,buy.getNumOfItems());
}
}
itemMan.updateInventory();
}
private static void Repair(RepairMsg msg, ClientConnection origin) {
@ -1646,14 +1678,21 @@ public class ClientMessagePump implements NetMsgHandler { @@ -1646,14 +1678,21 @@ public class ClientMessagePump implements NetMsgHandler {
max *= (1 + (durMod * 0.01f));
if (dur >= max || dur < 1) {
//redundancy message to clear item from window in client
if (!DbManager.ItemQueries.SET_DURABILITY(toRepair, dur))
return;
toRepair.setDurabilityCurrent(max);
msg.setupRepairAck(max - dur);
dispatch = Dispatch.borrow(player, msg);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
return;
}
//TODO get cost to repair
int cost = (int) ((max - dur) * 80.1);
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)
@ -1847,6 +1886,7 @@ public class ClientMessagePump implements NetMsgHandler { @@ -1847,6 +1886,7 @@ public class ClientMessagePump implements NetMsgHandler {
switch (protocolMsg) {
case SETSELECTEDOBECT:
KeyCloneAudit.auditTargetMsg(msg);
ClientMessagePump.targetObject((TargetObjectMsg) msg, origin);
break;

2
src/engine/net/client/handlers/ActivateNPCMsgHandler.java

@ -78,7 +78,7 @@ public class ActivateNPCMsgHandler extends AbstractClientMsgHandler { @@ -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());

15
src/engine/net/client/handlers/ArcMineChangeProductionMsgHandler.java

@ -11,6 +11,7 @@ import engine.objects.GuildStatusController; @@ -11,6 +11,7 @@ import engine.objects.GuildStatusController;
import engine.objects.Mine;
import engine.objects.PlayerCharacter;
import engine.objects.Resource;
import org.pmw.tinylog.Logger;
/*
* @Author:
@ -35,26 +36,28 @@ public class ArcMineChangeProductionMsgHandler extends AbstractClientMsgHandler @@ -35,26 +36,28 @@ public class ArcMineChangeProductionMsgHandler extends AbstractClientMsgHandler
//TODO verify this against the warehouse?
if (GuildStatusController.isInnerCouncil(playerCharacter.getGuildStatus()) == false) // is this only GL?
if (!GuildStatusController.isInnerCouncil(playerCharacter.getGuildStatus())) // is this only GL?
return true;
Mine mine = Mine.getMine(changeProductionMsg.getMineID());
if (mine == null)
if (mine == null) {
Logger.error("Player Character: " + playerCharacter.getName() + " Tried To Change Mine: " + changeProductionMsg.getMineID() + " and Mine was Null");
return true;
}
//make sure mine belongs to guild
if (mine.getOwningGuild().isEmptyGuild() ||
mine.getOwningGuild().getObjectUUID() != playerCharacter.getGuild().getObjectUUID())
if (mine.getOwningGuild().isEmptyGuild() || mine.getOwningGuild().getObjectUUID() != playerCharacter.getGuild().getObjectUUID())
return true;
//make sure valid resource
Resource resource = Resource.resourceByHash.get(changeProductionMsg.getResourceHash());
if (resource == null)
if (resource == null) {
Logger.error("Player Character: " + playerCharacter.getName() + " Tried To Change Mine: " + changeProductionMsg.getMineID() + " and Resource was Null");
return true;
}
//update resource

15
src/engine/net/client/handlers/ChangeAltitudeHandler.java

@ -9,6 +9,7 @@ @@ -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,18 +43,24 @@ public class ChangeAltitudeHandler extends AbstractClientMsgHandler { @@ -42,18 +43,24 @@ 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())
return false;
// Find out if we already have an altitude timer running and if so
// do not process more alt change requests
pc.updateFlight();
if (pc.getTakeOffTime() != 0)
return false;
pc.setTakeOffTime(System.currentTimeMillis());
// remove all movement timers and jobs
//TODO: test if they can fly
@ -67,7 +74,7 @@ public class ChangeAltitudeHandler extends AbstractClientMsgHandler { @@ -67,7 +74,7 @@ public class ChangeAltitudeHandler extends AbstractClientMsgHandler {
if (pc.getAltitude() == 0 && !msg.up())
return true;
pc.update();
pc.update(false);
pc.stopMovement(pc.getLoc());
msg.setStartAlt(pc.getAltitude());
if (msg.up()) {
@ -132,7 +139,7 @@ public class ChangeAltitudeHandler extends AbstractClientMsgHandler { @@ -132,7 +139,7 @@ public class ChangeAltitudeHandler extends AbstractClientMsgHandler {
}
if (msg.up()) {
pc.update();
pc.update(false);
pc.setDesiredAltitude(targetAlt);
pc.setTakeOffTime(System.currentTimeMillis());
} else {
@ -158,7 +165,7 @@ public class ChangeAltitudeHandler extends AbstractClientMsgHandler { @@ -158,7 +165,7 @@ public class ChangeAltitudeHandler extends AbstractClientMsgHandler {
} else
pc.setDesiredAltitude(targetAlt);
pc.update();
pc.update(false);
pc.setTakeOffTime(System.currentTimeMillis());

2
src/engine/net/client/handlers/CityDataHandler.java

@ -63,7 +63,7 @@ public class CityDataHandler extends AbstractClientMsgHandler { @@ -63,7 +63,7 @@ public class CityDataHandler extends AbstractClientMsgHandler {
// If the hotZone has changed then update the client's map accordingly.
if (playerCharacter.getTimeStamp("hotzoneupdate") <= ZoneManager.hotZoneLastUpdate.toEpochMilli() && ZoneManager.hotZone != null) {
if (playerCharacter.getTimestamps().containsKey("hotzoneupdate") && playerCharacter.getTimeStamp("hotzoneupdate") <= ZoneManager.hotZoneLastUpdate.toEpochMilli() && ZoneManager.hotZone != null) {
HotzoneChangeMsg hotzoneChangeMsg = new HotzoneChangeMsg(Enum.GameObjectType.Zone.ordinal(), ZoneManager.hotZone.getObjectUUID());
dispatch = Dispatch.borrow(playerCharacter, hotzoneChangeMsg);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);

2
src/engine/net/client/handlers/DestroyBuildingHandler.java

@ -62,7 +62,7 @@ public class DestroyBuildingHandler extends AbstractClientMsgHandler { @@ -62,7 +62,7 @@ public class DestroyBuildingHandler extends AbstractClientMsgHandler {
if (city != null)
bane = city.getBane();
if (bane != null && bane.getSiegePhase() == Enum.SiegePhase.WAR) {
if (bane != null){// && bane.getSiegePhase() == Enum.SiegePhase.WAR) {
ErrorPopupMsg.sendErrorPopup(pc, 171);
return true;
}

2
src/engine/net/client/handlers/GroupInviteResponseHandler.java

@ -102,7 +102,7 @@ public class GroupInviteResponseHandler extends AbstractClientMsgHandler { @@ -102,7 +102,7 @@ public class GroupInviteResponseHandler extends AbstractClientMsgHandler {
// Run Keyclone Audit
KEYCLONEAUDIT.audit(player, group);
//KEYCLONEAUDIT.audit(player, group);
return true;
}

2
src/engine/net/client/handlers/HirelingServiceMsgHandler.java

@ -61,7 +61,7 @@ public class HirelingServiceMsgHandler extends AbstractClientMsgHandler { @@ -61,7 +61,7 @@ public class HirelingServiceMsgHandler extends AbstractClientMsgHandler {
return true;
npc.setRepairCost(msg.repairCost);
npc.setSpecialPrice(msg.repairCost);
ManageNPCMsg outMsg = new ManageNPCMsg(npc);
Dispatch dispatch = Dispatch.borrow(player, msg);

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

Loading…
Cancel
Save