Compare commits

...

1163 Commits

Author SHA1 Message Date
FatBoy-DOTC a97734bac0 fix charge bug 2 weeks ago
FatBoy-DOTC 9caeb80ccc replace rune with wrapped rune 2 weeks ago
FatBoy-DOTC 0e3e334cc1 replace rune with wrapped rune 2 weeks ago
FatBoy-DOTC 536d35bb49 hotzone work 2 weeks ago
FatBoy-DOTC f57f300716 hotzone work 2 weeks ago
FatBoy-DOTC 62ab1b9fb2 hotzone work 2 weeks ago
FatBoy-DOTC 6b846cba0f proper order of operations for assinging hotzone 2 weeks ago
FatBoy-DOTC 7b8831ebdd lore mine charter type declaration 2 weeks ago
FatBoy-DOTC 6b92225a5f enable r8 hotzone 2 weeks ago
FatBoy-DOTC bbdc58c217 enable r8 hotzone 2 weeks ago
FatBoy-DOTC 537a30710a perpetual movement machine fixed 2 weeks ago
FatBoy-DOTC 5626255b12 mob clear effects on death 2 weeks ago
FatBoy-DOTC ea8a7c0e39 mob clear effects on death 2 weeks ago
FatBoy-DOTC f7f5aa59a0 mob clear effects on death 2 weeks ago
FatBoy-DOTC b2038e201c player location sync 2 weeks ago
FatBoy-DOTC dbe748bcdd update location 2 weeks ago
FatBoy-DOTC 165e721eb8 update location 2 weeks ago
FatBoy-DOTC f7f306855a disable refresh loaded objects 2 weeks ago
FatBoy-DOTC 6a54767a53 mele sync update 2 weeks ago
FatBoy-DOTC 9b8de72a6f disable lore flag for mines 2 weeks ago
FatBoy-DOTC 1a0ad765bf rnaodm flag mine as lore or arac 2 weeks ago
FatBoy-DOTC 69c74240da rnaodm flag mine as lore or arac 2 weeks ago
FatBoy-DOTC fe498e9b20 show lore or arac on mine info 2 weeks ago
FatBoy-DOTC ee7e16c32e LoreEnfce bool for lore mine manager run 2 weeks ago
FatBoy-DOTC 7820ff06c9 additional pet health modifiers 2 weeks ago
FatBoy-DOTC 41713a9412 Lore Enforced Mines System 2 weeks ago
FatBoy-DOTC e03dc8d8be fix castable enchant duration counter 2 weeks ago
FatBoy-DOTC 8c2ddd266d show macrozone name and camp name when dropping runes 2 weeks ago
FatBoy-DOTC a290e3659e fix for mele zerg multiplier values 2 weeks ago
FatBoy-DOTC 676f0e7023 calculate damage BEFORE modifyHealth is called in CombatManager 2 weeks ago
FatBoy-DOTC 1fda6cc80d interest management 2 weeks ago
FatBoy-DOTC 04a2d6fb1c interest management 2 weeks ago
FatBoy-DOTC 7eb6535051 interest management 2 weeks ago
FatBoy-DOTC b4b3b0ae17 interest management 2 weeks ago
FatBoy-DOTC 2681671543 interest management 2 weeks ago
FatBoy-DOTC 50bf375006 update loaded players on screen 2 weeks ago
FatBoy-DOTC 9fa3c9d7aa order of update operations 2 weeks ago
FatBoy-DOTC dbf681b065 box flag effect finished 2 weeks ago
FatBoy-DOTC 3fdc299210 box flag effect 2 weeks ago
FatBoy-DOTC 7bf4f0627e player update bug 2 weeks ago
FatBoy-DOTC 47f39fd963 player update bug 2 weeks ago
FatBoy-DOTC a92a67579a player update bug 2 weeks ago
FatBoy-DOTC 6dfac2d604 orintstats to show boxed status 2 weeks ago
FatBoy-DOTC de1e8eed98 rollback visual BOXED indicator 2 weeks ago
FatBoy-DOTC 0ec2add724 disable hotzone system 2 weeks ago
FatBoy-DOTC 87675bb950 HZ related stuff 2 weeks ago
FatBoy-DOTC 873e56f076 HZ related stuff 2 weeks ago
FatBoy-DOTC 01b59cce99 HZ related stuff 2 weeks ago
FatBoy-DOTC 8c9696a3f9 HZ related stuff 2 weeks ago
FatBoy-DOTC 128f677d0e HZ related stuff 2 weeks ago
FatBoy-DOTC a7b9fec032 HZ related stuff 2 weeks ago
FatBoy-DOTC d25109fcf6 return summon recycle timer when declined 2 weeks ago
FatBoy-DOTC 9283181a14 r8 hotzones loot manager 2 weeks ago
FatBoy-DOTC 8dd4953023 r8 hotzones 2 weeks ago
FatBoy-DOTC 5ba476e5a5 new box flag system 2 weeks ago
FatBoy-DOTC 0f402ac0cc new box flag system 2 weeks ago
FatBoy-DOTC 9032565220 stop invisible player plague 2 weeks ago
FatBoy-DOTC 8194bd8ef2 stop invisible player plague 2 weeks ago
FatBoy-DOTC 78911a0a21 stop invisible player plague 2 weeks ago
FatBoy-DOTC d96a2a8d25 stop invisible player plague 2 weeks ago
FatBoy-DOTC 76c637e733 stop invisible player plague 2 weeks ago
FatBoy-DOTC 0331fc88af add 5 units to cast range server side for desync 2 weeks ago
FatBoy-DOTC 03f6ee6c70 commented ready for 5 man weekends 2 weeks ago
FatBoy-DOTC 97d5a19e91 building gold cap increased to 100 million 2 weeks ago
FatBoy-DOTC 6d064636a5 mob refresh disabled 2 weeks ago
FatBoy-DOTC d67bf0bc64 guards hotfix 2 weeks ago
FatBoy-DOTC 199215f2e6 decrease player update tick form 1000MS to 100MS 2 weeks ago
FatBoy-DOTC 602b16457f finish checks for increased player inventory gold limits 2 weeks ago
FatBoy-DOTC 7c67e15d40 only delete runes in safezone 2 weeks ago
FatBoy-DOTC 2d69e335e0 hotifx + gold cap increase 2 weeks ago
FatBoy-DOTC afeb4f59bd disable hellgates for production 2 weeks ago
FatBoy-DOTC dd2707f6fb attempted invis character sync fix 2 weeks ago
FatBoy-DOTC 49ce99fd58 special hellgate mob AI distance 3 weeks ago
FatBoy-DOTC 65e306c3cb 5 second player reload intervals 3 weeks ago
FatBoy-DOTC 86db21de43 hellgates revised 3 weeks ago
FatBoy-DOTC 1f897a3cb8 hellgates revised 3 weeks ago
FatBoy-DOTC 47c47bb61b hellgates revised 3 weeks ago
FatBoy-DOTC f62794f8ab hellgates revised 3 weeks ago
FatBoy-DOTC e9d9f50c9e hellgates maybe? round 7 3 weeks ago
FatBoy-DOTC e3ec9ac56f hellgates maybe? round 7 3 weeks ago
FatBoy-DOTC 2612a7f074 hellgates maybe? round 6 3 weeks ago
FatBoy-DOTC e71ca71b30 hellgates maybe? round 5 3 weeks ago
FatBoy-DOTC 6db31794fc hellgates maybe? round 5 3 weeks ago
FatBoy-DOTC b06d854182 hellgates maybe? round 4 3 weeks ago
FatBoy-DOTC 6080bae50d hellgates maybe? round 3 3 weeks ago
FatBoy-DOTC 49c956d2bf hellgates maybe? round 2 3 weeks ago
FatBoy-DOTC 49ca340b36 hellgates maybe? 3 weeks ago
FatBoy-DOTC 43072786b1 null city bug 3 weeks ago
FatBoy-DOTC aba82616df /zerg command 3 weeks ago
FatBoy-DOTC 78f95d0173 /zerg command 3 weeks ago
FatBoy-DOTC 2a7fd87686 add mob adding stronghold mobs 3 weeks ago
FatBoy-DOTC 9078a41c58 add mob adding stronghold mobs 3 weeks ago
FatBoy-DOTC 2a0e780306 add mob adding stronghold mobs 3 weeks ago
FatBoy-DOTC 77a73e9171 mine teleportation disabled for 5 minutes after window closes 3 weeks ago
FatBoy-DOTC 8a4db1b1de items looted from corpses lose castable enchants 3 weeks ago
FatBoy-DOTC a5186265e2 use of proper stack ranks 3 weeks ago
FatBoy-DOTC b7e4f309e8 hotfix for location sync 3 weeks ago
FatBoy-DOTC a7d01cc461 disable DB write for cheaters 3 weeks ago
FatBoy-DOTC 28ca527aca debuff priest 100% at 3 man mines 3 weeks ago
FatBoy-DOTC 9277ddd8ef mob AI work 3 weeks ago
FatBoy-DOTC 16df24ea27 remove name form PVE title 3 weeks ago
FatBoy-DOTC e6f92d105d remove name form PVE title 3 weeks ago
FatBoy-DOTC 887501c040 allow pve mode toons to cast summon 3 weeks ago
FatBoy-DOTC 35ab20701c increase mine production 3 weeks ago
FatBoy-DOTC 617cad69e1 increase mine production 3 weeks ago
FatBoy-DOTC 4268d39d17 strip hones and procs when buying or taking from NPC inventory 3 weeks ago
FatBoy-DOTC 3561564f8c fix location desync caused by power casting 3 weeks ago
FatBoy-DOTC f4361113ed properly configure hitbox radius 3 weeks ago
FatBoy-DOTC 32563e3f5f mele / player location sync 3 weeks ago
FatBoy-DOTC 011ceea598 fix rolling bug 3 weeks ago
FatBoy-DOTC eaeb2eb943 forge manager cleanup and special drop rates 3 weeks ago
FatBoy-DOTC 3b1bb803a8 properly calibrated drop rates 3 weeks ago
FatBoy-DOTC acb111a114 mob retaliate 3 weeks ago
FatBoy-DOTC aaa737649e atr check failure 3 weeks ago
FatBoy-DOTC 67653febd5 weapon enchants used as self buff 3 weeks ago
FatBoy-DOTC 7227a5c860 weapon enchants used as self buff 3 weeks ago
FatBoy-DOTC b15c335b42 spell atr bug 3 weeks ago
FatBoy-DOTC c849bf0a1d proper isBoxed info command 3 weeks ago
FatBoy-DOTC 6bac4d830a attempt to fix boxed combat 3 weeks ago
FatBoy-DOTC 96122b5beb stop source type lookup console spam 3 weeks ago
FatBoy-DOTC 35ef86110f PVE flag 3 weeks ago
FatBoy-DOTC 3e04f36fd7 PVE flag 3 weeks ago
FatBoy-DOTC 454335c233 PVE flag 3 weeks ago
FatBoy-DOTC 4b6b209188 PVE flag 4 weeks ago
FatBoy-DOTC 44b5e8cfd9 PVE flag 4 weeks ago
FatBoy-DOTC e1c109cd6c PVE flag 4 weeks ago
FatBoy-DOTC 71735c73ff PVE flag 4 weeks ago
FatBoy-DOTC 54b8a1df19 PVE flag 4 weeks ago
FatBoy-DOTC fed9ba4240 PVE flag 4 weeks ago
FatBoy-DOTC 64d9401089 PVE flag 4 weeks ago
FatBoy-DOTC 1b8403f07b tears of saedron to be comsumed on use 4 weeks ago
FatBoy-DOTC 95c13789c7 precise stance fix 4 weeks ago
FatBoy-DOTC d3fc4f2263 mob aggro issues 4 weeks ago
FatBoy-DOTC d562c49cd5 mob aggro issues 4 weeks ago
FatBoy-DOTC 83aa28cad4 correct chant refresh issues 4 weeks ago
FatBoy-DOTC 15a823a4e5 stun immunities 4 weeks ago
FatBoy-DOTC 4b2fbf2dc0 shade and mino racial immunities 4 weeks ago
FatBoy-DOTC e07fe59a12 sourcetype failed lookups 4 weeks ago
FatBoy-DOTC 8d950aaa91 disable new mob AI 4 weeks ago
FatBoy-DOTC 8fb88ee7e1 fate peddler price adjustments 4 weeks ago
FatBoy-DOTC 2cfc5b64a7 fate peddler price adjustments 4 weeks ago
FatBoy-DOTC cc385b923c mithril drop rate fixed 4 weeks ago
FatBoy-DOTC 6af4cd2fc2 mithril drop rates 4 weeks ago
FatBoy-DOTC 3990defd7a mithril drop rates 4 weeks ago
FatBoy-DOTC 12bb1a39f8 player update issue 4 weeks ago
FatBoy-DOTC 158dbf9141 remove ATR component form weapon powers 4 weeks ago
FatBoy-DOTC c8ae48ae60 mine zerg tracker 4 weeks ago
FatBoy-DOTC 76b75f0a37 despawn timer for mobs reset to 5 seconds min 4 weeks ago
FatBoy-DOTC 9b250a38f3 PR40 concs 4 weeks ago
FatBoy-DOTC cbcdaaa221 style casting fix 4 weeks ago
FatBoy-DOTC c761cd982f fix immunities 4 weeks ago
FatBoy-DOTC f4af11b38f print effects command 4 weeks ago
FatBoy-DOTC 8982c287b4 new finish power action system 4 weeks ago
FatBoy-DOTC 85e1f3434c use 3D range check for mob attacks 4 weeks ago
FatBoy-DOTC 9c623f277b simplified mob aI 4 weeks ago
FatBoy-DOTC f9f4665e52 simplified mob aI 4 weeks ago
FatBoy-DOTC ec23f78c58 simplified mob aI 4 weeks ago
FatBoy-DOTC 58b287bc4b simplified mob aI 4 weeks ago
FatBoy-DOTC 89b5ebe7aa simplified mob aI 4 weeks ago
FatBoy-DOTC 169f49e6c3 simplified mob aI 4 weeks ago
FatBoy-DOTC bfc0c57dd8 simplified mob aI 4 weeks ago
FatBoy-DOTC 1c5d78d566 simplified mob aI 4 weeks ago
FatBoy-DOTC a46619c50a simplified mob aI 4 weeks ago
FatBoy-DOTC d4e430e816 simplified mob aI 4 weeks ago
FatBoy-DOTC e49fc398ed Merge branch 'lakebane-jobs' into lakebane 4 weeks ago
FatBoy-DOTC ef9c431d5e fix for dodging spells 4 weeks ago
FatBoy-DOTC cf6db2444c fix for backstab 4 weeks ago
FatBoy-DOTC d074aa8f1c fix for backstab 4 weeks ago
FatBoy-DOTC 4ea4609b1b check for immunity and no od prior to running power action 4 weeks ago
FatBoy-DOTC 58e84bfc21 remove style casting 4 weeks ago
FatBoy-DOTC 0a82a69a95 remove style casting 4 weeks ago
FatBoy-DOTC b33af64f60 remove unessecary player sync 4 weeks ago
FatBoy-DOTC 6311f8b2f8 different location sync system 4 weeks ago
FatBoy-DOTC e4ac2bc489 3 man zerg multiplier update 4 weeks ago
FatBoy-DOTC 5b6896e537 strip item enchants 4 weeks ago
FatBoy-DOTC 46b9da0612 strip item enchants 4 weeks ago
FatBoy-DOTC 898f6dfa69 strip item enchants 4 weeks ago
FatBoy-DOTC 67628a21b3 proc chance broken into separate method 4 weeks ago
FatBoy-DOTC 9f09a0e8b0 proc chance broken into separate method 4 weeks ago
FatBoy-DOTC 251210d166 remove dungeon teleport from base game 4 weeks ago
FatBoy-DOTC 5841db2a0d serialize dungeon for teleport 4 weeks ago
FatBoy-DOTC 6127bbadb4 dungeon work 4 weeks ago
FatBoy-DOTC 8e5584f413 admin building creation 4 weeks ago
FatBoy-DOTC d5e69446c7 admin building creation 4 weeks ago
FatBoy-DOTC b3247160d7 fix join heavens host 1 month ago
FatBoy-DOTC 06e31c1243 update stat and mastery pricing 1 month ago
FatBoy-DOTC ac5528382c new combat manager first draft 1 month ago
FatBoy-DOTC 9d8467613a new combat manager first draft 1 month ago
FatBoy-DOTC 8ff0594333 announce XP rate on login 1 month ago
FatBoy-DOTC 2e7707fcbe remove mob ai spam logging 1 month ago
FatBoy-DOTC 78131ed6f2 attempt to stop second box crash 1 month ago
FatBoy-DOTC 9b2a1a271e attempt to stop second box crash 1 month ago
FatBoy-DOTC 846d720c2f attempt to stop second box crash 1 month ago
FatBoy-DOTC 9ba2f375cf hamlet guards don't aggro 1 month ago
FatBoy-DOTC 22c975d251 dungeon generation 1 month ago
FatBoy-DOTC 601687133f dungeon generation 1 month ago
FatBoy-DOTC 2c47f593f3 dungeon generation 1 month ago
FatBoy-DOTC 6d004d631c add XP config multiplier 1 month ago
FatBoy-DOTC 2b4a87777c rune merchant price adjustments 1 month ago
FatBoy-DOTC b795db7fbd fix casting form mob hates 1 month ago
FatBoy-DOTC af684c6968 fix casting form mob hates 1 month ago
FatBoy-DOTC 80b1ab709d relog crash bug 1 month ago
FatBoy-DOTC 140ba6ae75 new mob aggro system 1 month ago
FatBoy-DOTC c24d779d08 clear recycle timer for reveal thyself 1 month ago
FatBoy-DOTC 5f169fcfae disconnect caught cheaters after trashing account 1 month ago
FatBoy-DOTC a5e0396dc6 Dungeon System draft 1 month ago
FatBoy-DOTC c5b2db051b run ban cleanup hourly 1 month ago
FatBoy-DOTC b94f8e4b03 build cleanup 1 month ago
FatBoy-DOTC dbfc33563c add stored procedure call 1 month ago
FatBoy-DOTC 57e7c3285f remove multibox checks for banned 1 month ago
FatBoy-DOTC c01d47fe21 perma root and perma stun 1 month ago
FatBoy-DOTC d5eb423db8 damage effect modifier 1 month ago
FatBoy-DOTC 69113ee3c4 catch failure in combat stats to prevent deadlock 1 month ago
FatBoy-DOTC c1aa6e2434 cannot sacrifice on self 1 month ago
FatBoy-DOTC 7820743222 catch null checks in calculate defense 1 month ago
FatBoy-DOTC e6762ef9b5 mele attack null checks 1 month ago
FatBoy-DOTC 81b60cd269 mele attack null checks 1 month ago
FatBoy-DOTC 755d89ebe0 mele attack null checks 1 month ago
FatBoy-DOTC aab28cd68c mele attack null checks 1 month ago
FatBoy-DOTC 97b2af52b9 mele attack null checks 1 month ago
FatBoy-DOTC 16a0b9c0e3 defense calc null checks 1 month ago
FatBoy-DOTC bfd89036b2 healer def stance ATR removed again 1 month ago
FatBoy-DOTC 9cad140836 saetors no longer parry incoming ranged damage 1 month ago
FatBoy-DOTC a9ca96bf96 glass items can only ever take 1 point of damage 1 month ago
FatBoy-DOTC 1ef18490b5 allow deleting shrines by players 1 month ago
FatBoy-DOTC 8d739c3dae detect multibox launcher 1 month ago
FatBoy-DOTC 44f5fb02a3 detect multibox launcher 1 month ago
FatBoy-DOTC 240198eec6 ring bonuses calculated specifically 1 month ago
FatBoy-DOTC dfe300ba4b ring bonuses calculated specifically 1 month ago
FatBoy-DOTC b48d294eca update XP scale 1 month ago
FatBoy-DOTC be27262e47 add strigoi fort to exception list 1 month ago
FatBoy-DOTC d1d51ef791 flat defense from rings calculated 1 month ago
FatBoy-DOTC e380c4dddb armor piercing fix 1 month ago
FatBoy-DOTC f9a7b91868 new XP system 1 month ago
FatBoy-DOTC cb73a81e33 fixed breathing 1 month ago
FatBoy-DOTC 47f1aa8a89 better random rolls 1 month ago
FatBoy-DOTC ca0738b6ed region heights issue resolved 1 month ago
FatBoy-DOTC 5fabd31495 region heights issue 1 month ago
FatBoy-DOTC e90465ee8f armorpiercing pierces armor instea dof reducing damage 1 month ago
FatBoy-DOTC 1b1c636628 fat coding fail 1 month ago
FatBoy-DOTC 5f28d3ae10 revert addition of new XP system for production 1 month ago
FatBoy-DOTC d0e93773ad revert addition of new XP system for production 1 month ago
FatBoy-DOTC 2160719126 player update cleanup 1 month ago
FatBoy-DOTC 0449465af9 update location for player update 1 month ago
FatBoy-DOTC 891e350362 cancel casting of powers player does not have 1 month ago
FatBoy-DOTC 942c37442e mines run at 1:00 am CST 1 month ago
FatBoy-DOTC 0571d5ded3 race type cleanup for saetor 1 month ago
FatBoy-DOTC 1f63df4f08 new experience 1 month ago
FatBoy-DOTC eec07f3a28 new experience 1 month ago
FatBoy-DOTC a199014a98 potential mele range sync fix 1 month ago
FatBoy-DOTC 48f8cf32b7 mine anti-zerg 1 month ago
FatBoy-DOTC f28b15b95e disable force DC 1 month ago
FatBoy-DOTC 8e5aec841d characters count at mines for 3 minutes 1 month ago
FatBoy-DOTC 9b7bcdc043 ZergMultiplier scales correctly 1 month ago
FatBoy-DOTC 2dbaac5bcf null combat stats error 1 month ago
FatBoy-DOTC 2f201151df keyclone audit 1 month ago
FatBoy-DOTC 3d48951184 saetor parry all the time 1 month ago
FatBoy-DOTC 3d199a9362 new spell ATR 1 month ago
FatBoy-DOTC c8a95cab41 new spell ATR 1 month ago
FatBoy-DOTC 43631af53b cheat logging 1 month ago
FatBoy-DOTC 89e31fd159 cheat logging 1 month ago
FatBoy-DOTC ffecdbb06b new Fate Peddler 1 month ago
FatBoy-DOTC 7331c870c2 new Fate Peddler 1 month ago
FatBoy-DOTC 4b760baae4 new Fate Peddler 1 month ago
FatBoy-DOTC 8106b100ec all footwear has equal chance to drop movespeed suffixes 1 month ago
FatBoy-DOTC 53285ca898 all footwear has equal chance to drop movespeed suffixes 1 month ago
FatBoy-DOTC 9db7411ee6 calc OnTakeDamage in combat loop 1 month ago
FatBoy-DOTC a12687913e printstats showing spells and their ATR 1 month ago
FatBoy-DOTC 937656a91d sub race rune application check 1 month ago
FatBoy-DOTC 5f2034a35b atr calculation fix 1 month ago
FatBoy-DOTC 87d39ae29d target software identification 1 month ago
FatBoy-DOTC bd95a8d7af target software identification 1 month ago
FatBoy-DOTC 1fa9a88ae3 combat stats cleanup 1 month ago
FatBoy-DOTC 34e3ae20d7 zerg mechanic applications 1 month ago
FatBoy-DOTC 55b6d60141 zerg mechanic applications 1 month ago
FatBoy-DOTC 92d0aec77d zerg mechanic applications 1 month ago
FatBoy-DOTC 1282f58a3c players coutn towards mine cap for 3 minutes after leaving 1 month ago
FatBoy-DOTC 1070d61251 zerg mechanic for mines adjusted to 3x load range 1 month ago
FatBoy-DOTC f7ab5347ab new application of zerg multiplier 1 month ago
FatBoy-DOTC 517e64d613 global rune drops 1 month ago
FatBoy-DOTC 5ed31c5e2e revert cancel on take damage 1 month ago
FatBoy-DOTC c50bcb0a32 bug fix 1 month ago
FatBoy-DOTC 09a6e18d4f bug fix 1 month ago
FatBoy-DOTC b0dd7e9b59 bug fix 1 month ago
FatBoy-DOTC 92d685c3e3 bug fix 1 month ago
FatBoy-DOTC 84a1db1e09 log cheaters 1 month ago
FatBoy-DOTC d0e3cac4c3 log selected object UUID 1 month ago
FatBoy-DOTC 9a5fd53271 log trash disconnect for cheater 1 month ago
FatBoy-DOTC 8d4fb261b5 cancel on take damage everytime you take damage 1 month ago
FatBoy-DOTC 4a7a999ed1 pets to use owners ZergMultiplier 1 month ago
FatBoy-DOTC e69c0f2799 cannot repldeg to any non-open ToL 1 month ago
FatBoy-DOTC 9e36d558bf state zone name in PVP message 1 month ago
FatBoy-DOTC df2271fe2c universal rune drops 1 month ago
FatBoy-DOTC 1f7d2a14bf death no longer releases mine claims 1 month ago
FatBoy-DOTC a99047aee8 ranged based tracking 1 month ago
FatBoy-DOTC 5dc9e127bb undo 1 month ago
FatBoy-DOTC bb05bdd87c handle trainer inventories 1 month ago
FatBoy-DOTC 4c0b480aeb trainer merchants 1 month ago
FatBoy-DOTC 3cf38da567 no stam drain while TS 1 month ago
FatBoy-DOTC 96731bd9bb saetor inherit racetype 1 month ago
FatBoy-DOTC 9d79afa395 player update optimized 1 month ago
FatBoy-DOTC 944290f958 audit chat messages for target ID 1 month ago
FatBoy-DOTC e6eb753666 audit chat messages for target ID 1 month ago
FatBoy-DOTC 4ad7e0f021 fix track power range 1 month ago
FatBoy-DOTC 8d587538e0 uptime to show boxed and active players 1 month ago
FatBoy-DOTC 4ae64ab94c pet aggro fix 1 month ago
FatBoy-DOTC c5e6205801 invis mob solution 1 month ago
FatBoy-DOTC 5a3f4e690f mobs will attack player pets 1 month ago
FatBoy-DOTC 048474b014 must be in safezone to switch boxes 1 month ago
FatBoy-DOTC 24e01acff4 pet assistance 1 month ago
FatBoy-DOTC a75670bf0e retaliate handled properly 1 month ago
FatBoy-DOTC d56d58492a huntress pets properly granted modifiers 1 month ago
FatBoy-DOTC 7b33c1392a set mob level earlier in routine 1 month ago
FatBoy-DOTC 86c95f0eb5 disable gimme command 1 month ago
FatBoy-DOTC 6ed648d6d4 catch weird city null error 1 month ago
FatBoy-DOTC c722450f65 proper XP group scaling 1 month ago
FatBoy-DOTC bbcbd6fc39 hot fix for regen 1 month ago
FatBoy-DOTC 123c488fc6 hot fix for regen 1 month ago
FatBoy-DOTC f5ebda9147 hot fix for regen 1 month ago
FatBoy-DOTC 1132f88b85 hot fix for powers failure 1 month ago
FatBoy-DOTC edc4aa5d07 recovering rates 1 month ago
FatBoy-DOTC 734b67be6d recovering rates 1 month ago
FatBoy-DOTC 53c8b28d2d audit chat messages for target ID 1 month ago
FatBoy-DOTC 017026fd03 audit chat messages for target ID 1 month ago
FatBoy-DOTC 4e9b1927f2 fix mob target aggro issue 2 months ago
FatBoy-DOTC 56ce5b5a3c fix track power range 2 months ago
FatBoy-DOTC afd1b4e760 uptime to show boxed and active players 2 months ago
FatBoy-DOTC 1975e60f36 pet aggro fix 2 months ago
FatBoy-DOTC fbdca5b917 xp range fix 2 months ago
FatBoy-DOTC 78dfa0c68c invis mob solution 2 months ago
FatBoy-DOTC a04ad2f382 break point 2 months ago
FatBoy-DOTC 257a8aff15 break point 2 months ago
FatBoy-DOTC 291a20c4d0 break point 2 months ago
FatBoy-DOTC eec08ce962 break point 2 months ago
FatBoy-DOTC 99183dc248 break point 2 months ago
FatBoy-DOTC 6c7f01dc72 mobs will attack player pets 2 months ago
FatBoy-DOTC 6ebeb9cadf must be in safezone to switch boxes 2 months ago
FatBoy-DOTC 8e0f1090d9 fix white XP 2 months ago
FatBoy-DOTC bc0bc577ea fix white XP 2 months ago
FatBoy-DOTC 3b5c0e6210 must be in safezone to gain level up gold 2 months ago
FatBoy-DOTC d6fa7dba9d fix XP range 2 months ago
FatBoy-DOTC b5fbc8478d new Regen 2 months ago
FatBoy-DOTC b79c827d81 new Regen 2 months ago
FatBoy-DOTC b9b254f8e8 new Regen 2 months ago
FatBoy-DOTC 6834146eb2 new Regen 2 months ago
FatBoy-DOTC e9f1711120 pet assistance 2 months ago
FatBoy-DOTC 29f054e192 retaliate handled properly 2 months ago
FatBoy-DOTC 7d9c5d3498 huntress pets properly granted modifiers 2 months ago
FatBoy-DOTC 618353c088 set mob level earlier in routine 2 months ago
FatBoy-DOTC 24656b1030 expereince system rework 2 months ago
FatBoy-DOTC 27cb704837 expereince system rework 2 months ago
FatBoy-DOTC 6961b186a9 disable gimme command 2 months ago
FatBoy-DOTC bee91a6aa7 catch weird city null error 2 months ago
FatBoy-DOTC 8c5b1d56c2 proper XP group scaling 2 months ago
FatBoy-DOTC f21e8c130b stam ticks 2 months ago
FatBoy-DOTC 345c451ac8 stam ticks 2 months ago
FatBoy-DOTC c3a7262a7f logging for failed to move item to vault or bank 2 months ago
FatBoy-DOTC d1c6d9edec reveal thyself castable by all 2 months ago
FatBoy-DOTC 1e865eecbc increase starting gold to 1500 2 months ago
FatBoy-DOTC 5f735a49c1 mobs no longer double multiply for sitting target 2 months ago
FatBoy-DOTC e609c015b9 Dwarvish Wrath added to exception list 2 months ago
FatBoy-DOTC 5a198669b9 quick targeting check cleanup 2 months ago
FatBoy-DOTC fe399664f3 targeting object checks only count when targeting players 2 months ago
FatBoy-DOTC 3bc62e9baa 10 seconds for 7 stamina ticks in travel stance 2 months ago
FatBoy-DOTC cf23266f31 10 seconds for 7 stamina ticks in travel stance 2 months ago
FatBoy-DOTC b097472402 delete AI Players 2 months ago
FatBoy-DOTC 57b18c2d15 AI Players as mobs 2 months ago
FatBoy-DOTC 040eef576e disable AI Players 2 months ago
FatBoy-DOTC d76403a0c8 Ai Players 2 months ago
FatBoy-DOTC 8ce1054599 Ai Players 2 months ago
FatBoy-DOTC 0daf8cfe4c Ai Players 2 months ago
FatBoy-DOTC 898c4c2fa0 Ai Players 2 months ago
FatBoy-DOTC ecba693105 Ai Players 2 months ago
FatBoy-DOTC dbc0da20df pets issues fixed 2 months ago
FatBoy-DOTC 354d0ab283 pets issues 2 months ago
FatBoy-DOTC c1b66269bb new regen system 2 months ago
FatBoy-DOTC 7981acb582 new regen system 2 months ago
FatBoy-DOTC 03448397ee strike counter trash logging 2 months ago
FatBoy-DOTC 685dc572e8 strike counter 2 months ago
FatBoy-DOTC 5a161a0808 strike counter 2 months ago
FatBoy-DOTC 3e4aad9db9 aimbot detection 2 months ago
FatBoy-DOTC 47981872be network message validation 2 months ago
FatBoy-DOTC daea835613 network message validation 2 months ago
FatBoy-DOTC 55923559cd group tele allowe don all city zones 2 months ago
FatBoy-DOTC 9efde874f3 remove level difference form passive chance 2 months ago
FatBoy-DOTC 9b2b0073a5 gambler NPC 2 months ago
FatBoy-DOTC 33328f74db gambler NPC 2 months ago
FatBoy-DOTC 41023fb890 gambler NPC 2 months ago
FatBoy-DOTC 54a279c3e6 track threads being used 2 months ago
FatBoy-DOTC 29aea83217 track threads being used 2 months ago
FatBoy-DOTC 30d27f8a68 job worker thread to prevent deadlocks 2 months ago
FatBoy-DOTC 17e54ea4aa job worker thread 2 months ago
FatBoy-DOTC 86c0bbb065 passives 2 months ago
FatBoy-DOTC ec4cad5e19 added 250L wait to network selector 2 months ago
FatBoy-DOTC b674625f7b reduced admin command spam 2 months ago
FatBoy-DOTC d57b45ef9c fix event processing in network code 2 months ago
FatBoy-DOTC 2a38c60a67 Revert "fix event processing in network code" 2 months ago
FatBoy-DOTC cd1e38b184 fix event processing in network code 2 months ago
FatBoy-DOTC 69457d5f7e new curved map for hit chances 2 months ago
FatBoy-DOTC 7728a800d9 new hit chance scaling 2 months ago
FatBoy-DOTC 8b2c018103 mana can be recovered while casting - to match client 2 months ago
FatBoy-DOTC 76d39f5cc3 mana can be recovered while casting - to match client 2 months ago
FatBoy-DOTC 826457fb25 mana and stamina regen resynced 2 months ago
FatBoy-DOTC 0681d3d116 tears of saedron remove stat runes 2 months ago
FatBoy-DOTC ccdea6f970 players can teleport to their own cities 2 months ago
FatBoy-DOTC ab00fd7a85 limit dev commands 2 months ago
FatBoy-DOTC 70d67a2b7f update thread optimized 2 months ago
FatBoy-DOTC f5b27e0c5b no reverse KoS 2 months ago
FatBoy-DOTC 3c26df5f86 last tick on over time applies 2 months ago
FatBoy-DOTC 9ed43b5891 combatstats cleanup 2 months ago
FatBoy-DOTC 4814404f1c combatstats cleanup 2 months ago
FatBoy-DOTC b1d41e8e85 update delay removed 2 months ago
FatBoy-DOTC cc5aa4c140 ATR completed 2 months ago
FatBoy-DOTC 934c0a98f8 atr buff/debuffs 2 months ago
FatBoy-DOTC 91c2cd47fb def buff/debuffs 2 months ago
FatBoy-DOTC 22f14fb8f1 treb spam 2 months ago
FatBoy-DOTC 93a975dd42 optimized run time 2 months ago
FatBoy-DOTC 7d1570fdca group tele limit recyle power properly 2 months ago
FatBoy-DOTC 76db3e1f96 disable mob casting 2 months ago
FatBoy-DOTC afbe23fc03 use calculated value son PC for combat stats 2 months ago
FatBoy-DOTC 4e417c8810 audit hit/miss chances 2 months ago
FatBoy-DOTC d79c69658a parry chance removed 10x 2 months ago
FatBoy-DOTC 0d125e2640 hit chance 2 months ago
FatBoy-DOTC e4a3405032 location sync and def formula 2 months ago
FatBoy-DOTC c391272e5b can block spells 2 months ago
FatBoy-DOTC 0d3423d51b can block spells 2 months ago
FatBoy-DOTC 549ca25483 can block spells 2 months ago
FatBoy-DOTC 603d4ca3a8 reconstructed passive chance formulas 2 months ago
FatBoy-DOTC fababd3e42 reconstructed passive chance formulas 2 months ago
FatBoy-DOTC bec6230a06 box limiter 2 months ago
FatBoy-DOTC 773b6253b9 def formula 2 months ago
FatBoy-DOTC 1ffcc1086b def formula 2 months ago
FatBoy-DOTC 992d52a389 always allow parry on saetor 2 months ago
FatBoy-DOTC 61088d0b59 box limiter 2 months ago
FatBoy-DOTC 601e97eaca Revert "box limited config entry" 2 months ago
FatBoy-DOTC eae4675f85 box limited config entry 2 months ago
FatBoy-DOTC 84410114e7 mob casting time fixed 2 months ago
FatBoy-DOTC 70855acbcf mob casting time 2 months ago
FatBoy-DOTC 2a8e0dea73 mob casting time 2 months ago
FatBoy-DOTC 6c4f18218c atr calculations 2 months ago
FatBoy-DOTC 0b5f469b13 no footwear on saetors 2 months ago
FatBoy-DOTC 68a43388ff saetor can only parry naturally 2 months ago
FatBoy-DOTC 5fe12df436 mobs cannot cast debuffs 2 months ago
FatBoy-DOTC caa0aa5172 AI cast frequency 2 months ago
FatBoy-DOTC 37a81ed53e ATR system 2 months ago
FatBoy-DOTC 39afb33186 old regen system 2 months ago
FatBoy-DOTC 228152596c spell dodge chance resolved 2 months ago
FatBoy-DOTC d75a052bd3 non siege pets can always roam as a flag 2 months ago
FatBoy-DOTC 81d6a55096 stop bonus calc spam 2 months ago
FatBoy-DOTC 55d9cf6d26 calculate base skill 2 months ago
FatBoy-DOTC 9cf69ec73f calculate base skill 2 months ago
FatBoy-DOTC 4595582def calculate base skill 2 months ago
FatBoy-DOTC 0b2d598261 print new skill calculations to client 2 months ago
FatBoy-DOTC cf342cd1a6 print new skill calculations to client 2 months ago
FatBoy-DOTC 05bb323c0c print new skill calculations to client 2 months ago
FatBoy-DOTC c415bb15e2 use new skill level calculations 2 months ago
FatBoy-DOTC eac58b086b limiter for client syncing 2 months ago
FatBoy-DOTC fea39ffa85 calculate modified and base skill values 2 months ago
FatBoy-DOTC fb8971ce86 calculate modified and base skill values 2 months ago
FatBoy-DOTC e44dd5e2cc properly sync client for regen 2 months ago
FatBoy-DOTC 3ed303bec4 calculate combat stats spam fix 2 months ago
FatBoy-DOTC f4267c3c92 calculate combat stats spam fix 2 months ago
FatBoy-DOTC c5f678ea0e join heavens host allowed for prelates 2 months ago
FatBoy-DOTC 4fe3d92b3f optimize PlayerCombatStats calling 2 months ago
FatBoy-DOTC 284fc7e37e remove error logging spam 2 months ago
FatBoy-DOTC 402d69312c use new regen calculations 2 months ago
FatBoy-DOTC 198648d3db use new regen calculations 2 months ago
FatBoy-DOTC 3a01dbf5f6 shade hide power block 2 months ago
FatBoy-DOTC 0ec505e37f player lock fix 2 months ago
FatBoy-DOTC 1e26d7f38c player lock fix 2 months ago
FatBoy-DOTC 64f9f4d4b9 player lock fix 2 months ago
FatBoy-DOTC 89c06f714f player lock fix 2 months ago
FatBoy-DOTC 157d116626 player lock fix 2 months ago
FatBoy-DOTC de229ddde5 dont load cities without ToL 2 months ago
FatBoy-DOTC 8b456f66ef healers dont get ATR from def stance 2 months ago
FatBoy-DOTC 2e35e35a6e fury no longer grounded at end of flight chant 2 months ago
FatBoy-DOTC cca078f017 strip castable enchanst when moving to vault 2 months ago
FatBoy-DOTC f658a30132 atr % bonus accounted for 2 months ago
FatBoy-DOTC 0a827d2404 proper duel wield attack speed calc 2 months ago
FatBoy-DOTC 806adee3de fortitude fix 2 months ago
FatBoy-DOTC bdd108065b apply powerBlock on shade hide 2 months ago
FatBoy-DOTC 8d41c5475c unfuck fortitude 2 months ago
FatBoy-DOTC 99ad461a82 skin the beast work son all but templar 2 months ago
FatBoy-DOTC 9da56b4226 3 second power block for hide 2 months ago
FatBoy-DOTC beeca529cd fortitudes handled last 2 months ago
FatBoy-DOTC ebb765ae82 use total skill percent when calculating ATR 2 months ago
FatBoy-DOTC 65e391f6f7 Revert "use total skill instea dof modified for ATR" 2 months ago
FatBoy-DOTC ab45d92bd1 use total skill instea dof modified for ATR 2 months ago
FatBoy-DOTC a366c95941 can't TP to errant mines 2 months ago
FatBoy-DOTC f2d9eb003c temporary enchant timers 2 months ago
FatBoy-DOTC bb1a99912c temporary enchant stripping 2 months ago
FatBoy-DOTC fd30e52741 temporary enchant stripping 2 months ago
FatBoy-DOTC 58a0b6150f aI delay 2 months ago
FatBoy-DOTC 9aa053beb6 aI delay 2 months ago
FatBoy-DOTC 7eb084efaa aI delay 2 months ago
FatBoy-DOTC 1568377725 dex reductions 2 months ago
FatBoy-DOTC 7b32cfe235 shade backstabs 2 months ago
FatBoy-DOTC 7ef3efafd3 shade backstabs 2 months ago
FatBoy-DOTC ffdd79c497 blood mage fix 2 months ago
FatBoy-DOTC b156da7ded AP applies only to mele damage 2 months ago
FatBoy-DOTC 9278954f2f saetor can parry 2 months ago
FatBoy-DOTC 4324ebe855 Phaedra's Fury added to exception list for form break 2 months ago
FatBoy-DOTC 4a69dca5cc allow gimme 2 months ago
FatBoy-DOTC 2cc54b4002 100 ms delay between mob spawns 2 months ago
FatBoy-DOTC eac0aebd59 defense calc completed 2 months ago
FatBoy-DOTC 172dcfb6d8 defense calc completed 2 months ago
FatBoy-DOTC d320d83c22 defense calc completed 2 months ago
FatBoy-DOTC af2dd004e4 defense calc 2 months ago
FatBoy-DOTC dfbace76db defense calc 2 months ago
FatBoy-DOTC 119f762492 defense calc 2 months ago
FatBoy-DOTC e586c442c1 PlayerCombatStats dex penalty applied correctly 2 months ago
FatBoy-DOTC c01e87ee8b PlayerCombatStats dex penalty applied correctly 2 months ago
FatBoy-DOTC af4025d948 PlayerCombatStats dex penalty applied correctly 2 months ago
FatBoy-DOTC b7c2b7a0d5 PlayerCombatStats dex penalty applied correctly 2 months ago
FatBoy-DOTC f073a93d47 PlayerCombatStats dex penalty applied correctly 2 months ago
FatBoy-DOTC 47914838f5 PlayerCombatStats dex penalty applied correctly 2 months ago
FatBoy-DOTC 69e2630d77 PlayerCombatStats dex penalty applied correctly 2 months ago
FatBoy-DOTC 08148c058c PlayerCombatStats defense formula 2 months ago
FatBoy-DOTC a7ee8f553b PlayerCombatStats proc chances 2 months ago
FatBoy-DOTC 8395bb80f1 PlayerCombatStats use in combat 2 months ago
FatBoy-DOTC becd3cbf65 PlayerCombatStats use in combat 2 months ago
FatBoy-DOTC 80ec681a2c PlayerCombatStats 30% damage reduction for duel wielding 2 months ago
FatBoy-DOTC 96a80ce1b6 PlayerCombatStats attack delay 2 months ago
FatBoy-DOTC f18cf5c8a6 PlayerCombatStats modified skills 2 months ago
FatBoy-DOTC 4c21159553 PlayerCombatStats modified skills 2 months ago
FatBoy-DOTC 475c0a9b09 PlayerCombatStats modified skills 2 months ago
FatBoy-DOTC f80ad61179 PlayerCombatStats weapon speed enchants applied separately 2 months ago
FatBoy-DOTC 10ccfb1086 PlayerCombatStats weapon speed enchants applied separately 2 months ago
FatBoy-DOTC 44197fd83c PlayerCombatStats revision 2 months ago
FatBoy-DOTC 0d9e03f848 PlayerCombatStats weapon speed calculations complete 2 months ago
FatBoy-DOTC 810812d06b PlayerCombatStats weapon speed calculations 2 months ago
FatBoy-DOTC 539d7f6e79 PlayerCombatStats def calculations completed 2 months ago
FatBoy-DOTC 3358d9e943 PlayerCombatStats def calculations 2 months ago
FatBoy-DOTC eeffd9b357 PlayerCombatStats atr calculations completed 2 months ago
FatBoy-DOTC b33f41200e PlayerCombatStats atr 2 months ago
FatBoy-DOTC 030d1110b9 PlayerCombatStats proper delays 2 months ago
FatBoy-DOTC 09af8084b9 PlayerCombatStats final 2 months ago
FatBoy-DOTC 0cff9524c2 PlayerCombatStats final 2 months ago
FatBoy-DOTC f6299f5b97 PlayerCombatStats final 2 months ago
FatBoy-DOTC b1250ae4e4 PlayerCombatStats proper stance calculations 2 months ago
FatBoy-DOTC a9144471b1 PlayerCombatStats defense proper rounding 2 months ago
FatBoy-DOTC 9f924da18b PlayerCombatStats min/max rounding final 2 months ago
FatBoy-DOTC aac92f1760 PlayerCombatStats defense final 2 months ago
FatBoy-DOTC fdf42bd913 PlayerCombatStats defense 2 months ago
FatBoy-DOTC ecee2f2e8c PlayerCombatStats damage calc final 2 months ago
FatBoy-DOTC 1b487fdbb6 PlayerCombatStats damage calc 2 months ago
FatBoy-DOTC bb7bd6d71b PlayerCombatStats atr final 2 months ago
FatBoy-DOTC 34178906a3 PlayerCombatStats attack speed final 2 months ago
FatBoy-DOTC c689722459 PlayerCombatStats object 2 months ago
FatBoy-DOTC 8e4ff8c67f PlayerCombatStats object 2 months ago
FatBoy-DOTC 4ff22d1d20 PlayerCombatStats object 2 months ago
FatBoy-DOTC 5ed7712aed PlayerCombatStats object 2 months ago
FatBoy-DOTC a6fcb5ea00 weapon speed 2 months ago
FatBoy-DOTC 8f402c8c03 weapon speed 2 months ago
FatBoy-DOTC 5761e313fd weapon speed 2 months ago
FatBoy-DOTC 441771839a new stat calculations 2 months ago
FatBoy-DOTC ad6700974f new stat calculations 2 months ago
FatBoy-DOTC 499aec2c61 new stat calculations 2 months ago
FatBoy-DOTC ceed4c641a new stat calculations 2 months ago
FatBoy-DOTC 669c0b4cd7 attack speed 2 months ago
FatBoy-DOTC 7964de1045 attack speed 2 months ago
FatBoy-DOTC 961e2915b4 attack speed 2 months ago
FatBoy-DOTC 6c6a64fa98 mobs dont chase invisible players 2 months ago
FatBoy-DOTC 7a8a751bca stealing/peeking fix 2 months ago
FatBoy-DOTC 69bf6ef8cd combat formula and steal 2 months ago
FatBoy-DOTC 05e542215d allow 5th disc at 70 2 months ago
FatBoy-DOTC 868eaab5ed mantle of stone added to form break exception list 2 months ago
FatBoy-DOTC e7d22717cd attack speed calculations 2 months ago
FatBoy-DOTC bbabf814e1 attack speed calculations 2 months ago
FatBoy-DOTC 938fcb1352 allow print bonuses 2 months ago
FatBoy-DOTC 42a71396cd persist print commands for non-testmode 2 months ago
FatBoy-DOTC 9ec95b974f mob work 2 months ago
FatBoy-DOTC 49ea9e50cf mob work 2 months ago
FatBoy-DOTC 456edce9fc mob work 2 months ago
FatBoy-DOTC 537512ed5d mob work 2 months ago
FatBoy-DOTC d0efd08a84 mobbase effect info command 2 months ago
FatBoy-DOTC bb7ba9a6df mobbase effect info command 2 months ago
FatBoy-DOTC 09695d97db mobbase effect info command 2 months ago
FatBoy-DOTC 4fe4835c29 mobbase effects 2 months ago
FatBoy-DOTC 86435a3563 respawn thread optimized 2 months ago
FatBoy-DOTC bc84c7537b optimized regen client sync 2 months ago
FatBoy-DOTC 29736f9c8f optimized regen client sync 2 months ago
FatBoy-DOTC 99a9cd297c optimized mob ai thread 2 months ago
FatBoy-DOTC e86749febd optimized bane thread 2 months ago
FatBoy-DOTC 4b86fbb12c optimized regen 2 months ago
FatBoy-DOTC 4c342c9b9a bard uses pathfinding 3 months ago
FatBoy-DOTC d2e0b7b95c bard uses pathfinding 3 months ago
FatBoy-DOTC 53fe763764 boxed characters dont get ding gold 3 months ago
FatBoy-DOTC 86d7233aa4 remove console spam 3 months ago
FatBoy-DOTC d19ea0968a allowed casts in form 3 months ago
FatBoy-DOTC 7eb49446c1 correct use of proper stat for ATR calculation 3 months ago
FatBoy-DOTC 01a88c85a6 correct use of proper stat for ATR calculation 3 months ago
FatBoy-DOTC 5492374f2c saetor in who window, skin the beast double point value 3 months ago
FatBoy-DOTC 9ca00be694 saetor in who window, skin the beast double point value 3 months ago
FatBoy-DOTC 23d9807fe3 infastructure for exclusion to breaking form from powers 3 months ago
FatBoy-DOTC 8a3e3ae866 special case weapon powers requiring hit rolls 3 months ago
FatBoy-DOTC 117646cda4 limit spamming messages ot client for stat sync 3 months ago
FatBoy-DOTC 6cf502c4bb mob drop aggro check 3 months ago
FatBoy-DOTC 1bb99127c4 mob drop aggro check 3 months ago
FatBoy-DOTC 8aeccd35c9 mob drop aggro check 3 months ago
FatBoy-DOTC c90b94d1ec endless player guard combat cycle 3 months ago
FatBoy-DOTC 031fd24842 PLayerCharacter.java Cleanup 3 months ago
FatBoy-DOTC e1c07deb52 remove debug logs from stam/health consumption 3 months ago
FatBoy-DOTC 5f10c24f03 health degregation for swimming 3 months ago
FatBoy-DOTC f643caacbe health degregation for swimming 3 months ago
FatBoy-DOTC cb5ab26924 recovery system fully synced to client 3 months ago
FatBoy-DOTC 94c9e92553 mob loot system addressed 3 months ago
FatBoy-DOTC 507638594d updated regen system 3 months ago
FatBoy-DOTC e72c4886e8 updated regen system 3 months ago
FatBoy-DOTC 5ba11a6238 updated regen system 3 months ago
FatBoy-DOTC 2fc7671051 updated regen system 3 months ago
FatBoy-DOTC d142097b0f updated regen system 3 months ago
FatBoy-DOTC 4330bb3ecd updated regen system 3 months ago
FatBoy-DOTC 2e1dd27332 updated regen system 3 months ago
FatBoy-DOTC 4f08d7286e mob respawn issue resolved 3 months ago
FatBoy-DOTC 7f8fb13552 mana regen change 3 months ago
FatBoy-DOTC 93e0d119b0 mana regen change 3 months ago
FatBoy-DOTC a9bc44f19b fifth disc for level 80 3 months ago
FatBoy-DOTC 83bc09f34b fifth disc for level 80 3 months ago
FatBoy-DOTC 4386e1c828 throttled xp for killing same person 3 months ago
FatBoy-DOTC 72b2e54331 banes to set default times 3 months ago
FatBoy-DOTC e912c24025 5th hireling in r8 ToL 3 months ago
FatBoy-DOTC c9c1f6ba1c wall bonus HP 3 months ago
FatBoy-DOTC abda30fc25 wall bonus HP 3 months ago
FatBoy-DOTC 62c188c5c7 wall bonus HP 3 months ago
FatBoy-DOTC 67f7b6f3f8 wall bonus HP 3 months ago
FatBoy-DOTC f04ccb9403 wall bonus HP 3 months ago
FatBoy-DOTC b71bb60669 allow 5th slot in r8 TOL + wall health upgrade for r8 trees 3 months ago
FatBoy-DOTC 5eab1ad1c0 allow 5th slot in r8 TOL + wall health upgrade 3 months ago
FatBoy-DOTC f96d0caf3c stun grounds 1 tier per 1.5 seconds of stunned 3 months ago
FatBoy-DOTC 3e6655a199 cant change altitude while stunned 3 months ago
FatBoy-DOTC 386cdc8c18 cant change altitude while stunned 3 months ago
FatBoy-DOTC 63b40c27a5 fall slowly while stunned 3 months ago
FatBoy-DOTC 6985dffda4 no more spamming console 3 months ago
FatBoy-DOTC 88e16448a8 gold and conc on promotion 3 months ago
FatBoy-DOTC 4cb428e993 noob island progression changes 3 months ago
FatBoy-DOTC af9945f9db added null check for endEffect 3 months ago
FatBoy-DOTC f0594fb1b2 sitting only toggle when casting spells not skills 3 months ago
FatBoy-DOTC a155bc0308 modified ht chance 3 months ago
FatBoy-DOTC dce7444483 modified ht chance 3 months ago
FatBoy-DOTC 76eed79b0a repair cost formula fixed 3 months ago
FatBoy-DOTC f73ed17c05 repair cost formula 3 months ago
FatBoy-DOTC b049d21aff corpse timer 3 months ago
FatBoy-DOTC f6cce5ee1f corpse timer 3 months ago
FatBoy-DOTC 8038c2ebe2 arena que messages 3 months ago
FatBoy-DOTC 9f51b9af57 arena que messages 3 months ago
FatBoy-DOTC cbc75bf9d7 irekei healer blood prophet 3 months ago
FatBoy-DOTC 0ecfa546cd SDR bind loc for errants 3 months ago
FatBoy-DOTC b89fb0803d SDR bind loc for errants 3 months ago
FatBoy-DOTC 11005d58a7 SDR bind loc for errants 3 months ago
FatBoy-DOTC b0c6239314 SDR bind loc for errants 3 months ago
FatBoy-DOTC 67f66155e9 SDR bind loc for errants 3 months ago
FatBoy-DOTC 7fbae12e99 mob update 3 months ago
FatBoy-DOTC 65580c0a47 mob update 3 months ago
FatBoy-DOTC 236afe4cc6 mob update 3 months ago
FatBoy-DOTC c23a6af28f mob update 3 months ago
FatBoy-DOTC 2535106d2c player update sync 3 months ago
FatBoy-DOTC d8379ae5a9 shades dont break hide when moving 3 months ago
FatBoy-DOTC 9f13f5fc5d add sprint to shade stealth 3 months ago
FatBoy-DOTC 884cb30ebd trade bug 3 months ago
FatBoy-DOTC 30488e5da6 maintenance bug 3 months ago
FatBoy-DOTC b7e798a950 spire effect extension 3 months ago
FatBoy-DOTC e999ca3f68 spire effect extension 3 months ago
FatBoy-DOTC 039638c0d8 stackable enum types 3 months ago
FatBoy-DOTC f282504896 irekei movepseed 3 months ago
FatBoy-DOTC 0062936ac6 irekei movepseed 3 months ago
FatBoy-DOTC 19c41daa86 irekei movepseed 3 months ago
FatBoy-DOTC d860b16cfd irekei movepseed 3 months ago
FatBoy-DOTC e3b42a8ad9 irekei movepseed 3 months ago
FatBoy-DOTC 20bd7a82af proper flying check for speed calculation 3 months ago
FatBoy-DOTC e607eb8220 irekei movespeed sync 3 months ago
FatBoy-DOTC 38ca49d1a5 errants bind loc to tree in SDR 3 months ago
FatBoy-DOTC a21bdfe031 blood prophet for all irekei mage/healers 3 months ago
FatBoy-DOTC f95832b87c xp modifiers 3 months ago
FatBoy-DOTC feff9b3540 cant get XP for suicide 3 months ago
FatBoy-DOTC 78118aa08c update inventory when getting conc and gold at start 3 months ago
FatBoy-DOTC 3539372437 powers manager fixes 3 months ago
FatBoy-DOTC 7c498625bd bounds error 3 months ago
FatBoy-DOTC e379016123 bane mechanic complete - working 3 months ago
FatBoy-DOTC afa68b840c bane mechanic complete - working 3 months ago
FatBoy-DOTC 1926deb7f9 bane mechanic complete - working 3 months ago
FatBoy-DOTC 25c1f34c23 bane mechanic 3 months ago
FatBoy-DOTC d0e04e53ad bane mechanic 3 months ago
FatBoy-DOTC e475fb5cc9 wildkins chase removes snare 3 months ago
FatBoy-DOTC f72f632cd8 login crash bug 3 months ago
FatBoy-DOTC 02ea27fc6f login crash bug 3 months ago
FatBoy-DOTC 5d338bb87c login crash bug 3 months ago
FatBoy-DOTC f9f08c2886 login crash bug 3 months ago
FatBoy-DOTC dcc139043d stop movement on cast 3 months ago
FatBoy-DOTC 520219404c NPC special price option 3 months ago
FatBoy-DOTC f97991f00d NPC special price option 3 months ago
FatBoy-DOTC 7b7e1c5337 NPC special price option 3 months ago
FatBoy-DOTC 6e66659940 NPC special price option 3 months ago
FatBoy-DOTC 3d83baed78 all sages can repair everything 3 months ago
FatBoy-DOTC 049b27da96 all sages can repair everything 3 months ago
FatBoy-DOTC 6bcbe0f633 all sages can repair everything 3 months ago
FatBoy-DOTC 8c44e39275 all sages can repair everything 3 months ago
FatBoy-DOTC e36ab1f5d2 corspe timer reduced to 10 minutes(from 15) 3 months ago
FatBoy-DOTC 865c775f41 Arena death message 3 months ago
FatBoy-DOTC 198778ba2d arena circle addition 3 months ago
FatBoy-DOTC 215aabdc5f arena circle addition 3 months ago
FatBoy-DOTC 8d92c8be37 Arena System complete feature 3 months ago
FatBoy-DOTC 93b3ce07f0 Arena System prize 3 months ago
FatBoy-DOTC f9b7c8b851 Arena System 3 months ago
FatBoy-DOTC b3cf72abdc Arena System 3 months ago
FatBoy-DOTC 65fddd06a9 Arena System 3 months ago
FatBoy-DOTC 41f4a8ff58 Arena System 3 months ago
FatBoy-DOTC a13d5018b9 Arena System 3 months ago
FatBoy-DOTC 2ac3ce5bc8 Arena System 3 months ago
FatBoy-DOTC 85514987e7 Arena Manager NPC 3 months ago
FatBoy-DOTC c9eb07b5ba Enrollment officer dialog option added 3 months ago
FatBoy-DOTC 7201b61498 Enrollment officer dialog option added 3 months ago
FatBoy-DOTC 55b3161900 Enrollment officer dialog 3 months ago
FatBoy-DOTC 9d5c4424a1 Arena Infrastructure 3 months ago
FatBoy-DOTC d507ba2339 force to stand when casting 3 months ago
FatBoy-DOTC 4ec5103454 saetor doomsayers 3 months ago
FatBoy-DOTC 3e09cd415e thread count on boot 3 months ago
FatBoy-DOTC 1098265145 player update handled in new thread 3 months ago
FatBoy-DOTC df7a106237 bane commander dialog reset options 3 months ago
FatBoy-DOTC 00b38970a1 bane commander dialog reset options 3 months ago
FatBoy-DOTC c1004e5817 bane commander dialog options 3 months ago
FatBoy-DOTC 13e9738345 bane commander dialog options 3 months ago
FatBoy-DOTC 1a7c1e2544 mine load error 3 months ago
FatBoy-DOTC ff082487b5 mine load error 3 months ago
FatBoy-DOTC 14cac0d892 mine load error 3 months ago
FatBoy-DOTC a8347e0b53 npc manager error spam 3 months ago
FatBoy-DOTC a73c3453ea npc manager error spam 3 months ago
FatBoy-DOTC a64932b2c9 Revert "npc manager error spam" 3 months ago
FatBoy-DOTC 685297171c npc manager error spam 3 months ago
FatBoy-DOTC 2e3e403165 trouble shooting mine bug 3 months ago
FatBoy-DOTC fbd910ef50 fix for flying bug 3 months ago
FatBoy-DOTC 30129d161f force respawn of dead players throwing error 3 months ago
FatBoy-DOTC a6510af56d force respawn of dead players throwing error 3 months ago
FatBoy-DOTC 9830920635 bane mechanic thread finalized 3 months ago
FatBoy-DOTC 93025b72cd bane mechanic thread finalized 3 months ago
FatBoy-DOTC 22639baa4c bane mechanic thread 3 months ago
FatBoy-DOTC 1aba8dfb11 bane mechanic thread 3 months ago
FatBoy-DOTC 8b4eb96262 bane mechanic thread 3 months ago
FatBoy-DOTC cafe6cd2fe bane mechanic thread 3 months ago
FatBoy-DOTC da6140f6f4 bane mechanic thread 3 months ago
FatBoy-DOTC 3fc68ce2ff bane mechanic thread 3 months ago
FatBoy-DOTC 5e8927245b bane mechanic thread 3 months ago
FatBoy-DOTC 75de1b3ae8 initiate baneAtendees 3 months ago
FatBoy-DOTC 6743114d19 update bane time first try 3 months ago
FatBoy-DOTC 28cca67cb3 Revert "update bane time first try" 3 months ago
FatBoy-DOTC bad7c6e798 update bane time first try 3 months ago
FatBoy-DOTC ecd3b38d3a update map when bane set 3 months ago
FatBoy-DOTC 8f09f16603 update map when bane set 3 months ago
FatBoy-DOTC 80812cb402 update map when bane set 3 months ago
FatBoy-DOTC 66fbf7aee6 update map when bane set 3 months ago
FatBoy-DOTC a92c603ab2 update map when bane set 3 months ago
FatBoy-DOTC 365438370d update map when bane set 3 months ago
FatBoy-DOTC a40b8fc915 update map when bane set 3 months ago
FatBoy-DOTC 5d92c1c86d bane system work 3 months ago
FatBoy-DOTC c526fd8847 bane system work 3 months ago
FatBoy-DOTC cd767dc68c bane system work 3 months ago
FatBoy-DOTC e21ebc75ee pets dont get sent home 3 months ago
FatBoy-DOTC 931eaaae4a city bane status update fix 3 months ago
FatBoy-DOTC 4d487e6bf0 city bane status update fix 3 months ago
FatBoy-DOTC 6c45a6573a null checks 3 months ago
FatBoy-DOTC 45b0dda7d9 remove duplicated gold and conc grants at character creation 3 months ago
FatBoy-DOTC caf3bc7470 remove option for 10 and 20 man banes based on trees in nation 3 months ago
FatBoy-DOTC 5259b801f7 bane ZergMultiplier value sfor 20-unlimited banes 3 months ago
FatBoy-DOTC 77e6d0db75 player guards to drop aggro once player leaves city 3 months ago
FatBoy-DOTC b2d7e5ec1e bane commander NPC work 3 months ago
FatBoy-DOTC 15bc99d216 bane commander NPC work 3 months ago
FatBoy-DOTC 63c6e2abd7 bane zerg mechanics enabled 3 months ago
FatBoy-DOTC 8ab97a1b36 bane zerg mechanics enabled 3 months ago
FatBoy-DOTC d1aa581879 players coutn towards Siege Cap at banes for 3 minutes after leaving bane area 3 months ago
FatBoy-DOTC 5f56143c5e fixed bug with negative xp when setting level to 10 3 months ago
FatBoy-DOTC 1a2b558ac3 fixed bug with negative xp when setting level to 10 3 months ago
FatBoy-DOTC 4f4ff74bf1 fixed bug with negative xp when setting level to 10 3 months ago
FatBoy-DOTC ded3b08080 fixed random rune drop chance 3 months ago
FatBoy-DOTC 14a29c8612 fixed NPC interaction 3 months ago
FatBoy-DOTC e66e430d30 fixed NPC interaction 3 months ago
FatBoy-DOTC c833f560c1 guard minion retaliation 3 months ago
FatBoy-DOTC 454c721842 zerg mechanic values adjusted 3 months ago
FatBoy-DOTC 26eda324dc adjusted global drop rates 3 months ago
FatBoy-DOTC 16951d36a2 bane commander NPC 3 months ago
FatBoy-DOTC e1d36125d2 bane commander NPC 3 months ago
FatBoy-DOTC 7a3c259d2f bane commander NPC 3 months ago
FatBoy-DOTC aa5fb2a2c5 bane commander NPC 3 months ago
FatBoy-DOTC a92cc6506c bane commander NPC 3 months ago
FatBoy-DOTC 3971548142 bane commander NPC 3 months ago
FatBoy-DOTC d94de771bf bane commander NPC 3 months ago
FatBoy-DOTC c5f47ffcd4 bane commander NPC 3 months ago
FatBoy-DOTC b336235ad7 bane commander NPC 3 months ago
FatBoy-DOTC eea07309aa bane commander NPC 3 months ago
FatBoy-DOTC 5529170036 bane commander NPC 3 months ago
FatBoy-DOTC 3d745e93b6 bane commander NPC 3 months ago
FatBoy-DOTC 019082bec7 bane commander NPC 3 months ago
FatBoy-DOTC 855cceea70 bane commander NPC 3 months ago
FatBoy-DOTC 487eae85e1 bane commander NPC 3 months ago
FatBoy-DOTC 5d188e61c0 bane commander NPC 3 months ago
FatBoy-DOTC 546c335198 bane commander NPC 3 months ago
FatBoy-DOTC aaecc5eda2 bane commander NPC 3 months ago
FatBoy-DOTC d13e939ddd bane commander NPC 3 months ago
FatBoy-DOTC afea79474e bane commander NPC 3 months ago
FatBoy-DOTC 05f555b5b5 bane commander NPC 3 months ago
FatBoy-DOTC 85931b6dc2 bane commander NPC 3 months ago
FatBoy-DOTC 9f0c7f6a76 bane commander NPC 3 months ago
FatBoy-DOTC 022c06c803 bane commander NPC 3 months ago
FatBoy-DOTC 1b72e7d6b7 bane commander NPC 3 months ago
FatBoy-DOTC 666ac6df5b bane commander NPC 3 months ago
FatBoy-DOTC 36481a53d9 bane commander NPC 3 months ago
FatBoy-DOTC 5a9901d775 bane commander NPC 3 months ago
FatBoy-DOTC b3a24d0158 fixed bug with trebs spamming console 3 months ago
FatBoy-DOTC 8890826070 fixed bug with trebs spamming console 3 months ago
FatBoy-DOTC daa84a1fef added MB_WORLD_TESTMODE to config manager and file 3 months ago
FatBoy-DOTC a4bd47f001 audit command for drop rates 3 months ago
FatBoy-DOTC d031f1be01 audit command for drop rates 3 months ago
FatBoy-DOTC a48abc59ce audit command for drop rates 3 months ago
FatBoy-DOTC 878f05c323 audit command for drop rates 3 months ago
FatBoy-DOTC d462711d25 audit command for drop rates 3 months ago
FatBoy-DOTC 40a0120a28 +1% drop disp[arity for mobs unde rlevel 50 AND introduce guard drops 3 months ago
FatBoy-DOTC ac812eaeae allow goto and teleportmode for players 3 months ago
FatBoy-DOTC 9965223d9b revert steward and builder sell inventory 7 months ago
FatBoy-DOTC 08b99d0d3a revert steward and builder sell inventory 7 months ago
FatBoy-DOTC 519a6a2b1e revert steward and builder sell inventory 7 months ago
FatBoy-DOTC 524f5d470b protocol error logging 7 months ago
FatBoy-DOTC 6631c6a5d7 protocol error logging 7 months ago
FatBoy-DOTC 10f95fb0d9 fixed banestone roll times 7 months ago
FatBoy-DOTC a315366026 disconnect after 10 minutes dead 7 months ago
FatBoy-DOTC 1901c9a679 disconnect after 10 minutes dead 7 months ago
FatBoy-DOTC 415ad5402f disconnect after 10 minutes dead 7 months ago
FatBoy-DOTC 9a40e12dbc castable enchants removed when item leaves players immediate posession 7 months ago
FatBoy-DOTC a1af663796 irekei healers get blood prophet 7 months ago
FatBoy-DOTC 78b7ddb32a saetor trains undone 7 months ago
FatBoy-DOTC 5e5ee4fed1 saetor trains 7 months ago
FatBoy-DOTC 84c022a39b saetor trains 7 months ago
FatBoy-DOTC 300741b05a saetor trains 7 months ago
FatBoy-DOTC dc685a01c6 remove roots form wildkins chase 7 months ago
FatBoy-DOTC 752f897a34 juiced up droppers 7 months ago
FatBoy-DOTC 722cb6b1fd Revert "high str NPCs" 7 months ago
FatBoy-DOTC 50c095cd09 high str NPCs 7 months ago
FatBoy-DOTC c23546eb46 10% cost for magical random rolls removed 7 months ago
FatBoy-DOTC 36340c4e52 fixed production bug for mines 7 months ago
FatBoy-DOTC a7ab38f40c can teleport to owned mines 7 months ago
FatBoy-DOTC 0901c03b74 can teleport to owned mines 7 months ago
FatBoy-DOTC 50817352c1 teleport to mines 7 months ago
FatBoy-DOTC ee4a7447bc teleport to mines 7 months ago
FatBoy-DOTC a6d3c827ad teleport to mines 7 months ago
FatBoy-DOTC d4ea31b91f teleport to mines 7 months ago
FatBoy-DOTC 210faaec6d refund gold for cancelled rolled items 7 months ago
FatBoy-DOTC 16be9b9dae refund gold for cancelled rolled items 7 months ago
FatBoy-DOTC 2b8f709182 stun grounds 7 months ago
FatBoy-DOTC aec22d8563 disable keyclone audit 7 months ago
FatBoy-DOTC 1996d042f0 fly speed changes finished 7 months ago
FatBoy-DOTC 27b6665717 fly speed changes 7 months ago
FatBoy-DOTC ce20045611 Merge remote-tracking branch 'origin/lakebane-strongholds' into lakebane-strongholds 7 months ago
FatBoy-DOTC 277f8bfd69 fly speed changes 7 months ago
FatBoy-DOTC 1da2db856f fly speed completed 7 months ago
FatBoy-DOTC 33dfe1389c move buff grounding 7 months ago
FatBoy-DOTC 013b69405a move buff grounding 7 months ago
FatBoy-DOTC ca07a53835 cast while flying 7 months ago
FatBoy-DOTC bbdb6ae1f6 cast while flying 7 months ago
FatBoy-DOTC 4a63222318 cast while flying 7 months ago
FatBoy-DOTC 1a1c552964 cast while flying 7 months ago
FatBoy-DOTC 3587dc2d75 builders sell things at proper ranks 7 months ago
FatBoy-DOTC 96eb9a3ad0 builders sell things at proper ranks 7 months ago
FatBoy-DOTC eaa70f43c0 stewards sell things at proper ranks 7 months ago
FatBoy-DOTC a426b773d3 sage on TOL 7 months ago
FatBoy-DOTC 84841edda9 r8 gets extra hireling slot 7 months ago
FatBoy-DOTC d416dbe47b shade hide 7 months ago
FatBoy-DOTC 7052da7e54 shade hide 7 months ago
FatBoy-DOTC 8f2a2f0ba6 Rogue Druids 7 months ago
FatBoy-DOTC d575ba663d displayed maintenance for r8 tree no longer shows resource required 7 months ago
FatBoy-DOTC 964fe7f335 city serilizing bug 7 months ago
FatBoy-DOTC d3e92d6576 city serilizing bug 7 months ago
FatBoy-DOTC 9dbd6069f1 force respawn after 10 minutes dead 7 months ago
FatBoy-DOTC 7ae25c9a1b can now summon in combat 7 months ago
FatBoy-DOTC 689969a005 r* tree buildings acquire 10% more HP 7 months ago
FatBoy-DOTC b270e1ac8d r8 maintenance flat 3 mil 7 months ago
FatBoy-DOTC 95d38cea44 rogue can promote to druid 7 months ago
FatBoy-DOTC 3ed0765fe5 flying while having move buff fix 7 months ago
FatBoy-DOTC 0c90164c24 shade invis bug 7 months ago
FatBoy-DOTC a45fa39afc random roll magic extra cost removed 7 months ago
FatBoy-DOTC 8959f5e1c5 r7 votary grants PR40 boon 7 months ago
FatBoy-DOTC df338ab00e fix resource vendor pricing 7 months ago
FatBoy-DOTC ac7a2452d6 disable strongholds 7 months ago
FatBoy-DOTC 80104e6d07 fixed login bug 7 months ago
FatBoy-DOTC 8f394cd01d fixed login bug 7 months ago
FatBoy-DOTC e5a32c83c5 Revert "mine production values adjusted" 7 months ago
FatBoy-DOTC 8dce20e69f Revert "adjusted hit chance formula" 7 months ago
FatBoy-DOTC 3428a06bb8 adjusted hit chance formula 7 months ago
FatBoy-DOTC 177f9a1ff6 mine production values adjusted 7 months ago
FatBoy-DOTC 9d93944dd1 mob roll levels 7 months ago
FatBoy-DOTC a4cba1a352 better roll chance for high level vendors 7 months ago
FatBoy-DOTC 17b4232d80 better roll chance for high level vendors 7 months ago
FatBoy-DOTC 2eb58eb719 custom hit chance formula 7 months ago
FatBoy-DOTC db5a4195ad custom hit chance formula 7 months ago
FatBoy-DOTC 3fb29f8e2b custom hit chance formula 7 months ago
FatBoy-DOTC dacdb2cf35 stronghold mobs 7 months ago
FatBoy-DOTC c8473cbe03 stronghold mobs 7 months ago
FatBoy-DOTC e9edf8a7ea increase number of strongholds 7 months ago
FatBoy-DOTC 5a73aa3d90 increase number of strongholds 7 months ago
FatBoy-DOTC 04101c1c3e additional 60 second logout timer for players who have enemies nearby and aren't in safezone 7 months ago
FatBoy-DOTC 0c9343f24d additional 60 second logout timer for players who have enemies nearby and aren't in safezone 7 months ago
FatBoy-DOTC b71710871c track list construction 7 months ago
FatBoy-DOTC f6df6db17b level cap increased to 80 7 months ago
FatBoy-DOTC 3f8b3bc6cb PVP xp enabled 7 months ago
FatBoy-DOTC 383ef27128 can use abilities while flying 7 months ago
FatBoy-DOTC d8189768ae mine production cut in half 7 months ago
FatBoy-DOTC a5eb2fce75 mine management to show correct production amount 7 months ago
FatBoy-DOTC 1fe242a284 strip temporary item enchants when transfered 7 months ago
FatBoy-DOTC a4b83ca9a0 increase resists of the droppers 7 months ago
FatBoy-DOTC 2365b26c1c trainer buildinsg capped at r1 with 3 slots 7 months ago
FatBoy-DOTC 8fb044f71b trainer buildinsg capped at r1 with 3 slots 7 months ago
FatBoy-DOTC 5ce42475c4 force respawn after 10 minutes of unreleased corpse 7 months ago
FatBoy-DOTC 57b9d31fff dropper resists 7 months ago
FatBoy-DOTC 7671586cb0 terraform issue 7 months ago
FatBoy-DOTC a1997e31a8 terraform issue 7 months ago
FatBoy-DOTC f5478e9f64 terraform issue 7 months ago
FatBoy-DOTC 06abea3576 terraform issue 7 months ago
FatBoy-DOTC ae6b584a5f DS immunity fixed 7 months ago
FatBoy-DOTC 9e27c69906 trainer buildings get 3 slots at r1 7 months ago
FatBoy-DOTC 00afe27900 stealing from mobs works again 7 months ago
FatBoy-DOTC 4e5c1a32d3 stronghold mob equipsets 7 months ago
FatBoy-DOTC d4f5043a25 toughness sync issue 7 months ago
FatBoy-DOTC 03a5a55974 remove NPC slot error spam onboot 7 months ago
FatBoy-DOTC dbab4c1212 baked in stats null check 7 months ago
FatBoy-DOTC d186a96796 non vorg droppers cannot drop vorg items 7 months ago
FatBoy-DOTC 6880d014c3 elan vendor price increased to 1,000,000 7 months ago
FatBoy-DOTC 6542dec358 saetors can take disc runes 7 months ago
FatBoy-DOTC 1a2738c3a9 saetors can take disc runes 7 months ago
FatBoy-DOTC 12118ff125 fixed saetor promotions 7 months ago
FatBoy-DOTC c3a00186ff saetors allowed to take creation runes 7 months ago
FatBoy-DOTC fafa777e98 saetor creation fixed 7 months ago
FatBoy-DOTC d4da99f61c NPC sell% in safezone = 0 7 months ago
FatBoy-DOTC bb293c0c02 BH eyes get double value for points in skill (20 points = PR40) 7 months ago
FatBoy-DOTC 1e29971b3c safe NPC profits 7 months ago
FatBoy-DOTC 25d70cca4f error message for flying with movement buff 7 months ago
FatBoy-DOTC 362832a196 NPC safezone sell% = 0 7 months ago
FatBoy-DOTC ed150a5ccd gimme command bumps level to 75 7 months ago
FatBoy-DOTC d2247b66f1 safezone NPCs have 0% profit 7 months ago
FatBoy-DOTC 3b58ea716c custom range for booty sim command 7 months ago
FatBoy-DOTC 368e548e46 special case rolls for contracts, glass, resources and runes 7 months ago
FatBoy-DOTC 6f3612d196 Elf Blood Runes Free 7 months ago
FatBoy-DOTC 0f38146fcc extra stats on printstats 7 months ago
FatBoy-DOTC 1a13f3f096 hit roll formula fixed 7 months ago
FatBoy-DOTC 9cc102ca2a scrolls removed from form breaking 7 months ago
FatBoy-DOTC 50ff4b89bf granted concnc pot fixed 7 months ago
FatBoy-DOTC 9b898825ab no move buff while flying 7 months ago
FatBoy-DOTC 5be9033c40 no move buff while flying 7 months ago
FatBoy-DOTC 67e55ab0a0 no move buff while flying 7 months ago
FatBoy-DOTC 227549bf22 no move buff while flying 7 months ago
FatBoy-DOTC 19707d10a3 no move buff while flying 7 months ago
FatBoy-DOTC 91565ced89 no move buff while flying 7 months ago
FatBoy-DOTC 2383b00c8c mobs recall when out of range of their bind loc 7 months ago
FatBoy-DOTC 405063f036 guilds MOTD now persist 7 months ago
FatBoy-DOTC d2f3c6a879 potions and scrolls no longer count as casting a spell 7 months ago
FatBoy-DOTC 4f759c1bd2 shade sneak 7 months ago
FatBoy-DOTC 9d7f9ce7b3 no movement buffs while flying, cannot fly if you have a movement buff applied 7 months ago
FatBoy-DOTC 56f3dfce92 no movement buffs while flying, cannot fly if you have a movement buff applied 7 months ago
FatBoy-DOTC 9a66f18edb extra 60 seconds added to summon if enemies near and not in safezone 7 months ago
FatBoy-DOTC d7270ffb84 group teleport restricted to active banes and active mines 7 months ago
FatBoy-DOTC dd834a3104 cant delete buildings when baned 7 months ago
FatBoy-DOTC e28ed1b882 fortitude handled after resists 7 months ago
FatBoy-DOTC 2370123c72 hit roll formula added 7 months ago
FatBoy-DOTC 8a5133f04b character starts with 1000 gold and a conc pot 7 months ago
FatBoy-DOTC a0f874b319 cannot tax cities in realm 7 months ago
FatBoy-DOTC 415d11ae33 Vorg droppers increased level and resists 7 months ago
FatBoy-DOTC f93b1ce30e teleport to runegate power action fix for closest gate 7 months ago
FatBoy-DOTC 9fb2e4ff1b apply rune message work 7 months ago
FatBoy-DOTC 601d0f4324 special case drop rate for contracts runes and resources completed 7 months ago
FatBoy-DOTC cbf7db3347 mine production issue resolved 7 months ago
FatBoy-DOTC 217be1d234 Special Case rune contract and resource drops 7 months ago
FatBoy-DOTC 7fabd6554d glass chance is 10/100,000 7 months ago
FatBoy-DOTC d673819796 gimme command 7 months ago
FatBoy-DOTC a963a331a2 mobs that spawn with no loot respawn again 7 months ago
FatBoy-DOTC eda5b8995f stronghold mobs power sets 7 months ago
FatBoy-DOTC d5e95eedf3 stronghold loot adjustment 7 months ago
FatBoy-DOTC 032e703704 gimme command for testing 7 months ago
FatBoy-DOTC ad1444f5ba level 70+ is allowed to apply a fifth disc rune 7 months ago
FatBoy-DOTC a4b30b8620 level cap increased to 80 7 months ago
FatBoy-DOTC 9c002c7bff updated stronghold mobs 9 months ago
FatBoy-DOTC 90495a27d9 blood rune dropper issue resolved 9 months ago
FatBoy-DOTC 1246fa699a blood rune boot issue 9 months ago
FatBoy-DOTC 511d37f5e0 blood rune droppers moved to DB with client patch 9 months ago
FatBoy-DOTC 7a03a0eaa9 noob conc pots 9 months ago
FatBoy-DOTC 2f57cb613e noob conc pots 9 months ago
FatBoy-DOTC e386c3078a noob conc pots 9 months ago
FatBoy-DOTC 3802889834 allow applying blood runes 9 months ago
FatBoy-DOTC f825b2baba negate stronghold mobs from dropping equipment 9 months ago
FatBoy-DOTC 6c92abd083 present drops restricted to strongholds 9 months ago
FatBoy-DOTC c652379a5f mob region lookup 9 months ago
FatBoy-DOTC 61d34ab4ad hotfixes 9 months ago
FatBoy-DOTC d511641410 hotfixes 9 months ago
FatBoy-DOTC c8430625bf mob resists fix 9 months ago
FatBoy-DOTC a418224bbb start random roll at 0 to avoid illegal argument 9 months ago
FatBoy-DOTC 9e3c13dea3 generic resists added for mobs to stop crashing AI 9 months ago
FatBoy-DOTC 335850f7ff stronghold epics target playe rnot self 9 months ago
FatBoy-DOTC f6baf8fe83 resistance modifiers for mobs 9 months ago
FatBoy-DOTC 4c9b82b649 def and ATR cuts for stronghold mobs 9 months ago
FatBoy-DOTC f2570992e5 completed custom strongholds 9 months ago
FatBoy-DOTC 6911d6314d epic encounter naming convention 9 months ago
FatBoy-DOTC eaeea9730c epic encounter naming convention 9 months ago
FatBoy-DOTC fb0790a733 epic encounter after clearing a stronghold 9 months ago
FatBoy-DOTC 3230cd53e1 epic encounter after clearing a stronghold 9 months ago
FatBoy-DOTC edbce067b8 epic encounter after clearing a stronghold 9 months ago
FatBoy-DOTC 83877e5107 epic encounter after clearing a stronghold 9 months ago
FatBoy-DOTC 3a67540212 stronghold attack messages 9 months ago
FatBoy-DOTC 1a5db96023 stronghold mobs spawn 2x mines cap size 9 months ago
FatBoy-DOTC ef82f9ab5b stronghold mobs no longer lose bonuses from weapon powers 9 months ago
FatBoy-DOTC bf7e5c6333 stronghold guardian fix 9 months ago
FatBoy-DOTC 443f0f5450 stronghold guardian fix 9 months ago
FatBoy-DOTC cb1dccd630 stronghold guardian fix 9 months ago
FatBoy-DOTC 2e558acbee stronghold guardian fix 9 months ago
FatBoy-DOTC 74162ea54c stronghold guardian fix 9 months ago
FatBoy-DOTC ccbe4fba04 stronghold guardian fix 9 months ago
FatBoy-DOTC 5aeddb6166 stronghold guardian fix 9 months ago
FatBoy-DOTC 49df5203ae stronghold guardian fix 9 months ago
FatBoy-DOTC 0cfe801d18 stronghold guardian fix 9 months ago
FatBoy-DOTC 89c01e8244 random item generation fix 9 months ago
FatBoy-DOTC 6605e4dd61 update regions when changing mesh 9 months ago
FatBoy-DOTC d6239de6fd delete stronghold mobs form DB when finished 9 months ago
FatBoy-DOTC 99ad6f3712 delete stronghold mobs form DB when finished 9 months ago
FatBoy-DOTC f3041e7549 SetLoc for stronghold mobs 9 months ago
FatBoy-DOTC 1269031be3 SetLoc for stronghold mobs 9 months ago
FatBoy-DOTC ce96274f28 SetLoc for stronghold mobs 9 months ago
FatBoy-DOTC a9a9bd0a3d Stronghold variations 9 months ago
FatBoy-DOTC 33789adadc final strongholds update 9 months ago
FatBoy-DOTC 15b50a75c4 commander stats update 9 months ago
FatBoy-DOTC ead34dbb1f commander powers 9 months ago
FatBoy-DOTC a9b1356efa new stronghold mesh 9 months ago
FatBoy-DOTC 33e105bc7b naming convention 9 months ago
FatBoy-DOTC e5041147f4 added disc and rune to commander drops 9 months ago
FatBoy-DOTC 576e627ad1 fixed loot generation array size bug 9 months ago
FatBoy-DOTC 4059664354 stronghold loot 9 months ago
FatBoy-DOTC 974c0ca7e8 force load changes meshes 9 months ago
FatBoy-DOTC 8e7a7b8b6d stronghold scale set 9 months ago
FatBoy-DOTC 1e3b1db905 commander location set 9 months ago
FatBoy-DOTC 51c98746c4 make stronghold mobs aggro 9 months ago
FatBoy-DOTC 4c21439847 serialize the stronghold mine 9 months ago
FatBoy-DOTC 31385ee533 SCALING DOWN THE STRONGHOLD BUILDING 9 months ago
FatBoy-DOTC bd4e34e0e1 SCALING DOWN THE STRONGHOLD BUILDING 9 months ago
FatBoy-DOTC 9f591b166b Initial Stronghold Push 9 months ago
FatBoy-DOTC 7e457fa17b all items form "Noob Helper" cost 2 gold 9 months ago
FatBoy-DOTC 926b9d2bae R8 ToL can have 4 shrines 9 months ago
FatBoy-DOTC c5822b5acf dropper resists and level increase 9 months ago
FatBoy-DOTC 516b66a50a reintroduce blood rune droppers on 3 hour disc cycle 9 months ago
FatBoy-DOTC 39305d63c7 noob island gear 9 months ago
FatBoy-DOTC c0cb856961 noob island gear 9 months ago
FatBoy-DOTC 2fb97a676f allow some dev commands for players (print) 9 months ago
FatBoy-DOTC cbff151dc3 allow some dev commands for players (print) 9 months ago
FatBoy-DOTC eed75fd2fd repair costs calculated properly 9 months ago
FatBoy-DOTC 6374390b34 repair cost synced with server values 9 months ago
FatBoy-DOTC 2185d3ef7c rune merchants pricing adjusts 9 months ago
FatBoy-DOTC 4aaa96e36c resourc emerchant pricing adjust 9 months ago
FatBoy-DOTC bf86680547 higher present drop chance 9 months ago
FatBoy-DOTC 960307e262 rune pricing fix 9 months ago
FatBoy-DOTC eedf96cc31 resource pricing fix 9 months ago
FatBoy-DOTC 6fb5fce4d3 fixed profit error for NPCs 9 months ago
FatBoy-DOTC 7688d21fe6 boons refreshable, boon level determined by votary rank, shrines should work for all, boons nation friendly again 9 months ago
FatBoy-DOTC 23e60b36b4 General Cleanup and drop rates 9 months ago
FatBoy-DOTC ab8fc8e0a0 random vorg droppers, max durability repairable 9 months ago
FatBoy-DOTC b30f04046d uniform disc dropper times 9 months ago
FatBoy-DOTC 9bd03c7d43 pricing corrected for rune vendors 9 months ago
FatBoy-DOTC 78118a1ac1 fix for rune application 9 months ago
FatBoy-DOTC 1f863d0cce resource pricing fix 9 months ago
FatBoy-DOTC c49204aeeb NPC have 0 maint, fix for resource merchant 9 months ago
FatBoy-DOTC b1de3755fd display correct maintenance costs 9 months ago
FatBoy-DOTC 83a1cc5aba maintenance display on buildings 9 months ago
FatBoy-DOTC 9b0b15c31e remove refund for deranked building due to maintenance 9 months ago
FatBoy-DOTC 802651d2d4 rune application error fixed 9 months ago
FatBoy-DOTC 52a48e5618 rune application checks 9 months ago
FatBoy-DOTC 14fe248e19 mine serializing 9 months ago
FatBoy-DOTC 5b81be371e mine serializing 9 months ago
FatBoy-DOTC 82d67f2850 mine serializing 9 months ago
FatBoy-DOTC 1c342bd566 server pop on creation displays amount of realms captured 9 months ago
FatBoy-DOTC bb8ad3c971 character creation population message 9 months ago
FatBoy-DOTC e9fef85b72 set maintenance dates correctly 9 months ago
FatBoy-DOTC c0d1a4f274 mines produce once a day, maintenance system for TOL only 9 months ago
FatBoy-DOTC 94be3335a0 mine production change error tracking 9 months ago
FatBoy-DOTC 7d03f78546 rune application require/restrict actually use values 9 months ago
FatBoy-DOTC 023f933d0b rune application require/restrict actually use values 9 months ago
FatBoy-DOTC 9995cc01b7 rune application require/restrict actually use values 9 months ago
FatBoy-DOTC fd03b263d1 pets follow owners through teleporting 9 months ago
FatBoy-DOTC 6a09a3fd44 pets follow owners through teleporting 9 months ago
FatBoy-DOTC 1322f8610c safe guards dont kill pets anymore 9 months ago
FatBoy-DOTC 90ab6175b5 extra ToL slots 9 months ago
FatBoy-DOTC 2e3e9ee882 extra ToL slots 9 months ago
FatBoy-DOTC 5158329785 Saetor can take Chaos Shrine boon 9 months ago
FatBoy-DOTC b8e0165da2 allowed siege engineer alchemist and banker on ToL 9 months ago
FatBoy-DOTC 0fa6ebc136 fix pets 9 months ago
FatBoy-DOTC 4e5e362197 attempt to fix mine serialization 10 months ago
FatBoy-DOTC 61514fef2b attempt to fix mine serialization 10 months ago
FatBoy-DOTC 59e593ab0d attempt to fix mine serialization 10 months ago
FatBoy-DOTC 2c6ea98ef9 revert instant respawns 10 months ago
FatBoy-DOTC bd3ea16b57 faster respawns 10 months ago
FatBoy-DOTC 45165332f6 faster respawns 10 months ago
FatBoy-DOTC d764a66e55 logging 10 months ago
FatBoy-DOTC ac41e64429 logging 10 months ago
FatBoy-DOTC 462beb30b3 logging 10 months ago
FatBoy-DOTC 3a89e9c087 logging 10 months ago
FatBoy-DOTC e71863cbd2 logging 10 months ago
FatBoy-DOTC 5ec0ff0598 logging 10 months ago
FatBoy-DOTC 2ca9b77cfb logging 10 months ago
FatBoy-DOTC 4f535ef5fe loot manager for glass runes and contracts 10 months ago
FatBoy-DOTC a46ad71bb0 loot manager for glass runes and contracts 10 months ago
FatBoy-DOTC 90d6911d41 loot manager for glass runes and contracts 10 months ago
FatBoy-DOTC e13ebae0df loot manager for glass runes and contracts 10 months ago
FatBoy-DOTC 3e15fc8206 bootysim command work 10 months ago
FatBoy-DOTC 6a400467dd drop rate work 10 months ago
FatBoy-DOTC 488188e9c3 glass chance work 10 months ago
FatBoy-DOTC 0d31bc4280 contract and rune drop work 10 months ago
FatBoy-DOTC 6375b4431c box check 10 months ago
FatBoy-DOTC 683422f8a4 auto identify all items 10 months ago
FatBoy-DOTC e4dbad2669 generic loot system in place 10 months ago
FatBoy-DOTC 34721fdee8 generic loot system in place 10 months ago
FatBoy-DOTC f27668552c corrected pricing for +10 runes 10 months ago
FatBoy-DOTC 306fdf4235 permanent open runegates 10 months ago
FatBoy-DOTC 553b09d827 rune pricing corrected 10 months ago
FatBoy-DOTC 8ee17f0c64 fix resource merchant elan stones pricing 10 months ago
FatBoy-DOTC 7e5ad644d3 fix resource merchant elan stones 10 months ago
FatBoy-DOTC 846b8a7cde fix resource merchant margins 10 months ago
FatBoy-DOTC f27a4f174b error popup when trying to flag unboxed too frequently 10 months ago
FatBoy-DOTC c6d4375aa8 error popup when trying to flag unboxed too frequently 10 months ago
FatBoy-DOTC b9ec54c76a enrollment office removes DS effect 10 months ago
FatBoy-DOTC b351d7c1ae enrollment officer system 10 months ago
FatBoy-DOTC 729ebe7cd0 box checker 10 months ago
FatBoy-DOTC f51c28e708 revert boxing enforcement 10 months ago
FatBoy-DOTC 9fbf55127d sourcetype lookup fix 10 months ago
FatBoy-DOTC f9fd61dc6b revert sourcetype lookup fix 10 months ago
FatBoy-DOTC 4f198e1f53 Merge remote-tracking branch 'origin/lakebane-new' into lakebane-new 10 months ago
FatBoy-DOTC 24c85a5140 revert sourcetype lookup fix 10 months ago
FatBoy-DOTC 3e1a5f4ccd SpurceType lookup fixes for Piercing Crushing and Slashing 10 months ago
FatBoy-DOTC 34e5a3878c SpurceType lookup fixes for Piercing Crushing and Slashing 10 months ago
FatBoy-DOTC 663e285091 Deathshroud applied ot all boxed characters 10 months ago
FatBoy-DOTC d87c03bb79 fixed combat message to reflect proper zerg multiplier values 10 months ago
FatBoy-DOTC abc57688d3 reset zerg multipliers when window closes 10 months ago
FatBoy-DOTC 29671d56fc display zerg multiplier in ./info 10 months ago
FatBoy-DOTC e8cf6a722b remove hotzone form the game 10 months ago
FatBoy-DOTC 2793ec331b mines revert to claimable at 1am CST 10 months ago
FatBoy-DOTC 1a0b91b068 buying larger stacks of resources form resource vendor 10 months ago
FatBoy-DOTC bec6cbe6e6 implement stat modifications for the ZergMultiplier 10 months ago
FatBoy-DOTC f7ab10ff07 altered mine production values 10 months ago
FatBoy-DOTC 9671cbdc1a unlimited sub guilds 10 months ago
FatBoy-DOTC e0af1f5932 no caps on claimable mines for nations 10 months ago
FatBoy-DOTC 8cb52c6142 zerg multiplier resets for players after mine closes 10 months ago
FatBoy-DOTC e5133211a9 Zerg Mechanic for Mines 10 months ago
FatBoy-DOTC 8548612a80 items auto ID 10 months ago
FatBoy-DOTC 41c3193275 irekei movespeed fix 10 months ago
FatBoy-DOTC 15771d2802 new characters start at level 10 10 months ago
FatBoy-DOTC b4a62e5f3e update inventory when junking for gold 10 months ago
FatBoy-DOTC fc7e6735a1 mine tower health scales with cap size 10 months ago
FatBoy-DOTC aeb21c328e max slots for rank adjustments 10 months ago
FatBoy-DOTC 9a34b13c2e junk from inventory 10 months ago
FatBoy-DOTC 231feef7fe mines open during a reboot time frame now open correctly 10 months ago
FatBoy-DOTC 0e6b68139f refactor mine processing to HalfHourlyJob 10 months ago
FatBoy-DOTC ef62c2bb39 mines open and close 10 months ago
FatBoy-DOTC 8f68997f3c terraform size correction 10 months ago
FatBoy-DOTC aebe2698c3 terraform size correction 10 months ago
FatBoy-DOTC 54e7a8fc7f display mine times correctly 10 months ago
FatBoy-DOTC 8b4d37c53c fix for mines loading 10 months ago
FatBoy-DOTC fbfca46d2f fix for mines loading 10 months ago
FatBoy-DOTC 3228f473de fix for mines loading 10 months ago
FatBoy-DOTC 17fcf0ee40 duplicated zone loading disabled 10 months ago
FatBoy-DOTC 395fe31e02 duplicated zone loading disabled 10 months ago
FatBoy-DOTC e98f9cf1f7 duplicated zone loading disabled 10 months ago
FatBoy-DOTC fe0c0f97a5 duplicated zone loading disabled 10 months ago
FatBoy-DOTC 7e27838818 mine changes 10 months ago
FatBoy-DOTC bc8094c20c saetor race as minotaurs 10 months ago
  1. 150
      src/engine/Dungeons/Dungeon.java
  2. 105
      src/engine/Dungeons/DungeonManager.java
  3. 53
      src/engine/Enum.java
  4. 38
      src/engine/InterestManagement/InterestManager.java
  5. 116
      src/engine/ZergMehcanics/MineAntiZerg.java
  6. 38
      src/engine/db/handlers/dbAccountHandler.java
  7. 166
      src/engine/db/handlers/dbBaneHandler.java
  8. 14
      src/engine/db/handlers/dbCityHandler.java
  9. 56
      src/engine/db/handlers/dbContractHandler.java
  10. 17
      src/engine/db/handlers/dbHandlerBase.java
  11. 24
      src/engine/db/handlers/dbItemBaseHandler.java
  12. 24
      src/engine/db/handlers/dbItemHandler.java
  13. 38
      src/engine/db/handlers/dbNPCHandler.java
  14. 7
      src/engine/devcmd/cmds/AddGoldCmd.java
  15. 37
      src/engine/devcmd/cmds/AddMobCmd.java
  16. 47
      src/engine/devcmd/cmds/AddNPCCmd.java
  17. 54
      src/engine/devcmd/cmds/DungenonCmd.java
  18. 64
      src/engine/devcmd/cmds/GimmeCmd.java
  19. 77
      src/engine/devcmd/cmds/HotzoneCmd.java
  20. 38
      src/engine/devcmd/cmds/InfoCmd.java
  21. 5
      src/engine/devcmd/cmds/MineActiveCmd.java
  22. 75
      src/engine/devcmd/cmds/PrintEffectsCmd.java
  23. 2
      src/engine/devcmd/cmds/PrintSkillsCmd.java
  24. 56
      src/engine/devcmd/cmds/PrintStatsCmd.java
  25. 4
      src/engine/devcmd/cmds/SetLevelCmd.java
  26. 74
      src/engine/devcmd/cmds/SimulateBootyCmd.java
  27. 168
      src/engine/gameManager/ArenaManager.java
  28. 37
      src/engine/gameManager/BuildingManager.java
  29. 10
      src/engine/gameManager/ChatManager.java
  30. 382
      src/engine/gameManager/CombatManager.java
  31. 4
      src/engine/gameManager/ConfigManager.java
  32. 42
      src/engine/gameManager/DevCmdManager.java
  33. 289
      src/engine/gameManager/HellgateManager.java
  34. 238
      src/engine/gameManager/HotzoneManager.java
  35. 772
      src/engine/gameManager/LootManager.java
  36. 130
      src/engine/gameManager/LoreMineManager.java
  37. 123
      src/engine/gameManager/MaintenanceManager.java
  38. 17
      src/engine/gameManager/MovementManager.java
  39. 4
      src/engine/gameManager/NPCManager.java
  40. 633
      src/engine/gameManager/PowersManager.java
  41. 72
      src/engine/gameManager/SimulationManager.java
  42. 277
      src/engine/gameManager/SpecialLootHandler.java
  43. 347
      src/engine/gameManager/StrongholdManager.java
  44. 274
      src/engine/gameManager/ZergManager.java
  45. 73
      src/engine/gameManager/ZoneManager.java
  46. 2
      src/engine/job/AbstractJob.java
  47. 2
      src/engine/job/AbstractScheduleJob.java
  48. 2
      src/engine/job/JobContainer.java
  49. 75
      src/engine/job/JobThread.java
  50. 9
      src/engine/job/JobWorker.java
  51. 4
      src/engine/jobs/AbstractEffectJob.java
  52. 2
      src/engine/jobs/ActivateBaneJob.java
  53. 2
      src/engine/jobs/AttackJob.java
  54. 2
      src/engine/jobs/BaneDefaultTimeJob.java
  55. 2
      src/engine/jobs/BasicScheduledJob.java
  56. 2
      src/engine/jobs/BonusCalcJob.java
  57. 2
      src/engine/jobs/CSessionCleanupJob.java
  58. 2
      src/engine/jobs/ChangeAltitudeJob.java
  59. 2
      src/engine/jobs/ChantJob.java
  60. 2
      src/engine/jobs/CloseGateJob.java
  61. 4
      src/engine/jobs/DamageOverTimeJob.java
  62. 2
      src/engine/jobs/DatabaseUpdateJob.java
  63. 2
      src/engine/jobs/DebugTimerJob.java
  64. 2
      src/engine/jobs/DeferredPowerJob.java
  65. 2
      src/engine/jobs/DisconnectJob.java
  66. 2
      src/engine/jobs/DoorCloseJob.java
  67. 2
      src/engine/jobs/EndFearJob.java
  68. 2
      src/engine/jobs/FinishCooldownTimeJob.java
  69. 2
      src/engine/jobs/FinishEffectTimeJob.java
  70. 2
      src/engine/jobs/FinishRecycleTimeJob.java
  71. 2
      src/engine/jobs/FinishSpireEffectJob.java
  72. 12
      src/engine/jobs/FinishSummonsJob.java
  73. 2
      src/engine/jobs/LoadEffectsJob.java
  74. 2
      src/engine/jobs/LogoutCharacterJob.java
  75. 2
      src/engine/jobs/NoTimeJob.java
  76. 9
      src/engine/jobs/PersistentAoeJob.java
  77. 2
      src/engine/jobs/RefreshGroupJob.java
  78. 2
      src/engine/jobs/RemoveCorpseJob.java
  79. 2
      src/engine/jobs/SiegeSpireWithdrawlJob.java
  80. 2
      src/engine/jobs/StuckJob.java
  81. 2
      src/engine/jobs/SummonSendJob.java
  82. 2
      src/engine/jobs/TeleportJob.java
  83. 2
      src/engine/jobs/TrackJob.java
  84. 2
      src/engine/jobs/TransferStatOTJob.java
  85. 2
      src/engine/jobs/UpdateGroupJob.java
  86. 16
      src/engine/jobs/UpgradeBuildingJob.java
  87. 2
      src/engine/jobs/UpgradeNPCJob.java
  88. 2
      src/engine/jobs/UseItemJob.java
  89. 2
      src/engine/jobs/UseMobPowerJob.java
  90. 2
      src/engine/jobs/UsePowerJob.java
  91. 22
      src/engine/loot/ItemTableEntry.java
  92. 10
      src/engine/loot/ModTableEntry.java
  93. 2
      src/engine/math/Bounds.java
  94. 266
      src/engine/mobileAI/Behaviours/StandardMob.java
  95. 425
      src/engine/mobileAI/MobAI.java
  96. 26
      src/engine/mobileAI/Threads/MobAIThread.java
  97. 50
      src/engine/mobileAI/Threads/MobRespawnThread.java
  98. 188
      src/engine/mobileAI/utilities/CombatUtilities.java
  99. 14
      src/engine/mobileAI/utilities/MovementUtilities.java
  100. 2
      src/engine/net/AbstractConnection.java
  101. Some files were not shown because too many files have changed in this diff Show More

150
src/engine/Dungeons/Dungeon.java

@ -0,0 +1,150 @@ @@ -0,0 +1,150 @@
package engine.Dungeons;
import engine.Enum;
import engine.InterestManagement.WorldGrid;
import engine.gameManager.BuildingManager;
import engine.gameManager.PowersManager;
import engine.gameManager.ZoneManager;
import engine.math.Vector3fImmutable;
import engine.net.ByteBufferWriter;
import engine.objects.*;
import engine.powers.EffectsBase;
import engine.server.MBServerStatics;
import org.pmw.tinylog.Logger;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashSet;
public class Dungeon {
public static int NoFlyEffectID = -1733819072;
public static int NoTeleportEffectID = -1971545187;
public static int NoSummonEffectID = 2122002462;
public ArrayList<PlayerCharacter> participants;
public int maxPerGuild;
public Vector3fImmutable entrance;
public ArrayList<Mob> dungeon_mobs;
public Long respawnTime = 0L;
public Dungeon(Vector3fImmutable entrance, int maxCount){
this.participants = new ArrayList<>();
this.entrance = entrance;
this.dungeon_mobs = new ArrayList<>();
this.maxPerGuild = maxCount;
}
public void applyDungeonEffects(PlayerCharacter player){
EffectsBase noFly = PowersManager.getEffectByToken(NoFlyEffectID);
EffectsBase noTele = PowersManager.getEffectByToken(NoTeleportEffectID);
EffectsBase noSum = PowersManager.getEffectByToken(NoSummonEffectID);
if(noFly != null)
player.addEffectNoTimer(noFly.getName(),noFly,40,true);
if(noTele != null)
player.addEffectNoTimer(noTele.getName(),noTele,40,true);
if(noSum != null)
player.addEffectNoTimer(noSum.getName(),noSum,40,true);
}
public void removeDungeonEffects(PlayerCharacter player) {
EffectsBase noFly = PowersManager.getEffectByToken(NoFlyEffectID);
EffectsBase noTele = PowersManager.getEffectByToken(NoTeleportEffectID);
EffectsBase noSum = PowersManager.getEffectByToken(NoSummonEffectID);
for (Effect eff : player.effects.values()) {
if (noFly != null && eff.getEffectsBase().equals(noFly))
eff.endEffect();
if (noTele != null && eff.getEffectsBase().equals(noTele))
eff.endEffect();
if (noSum != null && eff.getEffectsBase().equals(noSum))
eff.endEffect();
}
}
public static void serializeForClientMsgTeleport(ByteBufferWriter writer) {
Guild rulingGuild = Guild.getErrantGuild();
Guild rulingNation = Guild.getErrantGuild();
Zone zone = ZoneManager.getZoneByUUID(994);
// Begin Serialzing soverign guild data
writer.putInt(Enum.GameObjectType.Zone.ordinal());
writer.putInt(994);
writer.putString("Whitehorn Citadel");
writer.putInt(rulingGuild.getObjectType().ordinal());
writer.putInt(rulingGuild.getObjectUUID());
writer.putString("Whitehorn Militants"); // guild name
writer.putString("In the Citadel, We Fight!"); // motto
writer.putString(rulingGuild.getLeadershipType());
// Serialize guild ruler's name
// If tree is abandoned blank out the name
// to allow them a rename.
writer.putString("Kol'roth The Destroyer");//sovreign
writer.putInt(rulingGuild.getCharter());
writer.putInt(0); // always 00000000
writer.put((byte)0);
writer.put((byte) 1);
writer.put((byte) 1); // *** Refactor: What are these flags?
writer.put((byte) 1);
writer.put((byte) 1);
writer.put((byte) 1);
GuildTag._serializeForDisplay(rulingGuild.getGuildTag(), writer);
GuildTag._serializeForDisplay(rulingNation.getGuildTag(), writer);
writer.putInt(0);// TODO Implement description text
writer.put((byte) 1);
writer.put((byte) 0);
writer.put((byte) 1);
// Begin serializing nation guild info
if (rulingNation.isEmptyGuild()) {
writer.putInt(rulingGuild.getObjectType().ordinal());
writer.putInt(rulingGuild.getObjectUUID());
} else {
writer.putInt(rulingNation.getObjectType().ordinal());
writer.putInt(rulingNation.getObjectUUID());
}
// Serialize nation name
writer.putString("Whitehorn Militants"); //nation name
writer.putInt(-1);//city rank, -1 puts it at top of list always
writer.putInt(0xFFFFFFFF);
writer.putInt(0);
writer.putString("Kol'roth The Destroyer");//nation ruler
writer.putLocalDateTime(LocalDateTime.now());
//location
Vector3fImmutable loc = Vector3fImmutable.getRandomPointOnCircle(BuildingManager.getBuilding(2827951).loc,30f);
writer.putFloat(loc.x);
writer.putFloat(loc.y);
writer.putFloat(loc.z);
writer.putInt(0);
writer.put((byte) 1);
writer.put((byte) 0);
writer.putInt(0x64);
writer.put((byte) 0);
writer.put((byte) 0);
writer.put((byte) 0);
}
}

105
src/engine/Dungeons/DungeonManager.java

@ -0,0 +1,105 @@ @@ -0,0 +1,105 @@
package engine.Dungeons;
import engine.Enum;
import engine.InterestManagement.WorldGrid;
import engine.gameManager.DbManager;
import engine.gameManager.ZoneManager;
import engine.math.Vector3fImmutable;
import engine.objects.*;
import engine.powers.EffectsBase;
import engine.server.MBServerStatics;
import java.util.ArrayList;
import java.util.HashSet;
public class DungeonManager {
public static ArrayList<Dungeon> dungeons;
private static final float dungeonAiRange = 64f;
private static final float maxTravel = 64f;
public static void joinDungeon(PlayerCharacter pc, Dungeon dungeon){
if(requestEnter(pc,dungeon)) {
dungeon.participants.add(pc);
dungeon.applyDungeonEffects(pc);
translocateToDungeon(pc, dungeon);
}
}
public static void leaveDungeon(PlayerCharacter pc, Dungeon dungeon){
dungeon.participants.remove(pc);
dungeon.removeDungeonEffects(pc);
translocateOutOfDungeon(pc);
}
public static boolean requestEnter(PlayerCharacter pc, Dungeon dungeon){
int current = 0;
Guild nation = pc.guild.getNation();
if(nation == null)
return false;
for(PlayerCharacter participant : dungeon.participants){
if(participant.guild.getNation().equals(nation)){
current ++;
}
}
if(current >= dungeon.maxPerGuild)
return false;
return true;
}
public static void translocateToDungeon(PlayerCharacter pc, Dungeon dungeon){
pc.teleport(dungeon.entrance);
pc.setSafeMode();
}
public static void translocateOutOfDungeon(PlayerCharacter pc){
pc.teleport(pc.bindLoc);
pc.setSafeMode();
}
public static void pulse_dungeons(){
for(Dungeon dungeon : dungeons){
//early exit, if no players present don't waste resources
if(dungeon.participants.isEmpty())
continue;
if(dungeon.respawnTime > 0 && System.currentTimeMillis() > dungeon.respawnTime){
respawnMobs(dungeon);
}
//remove any players that have left
HashSet<AbstractWorldObject> obj = WorldGrid.getObjectsInRangePartial(dungeon.entrance,4096f,MBServerStatics.MASK_PLAYER);
for(PlayerCharacter player : dungeon.participants)
if(!obj.contains(player))
leaveDungeon(player,dungeon);
//cycle dungeon mob AI
for(Mob mob : dungeon.dungeon_mobs)
dungeonMobAI(mob);
}
}
public static void dungeonMobAI(Mob mob){
}
public static void respawnMobs(Dungeon dungeon){
for(Mob mob : dungeon.dungeon_mobs){
if(!mob.isAlive() && mob.despawned)
mob.respawn();
if(!mob.isAlive() && !mob.despawned){
mob.despawn();
mob.respawn();
}
}
}
}

53
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),
@ -152,7 +150,8 @@ public class Enum { @@ -152,7 +150,8 @@ public class Enum {
NEPHFEMALE(2026, MonsterType.Nephilim, RunSpeed.STANDARD, CharacterSex.FEMALE, 1.1f),
HALFGIANTFEMALE(2027, MonsterType.HalfGiant, RunSpeed.STANDARD, CharacterSex.FEMALE, 1.15f),
VAMPMALE(2028, MonsterType.Vampire, RunSpeed.STANDARD, CharacterSex.MALE, 1),
VAMPFEMALE(2029, MonsterType.Vampire, RunSpeed.STANDARD, CharacterSex.FEMALE, 1);
VAMPFEMALE(2029, MonsterType.Vampire, RunSpeed.STANDARD, CharacterSex.FEMALE, 1),
SAETOR(1999,MonsterType.Minotaur, RunSpeed.MINOTAUR, CharacterSex.MALE,1);
@SuppressWarnings("unchecked")
private static HashMap<Integer, RaceType> _raceTypeByID = new HashMap<>();
@ -208,8 +207,8 @@ public class Enum { @@ -208,8 +207,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 +468,14 @@ public class Enum { @@ -469,11 +468,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 +778,7 @@ public class Enum { @@ -776,6 +778,7 @@ public class Enum {
Combat,
Spires,
Snare,
Snared,
Stun,
Blind,
Root,
@ -878,6 +881,7 @@ public class Enum { @@ -878,6 +881,7 @@ public class Enum {
Siege,
Slash,
Snare,
Snared,
Sorcery,
Spear,
SpearMastery,
@ -957,6 +961,17 @@ public class Enum { @@ -957,6 +961,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;
@ -964,8 +979,8 @@ public class Enum { @@ -964,8 +979,8 @@ public class Enum {
try {
returnMod = SourceType.valueOf(modName.replace(",", ""));
} catch (Exception e) {
Logger.error(modName);
Logger.error(e);
//Logger.error(modName);
//Logger.error(e);
return SourceType.None;
}
return returnMod;
@ -1016,6 +1031,7 @@ public class Enum { @@ -1016,6 +1031,7 @@ public class Enum {
Silence,
Slash,
Snare,
Snared,
Stance,
Stun,
Summon,
@ -1140,6 +1156,7 @@ public class Enum { @@ -1140,6 +1156,7 @@ public class Enum {
SkillDebuff,
SlashResistanceDebuff,
Snare,
Snared,
StackableAttrCONBuff,
StackableAttrDEXBuff,
StackableAttrSTRBuff,
@ -2306,9 +2323,9 @@ public class Enum { @@ -2306,9 +2323,9 @@ public class Enum {
public enum CityBoundsType {
GRID(640),
ZONE(875),
PLACEMENT(876);
GRID(544),
ZONE(672),
PLACEMENT(673);
public final float extents;

38
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;
@ -514,6 +511,18 @@ public enum InterestManager implements Runnable { @@ -514,6 +511,18 @@ public enum InterestManager implements Runnable {
if (player == null)
return;
for(PlayerCharacter pc : SessionManager.getAllActivePlayerCharacters()){
if(pc.equals(player)){
try{
WorldGrid.RemoveWorldObject(player);
}catch(Exception e){
}
}
}
ClientConnection origin = player.getClientConnection();
if (origin == null)
@ -521,10 +530,10 @@ public enum InterestManager implements Runnable { @@ -521,10 +530,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) {
@ -558,4 +567,23 @@ public enum InterestManager implements Runnable { @@ -558,4 +567,23 @@ public enum InterestManager implements Runnable {
playerCharacter.setDirtyLoad(true);
}
}
public void RefreshLoadedObjects(PlayerCharacter player){
try {
if (player == null)
return;
ClientConnection origin = player.getClientConnection();
if (origin == null)
return;
// Update loaded upbjects lists
player.setDirtyLoad(true);
updateStaticList(player, origin);
updateMobileList(player, origin);
}catch(Exception e){
Logger.error(e.getMessage());
}
}
}

116
src/engine/ZergMehcanics/MineAntiZerg.java

@ -0,0 +1,116 @@ @@ -0,0 +1,116 @@
package engine.ZergMehcanics;
import engine.InterestManagement.WorldGrid;
import engine.gameManager.BuildingManager;
import engine.gameManager.ZergManager;
import engine.objects.*;
import engine.server.MBServerStatics;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
public class MineAntiZerg {
public static HashMap<Mine,HashMap<PlayerCharacter,Long>> leaveTimers = new HashMap<>();
public static HashMap<Mine,ArrayList<PlayerCharacter>> currentPlayers = new HashMap<>();
public static void runMines(){
for(Mine mine : Mine.getMines()){
Building tower = BuildingManager.getBuildingFromCache(mine.getBuildingID());
if(tower == null)
continue;
if(!mine.isActive)
continue;
logPlayersPresent(tower,mine);
auditPlayersPresent(tower,mine);
auditPlayers(mine);
}
}
public static void logPlayersPresent(Building tower, Mine mine){
HashSet<AbstractWorldObject> loadedPlayers = WorldGrid.getObjectsInRangePartial(tower.loc, MBServerStatics.CHARACTER_LOAD_RANGE * 3,MBServerStatics.MASK_PLAYER);
ArrayList<PlayerCharacter> playersPresent = new ArrayList<>();
for(AbstractWorldObject player : loadedPlayers){
playersPresent.add((PlayerCharacter)player);
}
currentPlayers.put(mine,playersPresent);
}
public static void auditPlayersPresent(Building tower, Mine mine){
HashSet<AbstractWorldObject> loadedPlayers = WorldGrid.getObjectsInRangePartial(tower.loc, MBServerStatics.CHARACTER_LOAD_RANGE * 3,MBServerStatics.MASK_PLAYER);
ArrayList<PlayerCharacter> toRemove = new ArrayList<>();
for(PlayerCharacter player : currentPlayers.get(mine)){
if(!loadedPlayers.contains(player)){
toRemove.add(player);
}
}
currentPlayers.get(mine).removeAll(toRemove);
for(PlayerCharacter player : toRemove){
if(leaveTimers.containsKey(mine)){
leaveTimers.get(mine).put(player,System.currentTimeMillis());
}else{
HashMap<PlayerCharacter,Long> leaveTime = new HashMap<>();
leaveTime.put(player,System.currentTimeMillis());
leaveTimers.put(mine,leaveTime);
}
}
toRemove.clear();
for(PlayerCharacter player : leaveTimers.get(mine).keySet()){
long timeGone = System.currentTimeMillis() - leaveTimers.get(mine).get(player);
if(timeGone > 180000L) {//3 minutes
toRemove.add(player);
player.ZergMultiplier = 1.0f;
}
}
for(PlayerCharacter player : toRemove) {
leaveTimers.get(mine).remove(player);
}
}
public static void auditPlayers(Mine mine){
HashMap<Guild,ArrayList<PlayerCharacter>> playersByNation = new HashMap<>();
for(PlayerCharacter player : currentPlayers.get(mine)){
if(playersByNation.containsKey(player.guild.getNation())){
playersByNation.get(player.guild.getNation()).add(player);
}else{
ArrayList<PlayerCharacter> players = new ArrayList<>();
players.add(player);
playersByNation.put(player.guild.getNation(),players);
}
}
for(PlayerCharacter player : leaveTimers.get(mine).keySet()){
if(playersByNation.containsKey(player.guild.getNation())){
playersByNation.get(player.guild.getNation()).add(player);
}else{
ArrayList<PlayerCharacter> players = new ArrayList<>();
players.add(player);
playersByNation.put(player.guild.getNation(),players);
}
}
for(Guild nation : playersByNation.keySet()){
for(PlayerCharacter player : playersByNation.get(nation)){
player.ZergMultiplier = ZergManager.getCurrentMultiplier(playersByNation.get(nation).size(), mine.capSize);
}
}
}
}

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

@ -13,14 +13,13 @@ import engine.Enum; @@ -13,14 +13,13 @@ import engine.Enum;
import engine.Enum.GameObjectType;
import engine.gameManager.ConfigManager;
import engine.gameManager.DbManager;
import engine.net.DispatchMessage;
import engine.net.client.msg.chat.ChatSystemMsg;
import engine.objects.Account;
import engine.objects.PlayerCharacter;
import org.pmw.tinylog.Logger;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.*;
import java.util.ArrayList;
public class dbAccountHandler extends dbHandlerBase {
@ -77,18 +76,24 @@ public class dbAccountHandler extends dbHandlerBase { @@ -77,18 +76,24 @@ public class dbAccountHandler extends dbHandlerBase {
}
}
public void SET_TRASH(String machineID) {
public void SET_TRASH(String machineID, String type) {
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("INSERT INTO dyn_trash(`machineID`, `count`)"
+ " VALUES (?, 1) ON DUPLICATE KEY UPDATE `count` = `count` + 1;")) {
PreparedStatement preparedStatement = connection.prepareStatement(
"INSERT INTO dyn_trash(`machineID`, `count`, `type`)"
+ " VALUES (?, 1, ?) ON DUPLICATE KEY UPDATE `count` = `count` + 1;")) {
preparedStatement.setString(1, machineID);
preparedStatement.setString(2, type);
preparedStatement.execute();
} catch (SQLException e) {
Logger.error(e);
}
ChatSystemMsg chatMsg = new ChatSystemMsg(null, "Account: " + machineID + " has been kicked from game for cheating");
chatMsg.setMessageType(10);
chatMsg.setChannel(Enum.ChatChannelType.SYSTEM.getChannelID());
DispatchMessage.dispatchMsgToAll(chatMsg);
}
public ArrayList<String> GET_TRASH_LIST() {
@ -270,4 +275,21 @@ public class dbAccountHandler extends dbHandlerBase { @@ -270,4 +275,21 @@ public class dbAccountHandler extends dbHandlerBase {
}
}
public void TRASH_CHEATERS() {
try (Connection connection = DbManager.getConnection();
CallableStatement callableStatement = connection.prepareCall("{CALL BanAccountsWithMachineID()}")) {
boolean hasResultSet = callableStatement.execute();
if (!hasResultSet && callableStatement.getUpdateCount() > 0) {
Logger.info("TRASHED CHEATERS");
} else {
Logger.warn("No cheaters to trash.");
}
} catch (SQLException e) {
Logger.error("Error trashing cheaters: ", e);
}
}
}

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();

7
src/engine/devcmd/cmds/AddGoldCmd.java

@ -14,6 +14,7 @@ import engine.gameManager.ChatManager; @@ -14,6 +14,7 @@ import engine.gameManager.ChatManager;
import engine.objects.AbstractGameObject;
import engine.objects.Item;
import engine.objects.PlayerCharacter;
import engine.server.MBServerStatics;
/**
* @author Eighty
@ -46,10 +47,10 @@ public class AddGoldCmd extends AbstractDevCmd { @@ -46,10 +47,10 @@ public class AddGoldCmd extends AbstractDevCmd {
throwbackError(pc, "Quantity must be a number, " + words[0] + " is invalid");
return;
}
if (amt < 1 || amt > 10000000) {
throwbackError(pc, "Quantity must be between 1 and 10000000 (10 million)");
if (amt < 1 || amt > MBServerStatics.PLAYER_GOLD_LIMIT) {
throwbackError(pc, "Quantity must be between 1 and " + MBServerStatics.PLAYER_GOLD_LIMIT);
return;
} else if ((curAmt + amt) > 10000000) {
} else if ((curAmt + amt) > MBServerStatics.PLAYER_GOLD_LIMIT) {
throwbackError(pc, "This would place your inventory over 10,000,000 gold.");
return;
}

37
src/engine/devcmd/cmds/AddMobCmd.java

@ -9,12 +9,17 @@ @@ -9,12 +9,17 @@
package engine.devcmd.cmds;
import engine.Enum;
import engine.Enum.GameObjectType;
import engine.InterestManagement.InterestManager;
import engine.InterestManagement.WorldGrid;
import engine.devcmd.AbstractDevCmd;
import engine.gameManager.ChatManager;
import engine.gameManager.DbManager;
import engine.gameManager.LootManager;
import engine.gameManager.ZoneManager;
import engine.math.Vector3fImmutable;
import engine.mobileAI.utilities.MovementUtilities;
import engine.objects.*;
import org.pmw.tinylog.Logger;
@ -83,13 +88,41 @@ public class AddMobCmd extends AbstractDevCmd { @@ -83,13 +88,41 @@ public class AddMobCmd extends AbstractDevCmd {
}
Mob mob = Mob.createMob(loadID, pc.getLoc(),
null, true, zone, null, 0, "", 1);
Mob mob = Mob.createMob(loadID, pc.getLoc(),null, true, zone, null, 0, "", 1);
//Mob mob = Mob.createStrongholdMob(loadID,pc.loc,Guild.getErrantGuild(),true,zone,null,0,"Whitehorn Militant",75);
if (mob != null) {
mob.updateDatabase();
ChatManager.chatSayInfo(pc,
"Mob with ID " + mob.getDBID() + " added");
this.setResult(String.valueOf(mob.getDBID()));
mob.parentZone = zone;
mob.bindLoc = pc.loc;
mob.setLoc(pc.loc);
mob.equipmentSetID = 6327;
mob.runAfterLoad();
mob.setLevel((short)75);
mob.setResists(new Resists("Elite"));
mob.spawnTime = 10;
mob.BehaviourType = Enum.MobBehaviourType.Aggro;
zone.zoneMobSet.add(mob);
mob.isHellgateMob = true;
LootManager.GenerateStrongholdLoot(mob,false,false);
mob.healthMax = mob.mobBase.getHealthMax();
mob.setHealth(mob.healthMax);
mob.maxDamageHandOne = 1550;
mob.minDamageHandOne = 750;
mob.atrHandOne = 1800;
mob.defenseRating = 2200;
mob.setFirstName("Whitehorn Militant");
//InterestManager.setObjectDirty(mob);
//WorldGrid.addObject(mob,pc.loc.x,pc.loc.z);
//WorldGrid.updateObject(mob);
//guard.stronghold = mine;
mob.mobPowers.clear();
mob.mobPowers.put(429399948,20); // find weakness
} else {
throwbackError(pc, "Failed to create mob of type " + loadID);
Logger.error("Failed to create mob of type "

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

54
src/engine/devcmd/cmds/DungenonCmd.java

@ -0,0 +1,54 @@ @@ -0,0 +1,54 @@
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
package engine.devcmd.cmds;
import engine.Dungeons.DungeonManager;
import engine.Enum.GameObjectType;
import engine.devcmd.AbstractDevCmd;
import engine.gameManager.BuildingManager;
import engine.gameManager.ChatManager;
import engine.gameManager.DbManager;
import engine.gameManager.ZoneManager;
import engine.math.Vector3fImmutable;
import engine.objects.*;
import org.pmw.tinylog.Logger;
/**
* @author Eighty
*/
public class DungenonCmd extends AbstractDevCmd {
public DungenonCmd() {
super("dungeon");
}
@Override
protected void _doCmd(PlayerCharacter pc, String[] words,
AbstractGameObject target) {
Zone parent = ZoneManager.findSmallestZone(pc.loc);
if(parent == null)
return;
Vector3fImmutable loc = Vector3fImmutable.getRandomPointOnCircle(BuildingManager.getBuilding(2827951).loc,30f);
pc.teleport(loc);
}
@Override
protected String _getHelpString() {
return "indicate mob or building followed by an id and a level";
}
@Override
protected String _getUsageString() {
return "'/dungeon mob 2001 10'";
}
}

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

@ -0,0 +1,64 @@ @@ -0,0 +1,64 @@
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// 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 engine.server.MBServerStatics;
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 = MBServerStatics.PLAYER_GOLD_LIMIT - 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]";
}
}

38
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;
@ -331,13 +335,19 @@ public class InfoCmd extends AbstractDevCmd { @@ -331,13 +335,19 @@ public class InfoCmd extends AbstractDevCmd {
output += "Movement State: " + targetPC.getMovementState().name();
output += newline;
output += "Movement Speed: " + targetPC.getSpeed();
output += newline;
output += "Altitude : " + targetPC.getLoc().y;
output += newline;
output += "Swimming : " + targetPC.isSwimming();
output += newline;
output += "isMoving : " + targetPC.isMoving();
output += newline;
output += "Zerg Multiplier : " + targetPC.ZergMultiplier + newline;
output += "Hidden : " + targetPC.getHidden() + newline;
output += "Target Loc: " + targetPC.loc + newline;
output += "Player Loc: " + pc.loc + newline;
output += "Distance Squared: " + pc.loc.distanceSquared(targetPC.loc) + newline;
output += "IsBoxed: " + targetPC.isBoxed;
break;
case NPC:
@ -492,13 +502,16 @@ public class InfoCmd extends AbstractDevCmd { @@ -492,13 +502,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 +542,13 @@ public class InfoCmd extends AbstractDevCmd { @@ -529,6 +542,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);

75
src/engine/devcmd/cmds/PrintEffectsCmd.java

@ -0,0 +1,75 @@ @@ -0,0 +1,75 @@
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
package engine.devcmd.cmds;
import engine.Enum;
import engine.Enum.BuildingGroup;
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.server.MBServerStatics;
import engine.util.StringUtils;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author
*/
public class PrintEffectsCmd extends AbstractDevCmd {
public PrintEffectsCmd() {
super("printeffects");
}
@Override
protected void _doCmd(PlayerCharacter pc, String[] words,
AbstractGameObject target) {
if(!target.getObjectType().equals(GameObjectType.PlayerCharacter)) {
throwbackInfo(pc, "Target Must PlayerCharacter");
return;
}
String newline = "\r\n ";
String output = "Effects for Player:" + newline;
AbstractCharacter absTar = (AbstractCharacter) target;
for(String key : absTar.effects.keySet()){
Effect eff = absTar.effects.get(key);
if(eff.getJobContainer() != null) {
output += "[" + key + "] " + eff.getName() + " (" + eff.getTrains() + ") " + eff.getJobContainer().timeToExecutionLeft() * 0.001f + newline;
}else{
output += eff.getName() + " (" + eff.getTrains() + ") " + "PERMANENT" + newline;
}
}
throwbackInfo(pc, output);
}
@Override
protected String _getHelpString() {
return "Gets information on an Object.";
}
@Override
protected String _getUsageString() {
return "' /info targetID'";
}
}

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");
}

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

@ -9,7 +9,9 @@ @@ -9,7 +9,9 @@
package engine.devcmd.cmds;
import engine.Enum;
import engine.devcmd.AbstractDevCmd;
import engine.gameManager.PowersManager;
import engine.objects.*;
import java.util.HashMap;
@ -56,23 +58,43 @@ public class PrintStatsCmd extends AbstractDevCmd { @@ -56,23 +58,43 @@ 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;
newOut += "IS BOXED: " + tar.isBoxed + newline;
newOut += "=== POWERS ===" + newline;
for(CharacterPower power : pc.getPowers().values()){
if(power.getPower().requiresHitRoll) {
newOut += power.getPower().name + " ATR: " + Math.round(PlayerCombatStats.getSpellAtr(pc,power.getPower())) + 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());

10
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,15 @@ public enum ChatManager { @@ -84,6 +85,15 @@ public enum ChatManager {
if ((checkTime > 0L) && (curMsgTime - checkTime < FLOOD_TIME_THRESHOLD))
isFlood = true;
if(KeyCloneAudit.auditChatMsg(pc,msg.getMessage())){
return;
}
if(msg.getMessage().equalsIgnoreCase("./zerg")){
ZergManager.PrintDetailsToClient(pc);
return;
}
switch (protocolMsg) {
case CHATSAY:
ChatManager.chatSay(pc, msg.getMessage(), isFlood);

382
src/engine/gameManager/CombatManager.java

@ -8,6 +8,7 @@ @@ -8,6 +8,7 @@
package engine.gameManager;
import engine.Enum;
import engine.Enum.*;
import engine.exception.MsgSendException;
import engine.job.JobContainer;
@ -26,7 +27,6 @@ import engine.powers.effectmodifiers.WeaponProcEffectModifier; @@ -26,7 +27,6 @@ import engine.powers.effectmodifiers.WeaponProcEffectModifier;
import engine.server.MBServerStatics;
import org.pmw.tinylog.Logger;
import java.util.HashSet;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ThreadLocalRandom;
@ -301,6 +301,21 @@ public enum CombatManager { @@ -301,6 +301,21 @@ 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.combatStats == null){
attacker.combatStats = new PlayerCombatStats(attacker);
}
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)) {
@ -316,10 +331,13 @@ public enum CombatManager { @@ -316,10 +331,13 @@ public enum CombatManager {
else if (!tar.isActive())
return 0;
if (target.getObjectType().equals(GameObjectType.PlayerCharacter) && abstractCharacter.getObjectType().equals(GameObjectType.PlayerCharacter) && abstractCharacter.getTimers().get("Attack" + slot) == null)
if (target.getObjectType().equals(GameObjectType.PlayerCharacter) && abstractCharacter.getObjectType().equals(GameObjectType.PlayerCharacter) && abstractCharacter.getTimers().get("Attack" + slot) == null) {
if(((PlayerCharacter)target).combatStats == null){
((PlayerCharacter)target).combatStats = new PlayerCombatStats(((PlayerCharacter)target));
}
if (!((PlayerCharacter) abstractCharacter).canSee((PlayerCharacter) target))
return 0;
}
//must not be immune to all or immune to attack
Resists res = tar.getResists();
@ -414,7 +432,10 @@ public enum CombatManager { @@ -414,7 +432,10 @@ public enum CombatManager {
//Source can attack.
//NOTE Don't 'return;' beyond this point until timer created
if(abstractCharacter.getObjectType().equals(GameObjectType.PlayerCharacter)){
PlayerCharacter pc = (PlayerCharacter)abstractCharacter;
pc.updateMovementState();
}
boolean attackFailure = (wb != null) && (wb.getRange() > 35f) && abstractCharacter.isMoving();
//Target can't attack on move with ranged weapons.
@ -452,6 +473,28 @@ public enum CombatManager { @@ -452,6 +473,28 @@ public enum CombatManager {
//Range check.
//if(abstractCharacter.isMoving()){
// range += (abstractCharacter.getSpeed() * 0.1f); // add movement vector offset for moving attacker
//}
//if(AbstractWorldObject.IsAbstractCharacter(target)) {
// AbstractCharacter tarAc = (AbstractCharacter) target;
// if(tarAc != null && tarAc.isMoving()){
// range += (tarAc.getSpeed() * 0.1f); // add movement vector offset for moving target
// }
//}
//float attackerHitBox = abstractCharacter.calcHitBox(); // add attacker hitbox
//float targetHitBox = 0.0f;
//if(AbstractCharacter.IsAbstractCharacter(target)){
// AbstractCharacter targetCharacter = (AbstractCharacter)target;
// targetHitBox = targetCharacter.calcHitBox(); // add target hitbox
//}
//range += attackerHitBox + targetHitBox + 2.5f; // offset standard range to sync where client tries to stop
range += 2; //sync offset
if (NotInRange(abstractCharacter, target, range)) {
//target is in stealth and can't be seen by source
@ -475,6 +518,16 @@ public enum CombatManager { @@ -475,6 +518,16 @@ public enum CombatManager {
}
}
if(abstractCharacter.getObjectType().equals(GameObjectType.PlayerCharacter)){
PlayerCharacter pc = (PlayerCharacter)abstractCharacter;
if(pc.isBoxed){
if(target.getObjectType().equals(GameObjectType.PlayerCharacter)) {
ChatManager.chatSystemInfo(pc, "You Are PvE Flagged: Cannot Attack Players.");
attackFailure = true;
}
}
}
//TODO Verify attacker has los (if not ranged weapon).
if (!attackFailure) {
@ -483,16 +536,24 @@ public enum CombatManager { @@ -483,16 +536,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);
}
@ -537,14 +598,32 @@ public enum CombatManager { @@ -537,14 +598,32 @@ 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;
if( pc.combatStats == null){
pc.combatStats = new PlayerCombatStats(pc);
}
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 +717,15 @@ public enum CombatManager { @@ -638,7 +717,15 @@ public enum CombatManager {
}
} else {
AbstractCharacter tar = (AbstractCharacter) target;
defense = tar.getDefenseRating();
if(tar.getObjectType().equals(GameObjectType.PlayerCharacter)){
if(((PlayerCharacter)tar).combatStats == null){
((PlayerCharacter)tar).combatStats = new PlayerCombatStats((PlayerCharacter)tar);
}
((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 +733,24 @@ public enum CombatManager { @@ -646,24 +733,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 +779,25 @@ public enum CombatManager { @@ -692,7 +779,25 @@ public enum CombatManager {
PlayerBonuses bonus = ac.getBonuses();
float attackRange = getWeaponRange(wb, bonus);
dpj.attack(target, attackRange);
if(ac.isMoving()){
attackRange += (ac.getSpeed() * 0.1f);
}
if(AbstractWorldObject.IsAbstractCharacter(target)) {
//AbstractCharacter tarAc = (AbstractCharacter) target;
if(tarAc != null && tarAc.isMoving()){
attackRange += (tarAc.getSpeed() * 0.1f);
}
}
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 +812,25 @@ public enum CombatManager { @@ -707,7 +812,25 @@ 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(ac.isMoving()){
attackRange += (ac.getSpeed() * 0.1f);
}
if(AbstractWorldObject.IsAbstractCharacter(target)) {
//AbstractCharacter tarAc = (AbstractCharacter) target;
if(tarAc != null && tarAc.isMoving()){
attackRange += (tarAc.getSpeed() * 0.1f);
}
}
if(specialCaseHitRoll(dpj.getPowerToken())) {
if(hitLanded) {
dpj.attack(target, attackRange);
}
}else{
dpj.attack(target, attackRange);
}
}
}
@ -814,8 +937,28 @@ public enum CombatManager { @@ -814,8 +937,28 @@ 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.getPercentMod() + (mod.getRamp() * eff.getTrains());
}
}
}
if(armorPierce > 0){
damage *= 1 + (armorPierce * 0.01f);
}
}
//Resists.handleFortitude(tarAc,damageType,damage);
float d = 0f;
int originalDamage = (int)damage;
if(ac != null && ac.getObjectType().equals(GameObjectType.PlayerCharacter)){
damage *= ((PlayerCharacter)ac).ZergMultiplier;
} // Health modifications are modified by the ZergMechanic
errorTrack = 12;
//Subtract Damage from target's health
@ -829,9 +972,15 @@ public enum CombatManager { @@ -829,9 +972,15 @@ public enum CombatManager {
ac.setHateValue(damage * MBServerStatics.PLAYER_COMBAT_HATE_MODIFIER);
((Mob) tarAc).handleDirectAggro(ac);
}
if (tarAc.getHealth() > 0)
if (tarAc.getHealth() > 0) {
d = tarAc.modifyHealth(-damage, ac, false);
if(tarAc != null && tarAc.getObjectType().equals(GameObjectType.PlayerCharacter) && ((PlayerCharacter)ac).ZergMultiplier != 1.0f){
PlayerCharacter debugged = (PlayerCharacter)tarAc;
ChatManager.chatSystemInfo(debugged, "ZERG DEBUG: " + ac.getName() + " Hits You For: " + (int)damage + " instead of " + originalDamage);
}
}
tarAc.cancelOnTakeDamage();
} else if (target.getObjectType().equals(GameObjectType.Building)) {
@ -863,35 +1012,7 @@ public enum CombatManager { @@ -863,35 +1012,7 @@ public enum CombatManager {
errorTrack = 14;
//handle procs
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) {
int procChance = ThreadLocalRandom.current().nextInt(100);
if (procChance < MBServerStatics.PROC_CHANCE)
((WeaponProcEffectModifier) aem).applyProc(ac, target);
}
}
}
}
}
procChanceHandler(weapon,ac,tarAc);
errorTrack = 15;
@ -900,6 +1021,16 @@ public enum CombatManager { @@ -900,6 +1021,16 @@ public enum CombatManager {
if (ac.isAlive() && tarAc != null && tarAc.isAlive())
handleDamageShields(ac, tarAc, damage);
//handle mob hate values
if(target.getObjectType().equals(GameObjectType.Mob) && ac.getObjectType().equals(GameObjectType.PlayerCharacter)){
Mob mobTarget = (Mob)target;
if(mobTarget.hate_values.containsKey((PlayerCharacter) ac)){
mobTarget.hate_values.put((PlayerCharacter) ac,mobTarget.hate_values.get((PlayerCharacter) ac) + damage);
}else{
mobTarget.hate_values.put((PlayerCharacter) ac, damage);
}
}
} else {
// Apply Weapon power effect if any.
@ -915,7 +1046,26 @@ public enum CombatManager { @@ -915,7 +1046,26 @@ public enum CombatManager {
if (wp.requiresHitRoll() == false) {
PlayerBonuses bonus = ac.getBonuses();
float attackRange = getWeaponRange(wb, bonus);
dpj.attack(target, attackRange);
if(ac.isMoving()){
attackRange += (ac.getSpeed() * 0.1f);
}
if(AbstractWorldObject.IsAbstractCharacter(target)) {
AbstractCharacter tarAc = (AbstractCharacter) target;
if(tarAc != null && tarAc.isMoving()){
attackRange += (tarAc.getSpeed() * 0.1f);
}
}
if(specialCaseHitRoll(dpj.getPowerToken())) {
if(hitLanded) {
dpj.attack(target, attackRange);
}
}else{
dpj.attack(target, attackRange);
}
} else
((PlayerCharacter) ac).setWeaponPower(null);
}
@ -946,6 +1096,41 @@ public enum CombatManager { @@ -946,6 +1096,41 @@ public enum CombatManager {
}
}
private static void procChanceHandler(Item weapon, AbstractCharacter ac, AbstractCharacter tarAc) {
//no weapon means no proc
if(weapon == null)
return;
//caster is dead of null, no proc
if(ac == null || !ac.isAlive())
return;
//target is dead or null, no proc
if(tarAc == null || !tarAc.isAlive())
return;
//no effects on weapon, skip proc
if(weapon.effects == null || weapon.effects.isEmpty())
return;
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) {
try {
((WeaponProcEffectModifier) mod).applyProc(ac, tarAc);
break;
} catch (Exception e) {
Logger.error(eff.getName() + " Failed To Cast Proc");
}
}
}
}
}
}
public static boolean canTestParry(AbstractCharacter ac, AbstractWorldObject target) {
if (ac == null || target == null || !AbstractWorldObject.IsAbstractCharacter(target))
@ -964,6 +1149,12 @@ public enum CombatManager { @@ -964,6 +1149,12 @@ public enum CombatManager {
Item tarMain = tarItem.getItemFromEquipped(1);
Item tarOff = tarItem.getItemFromEquipped(2);
if(target.getObjectType().equals(GameObjectType.PlayerCharacter)){
PlayerCharacter pc = (PlayerCharacter) target;
if(pc.getRaceID() == 1999 && !isRanged(acMain) && !isRanged(acOff))
return true;
}
return !isRanged(acMain) && !isRanged(acOff) && !isRanged(tarMain) && !isRanged(tarOff);
}
@ -1022,10 +1213,12 @@ public enum CombatManager { @@ -1022,10 +1213,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) {
@ -1175,6 +1368,14 @@ public enum CombatManager { @@ -1175,6 +1368,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 +1386,7 @@ public enum CombatManager { @@ -1185,7 +1386,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 +1438,17 @@ public enum CombatManager { @@ -1237,14 +1438,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 +1526,13 @@ public enum CombatManager { @@ -1322,6 +1526,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 +1564,9 @@ public enum CombatManager { @@ -1353,9 +1564,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 +1649,31 @@ public enum CombatManager { @@ -1438,4 +1649,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

42
src/engine/gameManager/DevCmdManager.java

@ -56,6 +56,7 @@ public enum DevCmdManager { @@ -56,6 +56,7 @@ public enum DevCmdManager {
DevCmdManager.registerDevCmd(new PrintResistsCmd());
DevCmdManager.registerDevCmd(new PrintLocationCmd());
DevCmdManager.registerDevCmd(new InfoCmd());
DevCmdManager.registerDevCmd(new PrintEffectsCmd());
DevCmdManager.registerDevCmd(new aiInfoCmd());
DevCmdManager.registerDevCmd(new SimulateBootyCmd());
DevCmdManager.registerDevCmd(new GetHeightCmd());
@ -79,13 +80,13 @@ public enum DevCmdManager { @@ -79,13 +80,13 @@ 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());
DevCmdManager.registerDevCmd(new AddBuildingCmd());
DevCmdManager.registerDevCmd(new AddNPCCmd());
DevCmdManager.registerDevCmd(new AddMobCmd());
DevCmdManager.registerDevCmd(new DungenonCmd());
DevCmdManager.registerDevCmd(new RemoveObjectCmd());
DevCmdManager.registerDevCmd(new RotateCmd());
DevCmdManager.registerDevCmd(new FlashMsgCmd());
@ -103,6 +104,7 @@ public enum DevCmdManager { @@ -103,6 +104,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 +179,44 @@ public enum DevCmdManager { @@ -177,10 +179,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;
}

289
src/engine/gameManager/HellgateManager.java

@ -0,0 +1,289 @@ @@ -0,0 +1,289 @@
package engine.gameManager;
import engine.mobileAI.MobAI;
import engine.mobileAI.utilities.CombatUtilities;
import engine.mobileAI.utilities.MovementUtilities;
import engine.objects.*;
import engine.server.MBServerStatics;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.concurrent.ThreadLocalRandom;
public class HellgateManager {
public static ArrayList<Mob> hellgate_mobs;
public static ArrayList<Mob> hellgate_mini_bosses;
public static Mob hellgate_boss;
public static Long hellgate_time_completed = 0L;
public static final int citadel_ruins_zone_id = 993;
public static final int hell_portal_1_zone_id = 994;
public static final int hell_portal_2_zone_id = 996;
public static final int hell_portal_3_zone_id = 997;
public static final int hell_portal_4_zone_id = 998;
public static boolean initialized = false;
public static final ArrayList<Integer> static_rune_ids_low = new ArrayList<>(Arrays.asList(
250001, 250002, 250003, 250004, 250005, 250006, 250010, 250011,
250012, 250013, 250014, 250015, 250019, 250020, 250021, 250022,
250023, 250024, 250028, 250029, 250030, 250031, 250032, 250033,
250037, 250038, 250039, 250040, 250041, 250042
));
public static final ArrayList<Integer> static_rune_ids_mid = new ArrayList<>(Arrays.asList(
250006, 250007, 250008,
250015, 250016, 250017,
250024, 250025, 250026,
250033, 250034, 250035,
250042, 250043, 250044
));
public static final ArrayList<Integer> static_rune_ids_high = new ArrayList<>(Arrays.asList(
250007, 250008,
250016, 250017,
250025, 250026,
250034, 250035,
250043, 250044
));
public static void confiureHellgate(){
compile_mob_list();
}
public static void pulseHellgates(){
if(!initialized){
confiureHellgate();
if(hellgate_boss != null)
initialized = true;
return;
}
if(hellgate_mobs == null) {
return;
}
if(hellgate_mini_bosses == null) {
return;
}
if(hellgate_boss == null){
return;
}
if(!hellgate_boss.isAlive() && hellgate_time_completed == 0L)
hellgate_time_completed = System.currentTimeMillis();
if(hellgate_time_completed != 0L && System.currentTimeMillis() > hellgate_time_completed + MBServerStatics.THIRTY_MINUTES){
ResetHellgate();
}
}
public static void compile_mob_list(){
if(hellgate_mobs == null) {
hellgate_mobs =new ArrayList<>();
}
if(hellgate_mini_bosses == null) {
hellgate_mini_bosses =new ArrayList<>();
}
Zone hellgate_zone = ZoneManager.getZoneByUUID(citadel_ruins_zone_id);
if(hellgate_zone == null)
return;
for(Mob mob : hellgate_zone.zoneMobSet){
switch(mob.getMobBaseID()){
case 14163: // basic saetor warrior
mob.getCharItemManager().clearInventory();
SpecialLootHandler(mob,false,false);
mob.setResists(new Resists("Elite"));
mob.healthMax = 8500;
mob.setHealth(mob.healthMax);
hellgate_mobs.add(mob);
break;
case 12770: // minotaur mini boss
mob.getCharItemManager().clearInventory();
SpecialLootHandler(mob,true,false);
mob.setResists(new Resists("Elite"));
mob.healthMax = 12500;
mob.setHealth(mob.healthMax);
hellgate_mini_bosses.add(mob);
break;
case 14180: // mordoth, son of morlock
mob.getCharItemManager().clearInventory();
SpecialLootHandler(mob,false,true);
mob.setResists(new Resists("Elite"));
mob.healthMax = mob.mobBase.getHealthMax();
mob.setHealth(mob.healthMax);
hellgate_boss = mob;
break;
}
}
}
public static void ResetHellgate(){
hellgate_time_completed = 0L;
for(Mob mob : hellgate_mobs){
if(!mob.isAlive()){
if(!mob.despawned){
mob.despawn();
}
mob.respawn();
}
mob.setHealth(mob.healthMax);
SpecialLootHandler(mob,false,false);
}
for(Mob mob : hellgate_mini_bosses){
if(!mob.isAlive()){
if(!mob.despawned){
mob.despawn();
}
mob.respawn();
}
mob.setHealth(mob.healthMax);
SpecialLootHandler(mob,true,false);
}
if(!hellgate_boss.isAlive()){
if(!hellgate_boss.despawned){
hellgate_boss.despawn();
}
hellgate_boss.respawn();
}
hellgate_boss.setHealth(hellgate_boss.healthMax);
SpecialLootHandler(hellgate_boss,false,true);
}
public static void SpecialMobAIHandler(Mob mob){
if(mob.playerAgroMap.isEmpty())
return;
if(!mob.isAlive())
return;
if(mob.combatTarget == null)
MobAI.NewAggroMechanic(mob);
if(MovementUtilities.canMove(mob) && mob.combatTarget != null && !CombatUtilities.inRangeToAttack(mob,mob.combatTarget))
MobAI.chaseTarget(mob);
if(mob.combatTarget != null)
MobAI.CheckForAttack(mob);
if(mob.combatTarget == null && mob.loc.distanceSquared(mob.bindLoc) > 1024) {//32 units
mob.teleport(mob.bindLoc);
mob.setCombatTarget(null);
MovementUtilities.aiMove(mob,mob.bindLoc,true);
}
}
public static void SpecialLootHandler(Mob mob, Boolean commander, Boolean epic){
mob.getCharItemManager().clearInventory();
int contractRoll = ThreadLocalRandom.current().nextInt(1,101);
if(contractRoll <= 25){
//generate random contract
}
int runeRoll = ThreadLocalRandom.current().nextInt(1,101);
ItemBase runeBase = null;
int roll;
int itemId;
if(runeRoll <= 60 && !commander && !epic) {
//generate random rune (standard 5-30)
roll = ThreadLocalRandom.current().nextInt(static_rune_ids_low.size() + 1);
itemId = static_rune_ids_low.get(0);
try {
itemId = static_rune_ids_low.get(roll);
} catch (Exception e) {
}
runeBase = ItemBase.getItemBase(itemId);
if (runeBase != null) {
MobLoot rune = new MobLoot(mob, runeBase, true);
if (rune != null)
mob.getCharItemManager().addItemToInventory(rune);
}
}
if(runeRoll <= 50 && commander) {
//generate random rune (30-40)
roll = ThreadLocalRandom.current().nextInt(static_rune_ids_mid.size() + 1);
itemId = static_rune_ids_mid.get(0);
try {
itemId = static_rune_ids_mid.get(roll);
} catch (Exception e) {
}
runeBase = ItemBase.getItemBase(itemId);
if (runeBase != null) {
MobLoot rune = new MobLoot(mob, runeBase, true);
if (rune != null)
mob.getCharItemManager().addItemToInventory(rune);
}
}
if(runeRoll <= 80 && epic) {
//generate random rune (35-40)
roll = ThreadLocalRandom.current().nextInt(static_rune_ids_high.size() + 1);
itemId = static_rune_ids_high.get(0);
try {
itemId = static_rune_ids_high.get(roll);
} catch (Exception e) {
}
runeBase = ItemBase.getItemBase(itemId);
if (runeBase != null) {
MobLoot rune = new MobLoot(mob, runeBase, true);
if (rune != null)
mob.getCharItemManager().addItemToInventory(rune);
}
}
if(commander || epic) {
//handle special case for racial guards
roll = ThreadLocalRandom.current().nextInt(LootManager.racial_guard_uuids.size() + 1);
itemId = LootManager.racial_guard_uuids.get(0);
try {
itemId = LootManager.racial_guard_uuids.get(roll);
} catch (Exception e) {
}
runeBase = ItemBase.getItemBase(itemId);
if (runeBase != null) {
MobLoot rune = new MobLoot(mob, runeBase, true);
if (rune != null)
mob.getCharItemManager().addItemToInventory(rune);
}
}
if(epic){
//handle glass chance for epic
int glassRoll = ThreadLocalRandom.current().nextInt(1,101);
if(glassRoll < 5){
int glassID = LootManager.rollRandomItem(126);
ItemBase glassItem = ItemBase.getItemBase(glassID);
if (glassItem != null) {
MobLoot glass = new MobLoot(mob, glassItem, true);
if (glass != null)
mob.getCharItemManager().addItemToInventory(glass);
}
}
}
//handle gold drops
int goldDrop;
if(!commander && !epic){
goldDrop = ThreadLocalRandom.current().nextInt(25000);
mob.getCharItemManager().addGoldToInventory(goldDrop,false);
}
if(commander){
goldDrop = ThreadLocalRandom.current().nextInt(100000,250000);
mob.getCharItemManager().addGoldToInventory(goldDrop,false);
}
if(epic){
goldDrop = ThreadLocalRandom.current().nextInt(2500000,5000000);
mob.getCharItemManager().addGoldToInventory(goldDrop,false);
}
}
}

238
src/engine/gameManager/HotzoneManager.java

@ -0,0 +1,238 @@ @@ -0,0 +1,238 @@
package engine.gameManager;
import engine.Enum;
import engine.InterestManagement.WorldGrid;
import engine.math.Vector3fImmutable;
import engine.net.Dispatch;
import engine.net.DispatchMessage;
import engine.net.client.msg.HotzoneChangeMsg;
import engine.net.client.msg.chat.ChatSystemMsg;
import engine.objects.*;
import engine.server.MBServerStatics;
import org.pmw.tinylog.Logger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;
public class HotzoneManager {
public static Long lastPulseTime = 0L;
public static HashMap<Guild, ArrayList<PlayerCharacter>> playersPresent;
public static Mob hotzoneMob = null;
public static boolean three_quarter_health = false;
public static boolean half_health = false;
public static boolean quarter_health = false;
public static void SelectRandomHotzone(){
if(hotzoneMob != null){
hotzoneMob.killCharacter("Hotzone Over");
hotzoneMob.despawn();
hotzoneMob.spawnTime = 1000000000;
DbManager.MobQueries.DELETE_MOB( hotzoneMob);
}
Random random = new Random();
Zone newHotzone = null;
while (newHotzone == null || newHotzone.getObjectUUID() == 931 || newHotzone.getObjectUUID() == 913)
newHotzone = (Zone) ZoneManager.macroZones.toArray()[random.nextInt(ZoneManager.macroZones.size())];
ZoneManager.setHotZone(newHotzone);
ZoneManager.hotZone = newHotzone;
int R8UUId = 0;
switch(random.nextInt(5)) {
case 1:
R8UUId = 14152;
break;
case 2:
R8UUId = 14179;
break;
case 3:
R8UUId = 14180;
break;
case 4:
R8UUId = 14220;
break;
default:
R8UUId = 14319;
break;
}
Mob created = Mob.createMob(R8UUId,newHotzone.getLoc(), Guild.getErrantGuild(),true,newHotzone,null,0,"",85);
if(created == null){
Logger.error("Failed To Generate Hotzone R8 Mob");
return;
}
ChatSystemMsg chatMsg = new ChatSystemMsg(null, created.getFirstName() + " has spawned in " + newHotzone.getName() + ". Glory and riches await adventurers who dare defeat it!");
chatMsg.setMessageType(10);
chatMsg.setChannel(Enum.ChatChannelType.SYSTEM.getChannelID());
DispatchMessage.dispatchMsgToAll(chatMsg);
created.bindLoc = newHotzone.getLoc();
created.runAfterLoad();
WorldGrid.addObject(created,created.bindLoc.x,created.bindLoc.z);
created.teleport(created.bindLoc);
created.BehaviourType = Enum.MobBehaviourType.Aggro;
hotzoneMob = created;
created.setHealth(100000);
created.setResists(new Resists("Dropper"));
GenerateHotzoneEpicLoot(created);
ZoneManager.hotZone = newHotzone;
for(PlayerCharacter player : SessionManager.getAllActivePlayerCharacters()) {
HotzoneChangeMsg hcm = new HotzoneChangeMsg(Enum.GameObjectType.Zone.ordinal(), ZoneManager.hotZone.getObjectUUID());
Dispatch dispatch = Dispatch.borrow(player, hcm);
DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.SECONDARY);
}
three_quarter_health = false;
half_health = false;
quarter_health = false;
}
public static void GenerateHotzoneEpicLoot(Mob mob) {
mob.getCharItemManager().clearInventory();
Random random = new Random();
int roll;
int itemId;
//wrapped rune:
ItemBase runeBase = ItemBase.getItemBase(971070);
if (runeBase != null) {
MobLoot rune = new MobLoot(mob, runeBase, true);
if (rune != null)
mob.getCharItemManager().addItemToInventory(rune);
}
roll = ThreadLocalRandom.current().nextInt(1, 101);
if (roll >= 95) {
//glass
int glassID = LootManager.rollRandomItem(126);
ItemBase glassItem = ItemBase.getItemBase(glassID);
if (glassItem != null) {
MobLoot glass = new MobLoot(mob, glassItem, true);
if (glass != null)
mob.getCharItemManager().addItemToInventory(glass);
}
}
roll = ThreadLocalRandom.current().nextInt(1, 101);
if (roll >= 95) {
//r8 banescroll
int baneID = 910018;
ItemBase baneItem = ItemBase.getItemBase(baneID);
if (baneItem != null) {
MobLoot bane = new MobLoot(mob, baneItem, true);
if (bane != null)
mob.getCharItemManager().addItemToInventory(bane);
}
}
roll = ThreadLocalRandom.current().nextInt(1, 101);
if (roll >= 95) {
//guard captain
roll = ThreadLocalRandom.current().nextInt(LootManager.racial_guard_uuids.size() + 1);
itemId = LootManager.racial_guard_uuids.get(0);
try {
itemId = LootManager.racial_guard_uuids.get(roll);
} catch (Exception e) {
}
runeBase = ItemBase.getItemBase(itemId);
if (runeBase != null) {
MobLoot rune = new MobLoot(mob, runeBase, true);
if (rune != null)
mob.getCharItemManager().addItemToInventory(rune);
}
}
}
public static void ClearHotzone(){
ZoneManager.hotZone = null;
for(PlayerCharacter player : SessionManager.getAllActivePlayerCharacters()) {
HotzoneChangeMsg hcm = new HotzoneChangeMsg(Enum.GameObjectType.Zone.ordinal(), 0);
Dispatch dispatch = Dispatch.borrow(player, hcm);
DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.SECONDARY);
}
}
public static void pulse(){
if(HotzoneManager.playersPresent == null)
HotzoneManager.playersPresent = new HashMap<>();
if(ZoneManager.hotZone == null)
return;
if(lastPulseTime + 5000L > System.currentTimeMillis())
return;
lastPulseTime = System.currentTimeMillis();
//handle world announcements for HZ boss
if(hotzoneMob != null){
float health = hotzoneMob.getHealth();
if(health < 75000 && health > 50000 && !three_quarter_health){
//mob at 50%-75% health
three_quarter_health = true;
String name = hotzoneMob.getName();
ChatSystemMsg chatMsg = new ChatSystemMsg(null, name + " In The Hotzone Is At 75% Health");
chatMsg.setMessageType(10);
chatMsg.setChannel(Enum.ChatChannelType.SYSTEM.getChannelID());
DispatchMessage.dispatchMsgToAll(chatMsg);
}else if(health < 50000 && health > 25000 && !half_health){
//mob ta 25%-50% health
half_health = true;
String name = hotzoneMob.getName();
ChatSystemMsg chatMsg = new ChatSystemMsg(null, name + " In The Hotzone Is At 50% Health");
chatMsg.setMessageType(10);
chatMsg.setChannel(Enum.ChatChannelType.SYSTEM.getChannelID());
DispatchMessage.dispatchMsgToAll(chatMsg);
}else if(health < 25000 && !quarter_health){
//mob under 25% health
quarter_health = true;
String name = hotzoneMob.getName();
ChatSystemMsg chatMsg = new ChatSystemMsg(null, name + " In The Hotzone Is At 25% Health");
chatMsg.setMessageType(10);
chatMsg.setChannel(Enum.ChatChannelType.SYSTEM.getChannelID());
DispatchMessage.dispatchMsgToAll(chatMsg);
}else if (health > 75000){
//mob at 75% - 100% health
}
}
HashSet<AbstractWorldObject> inRange = WorldGrid.getObjectsInRangePartial(ZoneManager.hotZone.getLoc(),ZoneManager.hotZone.getBounds().getHalfExtents().x * 2, MBServerStatics.MASK_PLAYER);
//clear out old players who aren't here anymore
for(Guild nation : HotzoneManager.playersPresent.keySet()){
for(PlayerCharacter pc : HotzoneManager.playersPresent.get(nation)){
if (!inRange.contains(pc)) {
HotzoneManager.playersPresent.get(nation).remove(pc);
if(HotzoneManager.playersPresent.get(nation).size() < 1){
HotzoneManager.playersPresent.remove(nation);
}
}
}
}
//check status of current players/nation in vicinity
for(AbstractWorldObject awo : inRange){
PlayerCharacter pc = (PlayerCharacter)awo;
Guild nation = pc.guild.getNation();
if(HotzoneManager.playersPresent.containsKey(nation)){
//nation already here, add to list
if(HotzoneManager.playersPresent.get(nation).size() >= 5 && !HotzoneManager.playersPresent.get(nation).contains(pc)){
//more than 5, boot player out
MovementManager.translocate(pc, Vector3fImmutable.getRandomPointOnCircle(ZoneManager.getZoneByUUID(656).getLoc(),30f),Regions.GetRegionForTeleport(ZoneManager.getZoneByUUID(656).getLoc()));
}
if(!HotzoneManager.playersPresent.get(nation).contains(pc)){
//less than 5, allow player in
HotzoneManager.playersPresent.get(nation).add(pc);
}
}else{
ArrayList<PlayerCharacter> newList = new ArrayList<>();
newList.add(pc);
HotzoneManager.playersPresent.put(nation,newList);
}
}
}
}

772
src/engine/gameManager/LootManager.java

@ -14,10 +14,10 @@ import engine.net.DispatchMessage; @@ -14,10 +14,10 @@ import engine.net.DispatchMessage;
import engine.net.client.msg.ErrorPopupMsg;
import engine.net.client.msg.chat.ChatSystemMsg;
import engine.objects.*;
import engine.server.MBServerStatics;
import org.pmw.tinylog.Logger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;
/**
@ -34,6 +34,21 @@ public enum LootManager { @@ -34,6 +34,21 @@ 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));
public static final ArrayList<Integer> static_rune_ids = new ArrayList<>(Arrays.asList(
250001, 250002, 250003, 250004, 250005, 250006, 250007, 250008, 250010, 250011,
250012, 250013, 250014, 250015, 250016, 250017, 250019, 250020, 250021, 250022,
250023, 250024, 250025, 250026, 250028, 250029, 250030, 250031, 250032, 250033,
250034, 250035, 250037, 250038, 250039, 250040, 250041, 250042, 250043, 250044,
250115, 250118, 250119, 250120, 250121, 250122, 252123, 252124, 252125, 252126,
252127
));
// Drop Rates
public static float NORMAL_DROP_RATE;
@ -68,49 +83,85 @@ public enum LootManager { @@ -68,49 +83,85 @@ public enum LootManager {
public static void GenerateMobLoot(Mob mob) {
if(mob == null){
return;
}
if(!mob.getSafeZone()) {
SpecialLootHandler.RollContract(mob);
SpecialLootHandler.RollGlass(mob);
SpecialLootHandler.RollRune(mob);
SpecialLootHandler.RollRacialGuard(mob);
}
//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")) {
Zone camp = mob.getParentZone();
Zone macro = camp.getParent();
String name = camp.getName() + "(" + macro.getName() + ")";
ChatSystemMsg chatMsg = new ChatSystemMsg(null, mob.getName() + " in " + name + " 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;
// 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 +186,90 @@ public enum LootManager { @@ -135,6 +186,90 @@ 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 roll = ThreadLocalRandom.current().nextInt(static_rune_ids.size() + 1);
int itemId = static_rune_ids.get(0);
try {
itemId = static_rune_ids.get(roll);
}catch(Exception e){
}
ItemBase ib = ItemBase.getItemBase(itemId);
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 +291,10 @@ public enum LootManager { @@ -156,11 +291,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)
@ -171,14 +305,24 @@ public enum LootManager { @@ -171,14 +305,24 @@ public enum LootManager {
if (itemUUID == 0)
return null;
if (ItemBase.getItemBase(itemUUID).getType().ordinal() == Enum.ItemType.RESOURCE.ordinal()) {
if (ItemBase.getItemBase(itemUUID).getType().equals(Enum.ItemType.RESOURCE) || ItemBase.getItemBase(itemUUID).getName().equals("Mithril")) {
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 +340,12 @@ public enum LootManager { @@ -196,6 +340,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 +366,7 @@ public enum LootManager { @@ -216,7 +366,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);
@ -224,8 +374,23 @@ public enum LootManager { @@ -224,8 +374,23 @@ public enum LootManager {
return inItem;
if (prefixMod.action.length() > 0) {
inItem.setPrefix(prefixMod.action);
inItem.addPermanentEnchantment(prefixMod.action, 0, prefixMod.level, true);
String action = prefixMod.action;
if(action.equals("PRE-108") || action.equals("PRE-058") || action.equals("PRE-031")){//massive, barons and avatars to be replaced by leg or warlords
int roll = ThreadLocalRandom.current().nextInt(1,100);
if(inItem.getItemBase().getRange() > 15){
action = "PRE-040";
}else {
if (roll > 50) {
//set warlords
action = "PRE-021";
} else {
//set legendary
action = "PRE-040";
}
}
}
inItem.setPrefix(action);
inItem.addPermanentEnchantment(action, 0, prefixMod.level, true);
}
return inItem;
@ -248,14 +413,34 @@ public enum LootManager { @@ -248,14 +413,34 @@ 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);
if (suffixMod == null)
return inItem;
if (suffixMod.action.length() > 0) {
int moveSpeedRoll = ThreadLocalRandom.current().nextInt(100);
if(inItem.getItemBase().getValidSlot() == MBServerStatics.SLOT_FEET && moveSpeedRoll < 10){
int rankRoll = ThreadLocalRandom.current().nextInt(10);
String suffixSpeed = "SUF-148";
switch(rankRoll) {
case 1:
case 2:
case 3:
suffixSpeed = "SUF-149";
break;
case 4:
case 5:
case 6:
case 7:
suffixSpeed = "SUF-150";
break;
}
inItem.setSuffix(suffixSpeed);
inItem.addPermanentEnchantment(suffixSpeed, 0, suffixMod.level, false);
}else if (suffixMod.action.length() > 0) {
inItem.setSuffix(suffixMod.action);
inItem.addPermanentEnchantment(suffixMod.action, 0, suffixMod.level, false);
}
@ -263,23 +448,36 @@ public enum LootManager { @@ -263,23 +448,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 +497,7 @@ public enum LootManager { @@ -299,12 +497,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 +508,67 @@ public enum LootManager { @@ -315,45 +508,67 @@ public enum LootManager {
public static void GenerateLootDrop(Mob mob, int tableID, Boolean inHotzone) {
try {
MobLoot toAdd = getGenTableItem(tableID, mob, inHotzone);
if(toAdd != null){
ItemBase ib = toAdd.getItemBase();
switch(ib.getType()){
case CONTRACT:
case RUNE:
case RESOURCE:
return;
}
MobLoot toAdd = getGenTableItem(tableID, mob, inHotzone);
if (ib.getUUID() == 1580021)//mithril
return;
if (toAdd != null)
mob.getCharItemManager().addItemToInventory(toAdd);
} catch (Exception e) {
//TODO chase down loot generation error, affects roughly 2% of drops
int i = 0;
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 = 7.5f;
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) {
@ -365,12 +580,134 @@ public enum LootManager { @@ -365,12 +580,134 @@ public enum LootManager {
if (chanceRoll > bse.dropChance)
return;
if(bse.itemBase == 1580021)//mithril
return;
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 newFatePeddler(PlayerCharacter playerCharacter, Item gift) {
CharacterItemManager itemMan = playerCharacter.getCharItemManager();
if (itemMan == null)
return;
//check if player owns the gift he is trying to open
if (!itemMan.doesCharOwnThisItem(gift.getObjectUUID()))
return;
ItemBase ib = gift.getItemBase();
MobLoot winnings = null;
if (ib == null)
return;
switch (ib.getUUID()) {
case 971070: //wrapped rune
Random random = new Random();
int roll = random.nextInt(100);
int itemId;
ItemBase runeBase;
if (roll >= 90) {
//35 or 40
roll = ThreadLocalRandom.current().nextInt(HellgateManager.static_rune_ids_high.size() + 1);
itemId = HellgateManager.static_rune_ids_high.get(0);
try {
itemId = HellgateManager.static_rune_ids_high.get(roll);
} catch (Exception e) {
}
runeBase = ItemBase.getItemBase(itemId);
if (runeBase != null) {
MobLoot rune = new MobLoot(playerCharacter, runeBase, true);
if (rune != null)
playerCharacter.getCharItemManager().addItemToInventory(rune);
}
} else if (roll >= 65 && roll <= 89) {
//30,35 or 40
roll = ThreadLocalRandom.current().nextInt(HellgateManager.static_rune_ids_mid.size() + 1);
itemId = HellgateManager.static_rune_ids_mid.get(0);
try {
itemId = HellgateManager.static_rune_ids_mid.get(roll);
} catch (Exception e) {
}
runeBase = ItemBase.getItemBase(itemId);
if (runeBase != null) {
MobLoot rune = new MobLoot(playerCharacter, runeBase, true);
if (rune != null)
playerCharacter.getCharItemManager().addItemToInventory(rune);
}
} else {
//5-30
roll = ThreadLocalRandom.current().nextInt(HellgateManager.static_rune_ids_low.size() + 1);
itemId = HellgateManager.static_rune_ids_low.get(0);
try {
itemId = HellgateManager.static_rune_ids_low.get(roll);
} catch (Exception ignored) {
}
runeBase = ItemBase.getItemBase(itemId);
if (runeBase != null) {
MobLoot rune = new MobLoot(playerCharacter, runeBase, true);
if (rune != null)
playerCharacter.getCharItemManager().addItemToInventory(rune);
}
}
break;
case 971012: //wrapped glass
int chance = ThreadLocalRandom.current().nextInt(100);
if(chance == 50){
int ID = 7000000;
int additional = ThreadLocalRandom.current().nextInt(0,28);
ID += (additional * 10);
ItemBase glassBase = ItemBase.getItemBase(ID);
if(glassBase != null) {
winnings = new MobLoot(playerCharacter, glassBase, 1, false);
ChatManager.chatSystemInfo(playerCharacter, "You've Won A " + glassBase.getName());
}
}else{
ChatManager.chatSystemInfo(playerCharacter, "Please Try Again!");
}
break;
}
if (winnings == null) {
itemMan.consume(gift);
itemMan.updateInventory();
return;
}
//early exit if the inventory of the player will not hold the item
if (!itemMan.hasRoomInventory(winnings.getItemBase().getWeight())) {
ErrorPopupMsg.sendErrorPopup(playerCharacter, 21);
return;
}
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();
}
public static void peddleFate(PlayerCharacter playerCharacter, Item gift) {
//get table ID for the itembase ID
@ -392,12 +729,12 @@ public enum LootManager { @@ -392,12 +729,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 +750,276 @@ public enum LootManager { @@ -413,45 +750,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 > MBServerStatics.PLAYER_GOLD_LIMIT) {
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, 9);
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, 8);
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, 8);
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, 5);
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));
}
}
itemMan.consume(gift);
return null;
}
//add winnings to player inventory
public static void DropPresent(Mob mob){
int random = 971049 + ThreadLocalRandom.current().nextInt(24);
if (random > 971071)
random = 971071;
Item playerWinnings = winnings.promoteToItem(playerCharacter);
itemMan.addItemToInventory(playerWinnings);
itemMan.updateInventory();
ItemBase present = ItemBase.getItemBase(random);
if (present != null) {
MobLoot toAdd = new MobLoot(mob, present, true);
if (toAdd != null)
mob.getCharItemManager().addItemToInventory(toAdd);
}
}
public static void GenerateStrongholdLoot(Mob mob, boolean commander, boolean epic) {
mob.getCharItemManager().clearInventory();
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);
}
}
}
}

130
src/engine/gameManager/LoreMineManager.java

@ -0,0 +1,130 @@ @@ -0,0 +1,130 @@
package engine.gameManager;
import engine.Enum;
import engine.math.Vector3fImmutable;
import engine.objects.Guild;
import engine.objects.Mine;
import engine.objects.PlayerCharacter;
import engine.objects.Regions;
import java.util.*;
public class LoreMineManager {
//Saetor Allowed Charters:
//BARBARIAN
//MILITARY
//RANGER
//AMAZON
//WIZARD
//MERCENARY
//THIEVES
//SCOURGE
//UNHOLY
public static final Map<Enum.GuildType, List<String>> GUILD_RACES = new HashMap<>();
public static final Map<Enum.GuildType, List<String>> GUILD_CLASSES = new HashMap<>();
public static final Map<Enum.GuildType, Boolean> GUILD_GENDER_RESTRICTION = new HashMap<>();
static {
GUILD_RACES.put(Enum.GuildType.CATHEDRAL, Arrays.asList("Aelfborn", "Centaur", "Elf", "Half Giant", "Human"));
GUILD_CLASSES.put(Enum.GuildType.CATHEDRAL, Arrays.asList("Bard", "Channeler", "Crusader", "Nightstalker", "Prelate", "Priest", "Scout", "Sentinel"));
GUILD_RACES.put(Enum.GuildType.MILITARY, Arrays.asList("Centaur", "Half Giant", "Human", "Saetor"));
GUILD_CLASSES.put(Enum.GuildType.MILITARY, Arrays.asList("Bard", "Priest", "Scout", "Warlock", "Warrior", "Wizard"));
GUILD_RACES.put(Enum.GuildType.TEMPLE, Arrays.asList("Half Giant", "Human"));
GUILD_CLASSES.put(Enum.GuildType.TEMPLE, Arrays.asList("Assassin", "Bard", "Channeler", "Confessor", "Nightstalker", "Priest", "Scout", "Templar"));
GUILD_RACES.put(Enum.GuildType.BARBARIAN, Arrays.asList("Aelfborn", "Half Giant", "Human", "Minotaur", "Saetor"));
GUILD_CLASSES.put(Enum.GuildType.BARBARIAN, Arrays.asList("Barbarian", "Bard", "Doomsayer", "Fury", "Priest", "Scout", "Thief", "Warrior"));
GUILD_RACES.put(Enum.GuildType.RANGER, Arrays.asList("Aelfborn", "Elf", "Half Giant", "Human", "Shade", "Saetor"));
GUILD_CLASSES.put(Enum.GuildType.RANGER, Arrays.asList("Bard", "Channeler", "Druid", "Priest", "Ranger", "Scout", "Warrior"));
GUILD_RACES.put(Enum.GuildType.AMAZON, Arrays.asList("Aelfborn", "Elf", "Half Giant", "Human", "Saetor"));
GUILD_CLASSES.put(Enum.GuildType.AMAZON, Arrays.asList("Bard", "Druid", "Fury", "Huntress", "Priest", "Scout", "Warrior", "Wizard"));
GUILD_GENDER_RESTRICTION.put(Enum.GuildType.AMAZON, true); // Female only
GUILD_RACES.put(Enum.GuildType.NOBLE, Arrays.asList("Aelfborn", "Half Giant", "Human"));
GUILD_CLASSES.put(Enum.GuildType.NOBLE, Arrays.asList("Assassin", "Bard", "Channeler", "Priest", "Scout", "Thief", "Warlock", "Warrior", "Wizard"));
GUILD_RACES.put(Enum.GuildType.WIZARD, Arrays.asList("Aelfborn", "Elf", "Human", "Nephilim", "Shade", "Saetor"));
GUILD_CLASSES.put(Enum.GuildType.WIZARD, Arrays.asList("Assassin", "Bard", "Channeler", "Doomsayer", "Fury", "Necromancer", "Priest", "Warlock", "Wizard"));
GUILD_RACES.put(Enum.GuildType.MERCENARY, Arrays.asList("Aelfborn", "Aracoix", "Half Giant", "Human", "Shade", "Saetor"));
GUILD_CLASSES.put(Enum.GuildType.MERCENARY, Arrays.asList("Assassin", "Bard", "Priest", "Scout", "Thief", "Warlock", "Warrior"));
GUILD_RACES.put(Enum.GuildType.THIEVES, Arrays.asList("Aelfborn", "Aracoix", "Elf", "Human", "Irekei", "Nephilim", "Shade", "Vampire", "Saetor"));
GUILD_CLASSES.put(Enum.GuildType.THIEVES, Arrays.asList("Assassin", "Barbarian", "Bard", "Priest", "Scout", "Thief", "Wizard"));
GUILD_RACES.put(Enum.GuildType.DWARF, Arrays.asList("Dwarf"));
GUILD_CLASSES.put(Enum.GuildType.DWARF, Arrays.asList("Crusader", "Prelate", "Priest", "Sentinel", "Warrior"));
GUILD_RACES.put(Enum.GuildType.HIGHCOURT, Arrays.asList("Elf", "Minotaur"));
GUILD_CLASSES.put(Enum.GuildType.HIGHCOURT, Arrays.asList("Assassin", "Bard", "Channeler", "Druid", "Necromancer", "Priest", "Ranger", "Scout", "Thief", "Warrior", "Wizard"));
GUILD_RACES.put(Enum.GuildType.VIRAKT, Arrays.asList("Irekei"));
GUILD_CLASSES.put(Enum.GuildType.VIRAKT, Arrays.asList("Assassin", "Bard", "Channeler", "Fury", "Huntress", "Nightstalker", "Priest", "Ranger", "Scout", "Thief", "Warrior", "Wizard"));
GUILD_RACES.put(Enum.GuildType.SCOURGE, Arrays.asList("Aelfborn", "Human", "Minotaur", "Nephilim", "Saetor"));
GUILD_CLASSES.put(Enum.GuildType.SCOURGE, Arrays.asList("Bard", "Channeler", "Doomsayer", "Priest", "Scout", "Warrior", "Wizard"));
GUILD_RACES.put(Enum.GuildType.KHREE, Arrays.asList("Aracoix"));
GUILD_CLASSES.put(Enum.GuildType.KHREE, Arrays.asList("Assassin", "Barbarian", "Bard", "Huntress", "Priest", "Ranger", "Scout", "Thief", "Warlock", "Warrior"));
GUILD_RACES.put(Enum.GuildType.CENTAUR, Arrays.asList("Centaur"));
GUILD_CLASSES.put(Enum.GuildType.CENTAUR, Arrays.asList("Barbarian", "Crusader", "Druid", "Huntress", "Prelate", "Priest", "Ranger", "Sentinel", "Warrior"));
GUILD_RACES.put(Enum.GuildType.UNHOLY, Arrays.asList("Human", "Shade", "Vampire", "Saetor"));
GUILD_CLASSES.put(Enum.GuildType.UNHOLY, Arrays.asList("Assassin", "Channeler", "Necromancer", "Priest", "Scout", "Thief", "Warlock", "Warrior", "Wizard"));
}
public static void AuditPlayer(PlayerCharacter pc, Mine mine){
Guild nation = pc.guild.getNation();
if(mine.chosen_charters == null){
mine.chosen_charters = new HashMap<>();
}
Enum.GuildType guildType;
if (mine.chosen_charters.containsKey(nation)) {
guildType = mine.chosen_charters.get(nation);
}else{
guildType = Enum.GuildType.getGuildTypeFromInt(pc.guild.getCharter());
mine.chosen_charters.put(nation,guildType);
}
if(!validForCharter(pc,guildType)){
//bounce out to SDR
Vector3fImmutable bounceLoc = Vector3fImmutable.getRandomPointOnCircle(ZoneManager.getZoneByUUID(656).getLoc(),30f);
pc.setLoc(bounceLoc);
MovementManager.translocate(pc, bounceLoc, Regions.GetRegionForTeleport(ZoneManager.getZoneByUUID(656).getLoc()));
ChatManager.chatSystemInfo(pc, "You Failed To Meet Lore Requirements");
}
}
public static boolean validForCharter(PlayerCharacter pc, Enum.GuildType guildType) {
if(pc.getPromotionClass() == null)
return false;
// Define the races and classes for each GuildType
// Get the allowed races and classes for this guildType
List<String> allowedRaces = GUILD_RACES.getOrDefault(guildType, Collections.emptyList());
List<String> allowedClasses = GUILD_CLASSES.getOrDefault(guildType, Collections.emptyList());
// Validate player's race and class
if (!allowedRaces.contains(pc.getRace().getName()) || !allowedClasses.contains(pc.getPromotionClass().getName())) {
return false;
}
// Gender restriction check for AMAZON
if (guildType.equals(Enum.GuildType.AMAZON) && pc.isMale() && pc.getRaceID() != 1999) {
return false;
}
return true;
}
}

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;
}

17
src/engine/gameManager/MovementManager.java

@ -66,12 +66,6 @@ public enum MovementManager { @@ -66,12 +66,6 @@ public enum MovementManager {
if (!toMove.isAlive())
return;
if (toMove.getObjectType().equals(GameObjectType.PlayerCharacter)) {
if (((PlayerCharacter) toMove).isCasting())
((PlayerCharacter) toMove).update();
}
toMove.setIsCasting(false);
toMove.setItemCasting(false);
@ -96,7 +90,7 @@ public enum MovementManager { @@ -96,7 +90,7 @@ public enum MovementManager {
if (!toMove.isMoving())
toMove.resetLastSetLocUpdate();
else
toMove.update();
toMove.update(false);
// Update movement for the player
@ -105,6 +99,9 @@ public enum MovementManager { @@ -105,6 +99,9 @@ public enum MovementManager {
// ((Mob)toMove).updateLocation();
// get start and end locations for the move
Vector3fImmutable startLocation = new Vector3fImmutable(msg.getStartLat(), msg.getStartAlt(), msg.getStartLon());
//if(toMove.isMoving()){
// startLocation = toMove.getMovementLoc();
//}
Vector3fImmutable endLocation = new Vector3fImmutable(msg.getEndLat(), msg.getEndAlt(), msg.getEndLon());
// if (toMove.getObjectType() == GameObjectType.PlayerCharacter)
@ -351,7 +348,7 @@ public enum MovementManager { @@ -351,7 +348,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 +405,9 @@ public enum MovementManager { @@ -408,7 +405,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);

633
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,47 @@ public enum PowersManager { @@ -163,6 +164,47 @@ 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.getRecycleTimers().containsKey(msg.getPowerUsedID())) {
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() != 421084024 && origin.getPlayerCharacter().getPromotionClassID() != 2513) {
if (!origin.getPlayerCharacter().getPowers().containsKey(msg.getPowerUsedID())) {
Logger.error(origin.getPlayerCharacter().getFirstName() + " attempted to cast a power they do not have");
return;
}
}
//crusader sacrifice
if((msg.getPowerUsedID() == 428695403 && msg.getTargetID() == pc.getObjectUUID())){
RecyclePowerMsg recyclePowerMsg = new RecyclePowerMsg(msg.getPowerUsedID());
Dispatch dispatch = Dispatch.borrow(origin.getPlayerCharacter(), recyclePowerMsg);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY);
// Send Fail to cast message
if (pc != null) {
sendPowerMsg(pc, 2, msg);
if (pc.isCasting()) {
pc.update(false);
}
pc.setIsCasting(false);
}
return;
}
if(msg.getPowerUsedID() == -1851459567){//backstab
applyPower(pc,pc,pc.loc,-1851459567,msg.getNumTrains(),false);
}
if (usePowerA(msg, origin, sendCastToSelf)) {
// Cast failed for some reason, reset timer
@ -171,19 +213,20 @@ public enum PowersManager { @@ -171,19 +213,20 @@ 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);
}
}
if(msg.getPowerUsedID() == 429429978){
origin.getPlayerCharacter().getRecycleTimers().remove(429429978);
}
}
public static void useMobPower(Mob caster, AbstractCharacter target, PowersBase pb, int rank) {
@ -192,7 +235,8 @@ public enum PowersManager { @@ -192,7 +235,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);
}
}
@ -203,8 +247,56 @@ public enum PowersManager { @@ -203,8 +247,56 @@ public enum PowersManager {
if (playerCharacter == null)
return false;
//if(playerCharacter.getRecycleTimers().containsKey(msg.getPowerUsedID())){
// playerCharacter.setIsCasting(false);
// playerCharacter.setItemCasting(false);
// return false;
//}
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 +333,7 @@ public enum PowersManager { @@ -241,6 +333,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 +345,35 @@ public enum PowersManager { @@ -252,6 +345,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 +381,18 @@ public enum PowersManager { @@ -259,17 +381,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 +402,14 @@ public enum PowersManager { @@ -279,6 +402,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 +501,20 @@ public enum PowersManager { @@ -370,15 +501,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 +545,23 @@ public enum PowersManager { @@ -409,6 +545,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 +640,6 @@ public enum PowersManager { @@ -487,7 +640,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 +666,7 @@ public enum PowersManager { @@ -514,7 +666,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 +674,12 @@ public enum PowersManager { @@ -522,10 +674,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 +689,12 @@ public enum PowersManager { @@ -535,13 +689,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 +820,11 @@ public enum PowersManager { @@ -667,10 +820,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.
@ -700,14 +854,56 @@ public enum PowersManager { @@ -700,14 +854,56 @@ public enum PowersManager {
// called when a spell finishes casting. perform actions
public static void finishUsePower(final PerformActionMsg msg, PlayerCharacter playerCharacter, int casterLiveCounter, int targetLiveCounter) {
// if(true) {
// newFinishCast(msg);
// return;
//}
//if(HandleItemEnchantments(playerCharacter, msg)) {
// playerCharacter.setIsCasting(false);
// PerformActionMsg castMsg = new PerformActionMsg(msg);
// castMsg.setNumTrains(9999);
// castMsg.setUnknown04(2);
// DispatchMessage.dispatchMsgToInterestArea(playerCharacter, castMsg, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false);
// return;
//}
PerformActionMsg performActionMsg;
Dispatch dispatch;
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)//templar
PlayerCharacter.getPlayerCharacter(msg.getTargetID()).removeEffectBySource(EffectSourceType.Transform, msg.getNumTrains(), true);
}
if (playerCharacter.isCasting()) {
playerCharacter.update();
playerCharacter.update(false);
playerCharacter.updateStamRegen(-100);
}
@ -747,6 +943,9 @@ public enum PowersManager { @@ -747,6 +943,9 @@ public enum PowersManager {
return;
}
if(pb.targetSelf)
msg.setTargetID(playerCharacter.getObjectUUID());
int trains = msg.getNumTrains();
// verify player is not stunned or power type is blocked
@ -809,15 +1008,16 @@ public enum PowersManager { @@ -809,15 +1008,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
}
@ -906,6 +1106,13 @@ public enum PowersManager { @@ -906,6 +1106,13 @@ public enum PowersManager {
//Player didn't miss power, send finish cast. Miss cast already sent.
//if (playerCharacter.isBoxed) {
// if (AbstractCharacter.IsAbstractCharacter(target)) {
// if (target.getObjectType().equals(GameObjectType.PlayerCharacter)) {
// return;
// }
// }
//}
// finally Apply actions
for (ActionsBase ab : pb.getActions()) {
@ -915,7 +1122,7 @@ public enum PowersManager { @@ -915,7 +1122,7 @@ public enum PowersManager {
continue;
// If something blocks the action, then stop
if (ab.blocked(target, pb, trains)) {
if (ab.blocked(target, pb, trains, playerCharacter)) {
PowersManager.sendEffectMsg(playerCharacter, 5, ab, pb);
continue;
@ -1002,7 +1209,18 @@ public enum PowersManager { @@ -1002,7 +1209,18 @@ public enum PowersManager {
//DispatchMessage.dispatchMsgToInterestArea(playerCharacter, msg, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false);
//handle mob hate values
HashSet<AbstractWorldObject> mobs = WorldGrid.getObjectsInRangePartial(playerCharacter.loc,60.0f,MBServerStatics.MASK_MOB);
for(AbstractWorldObject awo : mobs){
Mob mobTarget = (Mob)awo;
if(mobTarget.hate_values != null) {
if (mobTarget.hate_values.containsKey(playerCharacter)) {
mobTarget.hate_values.put(playerCharacter, mobTarget.hate_values.get(playerCharacter) + pb.getHateValue(trains));
} else {
mobTarget.hate_values.put(playerCharacter, pb.getHateValue(trains));
}
}
}
}
@ -1091,7 +1309,7 @@ public enum PowersManager { @@ -1091,7 +1309,7 @@ public enum PowersManager {
continue;
// If something blocks the action, then stop
if (ab.blocked(target, pb, trains))
if (ab.blocked(target, pb, trains, caster))
continue;
// TODO handle overwrite stack order here
String stackType = ab.getStackType();
@ -1233,7 +1451,7 @@ public enum PowersManager { @@ -1233,7 +1451,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,
@ -1292,7 +1510,7 @@ public enum PowersManager { @@ -1292,7 +1510,7 @@ public enum PowersManager {
// Handle Accepting or Denying a summons.
// set timer based on summon type.
boolean wentThrough = false;
if (msg.accepted())
if (msg.accepted()) {
// summons accepted, let's move the player if within time
if (source.isAlive()) {
@ -1337,6 +1555,16 @@ public enum PowersManager { @@ -1337,6 +1555,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);
@ -1346,7 +1574,10 @@ public enum PowersManager { @@ -1346,7 +1574,10 @@ public enum PowersManager {
timers.put("Summon", jc);
wentThrough = true;
}
}else{
// recycle summons power
finishRecycleTime(428523680, source, true);
}
// Summons failed
if (!wentThrough)
// summons refused. Let's be nice and reset recycle timer
@ -1462,8 +1693,28 @@ public enum PowersManager { @@ -1462,8 +1693,28 @@ public enum PowersManager {
}
// create list of characters
HashSet<AbstractCharacter> trackChars = RangeBasedAwo.getTrackList(
allTargets, playerCharacter, maxTargets);
HashSet<AbstractCharacter> trackChars;
PowersBase trackPower = PowersManager.getPowerByToken(msg.getPowerToken());
if(trackPower != null && trackPower.category.equals("TRACK")){
trackChars = getTrackList(playerCharacter);
}else{
trackChars = RangeBasedAwo.getTrackList(allTargets, playerCharacter, maxTargets);
}
//switch(msg.getPowerToken()){
// case 431511776: // Hunt Foe Huntress
// case 429578587: // Hunt Foe Scout
// case 429503360: // Track Huntsman
// case 44106356: //
// trackChars = getTrackList(playerCharacter);
// break;
// default:
// trackChars = RangeBasedAwo.getTrackList(allTargets, playerCharacter, maxTargets);
// break;
//}
TrackWindowMsg trackWindowMsg = new TrackWindowMsg(msg);
@ -1476,6 +1727,30 @@ public enum PowersManager { @@ -1476,6 +1727,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);
@ -1591,6 +1866,10 @@ public enum PowersManager { @@ -1591,6 +1866,10 @@ public enum PowersManager {
private static void applyPowerA(AbstractCharacter ac, AbstractWorldObject target,
Vector3fImmutable targetLoc, PowersBase pb, int trains,
boolean fromItem) {
if(fromItem && pb.token == 429021400)
trains = 40;
int time = pb.getCastTime(trains);
if (!fromItem)
finishApplyPowerA(ac, target, targetLoc, pb, trains, false);
@ -1649,6 +1928,18 @@ public enum PowersManager { @@ -1649,6 +1928,18 @@ public enum PowersManager {
public static void finishApplyPowerA(AbstractCharacter ac,
AbstractWorldObject target, Vector3fImmutable targetLoc,
PowersBase pb, int trains, boolean fromChant) {
//if (ac.getObjectType().equals(GameObjectType.PlayerCharacter)){
// PlayerCharacter pc = (PlayerCharacter) ac;
// if (pc.isBoxed && pb.token != -2133617927) {
// if(AbstractCharacter.IsAbstractCharacter(target)){
// if (target.getObjectType().equals(GameObjectType.PlayerCharacter)){
// return;
// }
// }
// }
//}
// finally Apply actions
ArrayList<ActionsBase> actions = pb.getActions();
for (ActionsBase ab : actions) {
@ -1656,7 +1947,7 @@ public enum PowersManager { @@ -1656,7 +1947,7 @@ public enum PowersManager {
if (trains < ab.getMinTrains() || trains > ab.getMaxTrains())
continue;
// If something blocks the action, then stop
if (ab.blocked(target, pb, trains))
if (ab.blocked(target, pb, trains, ac))
// sendPowerMsg(pc, 5, msg);
continue;
// TODO handle overwrite stack order here
@ -1729,14 +2020,10 @@ public enum PowersManager { @@ -1729,14 +2020,10 @@ public enum PowersManager {
}
}
public static void runPowerAction(AbstractCharacter source,
AbstractWorldObject awo, Vector3fImmutable targetLoc,
ActionsBase ab, int trains, PowersBase pb) {
public static void runPowerAction(AbstractCharacter source, AbstractWorldObject awo, Vector3fImmutable targetLoc, ActionsBase ab, int trains, PowersBase pb) {
AbstractPowerAction pa = ab.getPowerAction();
if (pa == null) {
Logger.error(
"runPowerAction(): PowerAction not found of IDString: "
+ ab.getEffectID());
Logger.error("runPowerAction(): PowerAction not found of IDString: " + ab.getEffectID());
return;
}
pa.startAction(source, awo, targetLoc, trains, ab, pb);
@ -2189,7 +2476,7 @@ public enum PowersManager { @@ -2189,7 +2476,7 @@ public enum PowersManager {
// set player is not casting for regens
if (pc.isCasting()) {
pc.update();
pc.update(false);
}
pc.setIsCasting(false);
@ -2231,7 +2518,8 @@ public enum PowersManager { @@ -2231,7 +2518,8 @@ public enum PowersManager {
public static boolean testAttack(PlayerCharacter pc, AbstractWorldObject awo,
PowersBase pb, PerformActionMsg msg) {
// Get defense for target
float atr = CharacterSkill.getATR(pc, pb.getSkillName());
//float atr = CharacterSkill.getATR(pc, pb.getSkillName());
float atr = PlayerCombatStats.getSpellAtr(pc, pb);
float defense;
if (AbstractWorldObject.IsAbstractCharacter(awo)) {
@ -2241,28 +2529,26 @@ public enum PowersManager { @@ -2241,28 +2529,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 +2560,15 @@ public enum PowersManager { @@ -2274,6 +2560,15 @@ 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);
TargetedActionMsg cmm = new TargetedActionMsg(pc, 75, tarAc, MBServerStatics.COMBAT_SEND_BLOCK);
DispatchMessage.sendToAllInRange(tarAc, cmm);
return true;
}
}
return false;
@ -2321,7 +2616,12 @@ public enum PowersManager { @@ -2321,7 +2616,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 +2862,9 @@ public enum PowersManager { @@ -2562,7 +2862,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 +3010,191 @@ public enum PowersManager { @@ -2708,6 +3010,191 @@ 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:
case 429441979:
return false;
}
return true;
}
public static boolean HandleItemEnchantments(PlayerCharacter pc, PerformActionMsg msg){
switch(msg.getPowerUsedID()){
case 429505998: // Reinforce Item
case 429407694: // hone weapon
case 429440462: // hone armor
case 429016905: //poison blade
case 429505610: // poison blade
case 427908971: // consecrate weapon
case 429439055: // mark of slaying
case 429605702: // annoint blade
case 429414682: // slay rat
case 429594877: // consecrate weapon
case 429440895: // charm of slaying
case 429491437: // infuse with power
PowersBase pb = PowersManager.getPowerByToken(msg.getPowerUsedID());
if(pb == null)
return false;
for (ActionsBase action : pb.getActions()){
try {
if(msg.getNumTrains() > action.maxTrains)
continue;
EffectsBase eb = action.getPowerAction().getEffectsBase();
if(eb == null)
return false;
//Effect eff = pc.addEffectNoTimer(eb.getName(),eb,msg.getNumTrains(),false);
//if(eff == null){
// Logger.error(pc.getFirstName() + " failed to apply self buff: " + msg.getPowerUsedID());
//}
UsePowerJob asj = new UsePowerJob(pc,msg,pb.getToken(),pb,pc.getLiveCounter(),pc.getLiveCounter());
JobContainer jc = JobScheduler.getInstance().scheduleJob(asj, 1800000);
Effect eff = new Effect(jc, eb, msg.getNumTrains());
// pc.effects.put("CASTABLE", eff);
pc.addEffect("CASTABLE",1800,asj,eb,msg.getNumTrains());
pc.applyAllBonuses();
ApplyEffectMsg pum = new ApplyEffectMsg();
pum.setEffectID(eff.getEffectToken());
pum.setSourceType(pc.getObjectType().ordinal());
pum.setSourceID(pc.getObjectUUID());
pum.setTargetType(pc.getObjectType().ordinal());
pum.setTargetID(pc.getObjectUUID());
pum.setNumTrains(eff.getTrains());
pum.setUnknown05(1);
pum.setUnknown02(2);
pum.setUnknown06((byte) 1);
pum.setEffectSourceType(GameObjectType.PlayerCharacter.ordinal());
pum.setEffectSourceID(pc.getObjectUUID());
pum.setDuration(1800);
DispatchMessage.dispatchMsgToInterestArea(pc, pum, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true, false);
}
catch(Exception e){
}
}
return true;
}
return false;
}
}

72
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);
@ -94,16 +91,13 @@ public enum SimulationManager { @@ -94,16 +91,13 @@ public enum SimulationManager {
"Fatal error in City Pulse: DISABLED. Error Message : "
+ e.getMessage());
}
try {
//try {
if ((_updatePulseTime != 0)
&& (System.currentTimeMillis() > _updatePulseTime))
pulseUpdate();
} catch (Exception e) {
Logger.error(
"Fatal error in Update Pulse: DISABLED");
// _runegatePulseTime = 0;
}
// if ((_updatePulseTime != 0) && (System.currentTimeMillis() > _updatePulseTime))
// pulseUpdate();
//} catch (Exception e) {
// Logger.error("Fatal error in Update Pulse: DISABLED");
//}
try {
if ((_runegatePulseTime != 0)
@ -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 : "
@ -127,6 +130,25 @@ public enum SimulationManager { @@ -127,6 +130,25 @@ public enum SimulationManager {
}
//try{
// HellgateManager.pulseHellgates();
//}catch(Exception e){
// Logger.error("Failed to pulse hellgates");
// Logger.error(e.getMessage());
//}
try{
if(ZoneManager.hotZone != null && HotzoneManager.hotzoneMob != null && !HotzoneManager.hotzoneMob.isAlive()){
HotzoneManager.ClearHotzone();
}
}catch(Exception e){
}
try{
HotzoneManager.pulse();
}catch(Exception e){
//
}
SimulationManager.executionTime = Duration.between(startTime, Instant.now());
if (executionTime.compareTo(executionMax) > 0)
@ -154,7 +176,11 @@ public enum SimulationManager { @@ -154,7 +176,11 @@ public enum SimulationManager {
if (player == null)
continue;
player.update();
try {
player.update(false);
}catch(Exception e){
}
}
_updatePulseTime = System.currentTimeMillis() + 500;
@ -203,8 +229,12 @@ public enum SimulationManager { @@ -203,8 +229,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 +244,10 @@ public enum SimulationManager { @@ -214,6 +244,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();
}

277
src/engine/gameManager/SpecialLootHandler.java

@ -0,0 +1,277 @@ @@ -0,0 +1,277 @@
package engine.gameManager;
import engine.InterestManagement.WorldGrid;
import engine.math.Vector3fImmutable;
import engine.objects.*;
import engine.server.MBServerStatics;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;
public class SpecialLootHandler {
public static final List<Integer> DWARVEN_contracts = Arrays.asList(
35250, 35251, 35252, 35253, 35254, 35255, 35256, 35257, 35258, 35259, 35260, 35261, 35262, 35263
);
public static final List<Integer> INVORRI_contracts = Arrays.asList(
35050, 35051, 35052, 35053, 35054, 35055, 35056, 35057, 35058, 35059, 35060, 35061, 35062, 35063
);
public static final List<Integer> SHADE_contracts = Arrays.asList(
35400, 35401, 35402, 35403, 35404, 35405, 35406, 35407, 35408, 35409, 35410, 35411, 35412, 35413,
35414, 35415, 35416, 35417, 35418, 35419, 35420, 35421, 35422, 35423, 35424, 35425, 35426, 35427
);
public static final List<Integer> VAMPIRE_contracts = Arrays.asList(
35545, 35546, 35547, 35548, 35549, 35550, 35551, 35552, 35553, 35554, 35555, 35556, 35557, 35558,
35559, 35560, 35561, 35562, 35563, 35564, 35565, 35566, 35567, 35568, 35569, 35570
);
public static final List<Integer> IREKEI_contracts = Arrays.asList(
35100, 35101, 35102, 35103, 35104, 35105, 35106, 35107, 35108, 35109, 35110, 35111, 35112, 35113,
35114, 35115, 35116, 35117, 35118, 35119, 35120, 35121, 35122, 35123, 35124, 35125, 35126, 35127
);
public static final List<Integer> AMAZON_contracts = Arrays.asList(
35200, 35201, 35202, 35203, 35204, 35205, 35206, 35207, 35208, 35209, 35210, 35211, 35212, 35213
);
public static final List<Integer> GWENDANNEN_contracts = Arrays.asList(
35350, 35351, 35352, 35353, 35354, 35355, 35356, 35357, 35358, 35359, 35360, 35361, 35362, 35363,
35364, 35365, 35366, 35367, 35368, 35369, 35370, 35371, 35372, 35373, 35374, 35375, 35376, 35377
);
public static final List<Integer> NEPHILIM_contracts = Arrays.asList(
35500, 35501, 35502, 35503, 35504, 35505, 35506, 35507, 35508, 35509, 35510, 35511, 35512, 35513,
35514, 35515, 35516, 35517, 35518, 35519, 35520, 35521, 35522, 35523, 35524, 35525
);
public static final List<Integer> ELVEN_contracts = Arrays.asList(
35000, 35001, 35002, 35003, 35004, 35005, 35006, 35007, 35008, 35009, 35010, 35011, 35012, 35013,
35014, 35015, 35016, 35017, 35018, 35019, 35020, 35021, 35022, 35023, 35024, 35025, 35026, 35027
);
public static final List<Integer> CENTAUR_contracts = Arrays.asList(
35150, 35151, 35152, 35153, 35154, 35155, 35156, 35157, 35158, 35159, 35160, 35161, 35162, 35163,
35164, 35165, 35166, 35167, 35168, 35169, 35170, 35171, 35172, 35173, 35174, 35175, 35176, 35177
);
public static final List<Integer> LIZARDMAN_contracts = Arrays.asList(
35300, 35301, 35302, 35303, 35304, 35305, 35306, 35307, 35308, 35309, 35310, 35311, 35312, 35313
);
public static final List<Integer> GLASS_ITEMS = Arrays.asList(
7000100, 7000110, 7000120, 7000130, 7000140, 7000150, 7000160, 7000170, 7000180, 7000190,
7000200, 7000210, 7000220, 7000230, 7000240, 7000250, 7000270, 7000280
);
public static final List<Integer> STAT_RUNES = Arrays.asList(
250001, 250002, 250003, 250004, 250005, 250006, 250007, 250008, 250010, 250011,
250012, 250013, 250014, 250015, 250016, 250017, 250019, 250020, 250021, 250022,
250023, 250024, 250025, 250026, 250028, 250029, 250030, 250031, 250032, 250033,
250034, 250035, 250037, 250038, 250039, 250040, 250041, 250042, 250043, 250044
);
public static final List<Integer> racial_guard = 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
);
public static void RollContract(Mob mob){
Zone zone = getMacroZone(mob);
if(zone == null)
return;
int contactId = 0;
int roll = ThreadLocalRandom.current().nextInt(250);
if(roll == 125){
contactId = getContractForZone(zone);
}
if(contactId == 0)
return;
ItemBase contractBase = ItemBase.getItemBase(contactId);
if(contractBase == null)
return;
if(mob.getCharItemManager() == null)
return;
MobLoot contract = new MobLoot(mob,contractBase,false);
mob.getCharItemManager().addItemToInventory(contract);
}
public static Zone getMacroZone(Mob mob){
Zone parentZone = mob.parentZone;
if(parentZone == null)
return null;
while(!parentZone.isMacroZone() && !parentZone.equals(ZoneManager.getSeaFloor())){
parentZone = parentZone.getParent();
}
return parentZone;
//for(Zone zone : ZoneManager.macroZones){
// HashSet<AbstractWorldObject> inZone = WorldGrid.getObjectsInRangePartial(zone.getLoc(),zone.getBounds().getHalfExtents().x * 2f, MBServerStatics.MASK_MOB);
// if(inZone.contains(mob)){
// return zone;
// }
//}
//return null;
}
public static int getContractForZone(Zone zone){
Random random = new Random();
switch (zone.getObjectUUID())
{
case 178:
// Kralgaar Holm
return DWARVEN_contracts.get(random.nextInt(DWARVEN_contracts.size()));
case 122:
// Aurrochs Skrae
return INVORRI_contracts.get(random.nextInt(INVORRI_contracts.size()));
case 197:
// Ymur's Crown
return INVORRI_contracts.get(random.nextInt(INVORRI_contracts.size()));
case 234:
// Ecklund Wilds
return INVORRI_contracts.get(random.nextInt(INVORRI_contracts.size()));
case 313:
// Greensward Pyre
return SHADE_contracts.get(random.nextInt(SHADE_contracts.size()));
case 331:
// The Doomplain
return VAMPIRE_contracts.get(random.nextInt(VAMPIRE_contracts.size()));
case 353:
// Thollok Marsh
return LIZARDMAN_contracts.get(random.nextInt(LIZARDMAN_contracts.size()));
case 371:
// The Black Bog
return LIZARDMAN_contracts.get(random.nextInt(LIZARDMAN_contracts.size()));
case 388:
// Sevaath Mere
return LIZARDMAN_contracts.get(random.nextInt(LIZARDMAN_contracts.size()));
case 418:
// Valkos Wilds
return GWENDANNEN_contracts.get(random.nextInt(GWENDANNEN_contracts.size()));
case 437:
// Grimscairne
return SHADE_contracts.get(random.nextInt(SHADE_contracts.size()));
case 475:
// Phaedra's Prize
return AMAZON_contracts.get(random.nextInt(AMAZON_contracts.size()));
case 491:
// Holloch Forest
return GWENDANNEN_contracts.get(random.nextInt(GWENDANNEN_contracts.size()));
case 508:
// Aeran Belendor
return ELVEN_contracts.get(random.nextInt(ELVEN_contracts.size()));
case 532:
// Tainted Swamp
return NEPHILIM_contracts.get(random.nextInt(NEPHILIM_contracts.size()));
case 550:
// Aerath Hellendroth
return ELVEN_contracts.get(random.nextInt(ELVEN_contracts.size()));
case 569:
// Aedroch Highlands
return GWENDANNEN_contracts.get(random.nextInt(GWENDANNEN_contracts.size()));
case 590:
// Fellgrim Forest
return GWENDANNEN_contracts.get(random.nextInt(GWENDANNEN_contracts.size()));
case 616:
// Derros Plains
return CENTAUR_contracts.get(random.nextInt(CENTAUR_contracts.size()));
case 632:
// Ashfell Plain
return SHADE_contracts.get(random.nextInt(SHADE_contracts.size()));
case 717:
// Kharsoom
return IREKEI_contracts.get(random.nextInt(IREKEI_contracts.size()));
case 737:
// Leth'khalivar Desert
return IREKEI_contracts.get(random.nextInt(IREKEI_contracts.size()));
case 761:
// The Blood Sands
return IREKEI_contracts.get(random.nextInt(IREKEI_contracts.size()));
case 785:
// Vale of Nar Addad
return IREKEI_contracts.get(random.nextInt(IREKEI_contracts.size()));
case 824:
// Western Battleground
return NEPHILIM_contracts.get(random.nextInt(NEPHILIM_contracts.size()));
case 842:
// Pandemonium
return NEPHILIM_contracts.get(random.nextInt(NEPHILIM_contracts.size()));
case 951:
//Bone Marches
return VAMPIRE_contracts.get(random.nextInt(VAMPIRE_contracts.size()));
case 952:
//plain of ashes
return VAMPIRE_contracts.get(random.nextInt(VAMPIRE_contracts.size()));
}
return 0;
}
public static void RollGlass(Mob mob){
int roll = ThreadLocalRandom.current().nextInt(10000);
if(roll != 5000)
return;
Random random = new Random();
int glassId = GLASS_ITEMS.get(random.nextInt(GLASS_ITEMS.size()));
ItemBase glassBase = ItemBase.getItemBase(glassId);
if(glassBase == null)
return;
if(mob.getCharItemManager() == null)
return;
MobLoot glass = new MobLoot(mob,glassBase,false);
mob.getCharItemManager().addItemToInventory(glass);
}
public static void RollRune(Mob mob){
int runeID = 0;
int roll = ThreadLocalRandom.current().nextInt(250);
Random random = new Random();
if(roll == 125){
runeID = STAT_RUNES.get(random.nextInt(STAT_RUNES.size()));
}
if(runeID == 0)
return;
ItemBase runeBase = ItemBase.getItemBase(runeID);
if(runeBase == null)
return;
if(mob.getCharItemManager() == null)
return;
MobLoot rune = new MobLoot(mob,runeBase,false);
mob.getCharItemManager().addItemToInventory(rune);
}
public static void RollRacialGuard(Mob mob){
int roll = ThreadLocalRandom.current().nextInt(5000);
if(roll != 2500)
return;
Random random = new Random();
int guardId = racial_guard.get(random.nextInt(racial_guard.size()));
ItemBase guardBase = ItemBase.getItemBase(guardId);
if(guardBase == null)
return;
if(mob.getCharItemManager() == null)
return;
MobLoot guard = new MobLoot(mob,guardBase,false);
mob.getCharItemManager().addItemToInventory(guard);
}
}

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;
}
}
}
}

274
src/engine/gameManager/ZergManager.java

@ -0,0 +1,274 @@ @@ -0,0 +1,274 @@
package engine.gameManager;
import engine.InterestManagement.WorldGrid;
import engine.objects.*;
import engine.server.MBServerStatics;
import java.util.ArrayList;
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.50f;
case 5: return 0.0f;
case 6: return 0.0f;
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;
}
}
public static void MineTracker(Mine mine){
Building tower = BuildingManager.getBuildingFromCache(mine.getBuildingID());
if(tower == null)
return;
float affectedRange = MBServerStatics.CHARACTER_LOAD_RANGE * 3;
mine.zergTracker.compileCurrent(tower.loc, affectedRange);
mine.zergTracker.sortByNation();
mine.zergTracker.compileLeaveQue(tower.loc, affectedRange);
mine.zergTracker.processLeaveQue();
mine.zergTracker.applyMultiplier(mine.capSize);
}
public static void PrintDetailsToClient(PlayerCharacter pc){
String newline = "\r\n ";
String outstring = newline + "ZERG MANAGER DETAILS FOR: " + pc.getFirstName() + newline;
Mine attended = null;
for(Mine mine : Mine.getMines()){
Building tower = BuildingManager.getBuilding(mine.getBuildingID());
if(tower == null)
continue;
float rangeSquared = (MBServerStatics.CHARACTER_LOAD_RANGE * 3) * (MBServerStatics.CHARACTER_LOAD_RANGE * 3);
if(pc.loc.distanceSquared(tower.loc) < rangeSquared){
attended = mine;
}
}
if(attended != null){
outstring += "Mine Cap: " + attended.capSize + newline;
Building tower = BuildingManager.getBuilding(attended.getBuildingID());
if(tower == null)
return;
int count = 0;
ArrayList<PlayerCharacter> stillPresent = new ArrayList<>();
ArrayList<PlayerCharacter> gonePlayers = new ArrayList<>();
for(Integer countedID : attended.mineAttendees.keySet()){
PlayerCharacter counted = PlayerCharacter.getFromCache(countedID);
if(counted != null){
if(counted.guild.getNation().equals(pc.guild.getNation())) {
Long timeGone = System.currentTimeMillis() - attended.mineAttendees.get(countedID);
if(timeGone > 5000){
//outstring += counted.getFirstName() + " GONE FOR: " + timeGone/1000 + " SECONDS" + newline;
gonePlayers.add(counted);
}else{
//outstring += counted.getFirstName() + " STILL PRESENT" + newline;
stillPresent.add(counted);
}
count ++;
}
}
}
outstring += newline + "TOTAL NATION MEMBERS COUNTED: " + count + newline;
outstring += newline + "PLAYERS PRESENT:" + newline;
for(PlayerCharacter present : stillPresent){
outstring += present.getFirstName() + newline;
}
outstring += newline + "PLAYERS GONE:" + newline;
for(PlayerCharacter gone : gonePlayers){
Long timeGone = System.currentTimeMillis() - attended.mineAttendees.get(gone.getObjectUUID());
if(timeGone > 5000) {
outstring += gone.getFirstName() + " GONE FOR: " + timeGone / 1000 + " SECONDS" + newline;
}
}
}else{
outstring += "Mine: Not Within Mine Distance" + newline;
}
outstring += newline + "Zerg Multiplier: " + pc.ZergMultiplier + newline;
ChatManager.chatSystemInfo(pc, outstring);
}
}

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

9
src/engine/jobs/PersistentAoeJob.java

@ -40,11 +40,18 @@ public class PersistentAoeJob extends AbstractEffectJob { @@ -40,11 +40,18 @@ 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;
try {
if (!this.target.isAlive())
PowersManager.finishEffectTime(this.source, this.target, this.action, this.trains);
}catch(Exception e){
PowersManager.finishEffectTime(this.source, this.target, this.action, this.trains);
}
if (!this.source.isAlive())
PowersManager.finishEffectTime(this.source, this.target, this.action, this.trains);
else if (this.iteration < this.power.getChantIterations()) {

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) {

266
src/engine/mobileAI/Behaviours/StandardMob.java

@ -0,0 +1,266 @@ @@ -0,0 +1,266 @@
package engine.mobileAI.Behaviours;
import engine.Enum;
import engine.InterestManagement.InterestManager;
import engine.InterestManagement.WorldGrid;
import engine.math.Vector3fImmutable;
import engine.mobileAI.utilities.CombatUtilities;
import engine.mobileAI.utilities.MovementUtilities;
import engine.objects.*;
import engine.server.MBServerStatics;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
public class StandardMob {
public static void run(Mob mob){
HashSet<AbstractWorldObject> inRange = WorldGrid.getObjectsInRangePartial(mob.loc, MBServerStatics.CHARACTER_LOAD_RANGE, MBServerStatics.MASK_PLAYER);
if(inRange.isEmpty())
return;
if(!mob.isAlive()){
CheckForRespawn(mob);
return;
}
if (mob.isMoving()) {
mob.setLoc(mob.getMovementLoc());
mob.updateLocation();
}
if(mob.combatTarget == null) {
if (!inRange.isEmpty()) {
CheckForAggro(mob);
}
}else{
CheckToDropCombatTarget(mob);
if(mob.combatTarget == null){
CheckForAggro(mob);
}
}
if(MovementUtilities.canMove(mob))
CheckForMovement(mob);
if(mob.combatTarget != null && !mob.isMoving())
CheckForAttack(mob);
}
public static void CheckToDropCombatTarget(Mob mob){
if(!mob.combatTarget.isAlive()){
mob.setCombatTarget(null);
return;
}
if(mob.combatTarget.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)){
PlayerCharacter pcTarget = (PlayerCharacter) mob.combatTarget;
if (!mob.canSee(pcTarget)) {
mob.setCombatTarget(null);
return;
}
}
if(mob.bindLoc.distanceSquared(mob.combatTarget.loc) > 90 * 90){
mob.setCombatTarget(null);
}
}
public static void CheckForRespawn(Mob mob){
if (mob.deathTime == 0) {
mob.setDeathTime(System.currentTimeMillis());
return;
}
if (!mob.despawned) {
if (mob.getCharItemManager().getInventoryCount() > 0) {
if (System.currentTimeMillis() > mob.deathTime + MBServerStatics.DESPAWN_TIMER_WITH_LOOT) {
mob.despawn();
mob.deathTime = System.currentTimeMillis();
return;
}
//No items in inventory.
} else if (mob.isHasLoot()) {
if (System.currentTimeMillis() > mob.deathTime + MBServerStatics.DESPAWN_TIMER_ONCE_LOOTED) {
mob.despawn();
mob.deathTime = System.currentTimeMillis();
return;
}
//Mob never had Loot.
} else {
if (System.currentTimeMillis() > mob.deathTime + MBServerStatics.DESPAWN_TIMER_ONCE_LOOTED) {
mob.despawn();
mob.deathTime = System.currentTimeMillis();
return;
}
}
return;
}
if(Mob.discDroppers.contains(mob))
return;
float baseRespawnTimer = mob.spawnTime;
float reduction = (100-mob.level) * 0.01f;
float reducedRespawnTime = baseRespawnTimer * (1.0f - reduction);
float respawnTimer = reducedRespawnTime * 1000f;
if (System.currentTimeMillis() > (mob.deathTime + respawnTimer)) {
Zone.respawnQue.add(mob);
}
}
public static void CheckForAggro(Mob mob){
if(mob == null || !mob.isAlive() || mob.playerAgroMap.isEmpty()){
return;
}
if(!mob.BehaviourType.isAgressive)
return;
if(mob.BehaviourType.equals(Enum.MobBehaviourType.HamletGuard)){
return;
}
if(mob.hate_values == null)
mob.hate_values = new HashMap<>();
if(mob.combatTarget != null)
return;
HashSet<AbstractWorldObject> inRange = WorldGrid.getObjectsInRangePartial(mob.loc, 60f, MBServerStatics.MASK_PLAYER);
if(inRange.isEmpty()){
mob.setCombatTarget(null);
return;
}
//clear out any players who are not in hated range anymore
ArrayList<PlayerCharacter> toRemove = new ArrayList<>();
for(PlayerCharacter pc : mob.hate_values.keySet()){
if(!inRange.contains(pc))
toRemove.add(pc);
}
for(PlayerCharacter pc : toRemove){
mob.hate_values.remove(pc);
}
//find most hated target
PlayerCharacter mostHated = null;
for(AbstractWorldObject awo : inRange){
PlayerCharacter loadedPlayer = (PlayerCharacter)awo;
if (loadedPlayer == null)
continue;
//Player is Dead, Mob no longer needs to attempt to aggro. Remove them from aggro map.
if (!loadedPlayer.isAlive())
continue;
//Can't see target, skip aggro.
if (!mob.canSee(loadedPlayer))
continue;
// No aggro for this race type
if (mob.notEnemy != null && mob.notEnemy.size() > 0 && mob.notEnemy.contains(loadedPlayer.getRace().getRaceType().getMonsterType()))
continue;
//mob has enemies and this player race is not it
if (mob.enemy != null && mob.enemy.size() > 0 && !mob.enemy.contains(loadedPlayer.getRace().getRaceType().getMonsterType()))
continue;
if(mostHated == null)
mostHated = loadedPlayer;
if(mob.hate_values.containsKey(loadedPlayer))
if(mob.hate_values.get(loadedPlayer) > mob.hate_values.get(mostHated))
mostHated = loadedPlayer;
}
if(mostHated != null)
mob.setCombatTarget(mostHated);
}
public static void CheckForMovement(Mob mob){
if(!mob.BehaviourType.canRoam)
return;
if(mob.combatTarget != null){
//chase player
if(!CombatUtilities.inRange2D(mob,mob.combatTarget,mob.getRange())) {
if(mob.combatTarget.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) {
PlayerCharacter target = (PlayerCharacter)mob.combatTarget;
if(target.isMoving()){
MovementUtilities.aiMove(mob, mob.combatTarget.loc, false);
return;
}else{
Vector3fImmutable smoothLoc = Vector3fImmutable.getRandomPointOnCircle(mob.combatTarget.loc,mob.getRange() -1);
MovementUtilities.aiMove(mob, smoothLoc, false);
return;
}
}
MovementUtilities.aiMove(mob, mob.combatTarget.loc, false);
}
}else{
//patrol
if (mob.isMoving()) {
mob.stopPatrolTime = System.currentTimeMillis();
return;
}
if(mob.stopPatrolTime + 5000L < System.currentTimeMillis()) {
Vector3fImmutable patrolPoint = Vector3fImmutable.getRandomPointOnCircle(mob.bindLoc, 40f);
MovementUtilities.aiMove(mob, patrolPoint, true);
}
}
}
public static void CheckForAttack(Mob mob){
if(mob.isMoving())
return;
if(mob.getLastAttackTime() > System.currentTimeMillis())
return;
if (mob.BehaviourType.callsForHelp)
MobCallForHelp(mob);
ItemBase mainHand = mob.getWeaponItemBase(true);
ItemBase offHand = mob.getWeaponItemBase(false);
if(!CombatUtilities.inRangeToAttack(mob,mob.combatTarget))
return;
InterestManager.setObjectDirty(mob);
if (mainHand == null && offHand == null) {
CombatUtilities.combatCycle(mob, mob.combatTarget, true, null);
int delay = 3000;
mob.setLastAttackTime(System.currentTimeMillis() + delay);
} else if (mob.getWeaponItemBase(true) != null) {
int delay = 3000;
CombatUtilities.combatCycle(mob, mob.combatTarget, true, mob.getWeaponItemBase(true));
mob.setLastAttackTime(System.currentTimeMillis() + delay);
} else if (mob.getWeaponItemBase(false) != null) {
int attackDelay = 3000;
CombatUtilities.combatCycle(mob, mob.combatTarget, false, mob.getWeaponItemBase(false));
mob.setLastAttackTime(System.currentTimeMillis() + attackDelay);
}
}
public static void MobCallForHelp(Mob mob){
HashSet<AbstractWorldObject> mobs = WorldGrid.getObjectsInRangePartial(mob.loc,60f, MBServerStatics.MASK_MOB);
for(AbstractWorldObject awo : mobs){
Mob responder = (Mob)awo;
if(responder.combatTarget == null)
if(MovementUtilities.canMove(responder))
MovementUtilities.aiMove(responder,mob.loc,false);
}
}
}

425
src/engine/mobileAI/MobAI.java

@ -9,17 +9,18 @@ @@ -9,17 +9,18 @@
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;
import engine.math.Vector3fImmutable;
import engine.mobileAI.Behaviours.StandardMob;
import engine.mobileAI.Threads.MobAIThread;
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;
@ -27,6 +28,7 @@ import engine.server.MBServerStatics; @@ -27,6 +28,7 @@ import engine.server.MBServerStatics;
import org.pmw.tinylog.Logger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
@ -49,6 +51,7 @@ public class MobAI { @@ -49,6 +51,7 @@ public class MobAI {
return;
}
//mob casting disabled
if (target.getObjectType() == Enum.GameObjectType.PlayerCharacter && canCast(mob)) {
if (mob.isPlayerGuard() == false && MobCast(mob)) {
@ -82,8 +85,18 @@ public class MobAI { @@ -82,8 +85,18 @@ 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());
////(mob.getObjectUUID() + " " + mob.getName() + " Failed At: AttackTarget" + " " + e.getMessage());
}
}
@ -96,10 +109,16 @@ public class MobAI { @@ -96,10 +109,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;
}
@ -116,6 +135,9 @@ public class MobAI { @@ -116,6 +135,9 @@ public class MobAI {
if (mob.isMoving() && mob.getRange() > 20)
return;
if(target.combatStats == null)
target.combatStats = new PlayerCombatStats(target);
// add timer for last attack.
ItemBase mainHand = mob.getWeaponItemBase(true);
@ -146,8 +168,14 @@ public class MobAI { @@ -146,8 +168,14 @@ 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());
////(mob.getObjectUUID() + " " + mob.getName() + " Failed At: AttackPlayer" + " " + e.getMessage());
}
}
@ -156,6 +184,9 @@ public class MobAI { @@ -156,6 +184,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 +196,8 @@ public class MobAI { @@ -165,8 +196,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,14 +226,14 @@ public class MobAI { @@ -195,14 +226,14 @@ 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());
////(mob.getObjectUUID() + " " + mob.getName() + " Failed At: AttackBuilding" + " " + e.getMessage());
}
}
@ -215,6 +246,8 @@ public class MobAI { @@ -215,6 +246,8 @@ public class MobAI {
//no weapons, default mob attack speed 3 seconds.
//MobVsMobRetaliate(target,mob);
ItemBase mainHand = mob.getWeaponItemBase(true);
ItemBase offHand = mob.getWeaponItemBase(false);
@ -241,7 +274,7 @@ public class MobAI { @@ -241,7 +274,7 @@ public class MobAI {
}
}
} catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: AttackMob" + " " + e.getMessage());
////(mob.getObjectUUID() + " " + mob.getName() + " Failed At: AttackMob" + " " + e.getMessage());
}
}
@ -294,7 +327,7 @@ public class MobAI { @@ -294,7 +327,7 @@ public class MobAI {
}
}
} catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: AttackTarget" + " " + e.getMessage());
////(mob.getObjectUUID() + " " + mob.getName() + " Failed At: AttackTarget" + " " + e.getMessage());
}
}
@ -308,33 +341,36 @@ public class MobAI { @@ -308,33 +341,36 @@ public class MobAI {
if (mob == null)
return false;
if(mob.isPlayerGuard == true){
if (mob.mobPowers == null || mob.mobPowers.isEmpty())
return false;
if(mob.nextCastTime > System.currentTimeMillis())
return false;
mob.nextCastTime = System.currentTimeMillis() + 30000L;
int contractID;
if(mob.isPlayerGuard){
if(mob.BehaviourType.equals(Enum.MobBehaviourType.GuardMinion))
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())
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();
return true;
} catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: canCast" + " " + e.getMessage());
////(mob.getObjectUUID() + " " + mob.getName() + " Failed At: canCast" + " " + e.getMessage());
}
return false;
}
@ -388,6 +424,9 @@ public class MobAI { @@ -388,6 +424,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 +439,7 @@ public class MobAI { @@ -400,7 +439,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 {
@ -409,15 +448,15 @@ public class MobAI { @@ -409,15 +448,15 @@ 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);
mob.nextCastTime = System.currentTimeMillis() + randomCooldown;
try {
PowersManager.finishUseMobPower(msg, mob, 0, 0);
}catch(Exception e) {
return false;
}
return true;
}
} catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: MobCast" + " " + e.getMessage());
////(mob.getObjectUUID() + " " + mob.getName() + " Failed At: MobCast" + " " + e.getMessage());
}
return false;
}
@ -536,11 +575,10 @@ public class MobAI { @@ -536,11 +575,10 @@ 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) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: MobCast" + " " + e.getMessage());
////(mob.getObjectUUID() + " " + mob.getName() + " Failed At: MobCast" + " " + e.getMessage());
}
return false;
}
@ -576,7 +614,7 @@ public class MobAI { @@ -576,7 +614,7 @@ public class MobAI {
mob.nextCallForHelp = System.currentTimeMillis() + 60000;
} catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: MobCallForHelp" + " " + e.getMessage());
//(mob.getObjectUUID() + " " + mob.getName() + " Failed At: MobCallForHelp" + " " + e.getMessage());
}
}
@ -584,6 +622,37 @@ public class MobAI { @@ -584,6 +622,37 @@ public class MobAI {
try {
if (HellgateManager.hellgate_mobs != null && HellgateManager.hellgate_mobs.contains(mob)) {
HellgateManager.SpecialMobAIHandler(mob);
return;
}
if (HellgateManager.hellgate_mini_bosses != null && HellgateManager.hellgate_mini_bosses.contains(mob)) {
HellgateManager.SpecialMobAIHandler(mob);
return;
}
if(HellgateManager.hellgate_boss != null && mob.equals(HellgateManager.hellgate_boss)){
HellgateManager.SpecialMobAIHandler(mob);
return;
}
//boolean override = true;
//switch (mob.BehaviourType) {
// case GuardCaptain:
// case GuardMinion:
// case GuardWallArcher:
// case Pet1:
// case HamletGuard:
// override = false;
// break;
// }
//if(override){
// if(!mob.isSiege()) {
// StandardMob.run(mob);
// return;
// }
//}
//always check the respawn que, respawn 1 mob max per second to not flood the client
if (mob == null)
@ -625,9 +694,6 @@ public class MobAI { @@ -625,9 +694,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 +712,11 @@ public class MobAI { @@ -646,7 +712,11 @@ public class MobAI {
return;
}
if (mob.BehaviourType.ordinal() != Enum.MobBehaviourType.Pet1.ordinal())
if(mob.isAlive())
if(!mob.getMovementLoc().equals(Vector3fImmutable.ZERO))
mob.setLoc(mob.getMovementLoc());
if(mob.isPet() == false && mob.isPlayerGuard == false)
CheckToSendMobHome(mob);
if (mob.getCombatTarget() != null) {
@ -672,6 +742,7 @@ public class MobAI { @@ -672,6 +742,7 @@ public class MobAI {
}
}
//mob.refresh();
switch (mob.BehaviourType) {
case GuardCaptain:
@ -696,12 +767,14 @@ public class MobAI { @@ -696,12 +767,14 @@ public class MobAI {
if(mob.isAlive())
RecoverHealth(mob);
} catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: DetermineAction" + " " + e.getMessage());
//(mob.getObjectUUID() + " " + mob.getName() + " Failed At: DetermineAction" + " " + e.getMessage());
}
}
private static void CheckForAggro(Mob aiAgent) {
//old system
try {
//looks for and sets mobs combatTarget
@ -736,13 +809,11 @@ public class MobAI { @@ -736,13 +809,11 @@ public class MobAI {
continue;
// No aggro for this race type
if (aiAgent.notEnemy.size() > 0 && aiAgent.notEnemy.contains(loadedPlayer.getRace().getRaceType().getMonsterType()) == true)
if (aiAgent.notEnemy.size() > 0 && aiAgent.notEnemy.contains(loadedPlayer.getRace().getRaceType().getMonsterType()))
continue;
//mob has enemies and this player race is not it
if (aiAgent.enemy.size() > 0 && aiAgent.enemy.contains(loadedPlayer.getRace().getRaceType().getMonsterType()) == false)
if (aiAgent.enemy.size() > 0 && !aiAgent.enemy.contains(loadedPlayer.getRace().getRaceType().getMonsterType()))
continue;
if (MovementUtilities.inRangeToAggro(aiAgent, loadedPlayer)) {
@ -771,7 +842,7 @@ public class MobAI { @@ -771,7 +842,7 @@ public class MobAI {
}
}
} catch (Exception e) {
Logger.info(aiAgent.getObjectUUID() + " " + aiAgent.getName() + " Failed At: CheckForAggro" + " " + e.getMessage());
//(aiAgent.getObjectUUID() + " " + aiAgent.getName() + " Failed At: CheckForAggro" + " " + e.getMessage());
}
}
@ -832,7 +903,7 @@ public class MobAI { @@ -832,7 +903,7 @@ public class MobAI {
}
} catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: CheckMobMovement" + " " + e.getMessage());
//(mob.getObjectUUID() + " " + mob.getName() + " Failed At: CheckMobMovement" + " " + e.getMessage());
}
}
@ -857,31 +928,38 @@ public class MobAI { @@ -857,31 +928,38 @@ 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))) {
for(Effect eff : aiAgent.effects.values())
eff.endEffect();
if(Mob.discDroppers.contains(aiAgent))
return;
if (Zone.respawnQue.contains(aiAgent) == false) {
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);
}
}
} catch (Exception e) {
Logger.info(aiAgent.getObjectUUID() + " " + aiAgent.getName() + " Failed At: CheckForRespawn" + " " + e.getMessage());
//(aiAgent.getObjectUUID() + " " + aiAgent.getName() + " Failed At: CheckForRespawn" + " " + e.getMessage());
}
}
@ -896,8 +974,10 @@ public class MobAI { @@ -896,8 +974,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;
}
@ -905,26 +985,38 @@ public class MobAI { @@ -905,26 +985,38 @@ public class MobAI {
AttackTarget(mob, mob.getCombatTarget());
} catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: CheckForAttack" + " " + e.getMessage());
//(mob.getObjectUUID() + " " + mob.getName() + " Failed At: CheckForAttack" + " " + e.getMessage());
}
}
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()) {
if (mob.BehaviourType.ordinal() == Enum.MobBehaviourType.GuardCaptain.ordinal())
CheckForPlayerGuardAggro(mob);
} else {
CheckForAggro(mob);
if(mob.combatTarget == null)
NewAggroMechanic(mob);
}
}
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 +1026,6 @@ public class MobAI { @@ -934,7 +1026,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 +1036,7 @@ public class MobAI { @@ -945,7 +1036,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,16 +1044,22 @@ public class MobAI { @@ -953,16 +1044,22 @@ 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());
//(mob.getObjectUUID() + " " + mob.getName() + " Failed At: CheckToSendMobHome" + " " + e.getMessage());
}
}
private static void chaseTarget(Mob mob) {
public static void chaseTarget(Mob mob) {
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());
@ -993,7 +1090,7 @@ public class MobAI { @@ -993,7 +1090,7 @@ public class MobAI {
mob.updateMovementState();
mob.updateLocation();
} catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: chaseTarget" + " " + e.getMessage());
//(mob.getObjectUUID() + " " + mob.getName() + " Failed At: chaseTarget" + " " + e.getMessage());
}
}
@ -1006,7 +1103,7 @@ public class MobAI { @@ -1006,7 +1103,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;
@ -1025,37 +1122,41 @@ public class MobAI { @@ -1025,37 +1122,41 @@ public class MobAI {
mob.setCombatTarget(aggroMob);
}
} catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: SafeGuardAggro" + " " + e.getMessage());
//(mob.getObjectUUID() + " " + mob.getName() + " Failed At: SafeGuardAggro" + " " + e.getMessage());
}
}
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);
if (newTarget != null) {
if (newTarget.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) {
if (GuardCanAggro(mob, (PlayerCharacter) newTarget))
mob.setCombatTarget(newTarget);
} else
mob.setCombatTarget(newTarget);
}
CheckMobMovement(mob);
CheckForAttack(mob);
} catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: GuardCaptainLogic" + " " + e.getMessage());
//(mob.getObjectUUID() + " " + mob.getName() + " Failed At: GuardCaptainLogic" + " " + e.getMessage());
}
}
public static void GuardMinionLogic(Mob mob) {
try {
checkToDropGuardAggro(mob);
boolean isComanded = mob.npcOwner.isAlive();
if (!isComanded) {
GuardCaptainLogic(mob);
@ -1069,19 +1170,21 @@ public class MobAI { @@ -1069,19 +1170,21 @@ public class MobAI {
CheckMobMovement(mob);
CheckForAttack(mob);
} catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: GuardMinionLogic" + " " + e.getMessage());
//(mob.getObjectUUID() + " " + mob.getName() + " Failed At: GuardMinionLogic" + " " + e.getMessage());
}
}
public static void GuardWallArcherLogic(Mob mob) {
try {
checkToDropGuardAggro(mob);
if (mob.getCombatTarget() == null)
CheckForPlayerGuardAggro(mob);
else
CheckForAttack(mob);
} catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: GuardWallArcherLogic" + " " + e.getMessage());
//(mob.getObjectUUID() + " " + mob.getName() + " Failed At: GuardWallArcherLogic" + " " + e.getMessage());
}
}
@ -1093,12 +1196,16 @@ public class MobAI { @@ -1093,12 +1196,16 @@ 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);
CheckForAttack(mob);
} catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: PetLogic" + " " + e.getMessage());
//(mob.getObjectUUID() + " " + mob.getName() + " Failed At: PetLogic" + " " + e.getMessage());
}
}
@ -1114,7 +1221,7 @@ public class MobAI { @@ -1114,7 +1221,7 @@ public class MobAI {
CheckForAttack(mob);
} catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: HamletGuardLogic" + " " + e.getMessage());
//(mob.getObjectUUID() + " " + mob.getName() + " Failed At: HamletGuardLogic" + " " + e.getMessage());
}
}
@ -1129,17 +1236,11 @@ public class MobAI { @@ -1129,17 +1236,11 @@ public class MobAI {
if (mob.BehaviourType.isAgressive) {
AbstractWorldObject newTarget = ChangeTargetFromHateValue(mob);
if (newTarget != null)
mob.setCombatTarget(newTarget);
else {
if (mob.getCombatTarget() == null) {
if (mob.BehaviourType == Enum.MobBehaviourType.HamletGuard)
SafeGuardAggro(mob); //safehold guard
else
CheckForAggro(mob); //normal aggro
}
if (mob.getCombatTarget() == null) {
if (mob.BehaviourType == Enum.MobBehaviourType.HamletGuard)
SafeGuardAggro(mob); //safehold guard
else
NewAggroMechanic(mob);//CheckForAggro(mob); //normal aggro
}
}
@ -1153,8 +1254,9 @@ public class MobAI { @@ -1153,8 +1254,9 @@ 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());
//(mob.getObjectUUID() + " " + mob.getName() + " Failed At: DefaultLogic" + " " + e.getMessage());
}
}
@ -1204,7 +1306,7 @@ public class MobAI { @@ -1204,7 +1306,7 @@ public class MobAI {
}
}
} catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: CheckForPlayerGuardAggro" + e.getMessage());
//(mob.getObjectUUID() + " " + mob.getName() + " Failed At: CheckForPlayerGuardAggro" + e.getMessage());
}
}
@ -1267,7 +1369,7 @@ public class MobAI { @@ -1267,7 +1369,7 @@ public class MobAI {
}
}
} catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: GuardCanAggro" + " " + e.getMessage());
//(mob.getObjectUUID() + " " + mob.getName() + " Failed At: GuardCanAggro" + " " + e.getMessage());
}
return false;
}
@ -1316,56 +1418,107 @@ public class MobAI { @@ -1316,56 +1418,107 @@ public class MobAI {
}
}
} catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: randomGuardPatrolPoints" + " " + e.getMessage());
//(mob.getObjectUUID() + " " + mob.getName() + " Failed At: randomGuardPatrolPoints" + " " + e.getMessage());
}
}
public static AbstractWorldObject ChangeTargetFromHateValue(Mob mob) {
public static void RecoverHealth(Mob mob) {
//recover health
try {
if (mob.getTimestamps().containsKey("HEALTHRECOVERED") == false)
mob.getTimestamps().put("HEALTHRECOVERED", System.currentTimeMillis());
float CurrentHateValue = 0;
if (mob.isSit() && mob.getTimeStamp("HEALTHRECOVERED") < System.currentTimeMillis() + 3000)
if (mob.getHealth() < mob.getHealthMax()) {
if (mob.getCombatTarget() != null && mob.getCombatTarget().getObjectType().equals(Enum.GameObjectType.PlayerCharacter))
CurrentHateValue = ((PlayerCharacter) mob.getCombatTarget()).getHateValue();
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());
AbstractWorldObject mostHatedTarget = null;
if (mob.getHealth() > mob.getHealthMax())
mob.setHealth(mob.getHealthMax());
}
} catch (Exception e) {
//(mob.getObjectUUID() + " " + mob.getName() + " Failed At: RecoverHealth" + " " + e.getMessage());
}
}
for (Entry playerEntry : mob.playerAgroMap.entrySet()) {
public static void enterCombat(Mob mob){
mob.setCombat(true);
UpdateStateMsg rwss = new UpdateStateMsg();
rwss.setPlayer(mob);
DispatchMessage.sendToAllInRange(mob, rwss);
}
PlayerCharacter potentialTarget = PlayerCharacter.getFromCache((int) playerEntry.getKey());
public static void NewAggroMechanic(Mob mob){
if (potentialTarget.equals(mob.getCombatTarget()))
continue;
if(mob == null || !mob.isAlive() || mob.playerAgroMap.isEmpty()){
return;
}
if (potentialTarget != null && potentialTarget.getHateValue() > CurrentHateValue && MovementUtilities.inRangeToAggro(mob, potentialTarget)) {
CurrentHateValue = potentialTarget.getHateValue();
mostHatedTarget = potentialTarget;
}
if(mob.BehaviourType.equals(Enum.MobBehaviourType.HamletGuard)){
return;
}
}
return mostHatedTarget;
} catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: ChangeTargetFromMostHated" + " " + e.getMessage());
if(mob.hate_values == null)
mob.hate_values = new HashMap<>();
if(mob.combatTarget != null && mob.combatTarget.isAlive() && mob.combatTarget.loc.distanceSquared(mob.loc) < 90f)
return;
HashSet<AbstractWorldObject> inRange = WorldGrid.getObjectsInRangePartial(mob.loc,60.0f,MBServerStatics.MASK_PLAYER);
if(inRange.isEmpty()){
mob.setCombatTarget(null);
return;
}
return null;
}
public static void RecoverHealth(Mob mob){
//recover health
//clear out any players who are not in hated range anymore
ArrayList<PlayerCharacter> toRemove = new ArrayList<>();
for(PlayerCharacter pc : mob.hate_values.keySet()){
if(!inRange.contains(pc))
toRemove.add(pc);
}
for(PlayerCharacter pc : toRemove){
mob.hate_values.remove(pc);
}
if (mob.getTimestamps().containsKey("HEALTHRECOVERED") == false)
mob.getTimestamps().put("HEALTHRECOVERED", System.currentTimeMillis());
//find most hated target
PlayerCharacter mostHated = (PlayerCharacter)inRange.iterator().next();
for(AbstractWorldObject awo : inRange){
PlayerCharacter loadedPlayer = (PlayerCharacter)awo;
if (loadedPlayer == null)
continue;
if (mob.isSit() && mob.getTimeStamp("HEALTHRECOVERED") < System.currentTimeMillis() + 3000)
if (mob.getHealth() < mob.getHealthMax()) {
//Player is Dead, Mob no longer needs to attempt to aggro. Remove them from aggro map.
if (!loadedPlayer.isAlive())
continue;
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());
//Can't see target, skip aggro.
if (!mob.canSee(loadedPlayer))
continue;
// No aggro for this race type
if (mob.notEnemy != null && mob.notEnemy.size() > 0 && mob.notEnemy.contains(loadedPlayer.getRace().getRaceType().getMonsterType()))
continue;
//mob has enemies and this player race is not it
if (mob.enemy != null && mob.enemy.size() > 0 && !mob.enemy.contains(loadedPlayer.getRace().getRaceType().getMonsterType()))
continue;
if(mob.hate_values.containsKey(loadedPlayer))
if(mob.hate_values.get(loadedPlayer) > mob.hate_values.get(mostHated))
mostHated = loadedPlayer;
}
if(mostHated != null)
mob.setCombatTarget(mostHated);
}
public static void MobVsMobRetaliate(Mob retaliator, Mob attacker){
if(CombatUtilities.inRangeToAttack(retaliator,attacker)){
CombatUtilities.combatCycle(retaliator,attacker,true,null);
}
if (mob.getHealth() > mob.getHealthMax())
mob.setHealth(mob.getHealthMax());
}
}
}

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();
}

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

@ -22,7 +22,6 @@ import org.pmw.tinylog.Logger; @@ -22,7 +22,6 @@ import org.pmw.tinylog.Logger;
import java.util.concurrent.ThreadLocalRandom;
import static engine.math.FastMath.sqr;
import static java.lang.Math.pow;
public class CombatUtilities {
@ -101,9 +100,18 @@ public class CombatUtilities { @@ -101,9 +100,18 @@ public class CombatUtilities {
if (!target.isAlive())
return;
if (AbstractWorldObject.IsAbstractCharacter(target))
if(agent.isPet()){
try{
damage *= agent.getOwner().ZergMultiplier;
}catch(Exception ignored){
}
}
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.
@ -124,6 +132,8 @@ public class CombatUtilities { @@ -124,6 +132,8 @@ public class CombatUtilities {
}
public static boolean canSwing(Mob agent) {
if(!CombatUtilities.inRange2D(agent,agent.combatTarget,agent.getRange()))
return false;
return (agent.isAlive() && !agent.getBonuses().getBool(ModType.Stunned, SourceType.None));
}
@ -139,37 +149,32 @@ public class CombatUtilities { @@ -139,37 +149,32 @@ 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;
if(pc.combatStats == null)
pc.combatStats = new PlayerCombatStats(pc);
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 +212,10 @@ public class CombatUtilities { @@ -207,12 +212,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 +270,12 @@ public class CombatUtilities { @@ -267,12 +270,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 +297,6 @@ public class CombatUtilities { @@ -294,11 +297,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 +320,9 @@ public class CombatUtilities { @@ -322,9 +320,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 +331,9 @@ public class CombatUtilities { @@ -333,9 +331,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 +362,8 @@ public class CombatUtilities { @@ -364,8 +362,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 +379,8 @@ public class CombatUtilities { @@ -381,8 +379,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 +421,48 @@ public class CombatUtilities { @@ -423,92 +421,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));
}
}

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

@ -13,6 +13,7 @@ import engine.Enum; @@ -13,6 +13,7 @@ import engine.Enum;
import engine.Enum.GameObjectType;
import engine.Enum.ModType;
import engine.Enum.SourceType;
import engine.InterestManagement.InterestManager;
import engine.mobileAI.Threads.MobAIThread;
import engine.exception.MsgSendException;
import engine.gameManager.MovementManager;
@ -98,20 +99,24 @@ public class MovementUtilities { @@ -98,20 +99,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);
}
@ -189,6 +194,7 @@ public class MovementUtilities { @@ -189,6 +194,7 @@ public class MovementUtilities {
public static void aiMove(Mob agent, Vector3fImmutable vect, boolean isWalking) {
//InterestManager.forceLoad(agent);
//update our walk/run state.
if (isWalking && !agent.isWalk()) {
agent.setWalkMode(true);

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<>();

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

Loading…
Cancel
Save