Compare commits

...

958 Commits

Author SHA1 Message Date
FatBoy-DOTC a7c3662463 fixed build error 6 months ago
FatBoy-DOTC 909e04b8d1 update inventory after resource purchase 6 months ago
FatBoy-DOTC a7d1dc5fd0 Merge branch 'lakebane-old' into lakebane-master 6 months ago
FatBoy-DOTC 2f87fd9812 r8 gains 25% resource mine production bonus 6 months ago
FatBoy-DOTC c696bd368e gold amount no longer reduced for mine production 6 months ago
FatBoy-DOTC 7716d82adb mines named correctly 6 months ago
FatBoy-DOTC 66804d5704 resource purchasing 6 months ago
FatBoy-DOTC 02aafc9274 resource purchasing 6 months ago
FatBoy-DOTC 2ef0d4305c divide by 0 error 6 months ago
FatBoy-DOTC 972c99a146 server to sell elans at correct costs 6 months ago
FatBoy-DOTC ad9d27c6ee server to sell resources at correct costs 6 months ago
FatBoy-DOTC e1d11d5d94 server to sell resources at correct costs 6 months ago
FatBoy-DOTC ca78a3b581 resource merchant to price resources correctly 6 months ago
FatBoy-DOTC bcaa5d42ff resource merchant to sell items correctly 6 months ago
FatBoy-DOTC 6dad14ae57 reimplement resource merchant with 5mil stacks 6 months ago
FatBoy-DOTC 6e465248b1 drop rates adjusted again again third time 6 months ago
FatBoy-DOTC 7c106d5d34 drop rates adjusted again again third time 6 months ago
FatBoy-DOTC 8135ef8e9c drop rates adjusted again again third time 6 months ago
FatBoy-DOTC db2d6a4bf3 drop rates adjusted again again 6 months ago
FatBoy-DOTC bb0a3b8b5b drop rates adjusted again 6 months ago
FatBoy-DOTC 0145a7264d updated maintenance system 6 months ago
FatBoy-DOTC 6eec56adb4 rune and contract drop rate 6 months ago
FatBoy-DOTC 01662aae07 mine close crash bug 6 months ago
FatBoy-DOTC 72d73883a4 catch process mine window logic 6 months ago
FatBoy-DOTC 9c64dbb70c SIXTH AFTER ROLLBACK: mob rune and contract drop annouces local 6 months ago
FatBoy-DOTC 9408602c9c FIFTH AFTER ROLLBACK: mob rune and contract work updated correctly 6 months ago
FatBoy-DOTC 58cf778ce4 FOURTH AFTER ROLLBACK: error catching for attempt ot upgrade warehouses 6 months ago
FatBoy-DOTC 885b612bd6 THIRD AFTER ROLLBACK: contract and rune and glass drop rates adjusted properly 6 months ago
FatBoy-DOTC bf69045b0b SECOND AFTER ROLLBACK: serialize MineTimes correctly 6 months ago
FatBoy-DOTC 8b03fbc15b FIRST AFTER ROLLBACK: reintroduce mines 6 months ago
FatBoy-DOTC 3c23a070df glass repairable for 3x base repair costs 6 months ago
FatBoy-DOTC c14cc98ca2 mines reset claimability at 3am CST 6 months ago
FatBoy-DOTC c326008112 drop rates adjusted again again third time 6 months ago
FatBoy-DOTC 90facabc7b drop rates adjusted again again third time 6 months ago
FatBoy-DOTC 6e26a8cfcf drop rates adjusted again again third time 6 months ago
FatBoy-DOTC 4b1ab35a36 drop rates adjusted again again 6 months ago
FatBoy-DOTC d733afef58 drop rates adjusted again 6 months ago
FatBoy-DOTC f30a02a6d5 updated maintenance system 6 months ago
FatBoy-DOTC b255b1c9f4 rune and contract drop rate 6 months ago
FatBoy-DOTC 6151a9e650 mine close crash bug 6 months ago
FatBoy-DOTC 0f7ef9f56b city data msg catch 6 months ago
FatBoy-DOTC 6d68d048b0 catch process mine window logic 6 months ago
FatBoy-DOTC 8ccdbf8cc9 SIXTH AFTER ROLLBACK: mob rune and contract drop annouces local 6 months ago
FatBoy-DOTC 1798a8f170 FIFTH AFTER ROLLBACK: mob rune and contract work updated correctly 6 months ago
FatBoy-DOTC 737da1bf14 FOURTH AFTER ROLLBACK: error catching for attempt ot upgrade warehouses 6 months ago
FatBoy-DOTC 45eb0776d6 THIRD AFTER ROLLBACK: contract and rune and glass drop rates adjusted properly 6 months ago
FatBoy-DOTC f4346b97f7 SECOND AFTER ROLLBACK: serialize MineTimes correctly 6 months ago
FatBoy-DOTC cf6f684f5e FIRST AFTER ROLLBACK: reintroduce mines 6 months ago
FatBoy-DOTC a8e3cfa8f7 new mine handling system 6 months ago
FatBoy-DOTC 0028b7be69 pet msg toggle handling 6 months ago
FatBoy-DOTC 3f11996b40 box limits resolved 6 months ago
FatBoy-DOTC 779f5bbb5b null resolution 6 months ago
FatBoy-DOTC 37c89e6073 Box Tracker 6 months ago
FatBoy-DOTC 83499816eb Box Tracker 6 months ago
FatBoy-DOTC 0eb8da855d maintenance resolution 6 months ago
FatBoy-DOTC 36fb3f12b1 30 second delay to zerg mechanic running 6 months ago
FatBoy-DOTC ba642e049e null check fix 6 months ago
FatBoy-DOTC 98835cad90 revert boxflag 6 months ago
FatBoy-DOTC 4d9600a8bf box flag checker 6 months ago
FatBoy-DOTC 4089f72d8f box flag checker 6 months ago
FatBoy-DOTC ead86efcf6 box flag checker 6 months ago
FatBoy-DOTC ae01a421de box flag checker 6 months ago
FatBoy-DOTC 469662f732 box flag checker 6 months ago
FatBoy-DOTC 8b9bc474b4 box flag checker 6 months ago
FatBoy-DOTC 3815f9df8e box flag checker 6 months ago
FatBoy-DOTC 6313182c4f mine window processing 6 months ago
FatBoy-DOTC 40bff54838 box flag situation looked into 6 months ago
FatBoy-DOTC 2b1299ec4a ZergMultiplier fix 6 months ago
FatBoy-DOTC 0955dff7aa city map serialization fix 6 months ago
FatBoy-DOTC 2b18765781 elan stones sell 10 for 1 mil from resource vendor 6 months ago
FatBoy-DOTC c55f67a977 resource vendor now sells in stack sizes of 500k purchase 6 months ago
FatBoy-DOTC 730467828c rune price ceiling adjustment 6 months ago
FatBoy-DOTC ad05f0d7bc gold from mines no longer produces at half value 6 months ago
FatBoy-DOTC c922d9c532 recall scroll set to 20 seconds 6 months ago
FatBoy-DOTC ed4d186b10 can no longer PVE to level 76 6 months ago
FatBoy-DOTC de1bc375ca forced hourly rune and contract drops 6 months ago
FatBoy-DOTC 1c48b28d4e maintenance fix 6 months ago
FatBoy-DOTC 0318459ff1 disc rune announcements 6 months ago
FatBoy-DOTC 4bdc207c37 maintenance completed 6 months ago
FatBoy-DOTC ba537d7b00 invisible cities on map logging 6 months ago
FatBoy-DOTC a0164d5abb invisible cities on map logging 6 months ago
FatBoy-DOTC eec5861944 invisible cities on map logging 6 months ago
FatBoy-DOTC 094a7a9498 new maintenance completed 6 months ago
FatBoy-DOTC d93892df6c new maintenance completed 6 months ago
FatBoy-DOTC 81150642f0 new maintenance completed 6 months ago
FatBoy-DOTC 7fb5ccf4f1 new maintenance completed 6 months ago
FatBoy-DOTC ab1e69a6ef maintenance rewrite - needs completeing for r8 6 months ago
FatBoy-DOTC 2d2832caf9 public variable 6 months ago
FatBoy-DOTC 5dee08d3ce Merge branch 'lakebane-mines' into lakebane-master 6 months ago
FatBoy-DOTC 75b68c0a8c disc spawn timers corrected 6 months ago
FatBoy-DOTC a9f006936b yet another attempt at mines 6 months ago
FatBoy-DOTC 917fddceeb yet another attempt at mines 6 months ago
FatBoy-DOTC a2da8f3861 yet another attempt at mines 6 months ago
FatBoy-DOTC b1b2912092 yet another attempt at mines 6 months ago
FatBoy-DOTC 3bcda38bb7 destroy and remove form cache and DB all buildinsg within city when its being destroyed 6 months ago
FatBoy-DOTC 918a797f34 timezone updated 6 months ago
FatBoy-DOTC ba9238a49a new mines system 6 months ago
FatBoy-DOTC bd5061a7e8 new mines system 6 months ago
FatBoy-DOTC 270301c35b new mines system 6 months ago
FatBoy-DOTC ffcaf0e063 new mines system 6 months ago
FatBoy-DOTC 6e7633828f new mines system 6 months ago
FatBoy-DOTC 3aac2410b0 new mines system 6 months ago
FatBoy-DOTC c90378e3f0 delay mine checks to 1 minute intervals 6 months ago
FatBoy-DOTC 4734f23805 check if mines are active before spamming them to open 6 months ago
FatBoy-DOTC 47503de748 system to open and close mines 6 months ago
FatBoy-DOTC 8ab2805e39 xp and range fix 6 months ago
FatBoy-DOTC 1d703b08a2 xp and range fix 6 months ago
FatBoy-DOTC a660457883 cannot get XP from the same character in PVP more than once per reboot 6 months ago
FatBoy-DOTC 4ca81b019b everyone gets an extra disc 6 months ago
FatBoy-DOTC 5f16b40092 PVP experience only after level 75 6 months ago
FatBoy-DOTC 0d7beb5a5a PVP experience only after level 75 6 months ago
FatBoy-DOTC b66e1c1f93 setlevel command goes to 80 now 6 months ago
FatBoy-DOTC f1e8384af0 mines will start again 6 months ago
FatBoy-DOTC c9dcb82c45 removed leadership cap 6 months ago
FatBoy-DOTC c2c946165c scaling XP gains for groups 6 months ago
FatBoy-DOTC ffd65b3641 mob range min set to 6 6 months ago
FatBoy-DOTC ba2084ceb0 level 80 characters get a 5th disc rune 6 months ago
FatBoy-DOTC 34ec123702 level cap increased to 80 Experience altered 6 months ago
FatBoy-DOTC 7c36325905 level cap increased to 80 Experience altered 6 months ago
FatBoy-DOTC 915f182d79 level cap increased to 80 6 months ago
FatBoy-DOTC fb1d6a3248 auto update NPC slot location and reload on mesh change for buildings 6 months ago
FatBoy-DOTC 6d16eccc24 shrines can be looted once destroyed 6 months ago
FatBoy-DOTC fa5cdae17e shrine delete button causes rubble pile 6 months ago
FatBoy-DOTC b46eb8639d capturing city will cede all buildinsg to conquerer 6 months ago
FatBoy-DOTC 58916c35c7 shrines can be destroyed 6 months ago
FatBoy-DOTC f80d50f95e buildings cannot be deleted if the city is under siege 6 months ago
FatBoy-DOTC 77f2e413c9 Mine time and cap changes 6 months ago
FatBoy-DOTC 5e84ee8b11 pet run/walk determined by owner 6 months ago
FatBoy-DOTC b6a9a0c813 detection of using /tar 6 months ago
FatBoy-DOTC f7e6307d66 Mine optimization 6 months ago
FatBoy-DOTC 1359417b40 databse update for stacked resources 6 months ago
FatBoy-DOTC 85077a5e56 databse update for stacked resources 6 months ago
FatBoy-DOTC 366815f1f9 databse update for stacked resources 6 months ago
FatBoy-DOTC 2ca51d6a83 merchant resource stacking 6 months ago
FatBoy-DOTC b7ebb728e2 attempted warehouse delay issue resolution 6 months ago
FatBoy-DOTC 023057668a attempted warehouse delay issue resolution 6 months ago
FatBoy-DOTC a11b590573 revert deposit change 6 months ago
FatBoy-DOTC 353d211a04 PC cleanup 6 months ago
FatBoy-DOTC c792e49fdc added 30 second delay to Enrollment Officer 6 months ago
FatBoy-DOTC f8e99a84b1 optimized ManageCityAssetMsgHandler 6 months ago
FatBoy-DOTC b28c157a5c Revert "optimized deleting items" 6 months ago
FatBoy-DOTC 85717a1880 Revert "optimized looting system" 6 months ago
FatBoy-DOTC 0ac7a1a7fa optimized deleting items 6 months ago
FatBoy-DOTC 7745ef6949 optimized looting system 6 months ago
FatBoy-DOTC 40078df067 optimized 6 months ago
FatBoy-DOTC bb28d38735 mob AI aggro cleanup 6 months ago
FatBoy-DOTC 7bd6e3a149 mob AI message cleanup 6 months ago
FatBoy-DOTC 72faafedfe resource merchant 6 months ago
FatBoy-DOTC e560c07aba track chaining for same nations 6 months ago
FatBoy-DOTC 742232166e prospector cost reduced to 500k on disc merchant 6 months ago
FatBoy-DOTC 910a5d9e3c prospector costs 500k 6 months ago
FatBoy-DOTC a943a5a51d update saetor stats 6 months ago
FatBoy-DOTC e3a278e090 moving in the air with movebuff will result in immediate ground 6 months ago
FatBoy-DOTC 5959209081 fly work 6 months ago
FatBoy-DOTC e222cb3543 zerg multiplier application work 6 months ago
FatBoy-DOTC a4efe199c6 saetor starting runes added 6 months ago
FatBoy-DOTC fa5ac4fea3 euro mines time changed up by 4 hours 6 months ago
FatBoy-DOTC f28c887b92 inline method 6 months ago
FatBoy-DOTC c1331efe38 add is alive check to box refresh 6 months ago
FatBoy-DOTC b113b55703 optimisation 6 months ago
FatBoy-DOTC 560466e3ef null check 6 months ago
FatBoy-DOTC 0457287905 fixed ballad of beregund the bold 6 months ago
FatBoy-DOTC db7e9276b1 fixed ballad of beregund the bold 6 months ago
FatBoy-DOTC a14057b9df resource stacking optimized location 6 months ago
FatBoy-DOTC 0a3624e503 5 second delay for switching boxes 6 months ago
FatBoy-DOTC 45048b2b4e box check only every 10 seconds 6 months ago
FatBoy-DOTC 27550293d6 box check only every 10 seconds 6 months ago
FatBoy-DOTC 422cf10eea box check only every 10 seconds 6 months ago
FatBoy-DOTC c412336257 box check only every 5 seconds 6 months ago
FatBoy-DOTC c8bea0d1ce resource merchant 6 months ago
FatBoy-DOTC e66a8459c0 flash message can be more than one word 6 months ago
FatBoy-DOTC 817067d242 flash message can be more than one word 6 months ago
FatBoy-DOTC 942288cee2 mob resists 6 months ago
FatBoy-DOTC 8d633adbb3 disc dropper resists 6 months ago
FatBoy-DOTC a821f7f7e4 r8 resists 6 months ago
FatBoy-DOTC 0581cab5cb mob resists 6 months ago
FatBoy-DOTC 6ee1c02e08 mob resists 6 months ago
FatBoy-DOTC 8379b48332 mob resists 6 months ago
FatBoy-DOTC e2ae758e36 bank refresh 6 months ago
FatBoy-DOTC 8f1855fb3f bank refresh 6 months ago
FatBoy-DOTC e15164bcb2 Boxed Flag 6 months ago
FatBoy-DOTC 836fa4f8dc Boxed Flag 6 months ago
FatBoy-DOTC fe7f4dc3ca stealth breaking when attacking 6 months ago
FatBoy-DOTC 19402bf06f stealth breaking when attacking 6 months ago
FatBoy-DOTC bed49c0230 stealth breaking when attacking 6 months ago
FatBoy-DOTC 9c79dca2c5 weird range check issue resolved 6 months ago
FatBoy-DOTC 3820d179c6 better protocol error tracking 6 months ago
FatBoy-DOTC 6e1db9489a track chaining for same nations 6 months ago
FatBoy-DOTC 8227db92c8 prospector cost reduced to 500k on disc merchant 6 months ago
FatBoy-DOTC 06309daae6 prospector costs 500k 6 months ago
FatBoy-DOTC 49e5be959f spells that target self now default to self target 6 months ago
FatBoy-DOTC 74a22d4cf5 update saetor stats 6 months ago
FatBoy-DOTC 3f827cebd8 boxed characters now get recurring travel stance effect 6 months ago
FatBoy-DOTC ae734cbb0a mob AI work 6 months ago
FatBoy-DOTC bde3e54fd4 mob AI work 6 months ago
FatBoy-DOTC fa5144c932 mob AI work 6 months ago
FatBoy-DOTC de08d0d210 mob AI work 6 months ago
FatBoy-DOTC 79a9bfd606 fix banks 6 months ago
FatBoy-DOTC 491519216c moving in the air with movebuff will result in immediate ground 6 months ago
FatBoy-DOTC 048c4dfb1b fly work 6 months ago
FatBoy-DOTC d14144cdf3 zerg multiplier application work 6 months ago
FatBoy-DOTC d610bccdee 5 second delay forced between warehouse transactions 6 months ago
FatBoy-DOTC 39f7be99b0 gold dupe prevention 6 months ago
FatBoy-DOTC 01aa226c62 transfer item to vault fixed 6 months ago
FatBoy-DOTC 87bd67b0f5 saetor starting runes added 6 months ago
FatBoy-DOTC 70edd4c19c euro mines time changed up by 4 hours 6 months ago
FatBoy-DOTC 6c86da0719 looting auto stacks resources 6 months ago
FatBoy-DOTC 84cc435a2b trading auto stacks resources 6 months ago
FatBoy-DOTC 5e61ef26e1 stack resources completed 6 months ago
FatBoy-DOTC 9e85c1e361 stack resources 6 months ago
FatBoy-DOTC 3d80a03e1e Resource Auto Stacking 6 months ago
FatBoy-DOTC 15136518a3 Resource Auto Stacking 6 months ago
FatBoy-DOTC b8abe94a8c Resource Auto Stacking 6 months ago
FatBoy-DOTC f2e4e8062e cant inventory junk more than 10 mil 6 months ago
FatBoy-DOTC feaa38ee98 mine caps 6 months ago
FatBoy-DOTC 6f453ab5c4 discs junkable 6 months ago
FatBoy-DOTC af839c108c runes and contracts drop rate increased by 3x 6 months ago
FatBoy-DOTC 8bac27f0fc mine cap sizes 6 months ago
FatBoy-DOTC bfb257c410 trainer buildings granted 3 slots at r1 6 months ago
FatBoy-DOTC 3be694275d removed 20 man mines 6 months ago
FatBoy-DOTC f885560e52 trainer upgrade cost reduced to 25% 6 months ago
FatBoy-DOTC a8a9cdb0f1 mob resist issue 6 months ago
FatBoy-DOTC 210cc94dac mob resist issue 6 months ago
FatBoy-DOTC bf503c0be0 mob resist issue 6 months ago
FatBoy-DOTC 24c16e6cf1 mob resist issue 6 months ago
FatBoy-DOTC a6fb7ec0a0 mob resist issue 6 months ago
FatBoy-DOTC cb9197013e mob resist issue 6 months ago
FatBoy-DOTC e1584161c9 mob resist issue 6 months ago
FatBoy-DOTC 0c85c1d289 mob resist issue 6 months ago
FatBoy-DOTC ead9683b98 mob resist issue 6 months ago
FatBoy-DOTC c29d6f548e mob resist issue 6 months ago
FatBoy-DOTC 5822cb1ab4 mob resist issue 6 months ago
FatBoy-DOTC 371d077320 mob resist issue 6 months ago
FatBoy-DOTC 984c4d205a mob resist issue 6 months ago
FatBoy-DOTC 8cc92e9792 mob resist issue 6 months ago
FatBoy-DOTC c1ea68aa41 mob resist issue 6 months ago
FatBoy-DOTC 324851a8ab mob resist issue 6 months ago
FatBoy-DOTC cd512100a2 mob resist issue 6 months ago
FatBoy-DOTC a0e78d8add mob resist issue 6 months ago
FatBoy-DOTC f02d79c65e mob resist issue 6 months ago
FatBoy-DOTC cfffb0c16a mob resist issue 6 months ago
FatBoy-DOTC 8804a3ecd4 mob resist issue 6 months ago
FatBoy-DOTC 16c84f2b30 mob resist issue 6 months ago
FatBoy-DOTC 5858aabc83 mob resist issue 7 months ago
FatBoy-DOTC 4b81a5c435 mob resist issue 7 months ago
FatBoy-DOTC c1107ae98d mob resist issue 7 months ago
FatBoy-DOTC c5f2464d55 mob resist issue 7 months ago
FatBoy-DOTC e0beab2dc5 mob resist issue 7 months ago
FatBoy-DOTC bcbeacd60e mob resist issue 7 months ago
FatBoy-DOTC e39c7bebb5 mob resist issue 7 months ago
FatBoy-DOTC 4e6e56350c mob resist issue 7 months ago
FatBoy-DOTC a33d650738 mob resist issue 7 months ago
FatBoy-DOTC 12b44e216c mob resist issue 7 months ago
FatBoy-DOTC a202a0544e mob resist issue 7 months ago
FatBoy-DOTC 8156f261fc mob aggro issue 7 months ago
FatBoy-DOTC 283ae37919 mob aggro issue 7 months ago
FatBoy-DOTC 3e30c7a01e no more dead or self track 7 months ago
FatBoy-DOTC a5570e4bb5 no more dead or self track 7 months ago
FatBoy-DOTC 290aec79ba pets kills are aded to kill spam 7 months ago
FatBoy-DOTC 1378bc8030 attempting to fly with movement buff will ground you 7 months ago
FatBoy-DOTC bd536961e2 removal group guil refreshes group windows 7 months ago
FatBoy-DOTC 17aee68575 2x xp for solo players without a group 7 months ago
FatBoy-DOTC a97f4e6da6 conc pots cant be deleted 7 months ago
FatBoy-DOTC 2274a9e16e Hamlet Guards Immune To All 7 months ago
FatBoy-DOTC 1caa704b6a removed BOXED text from flag 7 months ago
FatBoy-DOTC 1bb4e17ead Boxed Title 7 months ago
FatBoy-DOTC d84b214fd3 Boxed Title 7 months ago
FatBoy-DOTC 4440ed1f0d Boxed Title 7 months ago
FatBoy-DOTC f0ad1b730c Boxed Title 7 months ago
FatBoy-DOTC d968c4eca4 Boxed Title 7 months ago
FatBoy-DOTC 38816f25bb refiner? 7 months ago
FatBoy-DOTC 58f5bf05e0 refiner? 7 months ago
FatBoy-DOTC 78d9e3d6fc Blood rue dropper update 7 months ago
FatBoy-DOTC d1c07e88fc CC staff dropper 7 months ago
FatBoy-DOTC dcd108e3ac dropper resists 7 months ago
FatBoy-DOTC 2c2a2464ee dropper resists 7 months ago
FatBoy-DOTC ee5c254de4 box check 7 months ago
FatBoy-DOTC efa4ce91fa adjusted rates properly 7 months ago
FatBoy-DOTC cd45f49b07 cant delete disc runes 7 months ago
FatBoy-DOTC 116c9bfdfb debugging 7 months ago
FatBoy-DOTC 4ec7c3c4bd cleanup 7 months ago
FatBoy-DOTC 281dde533a cleanup 7 months ago
FatBoy-DOTC 55b6f95696 cleanup 7 months ago
FatBoy-DOTC e120ae6e18 cleanup 7 months ago
FatBoy-DOTC 9e44c9475a cleanup 7 months ago
FatBoy-DOTC 4d8cb339c3 errant characters recall to SDR 7 months ago
FatBoy-DOTC b1dfd9a40d shade sneak recast 7 months ago
FatBoy-DOTC cff6714160 remove day fo week bane placement restriction 7 months ago
FatBoy-DOTC 16a9d4e5c9 blood rune check work 7 months ago
FatBoy-DOTC 3189d64031 blood rune check work 7 months ago
FatBoy-DOTC 5cd94234e9 blood rune check work 7 months ago
FatBoy-DOTC b45b325cad human blood runes cost 0 7 months ago
FatBoy-DOTC b731291e6c human blood runes cost 0 7 months ago
FatBoy-DOTC c207bd14b6 human blood runes cost 0 7 months ago
FatBoy-DOTC 4924133416 humans can only apply 1 Blood Rune 7 months ago
FatBoy-DOTC 6769286c4a Adjust Mine Times 7 months ago
FatBoy-DOTC d21bf0185b catch exceptin for missing tokens 7 months ago
FatBoy-DOTC 3312ea292f healer archmage fix and saetor ranger fix 7 months ago
FatBoy-DOTC c7604d0f2c Allow Saetor Rangers 7 months ago
FatBoy-DOTC 1206441ab3 assorted fixes 7 months ago
FatBoy-DOTC 679346383a assorted fixes 7 months ago
FatBoy-DOTC e8df9ef0ea terraform update 7 months ago
FatBoy-DOTC 3d683fc9a3 dropper resists 7 months ago
FatBoy-DOTC fbeda13a48 dropper resists 7 months ago
FatBoy-DOTC d598887f61 enable minor version checks 7 months ago
FatBoy-DOTC 40372e1b35 enable minor version checks 7 months ago
FatBoy-DOTC 4476c3863d disable minor version checks 7 months ago
FatBoy-DOTC 08f94226ba Disc Droppers get increased stats 7 months ago
FatBoy-DOTC 7eb9eca7d0 Disc Droppers get 75% resist all 7 months ago
FatBoy-DOTC c43c3de18a zone loading 7 months ago
FatBoy-DOTC 9e0fa541a2 zone loading 7 months ago
FatBoy-DOTC 58035d0f93 zone loading 7 months ago
FatBoy-DOTC 92460d455b zone loading 7 months ago
FatBoy-DOTC 3c5f510969 zone loading 7 months ago
FatBoy-DOTC e3c8be6102 zone loading 7 months ago
FatBoy-DOTC 5f0eb266c2 zone loading 7 months ago
FatBoy-DOTC c721d6d4a8 zone loading 7 months ago
FatBoy-DOTC d0b716eb41 zone loading 7 months ago
FatBoy-DOTC a4a375e13b zone loading 7 months ago
FatBoy-DOTC c56702bd75 promoting to active duty 7 months ago
FatBoy-DOTC 5c023b4c4d log machine ID 7 months ago
FatBoy-DOTC 4b67cbef38 realm date time console spam fix 7 months ago
FatBoy-DOTC 6cf2705013 better DS application 7 months ago
FatBoy-DOTC 66bc73a2b6 harmful spells break stealth 7 months ago
FatBoy-DOTC 77cfa02bea players already flagged active cannot promote to active 7 months ago
FatBoy-DOTC 93773a7784 Enrollment officer no longer strips buffs 7 months ago
FatBoy-DOTC 42dd2b4e68 swap active character with NPC 7 months ago
FatBoy-DOTC 2aed3ef922 no longer delete gold 7 months ago
FatBoy-DOTC fb6a3706cd implement bane cap sizes based on trees in nation 7 months ago
FatBoy-DOTC 48e126823f players dont show up on their own track 7 months ago
FatBoy-DOTC b3de192f0b remove name override for vorg 7 months ago
FatBoy-DOTC 58d5c1969c attack range sync 7 months ago
FatBoy-DOTC 950108be87 Vorg Name Override 7 months ago
FatBoy-DOTC a9746b9a2b add npc command 7 months ago
FatBoy-DOTC eaa287e176 add npc command 7 months ago
FatBoy-DOTC 67cdf0e98a add npc command 7 months ago
FatBoy-DOTC 83e2b29635 added set profit dev command 7 months ago
FatBoy-DOTC c99a361ca7 added set profit dev command 7 months ago
FatBoy-DOTC f53c2c5cb0 vorg fix 7 months ago
FatBoy-DOTC 6680651801 disc droppers are alive at server up 7 months ago
FatBoy-DOTC 66fbbada48 mines close on time 7 months ago
FatBoy-DOTC ba1cb22662 runegates always open 7 months ago
FatBoy-DOTC bf9be1f7f9 runegates always open 7 months ago
FatBoy-DOTC bb4c1d48a4 mob desync issue 7 months ago
FatBoy-DOTC b33f451285 mob desync issue 7 months ago
FatBoy-DOTC f865f94806 mob desync issue 7 months ago
FatBoy-DOTC baf28519c2 mine fix dor delayed closing time 7 months ago
FatBoy-DOTC 4a2ef92d33 4 hour disc spawns 100% 7 months ago
FatBoy-DOTC c16ea8f3dd movement sync bug squashed 7 months ago
FatBoy-DOTC 882ed17b3a Pet damage scales with zerg multiplier 7 months ago
FatBoy-DOTC d06c298b09 revert power que 7 months ago
FatBoy-DOTC e4bad5f418 zerg mechanic work 7 months ago
FatBoy-DOTC 54c0b3d7ce mine work 7 months ago
FatBoy-DOTC 9d59bde22e mine pulse 7 months ago
fatboy 47243dd48d powers thread 7 months ago
fatboy bb6828ec8e powers thread 7 months ago
fatboy 5d0973c2bc mines thread 7 months ago
fatboy 4f216364a9 general cleanup 7 months ago
fatboy c1d193ee45 reduce runegate pulse from 3 seconds to half a second 7 months ago
fatboy 9879c1b18f various cleanups 7 months ago
FatBoy-DOTC 928845a220 disc fix 7 months ago
FatBoy-DOTC 3378272a19 optimize 7 months ago
FatBoy-DOTC e4c4643678 dieing resets ZergMultiplier 7 months ago
FatBoy-DOTC 3c1a217ac6 top of the hour disc spawns 7 months ago
FatBoy-DOTC 1567b22fe4 top of the hour disc spawns 7 months ago
FatBoy-DOTC 2067bbc6e1 mine closing bug 7 months ago
FatBoy-DOTC 9790423139 mine closing bug 7 months ago
FatBoy-DOTC d8a8c1a9a0 mine closing bug 7 months ago
FatBoy-DOTC 60ab4a846e update irekei move speed 7 months ago
FatBoy-DOTC 58f250fa64 mob casting temporarily disabled 7 months ago
FatBoy-DOTC a160df02c4 mines fix 7 months ago
FatBoy-DOTC 1fa7cbed12 vorg drop ranges 7 months ago
FatBoy-DOTC d16a56a582 vorg drop ranges 7 months ago
FatBoy-DOTC 69aca2c728 disc resapwn attempt 2 7 months ago
FatBoy-DOTC 159960d521 saetor can take born in the country 7 months ago
FatBoy-DOTC b9871a2729 blood horn and thrall can be taken on all minotaurs and saetors 7 months ago
FatBoy-DOTC 18f6822cb4 fix mines auto claim when rolle dover 7 months ago
FatBoy-DOTC 18731839f7 update mine times 7 months ago
FatBoy-DOTC 1d2e4d5608 desert r8 cant move 7 months ago
FatBoy-DOTC ef49d0cbe0 apply human and elf runes in game 7 months ago
FatBoy-DOTC 9604ee4399 sundancer given Find Weakness 7 months ago
FatBoy-DOTC e708bb02f5 npc buildings dont accumulate gold 7 months ago
FatBoy-DOTC 73c1f97051 mob cast fix 7 months ago
FatBoy-DOTC 7a445db673 zerg multiplier fix 7 months ago
FatBoy-DOTC b3d65ef700 mine lag fix 7 months ago
FatBoy-DOTC 7a7559dee5 NPC buildings dont run out of gold space on buildings 7 months ago
FatBoy-DOTC a902ff720a NPC buildings dont run out of gold space on buildings 7 months ago
FatBoy-DOTC 98cb307e09 extended summon timer now uses extended accept time 7 months ago
FatBoy-DOTC 0dca6c4662 universal mines round 2 7 months ago
FatBoy-DOTC c8310ec5ba universal mines round 2 7 months ago
FatBoy-DOTC 961258f67a reset mine production resources 7 months ago
FatBoy-DOTC 2854472ae0 fixed bug with mob cast time frequency 7 months ago
FatBoy-DOTC b81f088a3a disable mob changing target based on hate value 7 months ago
FatBoy-DOTC be4cbd3f6f vorg baked in stats 7 months ago
FatBoy-DOTC 7eb6deb1e9 fix cast bug for mob to PC 7 months ago
FatBoy-DOTC d04cad0484 adjust mines 7 months ago
FatBoy-DOTC a8a21e9e40 adjust mine times 7 months ago
FatBoy-DOTC 0d5ff59cb7 Revert "adjust mine times" 7 months ago
FatBoy-DOTC cdeebda6f8 adjust mine times 7 months ago
FatBoy-DOTC 3065f9f7eb disc droppers no longer spawn at server up 7 months ago
FatBoy-DOTC e2cca6201f summon fix 7 months ago
FatBoy-DOTC 1f7ea89d66 starting conc issue resolved 7 months ago
FatBoy-DOTC ce3eacda48 zerg mechanic work 7 months ago
FatBoy-DOTC 8a3a4645af zerg mechanic work 7 months ago
FatBoy-DOTC f074fe1825 zerg mechanic work 7 months ago
FatBoy-DOTC e47430e61b zerg mechanic work 7 months ago
FatBoy-DOTC b2718779f8 zerg mechanic work 7 months ago
fatboy 189d0624e7 grouping restriction update 7 months ago
fatboy a6cfe2fb76 disc droppers dont spawn at boot 7 months ago
fatboy fa37e1bcca disc dropper time delay 7 months ago
FatBoy-DOTC 7497526bd9 boons can be refreshed 7 months ago
FatBoy-DOTC b9c38d9d2b fleet of foot allowed for saetor 7 months ago
FatBoy-DOTC c8ec0fe191 sitting movement sync bug squashed 7 months ago
FatBoy-DOTC 1378ddcaef disable clanwarden drop 7 months ago
FatBoy-DOTC 78f8331582 potion cost bug 7 months ago
FatBoy-DOTC c197a385c5 mob aggro issue 7 months ago
FatBoy-DOTC 2c0899982c mine audit 7 months ago
FatBoy-DOTC 72bc753724 mine audit 7 months ago
FatBoy-DOTC c43f70128a mine audit 7 months ago
FatBoy-DOTC 95b23a35fc mine audit 7 months ago
FatBoy-DOTC 86d0254c2f mine audit 7 months ago
FatBoy-DOTC d09240d11a only start thread for mine being set to active 7 months ago
fatboy 5da4b66f81 prinstats will now show regen rates 7 months ago
fatboy 5247bf77fe luauptime shows boxed and active players online 7 months ago
fatboy f8a584d000 cannot summon outside of nation 7 months ago
fatboy 7c2915928d being banished form guild will remove you from any groups 7 months ago
fatboy 8308ac97e3 leaving guild will remove you from groups you are in 7 months ago
fatboy 75ea9092e2 cannot group outside of nation 7 months ago
fatboy d60532c23f cleanup 7 months ago
fatboy d8f1cf2087 cleanup 7 months ago
fatboy 379dbe668c nations can only have 1 bane placed on them at a time 7 months ago
fatboy 52a0c95002 cannot be subbed if you have a bane placed 7 months ago
fatboy 360a393a0f cannot invite guilds to sub if you are baned 7 months ago
fatboy 345f4e799b mines get caps 3/5/10/20 7 months ago
fatboy ef70d7b8ed 3 man mine value assigned 7 months ago
fatboy f98f54139a Threads for Zerg Mechanics 7 months ago
fatboy 7e3e337de0 Threads for Zerg Mechanics 7 months ago
FatBoy-DOTC 74f8f0640f 60 second vamp summon 7 months ago
FatBoy-DOTC 13babb630d all runes junk for 500k 7 months ago
FatBoy-DOTC cd87927241 addressed mine bug 7 months ago
FatBoy-DOTC e3377d26b1 mines only open at their correct times 7 months ago
FatBoy-DOTC e02dbd3632 Universal Mines 7 months ago
FatBoy-DOTC 0d7c2cd288 saetor cannot wear shoes 7 months ago
FatBoy-DOTC 60ba6d5b28 disc rune changes for prospector and black mask 7 months ago
FatBoy-DOTC 52c3f563a2 changed heal receptivity for vamps and elves 7 months ago
FatBoy-DOTC 5655aef57a 5% movespeeed increase for IREKEI 7 months ago
FatBoy-DOTC 487e557ef9 blood droppers 7 months ago
FatBoy-DOTC f95dd7f6f2 translocate doesnt break on take damage 7 months ago
FatBoy-DOTC 4f56cacaea unarmed mob damage addressed 7 months ago
FatBoy-DOTC 36f42770c8 unarmed mob damage addressed 7 months ago
FatBoy-DOTC 1dfac59b8c traveler and prospector droppers 1 hour spawn timers 7 months ago
FatBoy-DOTC d22b10e9ef traveler and prospector droppers 1 hour spawn timers 7 months ago
FatBoy-DOTC 5cdab459bc rogue/mage druids and saetor huntress/fury 7 months ago
FatBoy-DOTC f62d44d631 rogue/mage druids and saetor huntress/fury 7 months ago
FatBoy-DOTC 5ee3438e42 start with conc 7 months ago
FatBoy-DOTC 6b07058dd4 start with conc 7 months ago
FatBoy-DOTC 1f700cda4c start with conc 7 months ago
FatBoy-DOTC c5f5c33329 rune merchant cleanup 7 months ago
FatBoy-DOTC f3b00a6249 rune merchant cleanup 7 months ago
FatBoy-DOTC 9da4b85dd1 realm cleanup 7 months ago
FatBoy-DOTC 76da1d0cbf remove lizardman 7 months ago
FatBoy-DOTC dc5b05e5b5 test 7 months ago
FatBoy-DOTC 8414fb0039 test 7 months ago
FatBoy-DOTC 8cdd4910ca NPC buy/sell use DB values 7 months ago
FatBoy-DOTC ed7e7be3e8 extra summon time doesnt affect safezones 8 months ago
FatBoy-DOTC 642103b5a2 shadow mantle increased to 15 second duration 8 months ago
FatBoy-DOTC 1f95abf0b2 summon time takes +1 minute if non-nation players in load range 8 months ago
FatBoy-DOTC 434e64d7ba 5 second cast time for wizard single teleport 8 months ago
FatBoy-DOTC 665bc25126 5 second cast time for wizard single teleport 8 months ago
FatBoy-DOTC 8b01f80231 new ATR vs DEF formula for spells 8 months ago
FatBoy-DOTC 7fee52c861 cannot use movement speed buffs while flying 8 months ago
FatBoy-DOTC f8cf531136 condemn list options removed from ToL 8 months ago
FatBoy-DOTC 936f151a72 shadowmantle duration reduced to 10 seconds 8 months ago
FatBoy-DOTC 4707bb11f0 recall scrolls take double the time to execute 8 months ago
FatBoy-DOTC 4de40d054b BH eyes now see GM invis 8 months ago
FatBoy-DOTC af3eb1d85f contagion castable on players 8 months ago
FatBoy-DOTC 2990396778 bugfix - item pricing 8 months ago
FatBoy-DOTC 7f8652b477 dev commands broadcast to server 8 months ago
FatBoy-DOTC afae0e63ba saetor can now take "Chaos Boon" 8 months ago
FatBoy-DOTC 850d2dfea0 Nephilim Shrine renames Chaos Shrine 8 months ago
FatBoy-DOTC dcc92fd89d removed non-gold drops form safehold mobs 8 months ago
FatBoy-DOTC 1346f490c9 players can now use ./prinstats and ./printresists on themselves 8 months ago
FatBoy-DOTC 0c1b3d1460 Group translocate not allowed outside active banes and mines 8 months ago
FatBoy-DOTC d96f10b41e vorg stats finalized 8 months ago
FatBoy-DOTC 595d0ba9ba hit chance issue resolved 8 months ago
FatBoy-DOTC 505f8fdd90 hit chance issue resolved 8 months ago
FatBoy-DOTC bd098fcb24 hit chance work 8 months ago
FatBoy-DOTC dae20d5591 create saetor shrine blueprint 8 months ago
FatBoy-DOTC d33de60869 create saetor shrine object 8 months ago
FatBoy-DOTC 38c9612eb6 saetor skills 8 months ago
FatBoy-DOTC 4035f45c4f saetor skills 8 months ago
FatBoy-DOTC 39b235963a saetor skills 8 months ago
FatBoy-DOTC b142cded72 saetor skills 8 months ago
FatBoy-DOTC 0e7281fe6a saetor skills 8 months ago
FatBoy-DOTC fe39454113 saetor skills 8 months ago
FatBoy-DOTC 74cf9d16c5 saetor skills 8 months ago
FatBoy-DOTC 4b2563e4a1 saetor skills 8 months ago
FatBoy-DOTC 1e19e10755 saetor granted skills 8 months ago
FatBoy-DOTC 0c3e072e0e Backend Saetor work 8 months ago
FatBoy-DOTC aa10a4c9ac Backend Saetor work 8 months ago
FatBoy-DOTC 75947db6e5 Backend Saetor work 8 months ago
FatBoy-DOTC 9d28601761 Backend Saetor work 8 months ago
FatBoy-DOTC e8ca4863d5 Backend Saetor work 8 months ago
FatBoy-DOTC a8bfcd08cc Backend Saetor work 8 months ago
FatBoy-DOTC 8ae4ded83b safe guards dont aggro players 8 months ago
FatBoy-DOTC 5023d6bb73 Merge branch 'lakebane-mines' into lakebane-custom-races 8 months ago
FatBoy-DOTC ca47022d88 stats alteration for custom race 8 months ago
FatBoy-DOTC c304a59d95 See Invis Bug Addressed 8 months ago
FatBoy-DOTC 7dfc1dea0f fortitudes handled after resist calculations 8 months ago
FatBoy-DOTC 77fda6a18c altered atr vs def formula 8 months ago
FatBoy-DOTC b343f4d6d7 resource dupe 8 months ago
FatBoy-DOTC 77e9a4d9bf resource dupe 8 months ago
FatBoy-DOTC 512aba5cd9 resource dupe 8 months ago
FatBoy-DOTC 2d93e408c3 resource dupe 8 months ago
FatBoy-DOTC edd7be8734 resource dupe 8 months ago
FatBoy-DOTC 8c6637663d resource dupe 8 months ago
FatBoy-DOTC 4cb0f28e57 resource dupe 8 months ago
FatBoy-DOTC 4d21fc0353 daily reboot removal 8 months ago
FatBoy-DOTC 4d28cd2b25 daily reboot 8 months ago
FatBoy-DOTC 1be6884ab0 conc removal 8 months ago
FatBoy-DOTC 74eff825b0 daily auto reboot 8 months ago
FatBoy-DOTC 1ae1deabdc daily auto reboot 8 months ago
FatBoy-DOTC 54b7bcf907 pet buffs castable again 8 months ago
FatBoy-DOTC a8c768931e 2am daily reboot 8 months ago
FatBoy-DOTC 71687e39c8 2am daily reboot 8 months ago
FatBoy-DOTC 678e45ce6b 2am daily reboot 8 months ago
FatBoy-DOTC 5bfeafe8bf fixed scourge mother vorg drops 8 months ago
FatBoy-DOTC a492e833e8 disc droppers spawn 6 hours apart 8 months ago
FatBoy-DOTC 92436be3f9 vorg droppers increased difficulty 8 months ago
FatBoy-DOTC 8890e02981 mobs attack pets 8 months ago
FatBoy-DOTC 6fe8b80c87 remove resource drop server announcement 8 months ago
FatBoy-DOTC c2e0979dc3 drop rate work 8 months ago
FatBoy-DOTC 6023022077 drop rate work 8 months ago
FatBoy-DOTC 9a570de54c contract and rune drop work 8 months ago
FatBoy-DOTC d58d8ee67c Lizardman Race Added 9 months ago
FatBoy-DOTC 132addc0a9 Lizardman Race Added 9 months ago
FatBoy-DOTC 8bfba1b3a5 Saetor Race Added 9 months ago
FatBoy-DOTC 0d45bb5bc1 Saetor Race Added 9 months ago
FatBoy-DOTC 6ea4717263 custom races 9 months ago
FatBoy-DOTC 7153216f09 custom races 9 months ago
FatBoy-DOTC 114ccfee9d mob aggro 9 months ago
FatBoy-DOTC 23e0a0dcc7 mob aggro 9 months ago
FatBoy-DOTC b2a3eb3e6e uniform disc dropper respawns 9 months ago
FatBoy-DOTC 13a4ba6e0e terraformsize 9 months ago
FatBoy-DOTC eaa8828a24 terraformsize 9 months ago
FatBoy-DOTC 6bbe9317ac terraformsize 9 months ago
FatBoy-DOTC 0c56631b92 terraformsize 9 months ago
FatBoy-DOTC a81810d751 terraformsize 9 months ago
FatBoy-DOTC 9c75e7defe terraformsize 9 months ago
FatBoy-DOTC 6aba5be67a login crash bug 9 months ago
FatBoy-DOTC 9c867ee281 login crash bug 9 months ago
FatBoy-DOTC afc91e22e5 login crash bug 9 months ago
FatBoy-DOTC 6dac5c7ec8 login crash bug 9 months ago
FatBoy-DOTC c6c4a128a2 login crash bug 9 months ago
FatBoy-DOTC 28fa81962d login crash bug 9 months ago
FatBoy-DOTC 0759c56b14 login crash bug 9 months ago
FatBoy-DOTC 64e6e035c1 login crash bug 9 months ago
FatBoy-DOTC 31bf62a678 login crash bug 9 months ago
FatBoy-DOTC a924e4c876 login crash bug 9 months ago
FatBoy-DOTC 38e6bdf92d login crash bug 9 months ago
FatBoy-DOTC 69dd7bcc37 login crash bug 9 months ago
FatBoy-DOTC f26e8e4559 login crash bug 9 months ago
FatBoy-DOTC 16e8df3daf login crash bug 9 months ago
FatBoy-DOTC c98c64262b resource stacking bug 9 months ago
FatBoy-DOTC a6cf68ef07 resource stacking bug 9 months ago
FatBoy-DOTC 3b179a5703 resource stacking bug 9 months ago
FatBoy-DOTC 0638028a59 resource stacking bug 9 months ago
FatBoy-DOTC 912ebd4742 resource stacking bug 9 months ago
FatBoy-DOTC c1440f8f9e resource stacking bug 9 months ago
FatBoy-DOTC 8d32927241 resource stacking bug 9 months ago
FatBoy-DOTC d058e7506a resource stacking bug 9 months ago
FatBoy-DOTC dd548acfe1 resource stacking bug 9 months ago
FatBoy-DOTC acc0c1dc46 zerg test fixes 9 months ago
FatBoy-DOTC d0c74e0641 30 minute mine windows 9 months ago
FatBoy-DOTC 095a26e1d9 30 minute mine windows 9 months ago
FatBoy-DOTC 1cb0848690 30 minute mine windows 9 months ago
FatBoy-DOTC 60a7b395e5 30 minute mine windows 9 months ago
FatBoy-DOTC 09e57852f4 30 minute mine windows 9 months ago
FatBoy-DOTC c2fe156680 30 minute mine windows 9 months ago
FatBoy-DOTC b9545dbf76 30 minute mine windows 9 months ago
FatBoy-DOTC 8ce7c09000 30 minute mine windows 9 months ago
FatBoy-DOTC 9107540212 30 minute mine windows 9 months ago
FatBoy-DOTC 24bc0097be 30 minute mine windows 9 months ago
FatBoy-DOTC 7175f79bfe mine HP set to custom value after rebuild 9 months ago
FatBoy-DOTC 230a7460cd PC null catch 9 months ago
FatBoy-DOTC e172d3f2d0 Modified Vorg Boots 9 months ago
FatBoy-DOTC 2e78f44640 nation chat kill messages 9 months ago
FatBoy-DOTC 5c46af3c52 Bounty Hunter Eyes Fix 9 months ago
FatBoy-DOTC b9ec8fd540 vorg HA fix 9 months ago
FatBoy-DOTC d3bf19426c vorg HA fix 9 months ago
FatBoy-DOTC 734b46d816 vorg HA fix 9 months ago
FatBoy-DOTC 11310a5b64 vorg HA fix 9 months ago
FatBoy-DOTC 067f8f8d89 60 second default logout timer 9 months ago
FatBoy-DOTC afa9ddf89e allow BH and huntsman on all but priest 9 months ago
FatBoy-DOTC a6cee850a6 allow BH and huntsman on all but priest 9 months ago
FatBoy-DOTC 5f5616fd2d guards 9 months ago
FatBoy-DOTC dcd37bce13 guards 9 months ago
FatBoy-DOTC d438440556 guards 9 months ago
FatBoy-DOTC 9f58e211a8 guards 9 months ago
FatBoy-DOTC f52e67e80c guards 9 months ago
FatBoy-DOTC c520263179 combat bug fix 9 months ago
FatBoy-DOTC c9f246afec combat bug fix 9 months ago
FatBoy-DOTC cdf7fcc54d combat bug fix 9 months ago
FatBoy-DOTC 3553291d1d combat bug fix 9 months ago
FatBoy-DOTC 67ce60124f combat bug fix 9 months ago
FatBoy-DOTC 0e6ee13926 combat bug fix 9 months ago
FatBoy-DOTC 5b0ba790b3 combat bug fix 9 months ago
FatBoy-DOTC b53f2c2824 combat bug fix 9 months ago
FatBoy-DOTC b9a87ba407 combat bug fix 9 months ago
FatBoy-DOTC e3ed34a04b combat bug fix 9 months ago
FatBoy-DOTC 6915e30eb2 combat bug fix 9 months ago
FatBoy-DOTC e9c7cc8e04 combat bug fix 9 months ago
FatBoy-DOTC 90feaea89e combat bug fix 9 months ago
FatBoy-DOTC 174bceb49e combat bug fix 9 months ago
FatBoy-DOTC e3ec8d7737 combat bug fix 9 months ago
FatBoy-DOTC c44a7eafab combat bug fix 9 months ago
FatBoy-DOTC 879b52c7c7 combat bug fix 9 months ago
FatBoy-DOTC 1fe3f7dfb1 combat bug fix 9 months ago
FatBoy-DOTC 2c8517a1e4 combat bug fix 9 months ago
FatBoy-DOTC 4eff71f288 combat bug fix 9 months ago
FatBoy-DOTC 349b88f142 investigate vorg LA hood drop never occurring 9 months ago
FatBoy-DOTC 6b8d1e6f71 chinese mines moved earlier by 1 hour 9 months ago
FatBoy-DOTC 79022f0e3e enchant stripping bug 9 months ago
FatBoy-DOTC 523eb8529f enchant stripping bug 9 months ago
FatBoy-DOTC 5684fb6ce1 enchant stripping bug 9 months ago
FatBoy-DOTC feb23e63fe zerg mechanic overhaul 9 months ago
FatBoy-DOTC ab5943e4b2 zerg mechanic overhaul 9 months ago
FatBoy-DOTC 02d22f0881 Mines no longer produce hourly resources 9 months ago
FatBoy-DOTC 9b555c0259 Zerg multiplier reduction method 9 months ago
FatBoy-DOTC 6a4e0e32cc hard set mine windows 9 months ago
FatBoy-DOTC 5713dab8cf hard set mine windows 9 months ago
FatBoy-DOTC 71b7fd5c1b hard set mine windows 9 months ago
FatBoy-DOTC 39e6917ae8 hard set mine windows 9 months ago
FatBoy-DOTC 86c33c195c hard set mine windows 9 months ago
FatBoy-DOTC ad6fca61ed hard set mine windows 9 months ago
FatBoy-DOTC f2b91f875f hard set mine windows 9 months ago
FatBoy-DOTC ab2b7092fd hard set mine windows 9 months ago
FatBoy-DOTC d39137d900 hard set mine windows 9 months ago
FatBoy-DOTC d906d49e51 hard set mine windows 9 months ago
FatBoy-DOTC 54c48d398b hard set mine windows 9 months ago
FatBoy-DOTC 98fe77b148 hard set mine windows 9 months ago
FatBoy-DOTC 9ee3b9d7bb hard set mine windows 9 months ago
FatBoy-DOTC d6dd61e9c5 pet debugging 9 months ago
FatBoy-DOTC d92e5d4a45 pet debugging 9 months ago
FatBoy-DOTC d065e9ffc8 pet debugging 9 months ago
FatBoy-DOTC 2b63ed08b8 pet debugging 9 months ago
FatBoy-DOTC 50fb0d39c5 pet debugging 9 months ago
FatBoy-DOTC bb91502cb4 pet debugging 9 months ago
FatBoy-DOTC 8f6e13102d pet debugging 9 months ago
FatBoy-DOTC 0679ffcaec pet debugging 9 months ago
FatBoy-DOTC 9ab286166e zerg multiplier debug text 9 months ago
FatBoy-DOTC 0d4e8f3c9a pet buff trouble shooting 9 months ago
FatBoy-DOTC 02a78d538c pet buff trouble shooting 9 months ago
FatBoy-DOTC 9e74954422 pet buff trouble shooting 9 months ago
FatBoy-DOTC a267382481 pet buff trouble shooting 9 months ago
FatBoy-DOTC 0910b7184c pet buff trouble shooting 9 months ago
FatBoy-DOTC 297fe8c7a2 pet buff trouble shooting 9 months ago
FatBoy-DOTC 76405cb968 pet buff trouble shooting 9 months ago
FatBoy-DOTC a38e5b478a pet buff trouble shooting 9 months ago
FatBoy-DOTC 4540e5c770 castable enchants removed when being traded or banked or vaulted 9 months ago
FatBoy-DOTC aef12b2bb4 tree overlap reduction 9 months ago
FatBoy-DOTC a562af57e9 boon level based on votary rank 9 months ago
FatBoy-DOTC 03470c699d vorg stats 9 months ago
FatBoy-DOTC f777f480ad vorg stats 9 months ago
FatBoy-DOTC ce542ce319 combat problem chasing 9 months ago
FatBoy-DOTC 7ff879ea64 perfect conc 9 months ago
FatBoy-DOTC e4274994ff combat null fix 9 months ago
FatBoy-DOTC 547d222a2d test 9 months ago
FatBoy-DOTC 5159afc704 bugfix: null combat target 9 months ago
FatBoy-DOTC 3a771ac585 bane cap sized persist through reboots 9 months ago
FatBoy-DOTC 97fcbd8608 bane mechanic for zerg measures 9 months ago
FatBoy-DOTC 39aec46220 bane mechanic for zerg measures 9 months ago
FatBoy-DOTC 1db30e3c6b bane mechanic for zerg measures 9 months ago
FatBoy-DOTC 34cb943595 Revert "randomized mine times" 9 months ago
FatBoy-DOTC bef49fc720 Revert "randomized mine times" 9 months ago
FatBoy-DOTC 2bbdeb89ff Revert "randomized mine times" 9 months ago
FatBoy-DOTC 2f4287783e randomized mine times 9 months ago
FatBoy-DOTC 802d46d66e randomized mine times 9 months ago
FatBoy-DOTC de3f1cf004 randomized mine times 9 months ago
FatBoy-DOTC 90e85d3e46 taxing removed from r8 cities 9 months ago
FatBoy-DOTC 2e104741ba bounty hunter eyes see invis 9 months ago
FatBoy-DOTC 6461efa1a2 modified production values 9 months ago
FatBoy-DOTC 320ea7e81c planting on OB and Mael 9 months ago
FatBoy-DOTC 05eb8cd961 Mine Changes 9 months ago
FatBoy-DOTC 9909216e27 Mine Changes 9 months ago
FatBoy-DOTC 33a369821a Mine Changes 9 months ago
FatBoy-DOTC 6e93e40454 Mine Changes 9 months ago
FatBoy-DOTC c14fd84d96 Resource Merchant 9 months ago
FatBoy-DOTC 56c16fc06e Resource Merchant 9 months ago
FatBoy-DOTC 71274d25d0 Resource Merchant 9 months ago
FatBoy-DOTC 9d75116790 Resource Merchant 9 months ago
FatBoy-DOTC 629fce8cff Resource Merchant 9 months ago
FatBoy-DOTC 7fefd53be2 Resource Merchant 9 months ago
FatBoy-DOTC 8aab20caf4 Resource Merchant 9 months ago
FatBoy-DOTC 14ad0b7599 Resource Merchant 9 months ago
FatBoy-DOTC 267549ce15 Resource Merchant 9 months ago
FatBoy-DOTC 6e14f723da Resource Merchant 9 months ago
FatBoy-DOTC 46a9dad407 Resource Merchant 9 months ago
FatBoy-DOTC e89e2f51b7 Merge branch 'lakebane-zerg' into lakebane-master 9 months ago
FatBoy-DOTC 40290bdf97 test rune vendor 9 months ago
FatBoy-DOTC a37e30c550 test rune vendor 9 months ago
FatBoy-DOTC 0440aabd1e test rune vendor 9 months ago
FatBoy-DOTC fbc408f617 test rune vendor 9 months ago
FatBoy-DOTC 0f7410f55f test rune vendor 9 months ago
FatBoy-DOTC f82a19f243 test rune vendor 9 months ago
FatBoy-DOTC c9428d2b56 test rune vendor 9 months ago
FatBoy-DOTC c4bd766156 test rune vendor 9 months ago
FatBoy-DOTC 44cd8d0013 resource stacking update 9 months ago
FatBoy-DOTC 84a75f6b83 resource stacking update 9 months ago
FatBoy-DOTC be902cf09c loot update 9 months ago
FatBoy-DOTC 0289b5087d loot update 9 months ago
FatBoy-DOTC b5f36b60f7 loot update 9 months ago
FatBoy-DOTC 43409d2e4b booty sim 1000 iteration 9 months ago
FatBoy-DOTC 547de5033b rune and contract rate update 9 months ago
FatBoy-DOTC 2c7baaf2ac rune and contract rate update 9 months ago
FatBoy-DOTC 351437b46b rune and contract rate update 9 months ago
FatBoy-DOTC 1e9f1685da cannot delete gold 9 months ago
FatBoy-DOTC d9a03ebf93 resources auto stack when entering inventory 9 months ago
FatBoy-DOTC 666e3d5479 boons become nation friendly 9 months ago
FatBoy-DOTC 7efd276d52 grant conc pot when level set to 10 9 months ago
FatBoy-DOTC 46826163be test mechanics removed 9 months ago
FatBoy-DOTC e70b52d88c test mechanics removed 9 months ago
FatBoy-DOTC 106dd87216 zerg mechanic tweak 9 months ago
FatBoy-DOTC c964115c1e resource merchant work 9 months ago
FatBoy-DOTC 8c022596a7 resource merchant work 9 months ago
FatBoy-DOTC 2de240dd60 resource merchant work 9 months ago
FatBoy-DOTC 8e8876587c resource merchant work 9 months ago
FatBoy-DOTC 8f0e19a10c resource merchant work 9 months ago
FatBoy-DOTC 2222a335a1 resource merchant work 9 months ago
FatBoy-DOTC a7bc1d5a6a resource merchant work 9 months ago
FatBoy-DOTC 0e61f0e7b8 resource merchant work 9 months ago
FatBoy-DOTC 0d256c17b5 resource merchant work 9 months ago
FatBoy-DOTC 571ad4b466 resource merchant work 9 months ago
FatBoy-DOTC 9e7a8bef4a resource merchant work 9 months ago
FatBoy-DOTC 669db7f021 resource merchant work 9 months ago
FatBoy-DOTC 13513bcf2a resource merchant work 9 months ago
FatBoy-DOTC 149630ef5a resource merchant work 9 months ago
FatBoy-DOTC 257d864132 resource merchant work 9 months ago
FatBoy-DOTC 6247332f83 resource merchant work 9 months ago
FatBoy-DOTC e5d606fe8a resource merchant work 9 months ago
FatBoy-DOTC dc1720b38b resource merchant added 9 months ago
FatBoy-DOTC 7b5de5f3f5 runey work > profit slider 9 months ago
FatBoy-DOTC 7de9bdbbe4 runey work > profit slider 9 months ago
FatBoy-DOTC 88123ad99a runey work > profit slider 9 months ago
FatBoy-DOTC 0437f10bf9 runey work > profit slider 9 months ago
FatBoy-DOTC e93f09c184 runey work > profit slider 9 months ago
FatBoy-DOTC ee60f88e62 add UUID to slottest hireling list 9 months ago
FatBoy-DOTC 2d4d0f79f8 add UUID to slottest hireling list 9 months ago
FatBoy-DOTC 664eb04658 adjust "runey" location 9 months ago
FatBoy-DOTC 1fc9e6251e adjust "runey" location 9 months ago
FatBoy-DOTC 7eba9501a6 adjust "runey" location 9 months ago
FatBoy-DOTC 0eb67c83a3 stat runes junk for 500k each 9 months ago
FatBoy-DOTC 6668c01185 boxed characters to have pathfinding effect applied at all times 9 months ago
FatBoy-DOTC 76b89d898a added rune merchant 9 months ago
FatBoy-DOTC 6a28574471 adjusted and scaled mine hitpoints 9 months ago
FatBoy-DOTC 11faa98503 reduced reources drops 9 months ago
FatBoy-DOTC a32ba5e262 track range changes 9 months ago
FatBoy-DOTC 558b645274 erro log fix and zerg mechanic manager 9 months ago
FatBoy-DOTC a1115e728c custom rates for contracts runes and glass 9 months ago
FatBoy-DOTC 409f8aa847 various console error fixes 9 months ago
FatBoy-DOTC 78cf95d290 zerg mechanic work 9 months ago
FatBoy-DOTC 2c78e0728a Revert "Enchantment Exploring" 9 months ago
FatBoy-DOTC 31e56b4da6 Revert "zerg mechanic work" 9 months ago
FatBoy-DOTC ba3fd7215b zerg mechanic work 9 months ago
FatBoy-DOTC c08a93e85d Enchantment Exploring 9 months ago
FatBoy-DOTC b63a5fa1c1 Enchantment Exploring 9 months ago
FatBoy-DOTC c7494e8a9d Lore Rules 9 months ago
FatBoy-DOTC f69fde8a3a all items now AutoID 9 months ago
FatBoy-DOTC 05dace9194 asset windows to display correct modified maintenance 9 months ago
FatBoy-DOTC ae975b7591 asset windows to display correct modified maintenance 9 months ago
FatBoy-DOTC 02f376f418 inventory junking 9 months ago
FatBoy-DOTC 3c2d3782c2 inventory junking 9 months ago
FatBoy-DOTC daaa1d9ece inventory junking 9 months ago
FatBoy-DOTC 747056bc8c replace glass drop with HZ table drop 9 months ago
FatBoy-DOTC b6760d0775 new NPC for ToL support 9 months ago
FatBoy-DOTC ba4ab458a0 new NPC for ToL support 9 months ago
FatBoy-DOTC c04fd62e71 new NPC for ToL support 9 months ago
FatBoy-DOTC 97c063661a new NPC for ToL support 9 months ago
FatBoy-DOTC 62205150a7 new NPC for ToL support 9 months ago
FatBoy-DOTC 9f5bdce571 new NPC for ToL support 9 months ago
FatBoy-DOTC 22a0cb2474 Tol can now support 4 max slost at r7/8 9 months ago
FatBoy-DOTC 96c1e34a08 Tol can now support 4 max slost at r7/8 9 months ago
FatBoy-DOTC 3dc7f7c9ed remove combat/nocombat requirement form powers 9 months ago
FatBoy-DOTC cd1b15834a boxshroud fixes 9 months ago
FatBoy-DOTC 8a0303e0f5 boxshroud fixes 9 months ago
FatBoy-DOTC aa0e993038 boxshroud fixes 9 months ago
FatBoy-DOTC 3ef3a0c37c boxshroud fixes 9 months ago
FatBoy-DOTC a6a2629fd5 boxshroud fixes 9 months ago
FatBoy-DOTC e414304e94 boxshroud fixes 9 months ago
FatBoy-DOTC f5b08c1868 mines set to 5 cap, zerg mechanic buff/debuff introduced 9 months ago
FatBoy-DOTC 0bdcfe7b51 mines set to 5 cap, zerg mechanic buff/debuff introduced 9 months ago
FatBoy-DOTC c640caeb54 Zerg Mechanic Completed 9 months ago
FatBoy-DOTC 3d33a16d06 multiplier display 9 months ago
FatBoy-DOTC f4778d4f48 multiplier display 9 months ago
FatBoy-DOTC c8246ff317 multiplier display 9 months ago
FatBoy-DOTC 7a3a9c6254 multiplier display 9 months ago
FatBoy-DOTC 545796e297 players removed when leaving mines 9 months ago
FatBoy-DOTC 6b4eff4d4c players removed when leaving mines 9 months ago
FatBoy-DOTC 457ed4f4e6 mine show in system chat updated numbers 10 months ago
FatBoy-DOTC 8f2847a527 Mines calculate local players by guild 10 months ago
FatBoy-DOTC 7f5df22a14 mines to set random cap size at server boot 5/10/20 10 months ago
FatBoy-DOTC 4fd737e3ec mines to set random cap size at server boot 5/10/20 10 months ago
FatBoy-DOTC e891d353ba Vorg mobs drop random piece of set and spawn randomly between 5 and 45 minutes after death 10 months ago
FatBoy-DOTC c5376d24a5 NPC 5 minute upgrades 10 months ago
FatBoy-DOTC 85bf30cbdd remove DS on login when no other boxes logged in 10 months ago
FatBoy-DOTC 775410b00a Revert "5 minute upgrades for NPCs" 10 months ago
FatBoy-DOTC a8275c7cc7 Revert "5 minute upgrades for NPCs" 10 months ago
FatBoy-DOTC 03025e7f00 5 minute upgrades for initial placement 10 months ago
FatBoy-DOTC 1b7be0365a 5 minute upgrades for NPCs 10 months ago
FatBoy-DOTC de772237c9 5 minute upgrades for NPCs 10 months ago
FatBoy-DOTC e60c635c39 announce rates at login 10 months ago
FatBoy-DOTC 6db9f115b1 announce rates at login 10 months ago
FatBoy-DOTC 3f303e1c9e tweak 10 months ago
FatBoy-DOTC c0ec747e43 any mob over level 30 has a small chance to drop glass 10 months ago
FatBoy-DOTC b583034b4e hotzone removed from game 10 months ago
FatBoy-DOTC 3360a034b2 maintenenace only ran for ToL, 3,000,000 cost, recycling daily when payment isnt received 10 months ago
FatBoy-DOTC 668df83e33 boxed character fix, safezone equipment damage fix, trade fix, creation experience fix, sub guild limits removed 10 months ago
FatBoy-DOTC fa3234d0f5 xp and conc granted for noob 10 months ago
FatBoy-DOTC e8973ecb6d xp and conc granted for noob 10 months ago
FatBoy-DOTC 134aecf4d7 xp and conc granted for noob 10 months ago
FatBoy-DOTC 08cb49f641 xp and conc granted for noob 10 months ago
FatBoy-DOTC 2a06015a0e xp and conc granted for noob 10 months ago
FatBoy-DOTC 4559519512 xp and conc granted for noob 10 months ago
FatBoy-DOTC 42b2f886d5 xp and conc granted for noob 10 months ago
FatBoy-DOTC 0ce7f64d94 xp and conc granted for noob 10 months ago
FatBoy-DOTC 5fbd5ebb5c xp and conc granted for noob 10 months ago
FatBoy-DOTC 8fed2d3506 xp and conc granted for noob 10 months ago
FatBoy-DOTC e119f62049 xp and conc granted for noob 10 months ago
FatBoy-DOTC 228b0c74a9 xp and conc granted for noob 10 months ago
FatBoy-DOTC c73688de4d xp and conc granted for noob 10 months ago
FatBoy-DOTC 71288d0203 death in safe zone no longer causes item damage 10 months ago
FatBoy-DOTC db229dcf74 1000 unit missed spot 10 months ago
FatBoy-DOTC 2e4bf0823c standard 1000 inventory weight && fixed XP rates 5x/10x 10 months ago
FatBoy-DOTC d70f9f6dc3 box tweaking 10 months ago
FatBoy-DOTC a9ecf76585 deathshroud application 10 months ago
FatBoy-DOTC ea3c571485 deathshroud application 10 months ago
FatBoy-DOTC 5840de216d deathshroud application 10 months ago
FatBoy-DOTC c7d26f9dcc box limit adjustment 10 months ago
FatBoy-DOTC 5287b993fa collection of players for cities and mines 10 months ago
FatBoy-DOTC 33bd1a0906 characters logged in exceeding max:1 will be given PR999 death shroud 10 months ago
FatBoy-DOTC 5cd86bc033 characters logged in exceeding max:1 will be given PR999 death shroud 10 months ago
MagicBot 6641651f3c Unused method removed. 1 year ago
MagicBot dbf164bfb2 bonus code removal 1 year ago
MagicBot 8a617c3008 Siege minion spawn time set to 15m. 1 year ago
FatBoy-DOTC a50a2430ba hate value for chants to affect mobs in range 1 year ago
FatBoy-DOTC 5c3c552288 usage of AIAgentType for default patrol points 1 year ago
FatBoy-DOTC 69fdddfc71 hate value fix 1 year ago
FatBoy-DOTC db5b988275 usage of AIAgentType for pet checks in run after load 1 year ago
FatBoy-DOTC 4284757035 pet level set in run after load removed 1 year ago
FatBoy-DOTC b93a47acc0 pet death and dismissal fix 1 year ago
MagicBot d59f9857ce Cleanup in pet minion 1 year ago
FatBoy-DOTC 8ce212b74b Merge remote-tracking branch 'origin/mob-refactor2' into mob-refactor2 1 year ago
FatBoy-DOTC e78aea5735 Assign patrol points added as static method to NPC manager 1 year ago
MagicBot 9a3c5c3f40 Siege minion assigned UUID. 1 year ago
FatBoy-DOTC 60ca3f9c34 remove siege minion 1 year ago
FatBoy-DOTC e7e740dff1 blocked player character specific block in minion training message handler 1 year ago
MagicBot 8343a98d77 Minion added to map after runafterload. 1 year ago
MagicBot 5862039a00 Minion added to map after runafterload. 1 year ago
MagicBot 8af989b75f Fix is patrol logic bloc conditional. 1 year ago
MagicBot 08d0e5ff75 Logic isn't needed here. 1 year ago
MagicBot 5196d10e5c Logic isn't needed here. 1 year ago
MagicBot 3392ec463d Removed unused methods. 1 year ago
MagicBot 33529404cf Logic fix in siege minions. 1 year ago
MagicBot 00e7a36013 Logic fix in siege minions. 1 year ago
FatBoy-DOTC 3060b394ab removed siegeminion map from NPC 1 year ago
MagicBot a43d9022fe Siege engine slot override. 1 year ago
FatBoy-DOTC 6abdc68ca5 removed un-needed cast to player character for pets 1 year ago
FatBoy-DOTC 61c66b0e96 trebs slot in proper locations 1 year ago
FatBoy-DOTC 36cc23457a optimized slot for siege engines 1 year ago
FatBoy-DOTC d573b238de refactored mob get/set owner 1 year ago
FatBoy-DOTC 8afe25fe85 siege minions added to arty captain minion map 1 year ago
MagicBot f80647ff0d Spawn time set to 15s for debug. 1 year ago
MagicBot 7e64cbabf8 Update to slotting logic. 1 year ago
MagicBot 14a06410ae Update to slotting logic. 1 year ago
MagicBot 85c2a4f4f0 Add all as hirelings 1 year ago
FatBoy-DOTC da9e211ec7 SiegeEngine enum and logic added 1 year ago
MagicBot a81070c471 Pet level += 20 to conform to 24.3 1 year ago
MagicBot e3ad7efa4f Method renamed for new convention. 1 year ago
MagicBot a4dafd7155 Unused variable in signature. 1 year ago
MagicBot 645aec853e Bindloc not adjusted for pets. 1 year ago
MagicBot d8d5e4a3c4 Name set to default. 1 year ago
MagicBot 7a48c04057 Mobbase set properly. 1 year ago
MagicBot 64aaaa707e Behaviour type set for pets. 1 year ago
MagicBot 445d40dc5f Bonus code removed. 1 year ago
MagicBot ebdcb531f2 AI methods moved to ai class. 1 year ago
MagicBot c9cdb891d6 Cleanup of ownerNPC mess. 1 year ago
MagicBot f5c6c002a8 Unused method removed. 1 year ago
MagicBot d171c6bb9a Unused method removed. 1 year ago
MagicBot 1c81a4faed Wall archers static reverted. 1 year ago
MagicBot e7d1d5cb71 Constructor removed. 1 year ago
MagicBot 060d831d50 Comment for clarity. 1 year ago
MagicBot 316bd6dd01 Siege engines use slot system. 1 year ago
MagicBot 34081e5903 Ordinal comparison fix. 1 year ago
MagicBot e2d843b65e Signature refactor. 1 year ago
MagicBot a796f5fe4b More siege engine work. 1 year ago
MagicBot 51ee41c773 use of SiegeEngine Behaviour Type 1 year ago
MagicBot 7e5ed3efe5 sqrMagnitude not sqrRoot 1 year ago
MagicBot 8dd25ac315 Minions inherit patrol points form barracks. 1 year ago
MagicBot 1cdaa58e7a Wall archers set to static grid type. 1 year ago
MagicBot fa3aa24a3d Update to minion building/location mechanic. 1 year ago
MagicBot 091431d95b Dynamic set in all constructors. 1 year ago
MagicBot 1ecf0122ab Unused variable removed. 1 year ago
MagicBot 79980a1725 NoID constructor removed. 1 year ago
MagicBot 8badcc3f6e Refactored out redundant stat-xyz variables. 1 year ago
MagicBot 4d6e57257c Unused methods removed. 1 year ago
MagicBot a7a93b8500 Tweak to bindloc for minions. 1 year ago
MagicBot 85cc34fb4c AIinfo updated. 1 year ago
MagicBot 772a996b6e Tweak to behavior type setup. 1 year ago
MagicBot e67eff822d Propagate guardedCity. 1 year ago
MagicBot c39ed6120f Cleanup of bind/loc logic. 1 year ago
MagicBot c38f4e6543 Mask only needs be set once. 1 year ago
MagicBot 098433b697 Needs contract null check 1 year ago
MagicBot c8e20c905b Add to cache before setloc 1 year ago
MagicBot bd2446ba0a Minion uuid set pre configure 1 year ago
MagicBot c179e4aaf3 Don't override level or name for minions. 1 year ago
MagicBot 2f8de2a919 Worthless collection only used in 2 places. 1 year ago
MagicBot 338110973d Mobbase cannot be null. 1 year ago
MagicBot 3c9c4495bc playerGuard = true. 1 year ago
MagicBot 93476f782c Bind loc not overwritten. 1 year ago
MagicBot 3aec6ee578 More minion setup work. 1 year ago
MagicBot 3bca76d4c8 Setloc to spawn minion. 1 year ago
MagicBot b9d6f35aac Unused variable. 1 year ago
MagicBot 9b6959414a More flushing out minion support. 1 year ago
MagicBot 400dd6aa5e More granular error reporting. 1 year ago
MagicBot 14af2f6efd Minion spawning re-enabled for refactoring. 1 year ago
MagicBot 0a2de9e0d5 Contract handling cleanup. 1 year ago
MagicBot 89bfad78a6 Contract handling cleanup. 1 year ago
MagicBot 52486fa278 Contract handling cleanup. 1 year ago
MagicBot dc0e14eb21 AI added earlier in sequence for availability. 1 year ago
MagicBot 70278374e7 manager init moved to the top of method. 1 year ago
MagicBot ac3588c76a manager init moved to the top of method. 1 year ago
MagicBot ab335aef2a Enums are fragile. 1 year ago
MagicBot 719c855bdb Cleanup of inventoryManager usage. 1 year ago
MagicBot f283e50018 Disabled minions for now. 1 year ago
MagicBot 99b952ee28 Refactor towards new constructor. 1 year ago
MagicBot 24639b62c0 Refactor towards new constructor. 1 year ago
MagicBot 573cc531bf Refactor towards new constructor. 1 year ago
MagicBot 29e24bae93 Unused constructor removed. 1 year ago
MagicBot 22e4cc07c0 Separate pet and siege behaviour types. 1 year ago
MagicBot 9264347698 Minions inherit enemy/notenemy from captain. 1 year ago
MagicBot 579c26ac59 InitializeMob removed. 1 year ago
MagicBot ef577dd313 Removed catch to propagate error. 1 year ago
MagicBot 62c7e52487 Starting to whittle away at initmob method. 1 year ago
MagicBot 3534ac6477 Starting to whittle away at initmob method. 1 year ago
MagicBot 1738f7b311 Starting to whittle away at initmob method. 1 year ago
MagicBot eb25caec81 Object creation moved out of rs const. 1 year ago
MagicBot a6c60e2c04 Merge remote-tracking branch 'origin/master' into mobile-cleanup 1 year ago
MagicBot adafbdf6d3 Duplicate building and building ID values. 1 year ago
MagicBot 7eab14938d Exception for siege when slotting. 1 year ago
MagicBot 039e55673b Exception for siege when slotting. 1 year ago
MagicBot ec3a9b6cb4 Minions don't have contracts. 1 year ago
MagicBot 17a6494b2b Unused code. 1 year ago
MagicBot 0b05c7074f Slot all agents but true mobiles. 1 year ago
MagicBot 876ccc7cbf New constructor created. 1 year ago
MagicBot bdf14b8f24 Ordinal comparisons refactored. 1 year ago
MagicBot 43375a6f5b Only mobiles with contracts can be slotted. 1 year ago
MagicBot e00328ae13 Siege pets use slotting mechanic. 1 year ago
MagicBot 07c553294b Mobiles use new slotting mechanic. 1 year ago
  1. 60
      src/engine/Enum.java
  2. 10
      src/engine/InterestManagement/InterestManager.java
  3. 8
      src/engine/db/handlers/dbBlueprintHandler.java
  4. 1
      src/engine/db/handlers/dbCharacterSkillHandler.java
  5. 3
      src/engine/db/handlers/dbHandlerBase.java
  6. 68
      src/engine/db/handlers/dbItemBaseHandler.java
  7. 26
      src/engine/db/handlers/dbItemHandler.java
  8. 40
      src/engine/db/handlers/dbMineHandler.java
  9. 20
      src/engine/db/handlers/dbMobBaseHandler.java
  10. 39
      src/engine/db/handlers/dbMobHandler.java
  11. 18
      src/engine/db/handlers/dbResistHandler.java
  12. 37
      src/engine/db/handlers/dbRuneBaseHandler.java
  13. 7
      src/engine/db/handlers/dbSkillBaseHandler.java
  14. 4
      src/engine/devcmd/cmds/AddMobCmd.java
  15. 39
      src/engine/devcmd/cmds/AddNPCCmd.java
  16. 19
      src/engine/devcmd/cmds/EnchantCmd.java
  17. 2
      src/engine/devcmd/cmds/FlashMsgCmd.java
  18. 13
      src/engine/devcmd/cmds/InfoCmd.java
  19. 8
      src/engine/devcmd/cmds/MakeItemCmd.java
  20. 5
      src/engine/devcmd/cmds/MineActiveCmd.java
  21. 3
      src/engine/devcmd/cmds/PrintResistsCmd.java
  22. 7
      src/engine/devcmd/cmds/PrintStatsCmd.java
  23. 4
      src/engine/devcmd/cmds/PurgeObjectsCmd.java
  24. 4
      src/engine/devcmd/cmds/RemoveObjectCmd.java
  25. 2
      src/engine/devcmd/cmds/SetAdminRuneCmd.java
  26. 2
      src/engine/devcmd/cmds/SetBaseClassCmd.java
  27. 7
      src/engine/devcmd/cmds/SetLevelCmd.java
  28. 2
      src/engine/devcmd/cmds/SetPromotionClassCmd.java
  29. 2
      src/engine/devcmd/cmds/SetRuneCmd.java
  30. 26
      src/engine/devcmd/cmds/SimulateBootyCmd.java
  31. 2
      src/engine/devcmd/cmds/SlotTestCmd.java
  32. 2
      src/engine/devcmd/cmds/SplatMobCmd.java
  33. 41
      src/engine/devcmd/cmds/aiInfoCmd.java
  34. 72
      src/engine/devcmd/cmds/setProfit.java
  35. 11
      src/engine/gameManager/BuildingManager.java
  36. 88
      src/engine/gameManager/CombatManager.java
  37. 19
      src/engine/gameManager/DevCmdManager.java
  38. 385
      src/engine/gameManager/LootManager.java
  39. 450
      src/engine/gameManager/MaintenanceManager.java
  40. 3
      src/engine/gameManager/MovementManager.java
  41. 80
      src/engine/gameManager/NPCManager.java
  42. 281
      src/engine/gameManager/PowersManager.java
  43. 29
      src/engine/gameManager/SimulationManager.java
  44. 58
      src/engine/gameManager/ZergManager.java
  45. 8
      src/engine/jobs/ActivateBaneJob.java
  46. 5
      src/engine/jobs/AttackJob.java
  47. 4
      src/engine/jobs/EndFearJob.java
  48. 9
      src/engine/loot/ModTableEntry.java
  49. 2
      src/engine/math/Bounds.java
  50. 665
      src/engine/mobileAI/MobAI.java
  51. 2
      src/engine/mobileAI/Threads/MobAIThread.java
  52. 221
      src/engine/mobileAI/utilities/CombatUtilities.java
  53. 80
      src/engine/mobileAI/utilities/MovementUtilities.java
  54. 2
      src/engine/net/NetMsgFactory.java
  55. 202
      src/engine/net/client/ClientMessagePump.java
  56. 55
      src/engine/net/client/handlers/ActivateNPCMsgHandler.java
  57. 5
      src/engine/net/client/handlers/ArcLoginNotifyMsgHandler.java
  58. 21
      src/engine/net/client/handlers/BanishUnbanishHandler.java
  59. 9
      src/engine/net/client/handlers/CityDataHandler.java
  60. 9
      src/engine/net/client/handlers/DestroyBuildingHandler.java
  61. 7
      src/engine/net/client/handlers/GroupInviteHandler.java
  62. 21
      src/engine/net/client/handlers/InviteToSubHandler.java
  63. 22
      src/engine/net/client/handlers/LeaveGuildHandler.java
  64. 270
      src/engine/net/client/handlers/ManageCityAssetMsgHandler.java
  65. 20
      src/engine/net/client/handlers/MerchantMsgHandler.java
  66. 75
      src/engine/net/client/handlers/MinionTrainingMsgHandler.java
  67. 14
      src/engine/net/client/handlers/ObjectActionMsgHandler.java
  68. 7
      src/engine/net/client/handlers/OpenFriendsCondemnListMsgHandler.java
  69. 10
      src/engine/net/client/handlers/OrderNPCMsgHandler.java
  70. 10
      src/engine/net/client/handlers/PlaceAssetMsgHandler.java
  71. 2
      src/engine/net/client/handlers/RequestEnterWorldHandler.java
  72. 10
      src/engine/net/client/handlers/TaxCityMsgHandler.java
  73. 2
      src/engine/net/client/handlers/UpgradeAssetMsgHandler.java
  74. 150
      src/engine/net/client/msg/ApplyRuneMsg.java
  75. 6
      src/engine/net/client/msg/CityDataMsg.java
  76. 5
      src/engine/net/client/msg/CityZoneMsg.java
  77. 6
      src/engine/net/client/msg/ManageCityAssetsMsg.java
  78. 8
      src/engine/net/client/msg/ManageNPCMsg.java
  79. 3
      src/engine/net/client/msg/PlaceAssetMsg.java
  80. 2
      src/engine/net/client/msg/RefinerScreenMsg.java
  81. 1
      src/engine/net/client/msg/TrainMsg.java
  82. 66
      src/engine/net/client/msg/VendorDialogMsg.java
  83. 3
      src/engine/net/client/msg/login/CommitNewCharacterMsg.java
  84. 114
      src/engine/objects/AbstractCharacter.java
  85. 33
      src/engine/objects/AbstractIntelligenceAgent.java
  86. 6
      src/engine/objects/AbstractWorldObject.java
  87. 55
      src/engine/objects/Bane.java
  88. 44
      src/engine/objects/Blueprint.java
  89. 22
      src/engine/objects/Building.java
  90. 79
      src/engine/objects/CharacterItemManager.java
  91. 14
      src/engine/objects/CharacterSkill.java
  92. 5
      src/engine/objects/CharacterTitle.java
  93. 277
      src/engine/objects/City.java
  94. 11
      src/engine/objects/Contract.java
  95. 3
      src/engine/objects/Corpse.java
  96. 51
      src/engine/objects/Experience.java
  97. 22
      src/engine/objects/Guild.java
  98. 24
      src/engine/objects/Item.java
  99. 82
      src/engine/objects/ItemBase.java
  100. 4
      src/engine/objects/ItemFactory.java
  101. Some files were not shown because too many files have changed in this diff Show More

60
src/engine/Enum.java

@ -139,8 +139,8 @@ public class Enum {
HALFGIANTMALE(2010, MonsterType.HalfGiant, RunSpeed.STANDARD, CharacterSex.MALE, 1.15f), HALFGIANTMALE(2010, MonsterType.HalfGiant, RunSpeed.STANDARD, CharacterSex.MALE, 1.15f),
HUMANMALE(2011, MonsterType.Human, RunSpeed.STANDARD, CharacterSex.MALE, 1), HUMANMALE(2011, MonsterType.Human, RunSpeed.STANDARD, CharacterSex.MALE, 1),
HUMANFEMALE(2012, MonsterType.Human, RunSpeed.STANDARD, CharacterSex.FEMALE, 1), HUMANFEMALE(2012, MonsterType.Human, RunSpeed.STANDARD, CharacterSex.FEMALE, 1),
IREKEIMALE(2013, MonsterType.Irekei, RunSpeed.STANDARD, CharacterSex.MALE, 1.1f), IREKEIMALE(2013, MonsterType.Irekei, RunSpeed.IREKEI, CharacterSex.MALE, 1.1f),
IREKEIFEMALE(2014, MonsterType.Irekei, RunSpeed.STANDARD, CharacterSex.FEMALE, 1.1f), IREKEIFEMALE(2014, MonsterType.Irekei, RunSpeed.IREKEI, CharacterSex.FEMALE, 1.1f),
SHADEMALE(2015, MonsterType.Shade, RunSpeed.STANDARD, CharacterSex.MALE, 1), SHADEMALE(2015, MonsterType.Shade, RunSpeed.STANDARD, CharacterSex.MALE, 1),
SHADEFEMALE(2016, MonsterType.Shade, RunSpeed.STANDARD, CharacterSex.FEMALE, 1), SHADEFEMALE(2016, MonsterType.Shade, RunSpeed.STANDARD, CharacterSex.FEMALE, 1),
MINOMALE(2017, MonsterType.Minotaur, RunSpeed.MINOTAUR, CharacterSex.MALE, 1.3f), MINOMALE(2017, MonsterType.Minotaur, RunSpeed.MINOTAUR, CharacterSex.MALE, 1.3f),
@ -152,7 +152,9 @@ public class Enum {
NEPHFEMALE(2026, MonsterType.Nephilim, RunSpeed.STANDARD, CharacterSex.FEMALE, 1.1f), NEPHFEMALE(2026, MonsterType.Nephilim, RunSpeed.STANDARD, CharacterSex.FEMALE, 1.1f),
HALFGIANTFEMALE(2027, MonsterType.HalfGiant, RunSpeed.STANDARD, CharacterSex.FEMALE, 1.15f), HALFGIANTFEMALE(2027, MonsterType.HalfGiant, RunSpeed.STANDARD, CharacterSex.FEMALE, 1.15f),
VAMPMALE(2028, MonsterType.Vampire, RunSpeed.STANDARD, CharacterSex.MALE, 1), 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, 0.80000001f),
LIZARDMAN(1998, MonsterType.Reptile, RunSpeed.STANDARD, CharacterSex.MALE, 1.05f);
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private static HashMap<Integer, RaceType> _raceTypeByID = new HashMap<>(); private static HashMap<Integer, RaceType> _raceTypeByID = new HashMap<>();
@ -208,6 +210,7 @@ public class Enum {
SENTINEL(0, 0, 0, 0, 0, 0, 0), SENTINEL(0, 0, 0, 0, 0, 0, 0),
STANDARD(6.1900001f, 13.97f, 4.2199998f, 13.97f, 6.3299999f, 18.379999f, 6.5f), 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), CENTAUR(6.1900001f, 16.940001f, 5.5500002f, 16.940001f, 6.3299999f, 18.379999f, 6.5f),
IREKEI(6.35f, 15.25f, 4.2199998f, 14.5f, 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);
private float walkStandard; private float walkStandard;
@ -960,7 +963,17 @@ public class Enum {
SourceType returnMod; SourceType returnMod;
if (modName.isEmpty()) if (modName.isEmpty())
return SourceType.None; return SourceType.None;
switch(modName) {
case "Piercing":
modName = "Pierce";
break;
case "Crushing":
modName = "Crush";
break;
case "Slashing":
modName = "Slash";
break;
}
try { try {
returnMod = SourceType.valueOf(modName.replace(",", "")); returnMod = SourceType.valueOf(modName.replace(",", ""));
} catch (Exception e) { } catch (Exception e) {
@ -1652,6 +1665,24 @@ public class Enum {
return extents; return extents;
} }
public boolean isTrainerBuilding(){
switch(this){
case AMAZONHALL:
case CATHEDRAL:
case GREATHALL:
case KEEP:
case THIEFHALL:
case TEMPLEHALL:
case WIZARDHALL:
case ELVENHALL:
case ELVENSANCTUM:
case IREKEIHALL:
case FORESTHALL:
return true;
}
return false;
}
} }
public enum UpdateType { public enum UpdateType {
@ -2307,8 +2338,8 @@ public class Enum {
public enum CityBoundsType { public enum CityBoundsType {
GRID(640), GRID(640),
ZONE(875), ZONE(680),
PLACEMENT(876); PLACEMENT(681);
public final float extents; public final float extents;
@ -2822,7 +2853,6 @@ public class Enum {
public enum MobBehaviourType { public enum MobBehaviourType {
None(null, false, false, false, false, false), None(null, false, false, false, false, false),
//Power
Power(null, false, true, true, true, false), Power(null, false, true, true, true, false),
PowerHelpee(Power, false, true, true, false, true), PowerHelpee(Power, false, true, true, false, true),
PowerHelpeeWimpy(Power, true, false, true, false, false), PowerHelpeeWimpy(Power, true, false, true, false, false),
@ -2847,6 +2877,7 @@ public class Enum {
//Independent Types //Independent Types
SimpleStandingGuard(null, false, false, false, false, false), SimpleStandingGuard(null, false, false, false, false, false),
Pet1(null, false, false, true, false, false), Pet1(null, false, false, true, false, false),
SiegeEngine(null, false, false, false, false, false),
Simple(null, false, false, true, false, false), Simple(null, false, false, true, false, false),
Helpee(null, false, true, true, false, true), Helpee(null, false, true, true, false, true),
HelpeeWimpy(null, true, false, true, false, false), HelpeeWimpy(null, true, false, true, false, false),
@ -2857,13 +2888,12 @@ public class Enum {
HamletGuard(null, false, true, false, false, false), HamletGuard(null, false, true, false, false, false),
AggroWanderer(null, false, false, true, false, false); AggroWanderer(null, false, false, true, false, false);
private static HashMap<Integer, MobBehaviourType> _behaviourTypes = new HashMap<>(); public final MobBehaviourType BehaviourHelperType;
public MobBehaviourType BehaviourHelperType; public final boolean isWimpy;
public boolean isWimpy; public final boolean isAgressive;
public boolean isAgressive; public final boolean canRoam;
public boolean canRoam; public final boolean callsForHelp;
public boolean callsForHelp; public final boolean respondsToCallForHelp;
public boolean respondsToCallForHelp;
MobBehaviourType(MobBehaviourType helpeebehaviourType, boolean wimpy, boolean agressive, boolean canroam, boolean callsforhelp, boolean respondstocallforhelp) { MobBehaviourType(MobBehaviourType helpeebehaviourType, boolean wimpy, boolean agressive, boolean canroam, boolean callsforhelp, boolean respondstocallforhelp) {
this.BehaviourHelperType = helpeebehaviourType; this.BehaviourHelperType = helpeebehaviourType;
@ -2880,6 +2910,8 @@ public class Enum {
MOBILE, MOBILE,
PET, PET,
CHARMED, CHARMED,
SIEGEENGINE,
GUARD; GUARD;
} }
} }

10
src/engine/InterestManagement/InterestManager.java

@ -25,6 +25,7 @@ import engine.net.client.msg.MoveToPointMsg;
import engine.net.client.msg.UnloadObjectsMsg; import engine.net.client.msg.UnloadObjectsMsg;
import engine.objects.*; import engine.objects.*;
import engine.server.MBServerStatics; import engine.server.MBServerStatics;
import engine.util.BoxTracker;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
import java.util.ArrayList; import java.util.ArrayList;
@ -109,7 +110,7 @@ public enum InterestManager implements Runnable {
origin.sendMsg(moveMsg); origin.sendMsg(moveMsg);
} }
public static void reloadCharacter(AbstractCharacter absChar) { public static void reloadCharacter(AbstractCharacter absChar, boolean sendToSelf) {
UnloadObjectsMsg uom = new UnloadObjectsMsg(); UnloadObjectsMsg uom = new UnloadObjectsMsg();
uom.addObject(absChar); uom.addObject(absChar);
@ -210,7 +211,7 @@ public enum InterestManager implements Runnable {
if (origin == null) if (origin == null)
continue; continue;
if (!playerCharacter.isEnteredWorld()) if (!playerCharacter.enteredWorld)
continue; continue;
if (playerCharacter.getTeleportLock().readLock().tryLock()) { if (playerCharacter.getTeleportLock().readLock().tryLock()) {
@ -467,7 +468,7 @@ public enum InterestManager implements Runnable {
if (awonpc.despawned == true) if (awonpc.despawned == true)
continue; continue;
awonpc.playerAgroMap.put(player.getObjectUUID(), false); awonpc.playerAgroMap.put(player.getObjectUUID(), 0f);
((Mob) awonpc).setCombatTarget(null); ((Mob) awonpc).setCombatTarget(null);
lcm = new LoadCharacterMsg(awonpc, PlayerCharacter.hideNonAscii()); lcm = new LoadCharacterMsg(awonpc, PlayerCharacter.hideNonAscii());
@ -480,7 +481,7 @@ public enum InterestManager implements Runnable {
if (!awonpc.isAlive()) if (!awonpc.isAlive())
continue; continue;
awonpc.playerAgroMap.put(player.getObjectUUID(), false); awonpc.playerAgroMap.put(player.getObjectUUID(), 0f);
if ((awonpc.agentType.equals(Enum.AIAgentType.MOBILE))) if ((awonpc.agentType.equals(Enum.AIAgentType.MOBILE)))
((Mob) awonpc).setCombatTarget(null); ((Mob) awonpc).setCombatTarget(null);
@ -524,6 +525,7 @@ public enum InterestManager implements Runnable {
player.setDirtyLoad(true); player.setDirtyLoad(true);
updateStaticList(player, origin); updateStaticList(player, origin);
updateMobileList(player, origin); updateMobileList(player, origin);
BoxTracker.addPlayer(origin.machineID,player);
} }

8
src/engine/db/handlers/dbBlueprintHandler.java

@ -73,6 +73,14 @@ public class dbBlueprintHandler extends dbHandlerBase {
Blueprint._meshLookup.putIfAbsent(thisBlueprint.getMeshForRank(3), thisBlueprint); Blueprint._meshLookup.putIfAbsent(thisBlueprint.getMeshForRank(3), thisBlueprint);
Blueprint._meshLookup.putIfAbsent(thisBlueprint.getMeshForRank(7), thisBlueprint); Blueprint._meshLookup.putIfAbsent(thisBlueprint.getMeshForRank(7), thisBlueprint);
if(thisBlueprint.getName().contains("Vampire Shrine")){
Blueprint saetorShrine = new Blueprint(rs);
saetorShrine.setBlueprintUUID(1720000);
saetorShrine.rank1UUID = 1720000;
saetorShrine.rank3UUID = 1720000;
saetorShrine.rank7UUID = 1720000;
}
} }
} catch (SQLException e) { } catch (SQLException e) {

1
src/engine/db/handlers/dbCharacterSkillHandler.java

@ -14,6 +14,7 @@ import engine.gameManager.DbManager;
import engine.objects.AbstractCharacter; import engine.objects.AbstractCharacter;
import engine.objects.CharacterSkill; import engine.objects.CharacterSkill;
import engine.objects.PlayerCharacter; import engine.objects.PlayerCharacter;
import engine.objects.SkillsBase;
import engine.server.MBServerStatics; import engine.server.MBServerStatics;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;

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

@ -63,6 +63,9 @@ public abstract class dbHandlerBase {
} else { } else {
AbstractGameObject toAdd = localClass.getConstructor(ResultSet.class).newInstance(rs); AbstractGameObject toAdd = localClass.getConstructor(ResultSet.class).newInstance(rs);
DbManager.addToCache(toAdd); DbManager.addToCache(toAdd);
if(toAdd.getObjectType().equals(GameObjectType.Zone) && rs.getInt("canLoad") == 0){
continue;
}
objectList.add((T) toAdd); objectList.add((T) toAdd);
if (toAdd != null && toAdd instanceof AbstractWorldObject) if (toAdd != null && toAdd instanceof AbstractWorldObject)

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

@ -28,10 +28,67 @@ public class dbItemBaseHandler extends dbHandlerBase {
public void LOAD_BAKEDINSTATS(ItemBase itemBase) { public void LOAD_BAKEDINSTATS(ItemBase itemBase) {
int itemBaseID = itemBase.getUUID();
switch(itemBaseID){
case 27550://bow
case 27560://dagger
case 27570://hammer
case 27580://axe
case 27590://sword
//return new String[]{"PRE-010","SUF-260"};
itemBaseID = 8000000;
break;
case 27600://staff
//return new String[]{"PRE-334","PRE-315"};
itemBaseID = 8000010;
break;
case 188500://HA chest
case 188510://HA arms
case 188520://HA legs
case 188530://HA gloves
case 188550://HA helm
case 188720://CC hood
case 188900://MA chest
case 188910://MA Sleeves
case 188920://MA Legs
case 188930://MA gloves
case 188950://MA helm
case 189100://la chest
case 189110://la arms
case 189120://la legs
case 189130://la gloves
case 189150://la helm
case 189550://CC gloves
//return new String[]{"PRE-130", "PRE-232", "PRE-212", "PRE-222", "SUF-007"};
itemBaseID = 8000020;
break;
case 188540://HA boots
case 188940://MA boots
case 189140://LA boots
case 189560://CC boots
//return new String[]{"PRE-133", "PRE-230", "PRE-210", "PRE-220", "SUF-003","SUF-150"};
itemBaseID = 8000030;
break;
case 188700://CC robe
//return new String[]{"PRE-130", "PRE-232", "PRE-212", "PRE-222","SUF-317","SUF-317","SUF-317"};
itemBaseID = 8000040;
break;
case 189500://MA shield
case 189510://HA shield
//return new String[]{"PRE-125","PRE-125","PRE-125", "PRE-230", "PRE-210", "PRE-220"};
itemBaseID = 8000050;
}
try (Connection connection = DbManager.getConnection(); try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_item_bakedinstat` WHERE `itemID` = ?")) { PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_item_bakedinstat` WHERE `itemID` = ?")) {
preparedStatement.setInt(1, itemBase.getUUID()); preparedStatement.setInt(1, itemBaseID);
ResultSet rs = preparedStatement.executeQuery(); ResultSet rs = preparedStatement.executeQuery();
while (rs.next()) { while (rs.next()) {
@ -87,12 +144,19 @@ public class dbItemBaseHandler extends dbHandlerBase {
recordsRead++; recordsRead++;
itemBase = new ItemBase(rs); itemBase = new ItemBase(rs);
ItemBase.addToCache(itemBase); ItemBase.addToCache(itemBase);
//copy the vampire shrine for saetor and change uuid and name
if(itemBase.getName().contains("Vampire Shrine")){
ItemBase saetorShrine = new ItemBase(rs);
saetorShrine.setUUID(1035);
saetorShrine.setName(saetorShrine.getName().replace("Vampire","Saetor"));
ItemBase.addToCache(saetorShrine);
}
} }
} catch (SQLException e) { } catch (SQLException e) {
Logger.error(e); Logger.error(e);
} }
Logger.info("read: " + recordsRead + " cached: " + ItemBase.getUUIDCache().size()); Logger.info("read: " + recordsRead + " cached: " + ItemBase.getUUIDCache().size());
} }

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

@ -135,7 +135,11 @@ public class dbItemHandler extends dbHandlerBase {
ResultSet rs = preparedStatement.executeQuery(); ResultSet rs = preparedStatement.executeQuery();
if (rs.next()) if (rs.next())
worked = rs.getBoolean("result"); try {
worked = rs.getBoolean("result");
}catch(Exception e){
return true;
}
} catch (SQLException e) { } catch (SQLException e) {
Logger.error(e); Logger.error(e);
@ -350,7 +354,11 @@ public class dbItemHandler extends dbHandlerBase {
ResultSet rs = preparedStatement.executeQuery(); ResultSet rs = preparedStatement.executeQuery();
if (rs.next()) if (rs.next())
worked = rs.getBoolean("result"); try {
worked = rs.getBoolean("result");
} catch(Exception e){
worked = true;
}
} catch (SQLException e) { } catch (SQLException e) {
Logger.error(e); Logger.error(e);
@ -496,4 +504,18 @@ public class dbItemHandler extends dbHandlerBase {
return false; 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;
}
}
} }

40
src/engine/db/handlers/dbMineHandler.java

@ -9,12 +9,14 @@
package engine.db.handlers; package engine.db.handlers;
import engine.Enum; import engine.Enum;
import engine.gameManager.BuildingManager;
import engine.gameManager.DbManager; import engine.gameManager.DbManager;
import engine.objects.Mine; import engine.objects.Mine;
import engine.objects.MineProduction; import engine.objects.MineProduction;
import engine.objects.Resource; import engine.objects.Resource;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
import java.net.UnknownHostException;
import java.sql.Connection; import java.sql.Connection;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
@ -32,8 +34,24 @@ public class dbMineHandler extends dbHandlerBase {
if (id == 0) if (id == 0)
return null; return null;
Mine mine = (Mine) DbManager.getFromCache(Enum.GameObjectType.Mine, id); Mine mine = (Mine) DbManager.getFromCache(Enum.GameObjectType.Mine, id);
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM obj_mine;")) {
//preparedStatement.setInt(1, id);
ResultSet rs = preparedStatement.executeQuery();
while(rs.next()){
if(rs.getInt("UID") == id){
int towerUID = rs.getInt("mine_buildingUID");
mine = Mine.getMineFromTower(towerUID);
}
}
} catch (SQLException e) {
Logger.error(e);
}
if (mine != null) if (mine != null)
return mine; return mine;
@ -56,13 +74,27 @@ public class dbMineHandler extends dbHandlerBase {
ArrayList<Mine> mines = new ArrayList<>(); ArrayList<Mine> mines = new ArrayList<>();
//try (Connection connection = DbManager.getConnection();
// PreparedStatement preparedStatement = connection.prepareStatement("SELECT `obj_mine`.*, `object`.`parent` FROM `object` INNER JOIN `obj_mine` ON `obj_mine`.`UID` = `object`.`UID`")) {
// ResultSet rs = preparedStatement.executeQuery();
// mines = getObjectsFromRs(rs, 1000);
// } catch (SQLException e) {
// Logger.error(e);
//}
try (Connection connection = DbManager.getConnection(); try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT `obj_mine`.*, `object`.`parent` FROM `object` INNER JOIN `obj_mine` ON `obj_mine`.`UID` = `object`.`UID`")) { PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM obj_mine;")) {
ResultSet rs = preparedStatement.executeQuery(); ResultSet rs = preparedStatement.executeQuery();
mines = getObjectsFromRs(rs, 1000); while(rs.next()){
if(BuildingManager.getBuildingFromCache(rs.getInt("mine_buildingUID")) == null)
continue;
} catch (SQLException e) { mines.add(new Mine(rs));
}
} catch (SQLException | UnknownHostException e) {
Logger.error(e); Logger.error(e);
} }
return mines; return mines;

20
src/engine/db/handlers/dbMobBaseHandler.java

@ -21,6 +21,7 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
public class dbMobBaseHandler extends dbHandlerBase { public class dbMobBaseHandler extends dbHandlerBase {
@ -112,6 +113,25 @@ public class dbMobBaseHandler extends dbHandlerBase {
return mobBaseStats; return mobBaseStats;
} }
public void LOAD_ALL_MOBBASE_RACES() {
MobBase.mobbase_race_types = new HashMap<>();
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_npc_mobbase`;")) {
ResultSet rs = preparedStatement.executeQuery();
while (rs.next()) {
int id = rs.getInt("loadID");
if(MobBase.mobbase_race_types.containsKey(id) == false){
MobBase.mobbase_race_types.put(id,rs.getString("raceType"));
}
}
} catch (SQLException e) {
Logger.error(e);
}
}
public void LOAD_ALL_MOBBASE_SPEEDS(MobBase mobBase) { public void LOAD_ALL_MOBBASE_SPEEDS(MobBase mobBase) {
if (mobBase.getLoadID() == 0) if (mobBase.getLoadID() == 0)

39
src/engine/db/handlers/dbMobHandler.java

@ -28,31 +28,26 @@ public class dbMobHandler extends dbHandlerBase {
this.localObjectType = engine.Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); this.localObjectType = engine.Enum.GameObjectType.valueOf(this.localClass.getSimpleName());
} }
public Mob ADD_MOB(Mob toAdd) { public Mob PERSIST(Mob toAdd) {
Mob mobile = null; Mob mobile = null;
try (Connection connection = DbManager.getConnection(); try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("CALL `mob_CREATE`(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);")) { PreparedStatement preparedStatement = connection.prepareStatement("CALL `mob_CREATE`(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);")) {
preparedStatement.setLong(1, toAdd.getParentZoneID()); preparedStatement.setLong(1, toAdd.parentZoneUUID);
preparedStatement.setInt(2, toAdd.getMobBaseID()); preparedStatement.setInt(2, toAdd.loadID);
preparedStatement.setInt(3, toAdd.getGuildUUID()); preparedStatement.setInt(3, toAdd.guildUUID);
preparedStatement.setFloat(4, toAdd.getSpawnX()); preparedStatement.setFloat(4, toAdd.bindLoc.x);
preparedStatement.setFloat(5, toAdd.getSpawnY()); preparedStatement.setFloat(5, toAdd.bindLoc.y);
preparedStatement.setFloat(6, toAdd.getSpawnZ()); preparedStatement.setFloat(6, toAdd.bindLoc.z);
preparedStatement.setInt(7, 0); preparedStatement.setInt(7, 0);
preparedStatement.setFloat(8, toAdd.getSpawnRadius()); preparedStatement.setFloat(8, toAdd.spawnRadius);
preparedStatement.setInt(9, toAdd.getTrueSpawnTime()); preparedStatement.setInt(9, toAdd.spawnTime);
preparedStatement.setInt(10, toAdd.contractUUID);
if (toAdd.getContract() != null) preparedStatement.setInt(11, toAdd.buildingUUID);
preparedStatement.setInt(10, toAdd.getContract().getContractID()); preparedStatement.setInt(12, toAdd.level);
else preparedStatement.setString(13, toAdd.firstName);
preparedStatement.setInt(10, 0);
preparedStatement.setInt(11, toAdd.getBuildingID());
preparedStatement.setInt(12, toAdd.getLevel());
preparedStatement.setString(13, toAdd.getFirstName());
ResultSet rs = preparedStatement.executeQuery(); ResultSet rs = preparedStatement.executeQuery();
@ -106,17 +101,17 @@ public class dbMobHandler extends dbHandlerBase {
return row_count; return row_count;
} }
public void LOAD_PATROL_POINTS(Mob captain) { public void LOAD_GUARD_MINIONS(Mob guardCaptain) {
try (Connection connection = DbManager.getConnection(); try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `dyn_guards` WHERE `captainUID` = ?")) { PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `dyn_guards` WHERE `captainUID` = ?")) {
preparedStatement.setInt(1, captain.getObjectUUID()); preparedStatement.setInt(1, guardCaptain.getObjectUUID());
ResultSet rs = preparedStatement.executeQuery(); ResultSet rs = preparedStatement.executeQuery();
while (rs.next()) { while (rs.next()) {
String name = rs.getString("name"); String minionName = rs.getString("name");
Mob toCreate = Mob.createGuardMob(captain, captain.getGuild(), captain.getParentZone(), captain.building.getLoc(), captain.getLevel(), name); Mob toCreate = Mob.createGuardMinion(guardCaptain, guardCaptain.getLevel(), minionName);
if (toCreate == null) if (toCreate == null)
return; return;

18
src/engine/db/handlers/dbResistHandler.java

@ -23,7 +23,25 @@ public class dbResistHandler extends dbHandlerBase {
public dbResistHandler() { public dbResistHandler() {
} }
public void LOAD_RESISTS_FOR_MOBS() {
Resists resists = null;
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `static_npc_mob_resists`;")) {
ResultSet rs = preparedStatement.executeQuery();
while(rs.next()){
resists = new Resists(rs);
if(!Resists.mobResists.containsKey(rs.getInt("ID")))
Resists.mobResists.put(rs.getInt("ID"),resists);
}
} catch (SQLException e) {
Logger.error(e);
}
}
public Resists GET_RESISTS_FOR_MOB(int resistID) { public Resists GET_RESISTS_FOR_MOB(int resistID) {
Resists resists = null; Resists resists = null;

37
src/engine/db/handlers/dbRuneBaseHandler.java

@ -59,6 +59,43 @@ public class dbRuneBaseHandler extends dbHandlerBase {
rb.setLevelRequired(rs.getInt("requiredRuneID")); rb.setLevelRequired(rs.getInt("requiredRuneID"));
break; break;
} }
int id = rs.getInt("runeID");
switch(id) {
case 3001:
case 3002:
case 3003:
case 3004:
case 3007:
case 3008:
case 3009:
case 3013:
case 3014:
case 3016:
case 3017:
case 3018:
case 3019:
case 3020:
case 3021:
case 3026:
case 3030:
case 3031:
case 3033:
case 3037:
case 3040:
case 3045:
case 3046:
case 3047:
case 3048:
case 2514:
rb.getRace().put(1999, true);
break;
case 3035:
rb.getBaseClass().put(2501,true);
break;
case 3049:
rb.getRace().clear();
}
} }
} catch (SQLException e) { } catch (SQLException e) {

7
src/engine/db/handlers/dbSkillBaseHandler.java

@ -143,6 +143,13 @@ public class dbSkillBaseHandler extends dbHandlerBase {
SkillsBase.runeSkillsCache.get(runeID).put(token, amount); SkillsBase.runeSkillsCache.get(runeID).put(token, amount);
} }
//add saetor skills
HashMap<Integer, Integer> skills = new HashMap<>();
skills.put(71438003,15); // staff
skills.put(-61022283,10); // staff mastery
skills.put(95961104,10); // parry
SkillsBase.runeSkillsCache.put(1999,skills);
} catch (SQLException e) { } catch (SQLException e) {
Logger.error(e); Logger.error(e);

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

@ -43,7 +43,7 @@ public class AddMobCmd extends AbstractDevCmd {
MobBase mb = (MobBase) mobbaseAGO; MobBase mb = (MobBase) mobbaseAGO;
int loadID = mb.getObjectUUID(); int loadID = mb.getObjectUUID();
Mob mob = Mob.createMob(loadID, Vector3fImmutable.getRandomPointInCircle(pc.getLoc(), 100), Mob mob = Mob.createMob(loadID, Vector3fImmutable.getRandomPointInCircle(pc.getLoc(), 100),
null, true, zone, null, 0, "", 1); null, zone, null, null, "", 1);
if (mob != null) { if (mob != null) {
mob.updateDatabase(); mob.updateDatabase();
this.setResult(String.valueOf(mob.getDBID())); this.setResult(String.valueOf(mob.getDBID()));
@ -84,7 +84,7 @@ public class AddMobCmd extends AbstractDevCmd {
Mob mob = Mob.createMob(loadID, pc.getLoc(), Mob mob = Mob.createMob(loadID, pc.getLoc(),
null, true, zone, null, 0, "", 1); null, zone, null, null, "", 1);
if (mob != null) { if (mob != null) {
mob.updateDatabase(); mob.updateDatabase();
ChatManager.chatSayInfo(pc, ChatManager.chatSayInfo(pc,

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

@ -13,6 +13,7 @@ import engine.Enum.GameObjectType;
import engine.InterestManagement.WorldGrid; import engine.InterestManagement.WorldGrid;
import engine.devcmd.AbstractDevCmd; import engine.devcmd.AbstractDevCmd;
import engine.gameManager.*; import engine.gameManager.*;
import engine.math.Vector3fImmutable;
import engine.objects.*; import engine.objects.*;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
@ -70,28 +71,30 @@ public class AddNPCCmd extends AbstractDevCmd {
throwbackError(pc, "Failed to find zone to place npc in."); throwbackError(pc, "Failed to find zone to place npc in.");
return; return;
} }
Building building = null;
if (target != null) if (target != null)
if (target.getObjectType() == GameObjectType.Building) { if (target.getObjectType() == GameObjectType.Building) {
Building parentBuilding = (Building) target; building = (Building)target;
BuildingManager.addHirelingForWorld(parentBuilding, pc, parentBuilding.getLoc(), parentBuilding.getParentZone(), contract, level);
return;
} }
NPC created;
NPC npc = NPC.createNPC(name, contractID, Guild guild = null;
pc.getLoc(), null, zone, (short) level, null); Vector3fImmutable loc;
if(building != null){
if (npc != null) { guild = building.getGuild();
WorldGrid.addObject(npc, pc); loc = building.loc;
ChatManager.chatSayInfo(pc, } else{
"NPC with ID " + npc.getDBID() + " added"); loc = pc.loc;
this.setResult(String.valueOf(npc.getDBID())); }
} else { created = NPC.createNPC(name, contractID, loc, guild, zone, (short)level, building);
throwbackError(pc, "Failed to create npc of contract type " created.bindLoc = loc;
+ contractID); if(building != null) {
Logger.error( created.buildingUUID = building.getObjectUUID();
"Failed to create npc of contract type " + contractID); created.building = building;
NPCManager.slotCharacterInBuilding(created);
} }
created.setLoc(created.bindLoc);
created.updateDatabase();
throwbackInfo(pc, "Created NPC with UUID: " + created.getObjectUUID());
} }
@Override @Override

19
src/engine/devcmd/cmds/EnchantCmd.java

@ -11,6 +11,7 @@ package engine.devcmd.cmds;
import engine.devcmd.AbstractDevCmd; import engine.devcmd.AbstractDevCmd;
import engine.objects.*; import engine.objects.*;
import engine.powers.EffectsBase;
public class EnchantCmd extends AbstractDevCmd { public class EnchantCmd extends AbstractDevCmd {
@ -55,21 +56,9 @@ public class EnchantCmd extends AbstractDevCmd {
this.setResult(String.valueOf(item.getObjectUUID())); this.setResult(String.valueOf(item.getObjectUUID()));
} else { } else {
int cnt = words.length; int cnt = words.length;
for (int i = 1; i < cnt; i++) { String enchant = words[1];
String enchant = words[i]; enchant = EffectsBase.getItemEffectsByName(enchant.toLowerCase());
boolean valid = true; item.addPermanentEnchantmentForDev(enchant, 0);
for (Effect eff : item.getEffects().values()) {
if (eff.getEffectsBase().getIDString().equals(enchant)) {
throwbackError(pc, "This item already has that enchantment");
return;
}
}
if (valid) {
item.addPermanentEnchantmentForDev(enchant, rank);
this.setResult(String.valueOf(item.getObjectUUID()));
} else
throwbackError(pc, "Invalid Enchantment. Enchantment must consist of SUF-001 to SUF-328 or PRE-001 to PRE-334. Sent " + enchant + '.');
}
cim.updateInventory(); cim.updateInventory();
} }
} }

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

@ -30,7 +30,7 @@ public class FlashMsgCmd extends AbstractDevCmd {
this.sendUsage(pcSender); this.sendUsage(pcSender);
return; return;
} }
ChatManager.chatSystemFlash(args[0]); ChatManager.chatSystemFlash(String.join(" ", args));
} }
/** /**

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

@ -280,7 +280,7 @@ public class InfoCmd extends AbstractDevCmd {
output += newline; output += newline;
output += "Inventory Weight:" + (targetPC.getCharItemManager().getInventoryWeight() + targetPC.getCharItemManager().getEquipWeight()); output += "Inventory Weight:" + (targetPC.getCharItemManager().getInventoryWeight() + targetPC.getCharItemManager().getEquipWeight());
output += newline; output += newline;
output += "Max Inventory Weight:" + ((int) targetPC.statStrBase * 3); output += "Max Inventory Weight:" + targetPC.getInventoryCapacity();
output += newline; output += newline;
output += "ALTITUDE :" + targetPC.getAltitude(); output += "ALTITUDE :" + targetPC.getAltitude();
output += newline; output += newline;
@ -336,8 +336,9 @@ public class InfoCmd extends AbstractDevCmd {
output += "Swimming : " + targetPC.isSwimming(); output += "Swimming : " + targetPC.isSwimming();
output += newline; output += newline;
output += "isMoving : " + targetPC.isMoving(); output += "isMoving : " + targetPC.isMoving() + newline;
output += "Zerg Multiplier: " + targetPC.ZergMultiplier + newline;
output += "isBoxed: " + targetPC.isBoxed + newline;
break; break;
case NPC: case NPC:
@ -440,7 +441,9 @@ public class InfoCmd extends AbstractDevCmd {
output += "isSummonedPet: true"; output += "isSummonedPet: true";
else else
output += "isSummonedPet: false"; output += "isSummonedPet: false";
PlayerCharacter owner = targetMob.getOwner();
PlayerCharacter owner = (PlayerCharacter) targetMob.guardCaptain;
if (owner != null) if (owner != null)
output += " owner: " + owner.getObjectUUID(); output += " owner: " + owner.getObjectUUID();
output += newline; output += newline;
@ -523,7 +526,7 @@ public class InfoCmd extends AbstractDevCmd {
ConcurrentHashMap<String, Effect> effects = item.getEffects(); ConcurrentHashMap<String, Effect> effects = item.getEffects();
for (String name : effects.keySet()) { for (String name : effects.keySet()) {
Effect eff = effects.get(name); Effect eff = effects.get(name);
output += eff.getEffectsBase().getIDString(); output += eff.getEffectsBase().getIDString() + " Static:" + eff.isStatic();
output += newline; output += newline;
// output += eff.getEffectToken() + (eff.bakedInStat() ? " (baked in)" : "") + newline; // output += eff.getEffectToken() + (eff.bakedInStat() ? " (baked in)" : "") + newline;
} }

8
src/engine/devcmd/cmds/MakeItemCmd.java

@ -65,6 +65,10 @@ public class MakeItemCmd extends AbstractDevCmd {
if (item == null || !worked) { if (item == null || !worked) {
throwbackError(pc, "DB error 2: Unable to create item."); throwbackError(pc, "DB error 2: Unable to create item.");
if(item == null)
throwbackError(pc, "Item Null");
else
throwbackError(pc, "Worked = false");
return; return;
} }
@ -222,6 +226,10 @@ public class MakeItemCmd extends AbstractDevCmd {
if (item == null || !worked) { if (item == null || !worked) {
throwbackError(pc, "DB error 2: Unable to create item."); throwbackError(pc, "DB error 2: Unable to create item.");
if(item == null)
throwbackError(pc, "Item Null");
else
throwbackError(pc, "Worked = false");
return; return;
} }

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

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

3
src/engine/devcmd/cmds/PrintResistsCmd.java

@ -39,6 +39,9 @@ public class PrintResistsCmd extends AbstractDevCmd {
if (mb != null) if (mb != null)
name = mb.getFirstName(); name = mb.getFirstName();
type = "Mob"; type = "Mob";
throwbackInfo(pc, "Server resists for " + type + ' ' + name);
tar.getResists().printResistsToClient(pc);
return;
} else if (tar instanceof NPC) { } else if (tar instanceof NPC) {
NPC npc = (NPC) tar; NPC npc = (NPC) tar;
Contract contract = npc.getContract(); Contract contract = npc.getContract();

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

@ -9,6 +9,7 @@
package engine.devcmd.cmds; package engine.devcmd.cmds;
import engine.Enum;
import engine.devcmd.AbstractDevCmd; import engine.devcmd.AbstractDevCmd;
import engine.objects.*; import engine.objects.*;
@ -55,6 +56,7 @@ public class PrintStatsCmd extends AbstractDevCmd {
} }
public void printStatsPlayer(PlayerCharacter pc, PlayerCharacter tar) { public void printStatsPlayer(PlayerCharacter pc, PlayerCharacter tar) {
tar.calculateMaxHealthManaStamina();
String newline = "\r\n "; String newline = "\r\n ";
String out = "Server stats for Player " + tar.getFirstName() + newline; String out = "Server stats for Player " + tar.getFirstName() + newline;
out += "Unused Stats: " + tar.getUnusedStatPoints() + newline; out += "Unused Stats: " + tar.getUnusedStatPoints() + newline;
@ -72,6 +74,11 @@ public class PrintStatsCmd extends AbstractDevCmd {
out += "Main Hand: atr: " + tar.getAtrHandOne() + ", damage: " + tar.getMinDamageHandOne() + " to " + tar.getMaxDamageHandOne() + ", speed: " + tar.getSpeedHandOne() + 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 += "Off Hand: atr: " + tar.getAtrHandTwo() + ", damage: " + tar.getMinDamageHandTwo() + " to " + tar.getMaxDamageHandTwo() + ", speed: " + tar.getSpeedHandTwo() + newline;
out += "isAlive: " + tar.isAlive() + ", Combat: " + tar.isCombat() + newline; out += "isAlive: " + tar.isAlive() + ", Combat: " + tar.isCombat() + newline;
out += "Health Regen: " + tar.getRegenModifier(Enum.ModType.HealthRecoverRate) + newline;
out += "Stamina Regen: " + tar.getRegenModifier(Enum.ModType.StaminaRecoverRate) + newline;
out += "Mana Regen: " + tar.getRegenModifier(Enum.ModType.ManaRecoverRate) + newline;
out += "Zerg Multiplier: " + tar.ZergMultiplier + newline;
throwbackInfo(pc, out); throwbackInfo(pc, out);
} }

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

@ -59,7 +59,7 @@ public class PurgeObjectsCmd extends AbstractDevCmd {
if (npc != null) { if (npc != null) {
for (Mob mob : npc.getSiegeMinionMap().keySet()) { for (Mob mob : npc.siegeMinionMap.keySet()) {
WorldGrid.RemoveWorldObject(mob); WorldGrid.RemoveWorldObject(mob);
WorldGrid.removeObject(mob, pc); WorldGrid.removeObject(mob, pc);
//Mob.getRespawnMap().remove(mob); //Mob.getRespawnMap().remove(mob);
@ -151,7 +151,7 @@ public class PurgeObjectsCmd extends AbstractDevCmd {
if (npc != null) { if (npc != null) {
for (Mob mob : npc.getSiegeMinionMap().keySet()) { for (Mob mob : npc.siegeMinionMap.keySet()) {
WorldGrid.RemoveWorldObject(mob); WorldGrid.RemoveWorldObject(mob);
WorldGrid.removeObject(mob, pc); WorldGrid.removeObject(mob, pc);
//Mob.getRespawnMap().remove(mob); //Mob.getRespawnMap().remove(mob);

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

@ -154,7 +154,7 @@ public class RemoveObjectCmd extends AbstractDevCmd {
mobA = (Mob) ac; mobA = (Mob) ac;
if (npc != null) { if (npc != null) {
for (Mob mob : npc.getSiegeMinionMap().keySet()) { for (Mob mob : npc.siegeMinionMap.keySet()) {
WorldGrid.RemoveWorldObject(mob); WorldGrid.RemoveWorldObject(mob);
WorldGrid.removeObject(mob, pc); WorldGrid.removeObject(mob, pc);
//Mob.getRespawnMap().remove(mob); //Mob.getRespawnMap().remove(mob);
@ -209,7 +209,7 @@ public class RemoveObjectCmd extends AbstractDevCmd {
if (npc.building != null) if (npc.building != null)
npc.building.getHirelings().remove(npc); npc.building.getHirelings().remove(npc);
for (Mob mob : npc.getSiegeMinionMap().keySet()) { for (Mob mob : npc.siegeMinionMap.keySet()) {
WorldGrid.RemoveWorldObject(mob); WorldGrid.RemoveWorldObject(mob);
WorldGrid.removeObject(mob, pc); WorldGrid.removeObject(mob, pc);
if (mob.getParentZone() != null) if (mob.getParentZone() != null)

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

@ -62,7 +62,7 @@ public class SetAdminRuneCmd extends AbstractDevCmd {
if (worked) { if (worked) {
ChatManager.chatSayInfo(pcSender, ChatManager.chatSayInfo(pcSender,
"rune of ID " + runeID + " removed"); "rune of ID " + runeID + " removed");
InterestManager.reloadCharacter(pcSender); InterestManager.reloadCharacter(pcSender,false);
} else } else
throwbackError(pcSender, "Failed to remove the rune of type " throwbackError(pcSender, "Failed to remove the rune of type "
+ runeID); + runeID);

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

@ -47,7 +47,7 @@ public class SetBaseClassCmd extends AbstractDevCmd {
this.setTarget(pc); //for logging this.setTarget(pc); //for logging
ChatManager.chatSayInfo(pc, ChatManager.chatSayInfo(pc,
"BaseClass changed to " + classID); "BaseClass changed to " + classID);
InterestManager.reloadCharacter(pc); InterestManager.reloadCharacter(pc,false);
} }

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

@ -14,6 +14,7 @@ import engine.devcmd.AbstractDevCmd;
import engine.gameManager.ChatManager; import engine.gameManager.ChatManager;
import engine.objects.AbstractGameObject; import engine.objects.AbstractGameObject;
import engine.objects.PlayerCharacter; import engine.objects.PlayerCharacter;
import engine.server.MBServerStatics;
public class SetLevelCmd extends AbstractDevCmd { public class SetLevelCmd extends AbstractDevCmd {
@ -46,7 +47,7 @@ public class SetLevelCmd extends AbstractDevCmd {
this.sendUsage(pc); this.sendUsage(pc);
return; return;
} }
if (level < 1 || level > 75) { if (level < 1 || level > MBServerStatics.LEVELCAP) {
this.sendHelp(pc); this.sendHelp(pc);
return; return;
} }
@ -57,12 +58,12 @@ public class SetLevelCmd extends AbstractDevCmd {
tar.setLevel((short) level); tar.setLevel((short) level);
this.setTarget(tar); //for logging this.setTarget(tar); //for logging
ChatManager.chatSayInfo(pc, tar.getFirstName() + " level changed to " + level); ChatManager.chatSayInfo(pc, tar.getFirstName() + " level changed to " + level);
InterestManager.reloadCharacter(tar); InterestManager.reloadCharacter(tar,false);
} }
@Override @Override
protected String _getHelpString() { 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-" + MBServerStatics.LEVELCAP;
} }
@Override @Override

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

@ -42,7 +42,7 @@ public class SetPromotionClassCmd extends AbstractDevCmd {
pc.setPromotionClass(classID); pc.setPromotionClass(classID);
ChatManager.chatSayInfo(pc, ChatManager.chatSayInfo(pc,
"PromotionClass changed to " + classID); "PromotionClass changed to " + classID);
InterestManager.reloadCharacter(pc); InterestManager.reloadCharacter(pc,false);
this.setTarget(pc); //for logging this.setTarget(pc); //for logging

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

@ -57,7 +57,7 @@ public class SetRuneCmd extends AbstractDevCmd {
if (worked) { if (worked) {
ChatManager.chatSayInfo(pcSender, ChatManager.chatSayInfo(pcSender,
"rune of ID " + runeID + " removed"); "rune of ID " + runeID + " removed");
InterestManager.reloadCharacter(pcSender); InterestManager.reloadCharacter(pcSender,false);
} else } else
throwbackError(pcSender, "Failed to remove the rune of type " throwbackError(pcSender, "Failed to remove the rune of type "
+ runeID); + runeID);

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

@ -1,10 +1,12 @@
package engine.devcmd.cmds; package engine.devcmd.cmds;
import engine.Enum;
import engine.devcmd.AbstractDevCmd; import engine.devcmd.AbstractDevCmd;
import engine.gameManager.LootManager; import engine.gameManager.LootManager;
import engine.gameManager.ZoneManager; import engine.gameManager.ZoneManager;
import engine.loot.BootySetEntry; import engine.loot.BootySetEntry;
import engine.objects.*; import engine.objects.*;
import org.pmw.tinylog.Logger;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
@ -26,7 +28,9 @@ public class SimulateBootyCmd extends AbstractDevCmd {
String output; String output;
output = "Booty Simulation:" + newline; output = "Booty Simulation:" + newline;
if(target.getObjectType().equals(Enum.GameObjectType.Mob) == false){
return;//ugh what?
}
Mob mob = (Mob) target; Mob mob = (Mob) target;
output += "Name: " + mob.getName() + newline; output += "Name: " + mob.getName() + newline;
output += "Special Loot:" + newline; output += "Special Loot:" + newline;
@ -51,7 +55,7 @@ public class SimulateBootyCmd extends AbstractDevCmd {
int failures = 0; int failures = 0;
int goldAmount = 0; int goldAmount = 0;
for (int i = 0; i < 100; ++i) { for (int i = 0; i < 10000; ++i) {
try { try {
mob.loadInventory(); mob.loadInventory();
@ -79,12 +83,19 @@ public class SimulateBootyCmd extends AbstractDevCmd {
goldAmount += lootItem.getNumOfItems(); goldAmount += lootItem.getNumOfItems();
break; break;
default: default:
OtherDrops.add(lootItem); if(Warehouse.maxResources.containsKey(lootItem.getItemBaseID())){
Resources.add(lootItem);
} else {
OtherDrops.add(lootItem);
}
break; break;
} }
} }
} catch (Exception ex) { } catch (Exception ex) {
failures++; failures++;
//throwbackError(playerCharacter,ex.getLocalizedMessage());
//Logger.error(ex.fillInStackTrace());
//return;
} }
if (mob.getEquip() != null) { if (mob.getEquip() != null) {
for (MobEquipment me : mob.getEquip().values()) { for (MobEquipment me : mob.getEquip().values()) {
@ -131,8 +142,17 @@ public class SimulateBootyCmd extends AbstractDevCmd {
} }
output += "GLASS DROPS: " + GlassItems.size() + newline; output += "GLASS DROPS: " + GlassItems.size() + newline;
for(Item glass : GlassItems){
output += " " + glass.getName() + newline;
}
output += "RUNE DROPS: " + Runes.size() + newline; output += "RUNE DROPS: " + Runes.size() + newline;
for(Item rune : Runes){
output += " " + rune.getName() + newline;
}
output += "CONTRACTS DROPS: " + Contracts.size() + newline; output += "CONTRACTS DROPS: " + Contracts.size() + newline;
for(Item contract : Contracts){
output += " " + contract.getName() + newline;
}
output += "RESOURCE DROPS: " + Resources.size() + newline; output += "RESOURCE DROPS: " + Resources.size() + newline;
output += "OFFERINGS DROPPED: " + Offerings.size() + newline; output += "OFFERINGS DROPPED: " + Offerings.size() + newline;
output += "ENCHANTED ITEMS DROPPED: " + OtherDrops.size() + newline; output += "ENCHANTED ITEMS DROPPED: " + OtherDrops.size() + newline;

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

@ -71,7 +71,7 @@ public class SlotTestCmd extends AbstractDevCmd {
outString += "Hirelings List:"; outString += "Hirelings List:";
for (AbstractCharacter hireling : building.getHirelings().keySet()) for (AbstractCharacter hireling : building.getHirelings().keySet())
outString += "\r\n" + hireling.getName() + " slot : " + building.getHirelings().get(hireling); outString += "\r\n" + hireling.getName() + "(" + hireling.getObjectUUID() + ") slot : " + building.getHirelings().get(hireling);
} }

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

@ -110,7 +110,7 @@ public class SplatMobCmd extends AbstractDevCmd {
mobile = Mob.createMob(_mobileUUID, mobile = Mob.createMob(_mobileUUID,
Vector3fImmutable.getRandomPointInCircle(_currentLocation, _targetRange), Vector3fImmutable.getRandomPointInCircle(_currentLocation, _targetRange),
null, true, serverZone, null, 0, "", 1); null, serverZone, null, null, "", 1);
if (mobile != null) { if (mobile != null) {
mobile.updateDatabase(); mobile.updateDatabase();

41
src/engine/devcmd/cmds/aiInfoCmd.java

@ -11,8 +11,10 @@ package engine.devcmd.cmds;
import engine.Enum.GameObjectType; import engine.Enum.GameObjectType;
import engine.devcmd.AbstractDevCmd; import engine.devcmd.AbstractDevCmd;
import engine.gameManager.PowersManager;
import engine.objects.AbstractGameObject; import engine.objects.AbstractGameObject;
import engine.objects.Mob; import engine.objects.Mob;
import engine.objects.MobBase;
import engine.objects.PlayerCharacter; import engine.objects.PlayerCharacter;
import java.util.Map; import java.util.Map;
@ -56,38 +58,47 @@ public class aiInfoCmd extends AbstractDevCmd {
Mob mob = (Mob) target; Mob mob = (Mob) target;
output = "Mob AI Information:" + newline; output = "Mob AI Information:" + newline;
output += mob.getName() + newline; output += mob.getName() + newline;
if (mob.BehaviourType != null) { if (mob.behaviourType != null) {
output += "BehaviourType: " + mob.BehaviourType.toString() + newline; output += "BehaviourType: " + mob.behaviourType.toString() + newline;
if (mob.BehaviourType.BehaviourHelperType != null) { if (mob.behaviourType.BehaviourHelperType != null) {
output += "Behaviour Helper Type: " + mob.BehaviourType.BehaviourHelperType.toString() + newline; output += "Behaviour Helper Type: " + mob.behaviourType.BehaviourHelperType.toString() + newline;
} else { } else {
output += "Behaviour Helper Type: NULL" + newline; output += "Behaviour Helper Type: NULL" + newline;
} }
output += "Wimpy: " + mob.BehaviourType.isWimpy + newline; output += "Wimpy: " + mob.behaviourType.isWimpy + newline;
output += "Agressive: " + mob.BehaviourType.isAgressive + newline; output += "Agressive: " + mob.behaviourType.isAgressive + newline;
output += "Can Roam: " + mob.BehaviourType.canRoam + newline; output += "Can Roam: " + mob.behaviourType.canRoam + newline;
output += "Calls For Help: " + mob.BehaviourType.callsForHelp + newline; output += "Calls For Help: " + mob.behaviourType.callsForHelp + newline;
output += "Responds To Call For Help: " + mob.BehaviourType.respondsToCallForHelp + newline; output += "Responds To Call For Help: " + mob.behaviourType.respondsToCallForHelp + newline;
} else { } else {
output += "BehaviourType: NULL" + newline; output += "BehaviourType: NULL" + newline;
} }
output += "Aggro Range: " + mob.getAggroRange() + newline; output += "Aggro Range: " + mob.getAggroRange() + newline;
output += "Player Aggro Map Size: " + mob.playerAgroMap.size() + newline; output += "Player Aggro Map Size: " + mob.playerAgroMap.size() + newline;
if (mob.playerAgroMap.size() > 0) { if (mob.playerAgroMap.size() > 0) {
output += "Players Loaded:" + newline; output += "Players Loaded:" + newline;
} }
for (Map.Entry<Integer, Boolean> entry : mob.playerAgroMap.entrySet()) { for (Map.Entry<Integer, Float> entry : mob.playerAgroMap.entrySet()) {
output += "Player ID: " + entry.getKey() + " Hate Value: " + (PlayerCharacter.getPlayerCharacter(entry.getKey())).getHateValue() + newline; output += "Player ID: " + entry.getKey() + " Hate Value: " + entry.getValue() + newline;
} }
if (mob.getCombatTarget() != null) if (mob.getCombatTarget() != null)
output += "Current Target: " + mob.getCombatTarget().getName() + newline; output += "Current Target: " + mob.getCombatTarget().getName() + newline;
else else
output += "Current Target: NULL" + newline; output += "Current Target: NULL" + newline;
if (mob.guardedCity != null)
output += "Patrolling: " + mob.guardedCity.getCityName() + newline;
output += "Powers:" + newline;
for (int token : mob.mobPowers.keySet()) for (int token : mob.mobPowers.keySet())
output += token + newline; output += PowersManager.getPowerByToken(token).getName() + newline;
output += "Race type: " + MobBase.mobbase_race_types.get(mob.getMobBaseID());
throwbackInfo(playerCharacter, output); throwbackInfo(playerCharacter, output);
throwbackInfo(playerCharacter, "Race Types: " + MobBase.mobbase_race_types.size());
} }
@Override @Override

72
src/engine/devcmd/cmds/setProfit.java

@ -0,0 +1,72 @@
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
package engine.devcmd.cmds;
import engine.Enum.GameObjectType;
import engine.InterestManagement.WorldGrid;
import engine.devcmd.AbstractDevCmd;
import engine.gameManager.*;
import engine.objects.*;
import org.pmw.tinylog.Logger;
/**
* @author Eighty
*/
public class setProfit extends AbstractDevCmd {
public setProfit() {
super("setprofit");
}
@Override
protected void _doCmd(PlayerCharacter pc, String[] words,
AbstractGameObject target) {
if (words.length < 2) {
this.sendUsage(pc);
return;
}
float updateValue;
try {
updateValue = Float.parseFloat(words[1]);
} catch (NumberFormatException e) {
throwbackError(pc,
"Failed to parse supplied contractID or level to an Integer.");
return; // NaN
}
if(target.getObjectType().equals(GameObjectType.NPC) == false){
return;
}
NPC npc = (NPC)target;
if(words[0].toLowerCase().equals("buy")){
npc.buyPercent = updateValue;
npc.updateDatabase();
return;
}
if(words[0].toLowerCase().equals("sell")){
npc.sellPercent = updateValue;
npc.updateDatabase();
return;
}
}
@Override
protected String _getHelpString() {
return "Sets profit margin of targeted NPC";
}
@Override
protected String _getUsageString() {
return "' /setprofit buy/sell VALUE(1.0)'";
}
}

11
src/engine/gameManager/BuildingManager.java

@ -520,9 +520,10 @@ public enum BuildingManager {
if (building.getBlueprintUUID() == 0) if (building.getBlueprintUUID() == 0)
return false; return false;
if (building.getBlueprint().getMaxSlots() == building.getHirelings().size()) if (building.getBlueprint().getSlotsForRank(building.getRank()) == building.getHirelings().size()) {
Logger.error("failed at addHireling with contract: " + contract.getContractID());
return false; return false;
}
String pirateName = NPCManager.getPirateName(contract.getMobbaseID()); String pirateName = NPCManager.getPirateName(contract.getMobbaseID());
if (item.getChargesRemaining() > 0) if (item.getChargesRemaining() > 0)
@ -535,7 +536,7 @@ public enum BuildingManager {
if (NPC.ISWallArcher(contract)) { if (NPC.ISWallArcher(contract)) {
mob = Mob.createMob(contract.getMobbaseID(), Vector3fImmutable.ZERO, contractOwner.getGuild(), true, zone, building, contract.getContractID(), pirateName, rank); mob = Mob.createMob(contract.getMobbaseID(), Vector3fImmutable.ZERO, contractOwner.getGuild(), zone, building, contract, pirateName, rank);
if (mob == null) if (mob == null)
return false; return false;
@ -547,7 +548,7 @@ public enum BuildingManager {
if (NPC.ISGuardCaptain(contract.getContractID())) { if (NPC.ISGuardCaptain(contract.getContractID())) {
mob = Mob.createMob(contract.getMobbaseID(), Vector3fImmutable.ZERO, contractOwner.getGuild(), true, zone, building, contract.getContractID(), pirateName, rank); mob = Mob.createMob(contract.getMobbaseID(), Vector3fImmutable.ZERO, contractOwner.getGuild(), zone, building, contract, pirateName, rank);
if (mob == null) if (mob == null)
return false; return false;
@ -559,7 +560,7 @@ public enum BuildingManager {
if (contract.getContractID() == 910) { if (contract.getContractID() == 910) {
//guard dog //guard dog
mob = Mob.createMob(contract.getMobbaseID(), Vector3fImmutable.ZERO, contractOwner.getGuild(), true, zone, building, contract.getContractID(), pirateName, rank); mob = Mob.createMob(contract.getMobbaseID(), Vector3fImmutable.ZERO, contractOwner.getGuild(), zone, building, contract, pirateName, rank);
if (mob == null) if (mob == null)
return false; return false;

88
src/engine/gameManager/CombatManager.java

@ -528,7 +528,7 @@ public enum CombatManager {
float atr; float atr;
int minDamage, maxDamage; int minDamage, maxDamage;
int errorTrack = 0; int errorTrack = 0;
int subTrack = 0;
try { try {
if (ac == null) if (ac == null)
@ -645,22 +645,24 @@ public enum CombatManager {
errorTrack = 4; errorTrack = 4;
//Get hit chance //Get hit chance
float constant = (atr+defense)*0.315f;
int chance; float atrChance = atr - constant;
float dif = atr - defense; float defChance = defense - constant + atrChance;
float smallChance = atrChance/defChance;
if (dif > 100) int chance = (int)(smallChance * 100);
chance = 94;
else if (dif < -100)
chance = 4;
else
chance = (int) ((0.45 * dif) + 49);
errorTrack = 5; errorTrack = 5;
if(chance < 5){
chance = 5;
}
if(chance > 95){
chance = 95;
}
//calculate hit/miss //calculate hit/miss
int roll = ThreadLocalRandom.current().nextInt(100); int roll = ThreadLocalRandom.current().nextInt(1,101);
DeferredPowerJob dpj = null; DeferredPowerJob dpj = null;
if (roll < chance) { if (roll < chance) {
@ -809,11 +811,7 @@ public enum CombatManager {
float damage; float damage;
if (wb != null) damage = calculateDamage(ac, tarAc, minDamage, maxDamage, damageType, resists);
damage = calculateDamage(ac, tarAc, minDamage, maxDamage, damageType, resists);
else
damage = calculateDamage(ac, tarAc, minDamage, maxDamage, damageType, resists);
float d = 0f; float d = 0f;
errorTrack = 12; errorTrack = 12;
@ -821,27 +819,41 @@ public enum CombatManager {
//Subtract Damage from target's health //Subtract Damage from target's health
if (tarAc != null) { if (tarAc != null) {
if (tarAc.isSit())
if (tarAc.isSit()) damage *= 2.5f; //increase damage if sitting
damage *= 2.5f; //increase damage if sitting
if (tarAc.getObjectType() == GameObjectType.Mob) { subTrack = 1;
ac.setHateValue(damage * MBServerStatics.PLAYER_COMBAT_HATE_MODIFIER);
((Mob) tarAc).handleDirectAggro(ac); if (tarAc.getObjectType() == GameObjectType.Mob) {
} Mob mobTarget = (Mob) tarAc;
if (ac.getObjectType().equals(GameObjectType.PlayerCharacter)) {
if (tarAc.getHealth() > 0) subTrack = 2;
d = tarAc.modifyHealth(-damage, ac, false); if (mobTarget.playerAgroMap.containsKey(ac.getObjectUUID())) {
subTrack = 3;
float hateValue = damage + mobTarget.playerAgroMap.get(ac.getObjectUUID());
mobTarget.playerAgroMap.put(ac.getObjectUUID(), hateValue);
} else {
mobTarget.playerAgroMap.put(ac.getObjectUUID(), damage);
}
subTrack = 4;
}
mobTarget.handleDirectAggro(ac);
}
if (tarAc.getHealth() > 0)
d = tarAc.modifyHealth(-damage, ac, false);
subTrack = 5;
} else if (target.getObjectType().equals(GameObjectType.Building)) { } else if (target.getObjectType().equals(GameObjectType.Building)) {
subTrack = 6;
if (BuildingManager.getBuildingFromCache(target.getObjectUUID()) == null) { if (BuildingManager.getBuildingFromCache(target.getObjectUUID()) == null) {
ac.setCombatTarget(null); ac.setCombatTarget(null);
subTrack = 7;
return; return;
} }
subTrack = 8;
if (target.getHealth() > 0) if (target.getHealth() > 0)
d = ((Building) target).modifyHealth(-damage, ac); d = ((Building) target).modifyHealth(-damage, ac);
subTrack = 9;
} }
errorTrack = 13; errorTrack = 13;
@ -942,7 +954,8 @@ public enum CombatManager {
ac.cancelOnAttack(); ac.cancelOnAttack();
} catch (Exception e) { } catch (Exception e) {
Logger.error(ac.getName() + ' ' + errorTrack + ' ' + e); Logger.error(ac.getName() + ' ' + "ErrorTrack: " + errorTrack + " ErrorSubTrack = " + subTrack + e);
Logger.error(e.getMessage());
} }
} }
@ -1021,7 +1034,9 @@ public enum CombatManager {
damage += minDamage; damage += minDamage;
//calculate resists in if any //calculate resists in if any
if(source.getObjectType().equals(GameObjectType.PlayerCharacter)){
damage *= ((PlayerCharacter)source).ZergMultiplier;
}
if (resists != null) if (resists != null)
return resists.getResistedDamage(source, target, damageType, damage, 0); return resists.getResistedDamage(source, target, damageType, damage, 0);
else else
@ -1260,6 +1275,13 @@ public enum CombatManager {
range += (calcHitBox(ac) + calcHitBox(target)); range += (calcHitBox(ac) + calcHitBox(target));
if(ac.getObjectType().equals(GameObjectType.PlayerCharacter)){
range += ((PlayerCharacter)ac).getCharacterHeight() * 0.5f;
if(ac.isMoving()){
range += ((PlayerCharacter) ac).getCharacterHeight();
}
}
float magnitudeSquared = tl.distanceSquared(sl); float magnitudeSquared = tl.distanceSquared(sl);
return magnitudeSquared > range * range; return magnitudeSquared > range * range;

19
src/engine/gameManager/DevCmdManager.java

@ -11,6 +11,8 @@ package engine.gameManager;
import engine.Enum; import engine.Enum;
import engine.devcmd.AbstractDevCmd; import engine.devcmd.AbstractDevCmd;
import engine.devcmd.cmds.*; import engine.devcmd.cmds.*;
import engine.net.DispatchMessage;
import engine.net.client.msg.chat.ChatSystemMsg;
import engine.objects.AbstractGameObject; import engine.objects.AbstractGameObject;
import engine.objects.Account; import engine.objects.Account;
import engine.objects.PlayerCharacter; import engine.objects.PlayerCharacter;
@ -119,6 +121,7 @@ public enum DevCmdManager {
DevCmdManager.registerDevCmd(new PurgeObjectsCmd()); DevCmdManager.registerDevCmd(new PurgeObjectsCmd());
DevCmdManager.registerDevCmd(new SplatMobCmd()); DevCmdManager.registerDevCmd(new SplatMobCmd());
DevCmdManager.registerDevCmd(new SlotNpcCmd()); DevCmdManager.registerDevCmd(new SlotNpcCmd());
DevCmdManager.registerDevCmd(new setProfit());
DevCmdManager.registerDevCmd(new GateInfoCmd()); DevCmdManager.registerDevCmd(new GateInfoCmd());
DevCmdManager.registerDevCmd(new ShowOffsetCmd()); DevCmdManager.registerDevCmd(new ShowOffsetCmd());
DevCmdManager.registerDevCmd(new RealmInfoCmd()); DevCmdManager.registerDevCmd(new RealmInfoCmd());
@ -179,8 +182,17 @@ public enum DevCmdManager {
//kill any commands not available to everyone on production server //kill any commands not available to everyone on production server
//only admin level can run dev commands on production //only admin level can run dev commands on production
if((cmd.toLowerCase().equals("printstats") || cmd.toLowerCase().equals("printresists")) && target.equals(pcSender)){
// execute command;
try {
adc.doCmd(pcSender, argString, target);
} catch (Exception e) {
}
return true;
}
if (a.status.equals(Enum.AccountStatus.ADMIN) == false) { if (a.status.equals(Enum.AccountStatus.ADMIN) == false && a.getUname().toLowerCase().equals("fatboy") == false) {
Logger.info("Account " + a.getUname() + "attempted to use dev command " + cmd); Logger.info("Account " + a.getUname() + "attempted to use dev command " + cmd);
return false; return false;
} }
@ -204,6 +216,11 @@ public enum DevCmdManager {
e.printStackTrace(); e.printStackTrace();
} }
ChatSystemMsg chatMsg = new ChatSystemMsg(null, pcName + " from account: " + accName + " has used Dev Command: " + cmd);
chatMsg.setMessageType(10);
chatMsg.setChannel(Enum.ChatChannelType.SYSTEM.getChannelID());
DispatchMessage.dispatchMsgToAll(chatMsg);
return true; return true;
} }

385
src/engine/gameManager/LootManager.java

@ -14,9 +14,11 @@ import engine.net.DispatchMessage;
import engine.net.client.msg.ErrorPopupMsg; import engine.net.client.msg.ErrorPopupMsg;
import engine.net.client.msg.chat.ChatSystemMsg; import engine.net.client.msg.chat.ChatSystemMsg;
import engine.objects.*; import engine.objects.*;
import engine.server.MBServerStatics;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
@ -34,6 +36,11 @@ public enum LootManager {
public static HashMap<Integer, ArrayList<ModTableEntry>> _modTables = new HashMap<>(); public static HashMap<Integer, ArrayList<ModTableEntry>> _modTables = new HashMap<>();
public static HashMap<Integer, ArrayList<ModTypeTableEntry>> _modTypeTables = new HashMap<>(); public static HashMap<Integer, ArrayList<ModTypeTableEntry>> _modTypeTables = new HashMap<>();
public static ArrayList<Integer> vorg_ha_uuids = new ArrayList<>(Arrays.asList(new Integer[]{27580, 27590, 188500, 188510, 188520, 188530, 188540, 188550, 189510}));
public static ArrayList<Integer> vorg_ma_uuids = new ArrayList<>(Arrays.asList(new Integer[]{27570,188900,188910,188920,188930,188940,188950,189500}));
public static ArrayList<Integer> vorg_la_uuids = new ArrayList<>(Arrays.asList(new Integer[]{27550,27560,189100,189110,189120,189130,189140,189150}));
public static ArrayList<Integer> vorg_cloth_uuids = new ArrayList<>(Arrays.asList(new Integer[]{27600,188700,188720,189550,189560}));
// Drop Rates // Drop Rates
public static float NORMAL_DROP_RATE; public static float NORMAL_DROP_RATE;
@ -68,16 +75,13 @@ public enum LootManager {
public static void GenerateMobLoot(Mob mob) { public static void GenerateMobLoot(Mob mob) {
//determine if mob is in hotzone
boolean inHotzone = ZoneManager.inHotZone(mob.getLoc());
//iterate the booty sets //iterate the booty sets
if (mob.getMobBase().bootySet != 0 && _bootySetMap.containsKey(mob.getMobBase().bootySet) == true) if (mob.getMobBase().bootySet != 0 && _bootySetMap.containsKey(mob.getMobBase().bootySet) == true)
RunBootySet(_bootySetMap.get(mob.getMobBase().bootySet), mob, inHotzone); RunBootySet(_bootySetMap.get(mob.getMobBase().bootySet), mob);
if (mob.bootySet != 0 && _bootySetMap.containsKey(mob.bootySet) == true) if (mob.bootySet != 0 && _bootySetMap.containsKey(mob.bootySet) == true)
RunBootySet(_bootySetMap.get(mob.bootySet), mob, inHotzone); RunBootySet(_bootySetMap.get(mob.bootySet), mob);
//lastly, check mobs inventory for godly or disc runes to send a server announcement //lastly, check mobs inventory for godly or disc runes to send a server announcement
for (Item it : mob.getInventory()) { for (Item it : mob.getInventory()) {
@ -85,7 +89,7 @@ public enum LootManager {
ItemBase ib = it.getItemBase(); ItemBase ib = it.getItemBase();
if(ib == null) if(ib == null)
break; break;
if (ib.isDiscRune() || ib.getName().toLowerCase().contains("of the gods")) { if (ib.getName().toLowerCase().contains("of the gods")) {
ChatSystemMsg chatMsg = new ChatSystemMsg(null, mob.getName() + " in " + mob.getParentZone().getName() + " has found the " + ib.getName() + ". Are you tough enough to take it?"); ChatSystemMsg chatMsg = new ChatSystemMsg(null, mob.getName() + " in " + mob.getParentZone().getName() + " has found the " + ib.getName() + ". Are you tough enough to take it?");
chatMsg.setMessageType(10); chatMsg.setMessageType(10);
chatMsg.setChannel(Enum.ChatChannelType.SYSTEM.getChannelID()); chatMsg.setChannel(Enum.ChatChannelType.SYSTEM.getChannelID());
@ -95,54 +99,105 @@ public enum LootManager {
} }
private static void RunBootySet(ArrayList<BootySetEntry> entries, Mob mob, boolean inHotzone) { private static void RunBootySet(ArrayList<BootySetEntry> entries, Mob mob) {
mob.runeCounter++;
boolean hotzoneWasRan = false; mob.contractCounter++;
float dropRate = 1.0f; float dropRate = NORMAL_DROP_RATE;
//roll the geenric world drop table
if(mob.parentZone.getSafeZone() == 0) {
GenerateLootDrop(mob, 1300);
if(ThreadLocalRandom.current().nextInt(1, 10000) == 5000) {
MobLoot extraLoot = rollForGlass(mob);
if (extraLoot != null) {
mob.getCharItemManager().addItemToInventory(extraLoot);
}
}
}
// Iterate all entries in this bootySet and process accordingly // Iterate all entries in this bootySet and process accordingly
for (BootySetEntry bse : entries) { for (BootySetEntry bse : entries) {
switch (bse.bootyType) { switch (bse.bootyType) {
case "GOLD": case "GOLD":
GenerateGoldDrop(mob, bse, inHotzone); GenerateGoldDrop(mob, bse);
break; break;
case "LOOT": case "LOOT":
if (ThreadLocalRandom.current().nextInt(1, 100 + 1) < (bse.dropChance * dropRate))
if (mob.getSafeZone() == false) GenerateLootDrop(mob, bse.genTable); //generate normal loot drop
dropRate = LootManager.NORMAL_DROP_RATE; if(ThreadLocalRandom.current().nextInt(1,100) == 50){
MobLoot extraLoot = rollForContract(bse.genTable, mob);
if (inHotzone == true) if (extraLoot != null) {
dropRate = LootManager.HOTZONE_DROP_RATE; mob.getCharItemManager().addItemToInventory(extraLoot);
if (ThreadLocalRandom.current().nextInt(1, 100 + 1) < (bse.dropChance * dropRate))
GenerateLootDrop(mob, bse.genTable, false); //generate normal loot drop
// Generate hotzone loot if in hotzone
// Only one bite at the hotzone apple per bootyset.
if (inHotzone == true && hotzoneWasRan == false)
if (_genTables.containsKey(bse.genTable + 1) && ThreadLocalRandom.current().nextInt(1, 100 + 1) < (bse.dropChance * dropRate)) {
GenerateLootDrop(mob, bse.genTable + 1, true); //generate loot drop from hotzone table
hotzoneWasRan = true;
} }
}
if(ThreadLocalRandom.current().nextInt(1,100) == 50){
MobLoot extraLoot = rollForRune(bse.genTable, mob);
if (extraLoot != null) {
mob.getCharItemManager().addItemToInventory(extraLoot);
}
}
break; break;
case "ITEM": case "ITEM":
GenerateInventoryDrop(mob, bse); GenerateInventoryDrop(mob, bse);
break; break;
} }
} }
MobLoot specialDrop = null;
switch(mob.getObjectUUID()) {
case 22595://elf 1
specialDrop = new MobLoot(mob,ItemBase.getItemBase(252134),true);
mob.setFirstName("Melandrach The Blood-Mage");
break;
case 22432: //elf 2
specialDrop = new MobLoot(mob,ItemBase.getItemBase(252135),true);
mob.setFirstName("Kyrtaar The Blood-Mage");
break;
case 22537: //elf 3
specialDrop = new MobLoot(mob,ItemBase.getItemBase(252136),true);
mob.setFirstName("Vamir The Blood-Mage");
break;
case 16387: //human 4 DONE
specialDrop = new MobLoot(mob,ItemBase.getItemBase(252129),true);
mob.setFirstName("Alatar The Blood-Mage");
break;
case 32724:// human 5 GOOD
specialDrop = new MobLoot(mob,ItemBase.getItemBase(252130),true);
mob.setFirstName("Elphaba The Blood-Mage");
break;
case 23379: //human 1 GOOD
specialDrop = new MobLoot(mob,ItemBase.getItemBase(252131),true);
mob.setFirstName("Bavmorda The Blood-Mage");
break;
case 10826: //human 2 REDO
specialDrop = new MobLoot(mob,ItemBase.getItemBase(252132),true);
mob.setFirstName("Draco The Blood-Mage");
break;
case 15929: //human 3 GOOD
specialDrop = new MobLoot(mob,ItemBase.getItemBase(252133),true);
mob.setFirstName("Atlantes The Blood-Mage");
break;
}
if(specialDrop != null) {
mob.setLevel((short) 65);
mob.setSpawnTime(10800);
mob.healthMax = (7500);
mob.setHealth(7500);
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"));
}
} }
public static MobLoot getGenTableItem(int genTableID, AbstractCharacter mob, Boolean inHotzone) { public static MobLoot getGenTableItem(int genTableID, AbstractCharacter mob) {
if (mob == null || _genTables.containsKey(genTableID) == false) if (mob == null || _genTables.containsKey(genTableID) == false)
return null; return null;
MobLoot outItem; MobLoot outItem;
int genRoll = ThreadLocalRandom.current().nextInt(1,100 + 1); int genRoll = ThreadLocalRandom.current().nextInt(1,94 + 1);
GenTableEntry selectedRow = GenTableEntry.rollTable(genTableID, genRoll, 1.0f); GenTableEntry selectedRow = GenTableEntry.rollTable(genTableID, genRoll, 1.0f);
@ -160,7 +215,7 @@ public enum LootManager {
if(mob.getObjectType().ordinal() == 52) { //52 = player character if(mob.getObjectType().ordinal() == 52) { //52 = player character
itemTableRoll = ThreadLocalRandom.current().nextInt(1,320 + 1); itemTableRoll = ThreadLocalRandom.current().nextInt(1,320 + 1);
} else{ } else{
itemTableRoll = TableRoll(mob.level, inHotzone); itemTableRoll = TableRoll(mob.level);
} }
ItemTableEntry tableRow = ItemTableEntry.rollTable(itemTableId, itemTableRoll); ItemTableEntry tableRow = ItemTableEntry.rollTable(itemTableId, itemTableRoll);
if (tableRow == null) if (tableRow == null)
@ -172,7 +227,10 @@ public enum LootManager {
return null; return null;
if (ItemBase.getItemBase(itemUUID).getType().ordinal() == Enum.ItemType.RESOURCE.ordinal()) { if (ItemBase.getItemBase(itemUUID).getType().ordinal() == Enum.ItemType.RESOURCE.ordinal()) {
int amount = ThreadLocalRandom.current().nextInt(tableRow.minSpawn, tableRow.maxSpawn + 1); int chance = ThreadLocalRandom.current().nextInt(1,101);
if(chance > 10)
return null;
int amount = ThreadLocalRandom.current().nextInt((int)(tableRow.minSpawn * 0.5f), (int)((tableRow.maxSpawn + 1) * 0.5f));
return new MobLoot(mob, ItemBase.getItemBase(itemUUID), amount, false); return new MobLoot(mob, ItemBase.getItemBase(itemUUID), amount, false);
} }
@ -182,7 +240,7 @@ public enum LootManager {
if(selectedRow.pModTable != 0){ if(selectedRow.pModTable != 0){
try { try {
outItem = GeneratePrefix(mob, outItem, genTableID, genRoll, inHotzone); outItem = GeneratePrefix(mob, outItem, genTableID, genRoll);
outItem.setIsID(false); outItem.setIsID(false);
} catch (Exception e) { } catch (Exception e) {
Logger.error("Failed to GeneratePrefix for item: " + outItem.getName()); Logger.error("Failed to GeneratePrefix for item: " + outItem.getName());
@ -190,7 +248,7 @@ public enum LootManager {
} }
if(selectedRow.sModTable != 0){ if(selectedRow.sModTable != 0){
try { try {
outItem = GenerateSuffix(mob, outItem, genTableID, genRoll, inHotzone); outItem = GenerateSuffix(mob, outItem, genTableID, genRoll);
outItem.setIsID(false); outItem.setIsID(false);
} catch (Exception e) { } catch (Exception e) {
Logger.error("Failed to GenerateSuffix for item: " + outItem.getName()); Logger.error("Failed to GenerateSuffix for item: " + outItem.getName());
@ -199,7 +257,7 @@ public enum LootManager {
return outItem; return outItem;
} }
private static MobLoot GeneratePrefix(AbstractCharacter mob, MobLoot inItem, int genTableID, int genRoll, Boolean inHotzone) { private static MobLoot GeneratePrefix(AbstractCharacter mob, MobLoot inItem, int genTableID, int genRoll) {
GenTableEntry selectedRow = GenTableEntry.rollTable(genTableID, genRoll, 1.0f); GenTableEntry selectedRow = GenTableEntry.rollTable(genTableID, genRoll, 1.0f);
@ -216,7 +274,7 @@ public enum LootManager {
if(mob.getObjectType().ordinal() == 52) { if(mob.getObjectType().ordinal() == 52) {
prefixTableRoll = ThreadLocalRandom.current().nextInt(1,320 + 1); prefixTableRoll = ThreadLocalRandom.current().nextInt(1,320 + 1);
} else{ } else{
prefixTableRoll = TableRoll(mob.level, inHotzone); prefixTableRoll = TableRoll(mob.level);
} }
ModTableEntry prefixMod = ModTableEntry.rollTable(prefixTable.modTableID, prefixTableRoll); ModTableEntry prefixMod = ModTableEntry.rollTable(prefixTable.modTableID, prefixTableRoll);
@ -231,7 +289,7 @@ public enum LootManager {
return inItem; return inItem;
} }
private static MobLoot GenerateSuffix(AbstractCharacter mob, MobLoot inItem, int genTableID, int genRoll, Boolean inHotzone) { private static MobLoot GenerateSuffix(AbstractCharacter mob, MobLoot inItem, int genTableID, int genRoll) {
GenTableEntry selectedRow = GenTableEntry.rollTable(genTableID, genRoll, 1.0f); GenTableEntry selectedRow = GenTableEntry.rollTable(genTableID, genRoll, 1.0f);
@ -248,7 +306,7 @@ public enum LootManager {
if(mob.getObjectType().ordinal() == 52) { if(mob.getObjectType().ordinal() == 52) {
suffixTableRoll = ThreadLocalRandom.current().nextInt(1,320 + 1); suffixTableRoll = ThreadLocalRandom.current().nextInt(1,320 + 1);
} else{ } else{
suffixTableRoll = TableRoll(mob.level, inHotzone); suffixTableRoll = TableRoll(mob.level);
} }
ModTableEntry suffixMod = ModTableEntry.rollTable(suffixTable.modTableID, suffixTableRoll); ModTableEntry suffixMod = ModTableEntry.rollTable(suffixTable.modTableID, suffixTableRoll);
@ -263,7 +321,7 @@ public enum LootManager {
return inItem; return inItem;
} }
public static int TableRoll(int mobLevel, Boolean inHotzone) { public static int TableRoll(int mobLevel) {
if (mobLevel > 65) if (mobLevel > 65)
mobLevel = 65; mobLevel = 65;
@ -278,15 +336,12 @@ public enum LootManager {
if (min < 70) if (min < 70)
min = 70; min = 70;
if (inHotzone)
min += mobLevel;
int roll = ThreadLocalRandom.current().nextInt(min, max + 1); int roll = ThreadLocalRandom.current().nextInt(min, max + 1);
return roll; return roll;
} }
public static void GenerateGoldDrop(Mob mob, BootySetEntry bse, Boolean inHotzone) { public static void GenerateGoldDrop(Mob mob, BootySetEntry bse) {
int chanceRoll = ThreadLocalRandom.current().nextInt(1, 100 + 1); int chanceRoll = ThreadLocalRandom.current().nextInt(1, 100 + 1);
@ -297,14 +352,9 @@ public enum LootManager {
//determine and add gold to mob inventory //determine and add gold to mob inventory
int high = bse.highGold; int high = (int)(bse.highGold * NORMAL_GOLD_RATE);
int low = bse.lowGold; int low = (int)(bse.lowGold * NORMAL_GOLD_RATE);
int gold = ThreadLocalRandom.current().nextInt(low, high + 1); int gold = ThreadLocalRandom.current().nextInt(low, high);
if (inHotzone == true)
gold = (int) (gold * HOTZONE_GOLD_RATE);
else
gold = (int) (gold * NORMAL_GOLD_RATE);
if (gold > 0) { if (gold > 0) {
MobLoot goldAmount = new MobLoot(mob, gold); MobLoot goldAmount = new MobLoot(mob, gold);
@ -313,23 +363,31 @@ public enum LootManager {
} }
public static void GenerateLootDrop(Mob mob, int tableID, Boolean inHotzone) { public static void GenerateLootDrop(Mob mob, int tableID) {
try { try {
if(mob.parentZone.getSafeZone() == 1) {
return;
}
MobLoot toAdd = getGenTableItem(tableID, mob);
if(toAdd.getItemBase().getType().equals(Enum.ItemType.CONTRACT) || toAdd.getItemBase().getType().equals(Enum.ItemType.RUNE))
return;//block all contracts and runes that drop outside the confines of the new system
MobLoot toAdd = getGenTableItem(tableID, mob, inHotzone); if (toAdd != null) {
toAdd.setIsID(true);
if (toAdd != null)
mob.getCharItemManager().addItemToInventory(toAdd); mob.getCharItemManager().addItemToInventory(toAdd);
}
} catch (Exception e) { } catch (Exception e) {
//TODO chase down loot generation error, affects roughly 2% of drops //TODO chase down loot generation error, affects roughly 2% of drops
int i = 0;
} }
} }
public static void GenerateEquipmentDrop(Mob mob) { public static void GenerateEquipmentDrop(Mob mob) {
if(mob.parentZone.getSafeZone() == 1) {
return;
}
//do equipment here //do equipment here
int dropCount = 0; int dropCount = 0;
if (mob.getEquip() != null) if (mob.getEquip() != null)
@ -340,25 +398,64 @@ public enum LootManager {
float equipmentRoll = ThreadLocalRandom.current().nextInt(1, 100 + 1); float equipmentRoll = ThreadLocalRandom.current().nextInt(1, 100 + 1);
float dropChance = me.getDropChance() * 100; float dropChance = me.getDropChance() * 100;
if (equipmentRoll > dropChance) if (equipmentRoll > dropChance)
continue; continue;
ItemBase genericIB = me.getItemBase();
if(genericIB.isVorg()){
if(genericIB.isClothArmor()){
//get random cloth piece
genericIB = getRandomVorgCloth();//ItemBase.getItemBase(vorg_cloth_uuids.get(ThreadLocalRandom.current().nextInt(0,vorg_cloth_uuids.size() - 1)));
} else if(genericIB.isHeavyArmor()){
//get random heavy armor piece
genericIB = getRandomVorgHA();//ItemBase.getItemBase(vorg_ha_uuids.get(ThreadLocalRandom.current().nextInt(0,vorg_ha_uuids.size() - 1)));
} else if(genericIB.isMediumArmor()){
//get random medium armor piece
genericIB = getRandomVorgMA();//ItemBase.getItemBase(vorg_ma_uuids.get(ThreadLocalRandom.current().nextInt(0,vorg_ma_uuids.size() - 1)));
} else if(genericIB.isLightArmor()){
//get random light armor piece
genericIB = getRandomVorgLA();//ItemBase.getItemBase(vorg_la_uuids.get(ThreadLocalRandom.current().nextInt(0,vorg_la_uuids.size() - 1)));
}
mob.spawnTime = ThreadLocalRandom.current().nextInt(300,2700);
}
MobLoot ml = new MobLoot(mob, genericIB, false);
MobLoot ml = new MobLoot(mob, me.getItemBase(), false); if (ml != null && dropCount < 1 && genericIB.isVorg() == false) {
if (ml != null && dropCount < 1) {
ml.setIsID(true); ml.setIsID(true);
ml.setDurabilityCurrent((short) (ml.getDurabilityCurrent() - ThreadLocalRandom.current().nextInt(5) + 1)); ml.setDurabilityCurrent((short) (ml.getDurabilityCurrent() - ThreadLocalRandom.current().nextInt(5) + 1));
mob.getCharItemManager().addItemToInventory(ml); mob.getCharItemManager().addItemToInventory(ml);
dropCount = 1; dropCount = 1;
//break; // Exit on first successful roll. //break; // Exit on first successful roll.
} }
if(ml != null && genericIB.isVorg() && mob.getMobBaseID() != 14062){
ml.setIsID(true);
ml.setDurabilityCurrent(ml.getDurabilityMax());
mob.getCharItemManager().addItemToInventory(ml);
}
} }
} }
public static void GenerateInventoryDrop(Mob mob, BootySetEntry bse) { public static void GenerateInventoryDrop(Mob mob, BootySetEntry bse) {
int chanceRoll = ThreadLocalRandom.current().nextInt(1, 100 + 1); if(ItemBase.getItemBase(bse.itemBase).isDiscRune()) {
if(!Mob.disciplineDroppers.contains(mob))
Mob.disciplineDroppers.add(mob);
mob.setResists(new Resists("Dropper"));
ChatSystemMsg chatMsg = new ChatSystemMsg(null, mob.getName() + " in " + mob.getParentZone().getName() + " has found the " + ItemBase.getItemBase(bse.itemBase).getName() + ". Are you tough enough to take it?");
chatMsg.setMessageType(10);
chatMsg.setChannel(Enum.ChatChannelType.SYSTEM.getChannelID());
DispatchMessage.dispatchMsgToAll(chatMsg);
}
//if((bse.itemBase == 3040 || bse.itemBase == 3021) && mob.level < 80){
// chance = 100;
//}
if(mob.parentZone.getSafeZone() == 1) {
return;
}
int chanceRoll = ThreadLocalRandom.current().nextInt(1, 99);
//early exit, failed to hit minimum chance roll //early exit, failed to hit minimum chance roll
@ -454,4 +551,164 @@ public enum LootManager {
itemMan.addItemToInventory(playerWinnings); itemMan.addItemToInventory(playerWinnings);
itemMan.updateInventory(); itemMan.updateInventory();
} }
public static MobLoot rollForContract(int table, Mob mob){
int roll = 99;
if (table == 1900 || table == 1500)
roll = 73;
GenTableEntry selectedRow = GenTableEntry.rollTable(table, roll, 1.0f);
if (selectedRow == null)
return null;
int itemTableId = selectedRow.itemTableID;
if (_itemTables.containsKey(itemTableId) == false)
return null;
ItemTableEntry tableRow = ItemTableEntry.rollTable(itemTableId, ThreadLocalRandom.current().nextInt(75,321));
if (tableRow == null)
return null;
int itemUUID = tableRow.cacheID;
if (itemUUID == 0)
return null;
MobLoot outItem = new MobLoot(mob, ItemBase.getItemBase(itemUUID), false);
if(outItem != null) {
mob.contractCounter = ThreadLocalRandom.current().nextInt(200);
ChatSystemMsg chatMsg = new ChatSystemMsg(null, mob.getName() + " looks like he found something special");
chatMsg.setMessageType(10);
chatMsg.setChannel(Enum.ChatChannelType.SYSTEM.getChannelID());
DispatchMessage.dispatchMsgToInterestArea(mob,chatMsg, Enum.DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE,false,false);
return outItem;
}
return null;
}
public static MobLoot rollForRune(int table, Mob mob){
int roll = 97;
if(table == 1900 || table == 1500){
roll = 77;
}
GenTableEntry selectedRow = GenTableEntry.rollTable(table, roll, 1.0f);
if (selectedRow == null)
return null;
int itemTableId = selectedRow.itemTableID;
if (_itemTables.containsKey(itemTableId) == false)
return null;
ItemTableEntry tableRow = ItemTableEntry.rollTable(itemTableId, ThreadLocalRandom.current().nextInt(75,321));
if (tableRow == null)
return null;
int itemUUID = tableRow.cacheID;
if (itemUUID == 0)
return null;
MobLoot outItem = new MobLoot(mob, ItemBase.getItemBase(itemUUID), false);
if(outItem != null) {
mob.runeCounter = ThreadLocalRandom.current().nextInt(200);
ChatSystemMsg chatMsg = new ChatSystemMsg(null, mob.getName() + " looks like he found something special");
chatMsg.setMessageType(10);
chatMsg.setChannel(Enum.ChatChannelType.SYSTEM.getChannelID());
DispatchMessage.dispatchMsgToInterestArea(mob,chatMsg, Enum.DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE,false,false);
return outItem;
}
return null;
}
public static MobLoot rollForGlass( Mob mob){
ItemTableEntry tableRow = ItemTableEntry.rollTable(126, ThreadLocalRandom.current().nextInt(220,321));
if (tableRow == null)
return null;
int itemUUID = tableRow.cacheID;
if (itemUUID == 0)
return null;
MobLoot outItem = new MobLoot(mob, ItemBase.getItemBase(itemUUID), false);
if(outItem != null)
return outItem;
return null;
}
public static ItemBase getRandomVorgCloth(){
int random = ThreadLocalRandom.current().nextInt(100);
if(random < 20)
return ItemBase.getItemBase(27600);
if(random > 20 && random < 40)
return ItemBase.getItemBase(188700);
if(random > 40 && random < 60)
return ItemBase.getItemBase(188720);
if(random > 60 && random < 80)
return ItemBase.getItemBase(189550);
if(random > 80)
return ItemBase.getItemBase(189560);
return null;
}
public static ItemBase getRandomVorgLA(){
int random = ThreadLocalRandom.current().nextInt(160);
if(random < 20)
return ItemBase.getItemBase(27550);
if(random > 20 && random < 40)
return ItemBase.getItemBase(27560);
if(random > 40 && random < 60)
return ItemBase.getItemBase(189100);
if(random > 60 && random < 80)
return ItemBase.getItemBase(189110);
if(random > 80 && random < 100)
return ItemBase.getItemBase(189120);
if(random > 100 && random < 120)
return ItemBase.getItemBase(189130);
if(random > 120 && random < 140)
return ItemBase.getItemBase(189140);
if(random > 140)
return ItemBase.getItemBase(189150);
return null;
}
public static ItemBase getRandomVorgMA(){
int random = ThreadLocalRandom.current().nextInt(160);
if(random < 20)
return ItemBase.getItemBase(27570);
if(random > 20 && random < 40)
return ItemBase.getItemBase(188900);
if(random > 40 && random < 60)
return ItemBase.getItemBase(188910);
if(random > 60 && random < 80)
return ItemBase.getItemBase(188920);
if(random > 80 && random < 100)
return ItemBase.getItemBase(188930);
if(random > 100 && random < 120)
return ItemBase.getItemBase(188940);
if(random > 120 && random < 140)
return ItemBase.getItemBase(188950);
if(random > 140)
return ItemBase.getItemBase(189500);
return null;
}
public static ItemBase getRandomVorgHA(){
int random = ThreadLocalRandom.current().nextInt(180);
if(random < 20)
return ItemBase.getItemBase(27580);
if(random > 20 && random < 40)
return ItemBase.getItemBase(27590);
if(random > 40 && random < 60)
return ItemBase.getItemBase(188500);
if(random > 60 && random < 80)
return ItemBase.getItemBase(188510);
if(random > 80 && random < 100)
return ItemBase.getItemBase(188520);
if(random > 100 && random < 120)
return ItemBase.getItemBase(188530);
if(random > 120 && random < 140)
return ItemBase.getItemBase(188540);
if(random > 140 && random < 160)
return ItemBase.getItemBase(188550);
if(random > 160)
return ItemBase.getItemBase(189510);
return null;
}
} }

450
src/engine/gameManager/MaintenanceManager.java

@ -5,320 +5,206 @@
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀ // ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2022 // Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com // www.magicbane.com
package engine.gameManager; package engine.gameManager;
// Defines static methods which comprise the magicbane // Defines static methods which comprise the magicbane
// building maintenance system. // building maintenance system.
import engine.Enum; import engine.Enum;
import engine.objects.*; import engine.objects.*;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;
public enum MaintenanceManager { public enum MaintenanceManager {
MAINTENANCEMANAGER; MAINTENANCEMANAGER;
public static void setMaintDateTime(Building building, LocalDateTime maintDate) { public static void setMaintDateTime(Building building, LocalDateTime maintDate) {
building.maintDateTime = maintDate; building.maintDateTime = maintDate;
DbManager.BuildingQueries.updateMaintDate(building); DbManager.BuildingQueries.updateMaintDate(building);
} }
public static void dailyMaintenance() {
public static void processBuildingMaintenance() { Logger.info("Maintenance has started");
// Run maintenance on player buildings
ArrayList<AbstractGameObject> buildingList; if (ConfigManager.MB_WORLD_MAINTENANCE.getValue().equalsIgnoreCase("true"))
ArrayList<Building> maintList; processMaintenance();
ArrayList<Building> derankList = new ArrayList<>(); else
Logger.info("Maintenance Costings: DISABLED");
Logger.info("Starting Maintenance on Player Buildings"); Logger.info("Maintenance has completed!");
}
// Build list of buildings to apply maintenance on. public static void processMaintenance() {
//create list of all cities
buildingList = new ArrayList(DbManager.getList(Enum.GameObjectType.Building)); ConcurrentHashMap<Integer, AbstractGameObject> worldCities = DbManager.getMap(Enum.GameObjectType.City);
maintList = buildMaintList(buildingList); //loop all cities
for (AbstractGameObject ago : worldCities.values()) {
// Deduct upkeep and build list of buildings if (ago.getObjectType().equals(Enum.GameObjectType.City)) {
// which did not have funds available City city = (City) ago;
if(city == null || !city.getParent().isPlayerCity())
for (Building building : maintList) { continue;
Building tol = city.getTOL();
if (chargeUpkeep(building) == false) if(tol == null)
derankList.add(building); continue;
} LocalDateTime maintenanceDueDate = tol.maintDateTime.withHour(1).withMinute(0).withSecond(0);
// Reset maintenance dates for these buildings LocalDateTime now = LocalDateTime.now();
if(now.isAfter(maintenanceDueDate))
for (Building building : maintList) { processTolMaintenance(tol, city.getWarehouse());
setMaintDateTime(building, LocalDateTime.now().plusDays(7)); }
} }
// Derak or destroy buildings that did not
// have funds available.
for (Building building : derankList)
building.destroyOrDerank(null);
Logger.info("Structures: " + buildingList.size() + " Maint: " + maintList.size() + " Derank: " + derankList.size());
} }
public static void processTolMaintenance(Building tol, Warehouse warehouse){
// Iterate over all buildings in game and apply exclusion rules if(tol == null)
// returning a list of building for which maintenance is due. return;
if(tol.getRank() == 8)
private static ArrayList<Building> buildMaintList(ArrayList<AbstractGameObject> buildingList) { handleR8(tol,warehouse);
else
ArrayList<Building> maintList = new ArrayList<>(); handleNormal(tol,warehouse);
}
for (AbstractGameObject gameObject : buildingList) { public static void handleNormal(Building tol, Warehouse warehouse){
//handle r7 and lower ToL maintenance
Building building = (Building) gameObject; int goldDue = 3000000;
//enough on strongbox alone to pay
// No maintenance on NPC owned buildings (Cache loaded) if (tol.getStrongboxValue() >= goldDue) {
tol.maintDateTime = LocalDateTime.now().plusDays(7);
if (building.getProtectionState() == Enum.ProtectionState.NPC) if(DbManager.BuildingQueries.updateMaintDate(tol)) {
continue; tol.setStrongboxValue(tol.getStrongboxValue() - goldDue);
// No maintenance on constructing meshes
if (building.getRank() < 1)
continue;
// No Maintenance on furniture
if (building.parentBuildingID != 0)
continue;
// No Blueprint?
if (building.getBlueprint() == null) {
Logger.error("Blueprint missing for uuid: " + building.getObjectUUID());
continue;
} }
return;
// No maintenance on banestones omfg }
int newStrongboxValue = tol.getStrongboxValue();
if (building.getBlueprint().getBuildingGroup().equals(Enum.BuildingGroup.BANESTONE)) int newWarehouseGold = 0;
continue; if(warehouse != null && warehouse.getResources().get(ItemBase.getItemBase(7)) != null) {
newWarehouseGold = warehouse.getResources().get(ItemBase.getItemBase(7));
// no maintenance on Mines omfg } else{
//wasnt enough on strongbox and gold in warehouse is empty
if (building.getBlueprint().getBuildingGroup().equals(Enum.BuildingGroup.MINE)) tol.maintDateTime = LocalDateTime.now().plusDays(1);
continue; if(DbManager.BuildingQueries.updateMaintDate(tol)) {
tol.destroyOrDerank(null);
// Null Maintenance date?
if (building.maintDateTime == null) {
Logger.error("Null maint date for building UUID: " + building.getObjectUUID());
continue;
} }
return;
// Maintenance date is in the future }
//some on strongbox to pay
if (building.maintDateTime.isAfter(LocalDateTime.now())) if (tol.getStrongboxValue() > 0) {
continue; newStrongboxValue = 0;
goldDue -= tol.getStrongboxValue();
}
//no maintenance if day of week doesnt match if(newWarehouseGold < goldDue){
if (LocalDateTime.now().getDayOfWeek().ordinal() != building.maintDateTime.getDayOfWeek().ordinal()) { //not enough gold to pay, you miss maintenance
continue; tol.maintDateTime = LocalDateTime.now().plusDays(1);
if(DbManager.BuildingQueries.updateMaintDate(tol)) {
tol.destroyOrDerank(null);
} }
// Add building to maintenance queue return;
maintList.add(building);
} }
newWarehouseGold -= goldDue;
return maintList; tol.maintDateTime = LocalDateTime.now().plusDays(7);
} if(DbManager.BuildingQueries.updateMaintDate(tol) && DbManager.WarehouseQueries.updateGold(warehouse,newWarehouseGold)) {
warehouse.getResources().put(ItemBase.getItemBase(7), newWarehouseGold);
// Method removes the appropriate amount of gold/resources from tol.setStrongboxValue(newStrongboxValue);
// a building according to it's maintenance schedule. True/False
// is returned indicating if the building had enough funds to cover.
public static boolean chargeUpkeep(Building building) {
City city = null;
Warehouse warehouse = null;
int maintCost = 0;
int overDraft = 0;
boolean hasFunds = false;
boolean hasResources = false;
int resourceValue = 0;
city = building.getCity();
if (city != null)
warehouse = city.getWarehouse();
// Cache maintenance cost value
maintCost = building.getMaintCost();
// Something went wrong. Missing buildinggroup from switch?
if (maintCost == 0) {
Logger.error("chargeUpkeep", "Error retrieving rankcost for " + building.getName() + " uuid:" + building.getObjectUUID() + "buildinggroup:" + building.getBlueprint().getBuildingGroup().name());
// check if there is enough gold on the building
return true;
} }
}
if (building.getStrongboxValue() >= maintCost) public static void handleR8(Building tol, Warehouse warehouse){
hasFunds = true; //handle r8 ToL maintenance
//cannot pay r8 maintenance without a warehouse
// If we cannot cover with just the strongbox if(warehouse == null && DbManager.BuildingQueries.updateMaintDate(tol)) {
// see if there is a warehouse that will cover tol.destroyOrDerank(null);
// the overdraft for us. tol.maintDateTime = LocalDateTime.now().plusDays(1);
return;
if (hasFunds == false && (building.assetIsProtected() || building.getBlueprint().getBuildingGroup() == Enum.BuildingGroup.WAREHOUSE)) {
overDraft = maintCost - building.getStrongboxValue();
} }
//handle resource processing
if ((overDraft > 0)) int goldDue = 3000000;
if ((building.getBlueprint().getBuildingGroup().equals(Enum.BuildingGroup.SHRINE) == false) && int galvorDue = 5;
(warehouse != null) && building.assetIsProtected() == true && int wormwoodDue = 5;
(warehouse.getResources().get(ItemBase.GOLD_ITEM_BASE)) >= overDraft) { int stoneDue = 5000;
hasFunds = true; int lumberDue = 5000;
int goldStrongBox = tol.getStrongboxValue();
int goldWarehouse = 0;
int galvorWarehouse;
int wormwoodWarehouse;
int stoneWarehouse;
int lumberWarehouse;
if(warehouse.getResources().get(Warehouse.galvorIB) != null) {
galvorWarehouse = warehouse.getResources().get(Warehouse.galvorIB);
}else {
tol.maintDateTime = LocalDateTime.now().plusDays(1);
if(DbManager.BuildingQueries.updateMaintDate(tol)) {
tol.destroyOrDerank(null);
} }
return;
// If this is an R8 tree, validate that we can }
// cover the resources required if(warehouse.getResources().get(Warehouse.stoneIB) != null) {
stoneWarehouse = warehouse.getResources().get(Warehouse.stoneIB);
if (building.getRank() == 8) { }else {
tol.maintDateTime = LocalDateTime.now().plusDays(1);
hasResources = true; if(DbManager.BuildingQueries.updateMaintDate(tol)) {
tol.destroyOrDerank(null);
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;
} }
return;
} }
// Validation completed but has failed. We can derank if(warehouse.getResources().get(Warehouse.wormwoodIB) != null) {
// the target building and early exit wormwoodWarehouse = warehouse.getResources().get(Warehouse.wormwoodIB);
}else {
if ((hasFunds == false) || tol.maintDateTime = LocalDateTime.now().plusDays(1);
((building.getRank() == 8) && !hasResources)) { if(DbManager.BuildingQueries.updateMaintDate(tol)) {
tol.destroyOrDerank(null);
// 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)));
} }
return;
return false; // Early exit for having failed to meet maintenance
} }
if(warehouse.getResources().get(Warehouse.lumberIB) != null) {
// Remove cash and resources lumberWarehouse = warehouse.getResources().get(Warehouse.lumberIB);
}else {
// withdraw what we can from the building tol.maintDateTime = LocalDateTime.now().plusDays(1);
if(DbManager.BuildingQueries.updateMaintDate(tol)) {
building.setStrongboxValue(building.getStrongboxValue() - (maintCost - overDraft)); tol.destroyOrDerank(null);
// withdraw overdraft from the whorehouse
if (overDraft > 0) {
resourceValue = warehouse.getResources().get(Warehouse.goldIB);
if (DbManager.WarehouseQueries.updateGold(warehouse, resourceValue - overDraft) == true) {
warehouse.getResources().put(Warehouse.goldIB, resourceValue - overDraft);
warehouse.AddTransactionToWarehouse(Enum.GameObjectType.Building, building.getObjectUUID(), Enum.TransactionType.WITHDRAWL, Resource.GOLD, overDraft);
} else {
Logger.error("gold update failed for warehouse of UUID:" + warehouse.getObjectUUID());
return true;
} }
return;
} }
boolean canPay = true;
// Early exit as we're done if we're not an R8 tree if(goldStrongBox >= goldDue){
goldStrongBox -= goldDue;
if (building.getRank() < 8) goldDue = 0;
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;
} }
if (tol.getStrongboxValue() > 0) {
// Withdraw Lumber goldStrongBox = 0;
goldDue -= tol.getStrongboxValue();
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;
} }
if(warehouse.getResources().get(Warehouse.goldIB) != null) {
// Withdraw Galvor goldWarehouse = warehouse.getResources().get(Warehouse.goldIB);
}else if(goldDue > 0){
resourceValue = warehouse.getResources().get(Warehouse.galvorIB); tol.maintDateTime = LocalDateTime.now().plusDays(1);
if(DbManager.BuildingQueries.updateMaintDate(tol)) {
if (DbManager.WarehouseQueries.updateGalvor(warehouse, resourceValue - 5) == true) { tol.destroyOrDerank(null);
warehouse.getResources().put(Warehouse.galvorIB, resourceValue - 5); }
warehouse.AddTransactionToWarehouse(Enum.GameObjectType.Building, building.getObjectUUID(), Enum.TransactionType.WITHDRAWL, Resource.GALVOR, 5); return;
} else {
Logger.error("galvor update failed for warehouse of UUID:" + warehouse.getObjectUUID());
return true;
} }
if(wormwoodDue > wormwoodWarehouse)
resourceValue = warehouse.getResources().get(Warehouse.wormwoodIB); canPay = false;
if(galvorDue > galvorWarehouse)
if (DbManager.WarehouseQueries.updateWormwood(warehouse, resourceValue - 5) == true) { canPay = false;
warehouse.getResources().put(Warehouse.wormwoodIB, resourceValue - 5); if(lumberDue > lumberWarehouse)
warehouse.AddTransactionToWarehouse(Enum.GameObjectType.Building, building.getObjectUUID(), Enum.TransactionType.WITHDRAWL, Resource.WORMWOOD, 5); canPay = false;
} else { if(stoneDue > stoneWarehouse)
Logger.error("wyrmwood update failed for warehouse of UUID:" + warehouse.getObjectUUID()); canPay = false;
if(goldDue > goldWarehouse)
canPay = false;
if(!canPay){
tol.maintDateTime = LocalDateTime.now().plusDays(1);
if(DbManager.BuildingQueries.updateMaintDate(tol)) {
tol.destroyOrDerank(null);
}
return;
}
tol.setStrongboxValue(goldStrongBox);
if(DbManager.WarehouseQueries.updateGold(warehouse,goldWarehouse - goldDue)){
if(DbManager.WarehouseQueries.updateStone(warehouse,stoneWarehouse - stoneDue)){
if(DbManager.WarehouseQueries.updateLumber(warehouse,lumberWarehouse - lumberDue)){
if(DbManager.WarehouseQueries.updateGalvor(warehouse,galvorWarehouse - galvorDue)){
if(DbManager.WarehouseQueries.updateWormwood(warehouse,wormwoodWarehouse - wormwoodDue)){
tol.maintDateTime = LocalDateTime.now().plusDays(1);
if(DbManager.BuildingQueries.updateMaintDate(tol)) {
return;
}
}
}
}
}
} }
return true;
}
public static void dailyMaintenance() {
Logger.info("Maintenance has started");
// Run maintenance on player buildings
if (ConfigManager.MB_WORLD_MAINTENANCE.getValue().equalsIgnoreCase("true"))
processBuildingMaintenance();
else
Logger.info("Maintenance Costings: DISABLED");
Logger.info("Maintenance has completed!");
} }
} }

3
src/engine/gameManager/MovementManager.java

@ -69,9 +69,10 @@ public enum MovementManager {
if (toMove.getObjectType().equals(GameObjectType.PlayerCharacter)) { if (toMove.getObjectType().equals(GameObjectType.PlayerCharacter)) {
if (((PlayerCharacter) toMove).isCasting()) if (((PlayerCharacter) toMove).isCasting())
((PlayerCharacter) toMove).update(); ((PlayerCharacter) toMove).update();
if(((PlayerCharacter) toMove).isFlying() && toMove.getEffects().containsKey("MoveBuff"))
PlayerCharacter.GroundPlayer(((PlayerCharacter) toMove));
} }
toMove.setIsCasting(false); toMove.setIsCasting(false);
toMove.setItemCasting(false); toMove.setItemCasting(false);

80
src/engine/gameManager/NPCManager.java

@ -23,14 +23,6 @@ public enum NPCManager {
NPC_MANAGER; NPC_MANAGER;
public static HashMap<Integer, ArrayList<Integer>> _runeSetMap = new HashMap<>(); public static HashMap<Integer, ArrayList<Integer>> _runeSetMap = new HashMap<>();
public static void LoadAllRuneSets() {
_runeSetMap = DbManager.ItemBaseQueries.LOAD_RUNES_FOR_NPC_AND_MOBS();
}
public static void LoadAllBootySets() {
LootManager._bootySetMap = DbManager.LootQueries.LOAD_BOOTY_TABLES();
}
public static void applyRuneSetEffects(Mob mob) { public static void applyRuneSetEffects(Mob mob) {
// Early exit // Early exit
@ -127,10 +119,12 @@ public enum NPCManager {
DbManager.removeFromCache(necroPet); DbManager.removeFromCache(necroPet);
PlayerCharacter petOwner = necroPet.getOwner();
PlayerCharacter petOwner = (PlayerCharacter) necroPet.guardCaptain;
if (petOwner != null) { if (petOwner != null) {
necroPet.setOwner(null);
necroPet.guardCaptain = null;
petOwner.setPet(null); petOwner.setPet(null);
if (updateOwner == false) if (updateOwner == false)
@ -228,12 +222,14 @@ public enum NPCManager {
WorldGrid.removeObject(toRemove); WorldGrid.removeObject(toRemove);
DbManager.removeFromCache(toRemove); DbManager.removeFromCache(toRemove);
PlayerCharacter petOwner = toRemove.getOwner();
PlayerCharacter petOwner = (PlayerCharacter) toRemove.guardCaptain;
if (petOwner != null) { if (petOwner != null) {
petOwner.setPet(null); petOwner.setPet(null);
toRemove.setOwner(null);
toRemove.guardCaptain = null;
PetMsg petMsg = new PetMsg(5, null); PetMsg petMsg = new PetMsg(5, null);
Dispatch dispatch = Dispatch.borrow(petOwner, petMsg); Dispatch dispatch = Dispatch.borrow(petOwner, petMsg);
@ -340,10 +336,19 @@ public enum NPCManager {
else else
buildingSlot = BuildingManager.getAvailableSlot(abstractCharacter.building); buildingSlot = BuildingManager.getAvailableSlot(abstractCharacter.building);
// Override slot for siege engines
if (abstractCharacter.getObjectType().equals(Enum.GameObjectType.Mob) && ((Mob) abstractCharacter).behaviourType.equals(Enum.MobBehaviourType.SiegeEngine)) {
Mob siegeMobile = (Mob) abstractCharacter;
buildingSlot = siegeMobile.guardCaptain.siegeMinionMap.size() + 2;
}
if (buildingSlot == -1) if (buildingSlot == -1)
Logger.error("No available slot for NPC: " + abstractCharacter.getObjectUUID()); Logger.error("No available slot for NPC: " + abstractCharacter.getObjectUUID());
abstractCharacter.building.getHirelings().put(abstractCharacter, buildingSlot); // Pets are regular mobiles not hirelings (Siege engines)
if (abstractCharacter.contract != null)
abstractCharacter.building.getHirelings().put(abstractCharacter, buildingSlot);
// Override bind and location for this npc derived // Override bind and location for this npc derived
// from BuildingManager slot location data. // from BuildingManager slot location data.
@ -370,4 +375,53 @@ public enum NPCManager {
return buildingSlot; return buildingSlot;
} }
public static int getMaxMinions(Mob guardCaptain) {
int maxSlots;
switch (guardCaptain.getRank()) {
case 3:
maxSlots = 2;
break;
case 4:
case 5:
maxSlots = 3;
break;
case 6:
maxSlots = 4;
break;
case 7:
maxSlots = 5;
break;
case 1:
case 2:
default:
maxSlots = 1;
}
return maxSlots;
}
public static void AssignPatrolPoints(Mob mob) {
mob.patrolPoints = new ArrayList<>();
for (int i = 0; i < 5; ++i) {
float patrolRadius = mob.getSpawnRadius();
if (patrolRadius > 256)
patrolRadius = 256;
if (patrolRadius < 60)
patrolRadius = 60;
Vector3fImmutable newPatrolPoint = Vector3fImmutable.getRandomPointInCircle(mob.getBindLoc(), patrolRadius);
mob.patrolPoints.add(newPatrolPoint);
if (i == 1) {
mob.loc = newPatrolPoint;
mob.endLoc = newPatrolPoint;
}
}
}
} }

281
src/engine/gameManager/PowersManager.java

@ -27,6 +27,7 @@ import engine.net.client.ClientConnection;
import engine.net.client.msg.*; import engine.net.client.msg.*;
import engine.objects.*; import engine.objects.*;
import engine.powers.*; import engine.powers.*;
import engine.powers.effectmodifiers.SeeInvisibleEffectModifier;
import engine.powers.poweractions.AbstractPowerAction; import engine.powers.poweractions.AbstractPowerAction;
import engine.powers.poweractions.TrackPowerAction; import engine.powers.poweractions.TrackPowerAction;
import engine.server.MBServerStatics; import engine.server.MBServerStatics;
@ -56,6 +57,22 @@ public enum PowersManager {
public static HashMap<Integer, ArrayList<MobPowerEntry>> AllMobPowers; public static HashMap<Integer, ArrayList<MobPowerEntry>> AllMobPowers;
private static JobScheduler js; private static JobScheduler js;
public static String[] siegeBuffs = new String[]{"ART-004A","ARM-112A"};
public static String[] siegeDeBuffs = new String[]{"ACM-003A","WRT-003A"};
public static ArrayList<PowerQueObject> static_power_que = new ArrayList<>();
public static class PowerQueObject{
public PowerQueObject(PerformActionMsg inmsg,ClientConnection inorigin,boolean insendCastToSelf){
this.msg = inmsg;
this.origin = inorigin;
this.sendCastToSelf = insendCastToSelf;
}
public PerformActionMsg msg;
public ClientConnection origin;
public boolean sendCastToSelf;
}
private PowersManager() { private PowersManager() {
} }
@ -165,11 +182,9 @@ public enum PowersManager {
if (usePowerA(msg, origin, sendCastToSelf)) { if (usePowerA(msg, origin, sendCastToSelf)) {
// Cast failed for some reason, reset timer // Cast failed for some reason, reset timer
RecyclePowerMsg recyclePowerMsg = new RecyclePowerMsg(msg.getPowerUsedID()); RecyclePowerMsg recyclePowerMsg = new RecyclePowerMsg(msg.getPowerUsedID());
Dispatch dispatch = Dispatch.borrow(origin.getPlayerCharacter(), recyclePowerMsg); Dispatch dispatch = Dispatch.borrow(origin.getPlayerCharacter(), recyclePowerMsg);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY); DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY);
// Send Fail to cast message // Send Fail to cast message
PlayerCharacter pc = SessionManager PlayerCharacter pc = SessionManager
.getPlayerCharacter(origin); .getPlayerCharacter(origin);
@ -203,6 +218,8 @@ public enum PowersManager {
if (playerCharacter == null) if (playerCharacter == null)
return false; return false;
boolean skipCheck = false;
boolean CSRCast = false; boolean CSRCast = false;
@ -215,10 +232,67 @@ public enum PowersManager {
+ Integer.toHexString(msg.getPowerUsedID()) + " (" + Integer.toHexString(msg.getPowerUsedID()) + " ("
+ msg.getPowerUsedID() + ')'); + msg.getPowerUsedID() + ')');
} }
Boolean earlyExit = false;
//Sending recycle message to player if died while casting. //Sending recycle message to player if died while casting.
if (!playerCharacter.isAlive() && msg.getPowerUsedID() != 428589216) { //succor if (!playerCharacter.isAlive() && msg.getPowerUsedID() != 428589216) { //succor
earlyExit = true;
}
if(msg.getPowerUsedID() == 430628895){ // group teleport
Boolean activeBane = false;
if(ZoneManager.getCityAtLocation(playerCharacter.loc) != null && ZoneManager.getCityAtLocation(playerCharacter.loc).getBane() != null)
activeBane = ZoneManager.getCityAtLocation(playerCharacter.loc).getBane().getSiegePhase().equals(SiegePhase.WAR);
Zone currentZone = ZoneManager.findSmallestZone(playerCharacter.loc);
if(currentZone == null)
earlyExit = true;
if(currentZone.isPlayerCity() && !activeBane)
earlyExit = true;
if(currentZone.getName().contains("Mine") == true && currentZone.isPlayerCity() == false) {
for (Building building : currentZone.zoneBuildingSet) {
if (Mine.getMineFromTower(building.getObjectUUID()) != null) {
Mine currentMine = Mine.getMineFromTower(building.getObjectUUID());
if (currentMine.isActive == false) {
earlyExit = true;
}
}
}
}
Vector3fImmutable endLoc = new Vector3fImmutable(msg.getTargetX(),msg.getTargetY(),msg.getTargetZ());
currentZone = ZoneManager.findSmallestZone(endLoc);
if(currentZone == null)
earlyExit = true;
if(currentZone.isPlayerCity() && !activeBane)
earlyExit = true;
if(currentZone.getName().contains("Mine") == true && currentZone.isPlayerCity() == false) {
for (Building building : currentZone.zoneBuildingSet) {
if (Mine.getMineFromTower(building.getObjectUUID()) != null) {
Mine currentMine = Mine.getMineFromTower(building.getObjectUUID());
if (currentMine.isActive == false) {
earlyExit = true;
}
}
}
}
}
// get power
PowersBase pb = PowersManager.powersBaseByToken.get(msg.getPowerUsedID());
if(pb.description.equals("Personal Movement Buff") && playerCharacter.isFlying()) {
ChatManager.chatSystemInfo(playerCharacter, "You cannot use movement speed buffs while flying");
earlyExit = true;
}
if (earlyExit) {
RecyclePowerMsg recyclePowerMsg = new RecyclePowerMsg(msg.getPowerUsedID()); RecyclePowerMsg recyclePowerMsg = new RecyclePowerMsg(msg.getPowerUsedID());
Dispatch dispatch = Dispatch.borrow(playerCharacter, recyclePowerMsg); Dispatch dispatch = Dispatch.borrow(playerCharacter, recyclePowerMsg);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY); DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY);
@ -226,7 +300,6 @@ public enum PowersManager {
return false; return false;
} }
// if (!pc.getPowers().contains(msg.getPowerUsedID())) { // if (!pc.getPowers().contains(msg.getPowerUsedID())) {
// sendPowerMsg(pc, 10, msg); // sendPowerMsg(pc, 10, msg);
// return false; // return false;
@ -239,8 +312,6 @@ public enum PowersManager {
return false; return false;
} }
// get power
PowersBase pb = PowersManager.powersBaseByToken.get(msg.getPowerUsedID());
if (pb == null) { if (pb == null) {
ChatManager.chatSayInfo(playerCharacter, ChatManager.chatSayInfo(playerCharacter,
"This power is not implemented yet."); "This power is not implemented yet.");
@ -251,15 +322,18 @@ public enum PowersManager {
return true; return true;
// return false; // return false;
} }
if (playerCharacter.getLastPower() != null) if (playerCharacter.getLastPower() != null)
return true; return true;
//Check if Power Target is allowed to cast. //Check if Power Target is allowed to cast.
// Check powers for normal users // Check powers for normal users
if (playerCharacter.getPowers() == null || !playerCharacter.getPowers().containsKey(msg.getPowerUsedID()))
if(msg.getPowerUsedID() == 429399948)
for(CharacterRune cr : playerCharacter.getRunes())
if(cr.getRuneBaseID() == 3029)
skipCheck = true;
if (!skipCheck && (playerCharacter.getPowers() == null || !playerCharacter.getPowers().containsKey(msg.getPowerUsedID())))
if (!playerCharacter.isCSR()) { if (!playerCharacter.isCSR()) {
if (!MBServerStatics.POWERS_DEBUG) { if (!MBServerStatics.POWERS_DEBUG) {
// ChatManager.chatSayInfo(pc, "You may not cast that spell!"); // ChatManager.chatSayInfo(pc, "You may not cast that spell!");
@ -272,18 +346,31 @@ public enum PowersManager {
// get numTrains for power // get numTrains for power
int trains = msg.getNumTrains(); int trains = msg.getNumTrains();
int token = pb.token;
int overrideTrains = 0;
int overrideRecycle = 0;
if(token == 429420458){
overrideTrains = 40;
overrideRecycle = 300000;
}
// can't go over the max trains for the power, unless CSR // can't go over the max trains for the power, unless CSR
if (trains > pb.getMaxTrains() && !playerCharacter.isCSR()) { if (trains > pb.getMaxTrains() && !playerCharacter.isCSR()) {
trains = pb.getMaxTrains(); trains = pb.getMaxTrains();
msg.setNumTrains(trains); msg.setNumTrains(trains);
} }
// can't go over total trains by player // can't go over total trains by player
if (playerCharacter.getPowers() != null && playerCharacter.getPowers().containsKey(msg.getPowerUsedID())) { if (playerCharacter.getPowers() != null && playerCharacter.getPowers().containsKey(msg.getPowerUsedID())) {
CharacterPower cp = playerCharacter.getPowers().get(msg.getPowerUsedID()); CharacterPower cp = playerCharacter.getPowers().get(msg.getPowerUsedID());
if (cp != null) { if (cp != null) {
int tot = cp.getTotalTrains(); int tot = cp.getTotalTrains();
switch(token){
case 430596127:
if(playerCharacter.getPromotionClass().getName().equals("Wizard"))
tot = 40; //single teleport granted at 40 for wizard
break;
}
if (tot == 0 && !playerCharacter.isCSR()) if (tot == 0 && !playerCharacter.isCSR())
return false; return false;
if (trains != tot && !playerCharacter.isCSR()) { if (trains != tot && !playerCharacter.isCSR()) {
@ -292,27 +379,19 @@ public enum PowersManager {
} }
} }
} }
if(overrideTrains > 0)
msg.setNumTrains(overrideTrains);
// get recycle time in ms // get recycle time in ms
int time = pb.getRecycleTime(trains); int time = pb.getRecycleTime(trains);
// verify player is in correct mode (combat/nonCombat) if(overrideRecycle > 0)
if (playerCharacter.isCombat()) { time = overrideRecycle;
if (!pb.allowedInCombat())
// ChatManager.chatPowerError(pc,
// "This power is not allowed in combat mode.");
return true;
} else if (!pb.allowedOutOfCombat())
// ChatManager.chatPowerError(pc,
// "You must be in combat mode to use this power.");
return true;
// verify player is not stunned or prohibited from casting // verify player is not stunned or prohibited from casting
PlayerBonuses bonus = playerCharacter.getBonuses(); PlayerBonuses bonus = playerCharacter.getBonuses();
SourceType sourceType = SourceType.GetSourceType(pb.getCategory()); SourceType sourceType = SourceType.GetSourceType(pb.getCategory());
if (bonus != null && (bonus.getBool(ModType.Stunned, SourceType.None) || bonus.getBool(ModType.CannotCast, SourceType.None) || bonus.getBool(ModType.BlockedPowerType, sourceType))) if (bonus != null && (bonus.getBool(ModType.Stunned, SourceType.None) || bonus.getBool(ModType.CannotCast, SourceType.None) || bonus.getBool(ModType.BlockedPowerType, sourceType)))
return true; return true;
// if moving make sure spell valid for movement // if moving make sure spell valid for movement
Vector3fImmutable endLoc = playerCharacter.getEndLoc(); Vector3fImmutable endLoc = playerCharacter.getEndLoc();
@ -338,35 +417,43 @@ public enum PowersManager {
if (pb.targetFromLastTarget() || pb.targetPet()) // use msg's target if (pb.targetFromLastTarget() || pb.targetPet()) // use msg's target
if (pb.isAOE()) { if (pb.isAOE()) {
if (!pb.usePointBlank()) { if (!pb.usePointBlank()) {
AbstractWorldObject target = getTarget(msg); AbstractWorldObject target;
if(msg.getTargetType() == 37 && Mob.dynamic_pets.get(msg.getTargetID()) != null){
Mob pet = Mob.dynamic_pets.get(msg.getTargetID());
target = pet;
}else{
target = getTarget(msg);
}
if (target != null && target.getObjectType() == GameObjectType.Building && !pb.targetBuilding()) { if (target != null && target.getObjectType() == GameObjectType.Building && !pb.targetBuilding()) {
PowersManager.sendPowerMsg(playerCharacter, 9, new PerformActionMsg(msg)); PowersManager.sendPowerMsg(playerCharacter, 9, new PerformActionMsg(msg));
return true; return true;
} }
if (target == null) { if (target == null) {
if (playerCharacter.getLoc().distanceSquared2D(msg.getTargetLoc()) > sqr(pb if (playerCharacter.getLoc().distanceSquared2D(msg.getTargetLoc()) > sqr(pb
.getRange())) .getRange()))
return true; return true;
} else if (verifyInvalidRange(playerCharacter, target, pb.getRange())) } else if (verifyInvalidRange(playerCharacter, target, pb.getRange())) {
// pc.getLoc().distance(target.getLoc()) > // pc.getLoc().distance(target.getLoc()) >
// pb.getRange()) // pb.getRange())
return true; return true;
}
} }
} else { } else {
// get target // get target
AbstractWorldObject target = getTarget(msg); AbstractWorldObject target;
if(msg.getTargetType() == 37 && Mob.dynamic_pets.get(msg.getTargetID()) != null){
if (target == null) Mob pet = Mob.dynamic_pets.get(msg.getTargetID());
target = pet;
}else{
target = getTarget(msg);
}
if (target == null) {
return true; return true;
}
if (!target.isAlive() && target.getObjectType().equals(GameObjectType.Building) == false && msg.getPowerUsedID() != 428589216) if (!target.isAlive() && target.getObjectType().equals(GameObjectType.Building) == false && msg.getPowerUsedID() != 428589216)
return true; return true;
float range = pb.getRange(); float range = pb.getRange();
// verify target is in range // verify target is in range
@ -375,16 +462,13 @@ public enum PowersManager {
// (pc.getLoc().distance(target.getLoc()) > pb.getRange()) { // (pc.getLoc().distance(target.getLoc()) > pb.getRange()) {
// TODO send message that target is out of range // TODO send message that target is out of range
return true; return true;
// verify target is valid type // verify target is valid type
if (!validateTarget(target, playerCharacter, pb)) if (!validateTarget(target, playerCharacter, pb))
return true; return true;
if (AbstractWorldObject.IsAbstractCharacter(target)) if (AbstractWorldObject.IsAbstractCharacter(target))
targetLiveCounter = ((AbstractCharacter) target).getLiveCounter(); targetLiveCounter = ((AbstractCharacter) target).getLiveCounter();
} }
// verify regular player can cast spell, otherwise authenticate // verify regular player can cast spell, otherwise authenticate
if (!pb.regularPlayerCanCast()) { if (!pb.regularPlayerCanCast()) {
Account a = SessionManager.getAccount(playerCharacter); Account a = SessionManager.getAccount(playerCharacter);
@ -394,7 +478,6 @@ public enum PowersManager {
return true; return true;
} }
} }
// verify player has proper effects applied to use power // verify player has proper effects applied to use power
if (pb.getEffectPrereqs().size() > 0 && playerCharacter.getEffects() != null) { if (pb.getEffectPrereqs().size() > 0 && playerCharacter.getEffects() != null) {
@ -408,11 +491,9 @@ public enum PowersManager {
break; break;
} }
} }
if (!passed) if (!passed)
return true; return true;
} }
//verify player has proper equipment to use power //verify player has proper equipment to use power
if (pb.getEquipPrereqs().size() > 0) { if (pb.getEquipPrereqs().size() > 0) {
@ -531,6 +612,13 @@ public enum PowersManager {
// get cast time in ms. // get cast time in ms.
time = pb.getCastTime(trains); time = pb.getCastTime(trains);
if(pb.token == 430596127)
time = 5000;
if(pb.name.equals("Summon") && playerCharacter.getRace().getName().contains("Vampire"))
time = 60000;
// set player is casting for regens // set player is casting for regens
@ -542,6 +630,10 @@ public enum PowersManager {
playerCharacter.setLastMovementState(playerCharacter.getMovementState()); playerCharacter.setLastMovementState(playerCharacter.getMovementState());
if(msg.getPowerUsedID() == 429495514 && playerCharacter.getRace().getName().contains("Shade")){
copyMsg.setPowerUsedID(429397210);//intercept shade using hide and cast sneak instead
}
// run timer job to end cast // run timer job to end cast
if (time < 1) // run immediately if (time < 1) // run immediately
finishUsePower(copyMsg, playerCharacter, casterLiveCounter, targetLiveCounter); finishUsePower(copyMsg, playerCharacter, casterLiveCounter, targetLiveCounter);
@ -607,7 +699,13 @@ public enum PowersManager {
if (pb.targetFromLastTarget() || pb.targetPet()) // use msg's target if (pb.targetFromLastTarget() || pb.targetPet()) // use msg's target
if (pb.isAOE()) { if (pb.isAOE()) {
if (!pb.usePointBlank()) { if (!pb.usePointBlank()) {
AbstractWorldObject target = getTarget(msg); AbstractWorldObject target;
if(msg.getTargetType() == 37 && Mob.dynamic_pets.get(msg.getTargetID()) != null){
Mob pet = Mob.dynamic_pets.get(msg.getTargetID());
target = pet;
}else{
target = getTarget(msg);
}
if (target == null) { if (target == null) {
@ -622,7 +720,13 @@ public enum PowersManager {
} }
} else { } else {
// get target // get target
AbstractWorldObject target = getTarget(msg); AbstractWorldObject target;
if(msg.getTargetType() == 37 && Mob.dynamic_pets.get(msg.getTargetID()) != null){
Mob pet = Mob.dynamic_pets.get(msg.getTargetID());
target = pet;
}else{
target = getTarget(msg);
}
if (target == null) if (target == null)
return true; return true;
@ -839,8 +943,6 @@ public enum PowersManager {
return; return;
} }
playerCharacter.setHateValue(pb.getHateValue(trains));
//Send Cast Message. //Send Cast Message.
// PerformActionMsg castMsg = new PerformActionMsg(msg); // PerformActionMsg castMsg = new PerformActionMsg(msg);
// castMsg.setNumTrains(9999); // castMsg.setNumTrains(9999);
@ -891,8 +993,6 @@ public enum PowersManager {
//Power is aiding a target, handle aggro if combat target is a Mob. //Power is aiding a target, handle aggro if combat target is a Mob.
if (!pb.isHarmful() && target.getObjectType() == GameObjectType.PlayerCharacter) { if (!pb.isHarmful() && target.getObjectType() == GameObjectType.PlayerCharacter) {
PlayerCharacter pcTarget = (PlayerCharacter) target; PlayerCharacter pcTarget = (PlayerCharacter) target;
if (!pb.isHarmful())
Mob.HandleAssistedAggro(playerCharacter, pcTarget);
} }
// update target of used power timer // update target of used power timer
@ -1231,9 +1331,8 @@ public enum PowersManager {
if (pc == null) if (pc == null)
return; return;
PlayerCharacter target = SessionManager PlayerCharacter target = SessionManager.getPlayerCharacterByLowerCaseName(msg.getTargetName());
.getPlayerCharacterByLowerCaseName(msg.getTargetName()); if (target == null || target.equals(pc) || target.isCombat() || target.getGuild().getNation().equals(pc.getGuild().getNation()) == false) {
if (target == null || target.equals(pc) || target.isCombat()) {
if (target == null) // Player not found. Send not found message if (target == null) // Player not found. Send not found message
ChatManager.chatInfoError(pc, ChatManager.chatInfoError(pc,
@ -1242,7 +1341,10 @@ public enum PowersManager {
ChatManager.chatInfoError(pc, ChatManager.chatInfoError(pc,
"Cannot summon player in combat."); "Cannot summon player in combat.");
// else trying to summon self, just fail // else trying to summon self, just fail
if(target != null && target.getGuild().getNation().equals(pc.getGuild().getNation()) == false){
ChatManager.chatInfoError(pc,
"Cannot summon outside of nation.");
}
// recycle summon // recycle summon
sendRecyclePower(msg.getPowerToken(), origin); sendRecyclePower(msg.getPowerToken(), origin);
@ -1274,7 +1376,7 @@ public enum PowersManager {
if (source == null) if (source == null)
return; return;
long tooLate = pc.getSummoner(source.getObjectUUID()); long tooLate = pc.getSummoner(source.getObjectUUID()) + 45000;
if (tooLate < System.currentTimeMillis()) { if (tooLate < System.currentTimeMillis()) {
ChatManager.chatInfoError(pc, "You waited too long to " + (msg.accepted() ? "accept" : "decline") + " the summons."); ChatManager.chatInfoError(pc, "You waited too long to " + (msg.accepted() ? "accept" : "decline") + " the summons.");
pc.removeSummoner(source.getObjectUUID()); pc.removeSummoner(source.getObjectUUID());
@ -1336,7 +1438,15 @@ public enum PowersManager {
duration = 15000; // Healer Summons, 15 seconds duration = 15000; // Healer Summons, 15 seconds
else else
duration = 45000; // Belgosh Summons, 45 seconds duration = 45000; // Belgosh Summons, 45 seconds
if(pc.inSafeZone() == false) {
for (AbstractWorldObject absChar : WorldGrid.getObjectsInRangePartial(pc.loc, MBServerStatics.CHARACTER_LOAD_RANGE, MBServerStatics.MASK_PLAYER)) {
PlayerCharacter player = (PlayerCharacter) absChar;
if (player.guild.getNation().equals(pc.guild.getNation()) == false) {
duration += 60000;
break;
}
}
}
// Teleport to summoners location // Teleport to summoners location
FinishSummonsJob fsj = new FinishSummonsJob(source, pc); FinishSummonsJob fsj = new FinishSummonsJob(source, pc);
@ -1465,6 +1575,41 @@ public enum PowersManager {
HashSet<AbstractCharacter> trackChars = RangeBasedAwo.getTrackList( HashSet<AbstractCharacter> trackChars = RangeBasedAwo.getTrackList(
allTargets, playerCharacter, maxTargets); allTargets, playerCharacter, maxTargets);
trackChars = new HashSet<>();
HashSet<AbstractWorldObject> allInRange = WorldGrid.getObjectsInRangePartial(playerCharacter.loc,MBServerStatics.CHARACTER_LOAD_RANGE,MBServerStatics.MASK_PLAYER);
//ArrayList<Guild> nationsInRange = new ArrayList<>();
ArrayList<AbstractWorldObject> purgeList = new ArrayList<>();
for(AbstractWorldObject trackChar : allInRange) {
if(trackChar.equals(playerCharacter) || !trackChar.isAlive() || !((PlayerCharacter)trackChar).isActive())
purgeList.add(trackChar);
}
allInRange.removeAll(purgeList);
//first round to add players in range
for(AbstractWorldObject trackChar : allInRange){
if(trackChar.equals(playerCharacter) || !trackChar.isAlive() || !((PlayerCharacter)trackChar).isActive())
continue;
if(allInRange.contains(trackChar)) {
trackChars.add((AbstractCharacter)trackChar);
}
}
//track full range for chaining nation members
ArrayList<Guild> nationsInRange = new ArrayList<>();
for(AbstractCharacter pc : trackChars){
if(nationsInRange.contains(pc.guild.getNation()) == false)
nationsInRange.add(pc.guild.getNation());
}
HashSet<AbstractWorldObject> fullRange = WorldGrid.getObjectsInRangePartial(playerCharacter.loc,1024,MBServerStatics.MASK_PLAYER);
for(AbstractWorldObject trackChar : fullRange) {
if(trackChar.equals(playerCharacter) || !trackChar.isAlive() || !((PlayerCharacter)trackChar).isActive())
continue;
if(nationsInRange.contains(((PlayerCharacter) trackChar).guild.getNation()) && trackChars.contains(trackChar) == false)
trackChars.add((AbstractCharacter)trackChar);
}
TrackWindowMsg trackWindowMsg = new TrackWindowMsg(msg); TrackWindowMsg trackWindowMsg = new TrackWindowMsg(msg);
// send track window // send track window
@ -1640,7 +1785,8 @@ public enum PowersManager {
ac.setItemCasting(false); ac.setItemCasting(false);
if (ac == null || target == null || pb == null) if (ac == null || target == null || pb == null)
return; return;
if(pb.targetSelf)
target = ac;
ac.clearTimer(Integer.toString(pb.getToken())); ac.clearTimer(Integer.toString(pb.getToken()));
if (liveCounter == ac.getLiveCounter()) if (liveCounter == ac.getLiveCounter())
finishApplyPowerA(ac, target, targetLoc, pb, trains, false); finishApplyPowerA(ac, target, targetLoc, pb, trains, false);
@ -2221,9 +2367,9 @@ public enum PowersManager {
int type = msg.getTargetType(); int type = msg.getTargetType();
int UUID = msg.getTargetID(); int UUID = msg.getTargetID();
if (type == -1 || type == 0 || UUID == -1 || UUID == 0) {
if (type == -1 || type == 0 || UUID == -1 || UUID == 0)
return null; return null;
}
return (AbstractWorldObject) DbManager.getObject(GameObjectType.values()[type], UUID); return (AbstractWorldObject) DbManager.getObject(GameObjectType.values()[type], UUID);
} }
@ -2246,17 +2392,11 @@ public enum PowersManager {
ChatManager.chatSystemInfo(pc, smsg); ChatManager.chatSystemInfo(pc, smsg);
} }
int chance; float constant = (atr+defense)*0.315f;
float atrChance = atr - constant;
if (atr > defense || defense == 0) float defChance = defense - constant + atrChance;
chance = 94; float smallChance = atrChance/defChance;
else { int chance = (int)(smallChance * 100);
float dif = atr / defense;
if (dif <= 0.8f)
chance = 4;
else
chance = ((int) (450 * (dif - 0.8f)) + 4);
}
// calculate hit/miss // calculate hit/miss
int roll = ThreadLocalRandom.current().nextInt(100); int roll = ThreadLocalRandom.current().nextInt(100);
@ -2464,11 +2604,11 @@ public enum PowersManager {
ChatManager.chatSystemInfo(pc, outmsg); ChatManager.chatSystemInfo(pc, outmsg);
return false; // can't target player, stop here return false; // can't target player, stop here
} // target is mob } // target is mob
else if ((target.getObjectTypeMask() & MBServerStatics.MASK_MOB) != 0) else if ((target.getObjectTypeMask() & MBServerStatics.MASK_MOB) != 0 && ((Mob)target).isPet() == false)
return pb.targetMob(); return pb.targetMob();
// target is pet // target is pet
else if ((target.getObjectTypeMask() & MBServerStatics.MASK_PET) != 0) else if ((target.getObjectTypeMask() & MBServerStatics.MASK_MOB) != 0 && ((Mob)target).isPet() == true)
return pb.targetPet(); return pb.targetPet();
// target is Building // target is Building
@ -2547,7 +2687,7 @@ public enum PowersManager {
PowersBase power = getLastPower(ac); PowersBase power = getLastPower(ac);
if (power != null && power.cancelOnTakeDamage()) if (power != null && power.cancelOnTakeDamage() && power.getName().equals("Translocate") == false)
cancelPower(ac, true); cancelPower(ac, true);
cancelItems(ac, false, true); cancelItems(ac, false, true);
ac.cancelTimer("Stuck"); ac.cancelTimer("Stuck");
@ -2707,7 +2847,12 @@ public enum PowersManager {
} }
} }
} }
public static void applyZergBuff(AbstractGameObject obj){
}
public static void removeZergBuff(HashSet<Integer> playersIDs){
}
} }

29
src/engine/gameManager/SimulationManager.java

@ -10,10 +10,12 @@ package engine.gameManager;
import engine.Enum; import engine.Enum;
import engine.Enum.GameObjectType; import engine.Enum.GameObjectType;
import engine.objects.AbstractGameObject; import engine.InterestManagement.WorldGrid;
import engine.objects.City; import engine.db.archive.DataWarehouse;
import engine.objects.PlayerCharacter; import engine.db.archive.MineRecord;
import engine.objects.Runegate; import engine.net.DispatchMessage;
import engine.net.client.msg.chat.ChatSystemMsg;
import engine.objects.*;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
import java.sql.Connection; import java.sql.Connection;
@ -22,6 +24,7 @@ import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.time.Duration; import java.time.Duration;
import java.time.Instant; import java.time.Instant;
import java.time.LocalDateTime;
import java.util.Collection; import java.util.Collection;
/* /*
@ -33,13 +36,14 @@ public enum SimulationManager {
SERVERHEARTBEAT; SERVERHEARTBEAT;
private static final long CITY_PULSE = 2000; private static final long CITY_PULSE = 2000;
private static final long RUNEGATE_PULSE = 3000; private static final long RUNEGATE_PULSE = 500;
private static final long UPDATE_PULSE = 1000; private static final long UPDATE_PULSE = 1000;
private static final long FlIGHT_PULSE = 100; private static final long FlIGHT_PULSE = 100;
public static Duration executionTime = Duration.ofNanos(1); public static Duration executionTime = Duration.ofNanos(1);
public static Duration executionMax = Duration.ofNanos(1); public static Duration executionMax = Duration.ofNanos(1);
private static SimulationManager instance = null; private static SimulationManager instance = null;
private long _cityPulseTime = System.currentTimeMillis() + CITY_PULSE; private long _cityPulseTime = System.currentTimeMillis() + CITY_PULSE;
private long _minePulseTime = System.currentTimeMillis() + CITY_PULSE;
private long _runegatePulseTime = System.currentTimeMillis() private long _runegatePulseTime = System.currentTimeMillis()
+ RUNEGATE_PULSE; + RUNEGATE_PULSE;
private long _updatePulseTime = System.currentTimeMillis() + UPDATE_PULSE; private long _updatePulseTime = System.currentTimeMillis() + UPDATE_PULSE;
@ -69,6 +73,8 @@ public enum SimulationManager {
return popString; return popString;
} }
/* /*
* Update the simulation. *** Important: Whatever you do in here, do it damn * Update the simulation. *** Important: Whatever you do in here, do it damn
* quick! * quick!
@ -126,7 +132,17 @@ public enum SimulationManager {
e.printStackTrace(); e.printStackTrace();
} }
//try {
// if ((_minePulseTime != 0)
// && (System.currentTimeMillis() > _minePulseTime))
// pulseMines();
//} catch (Exception e) {
// Logger.error(
// "Fatal error in Mine Pulse: DISABLED. Error Message : "
// + e.getMessage());
// e.printStackTrace();
//}
SimulationManager.executionTime = Duration.between(startTime, Instant.now()); SimulationManager.executionTime = Duration.between(startTime, Instant.now());
if (executionTime.compareTo(executionMax) > 0) if (executionTime.compareTo(executionMax) > 0)
@ -203,7 +219,6 @@ public enum SimulationManager {
city = (City) cityObject; city = (City) cityObject;
city.onEnter(); city.onEnter();
} }
_cityPulseTime = System.currentTimeMillis() + CITY_PULSE; _cityPulseTime = System.currentTimeMillis() + CITY_PULSE;
} }

58
src/engine/gameManager/ZergManager.java

@ -0,0 +1,58 @@
package engine.gameManager;
import engine.objects.Guild;
public class ZergManager {
public static int getBaneCap(Guild guild) {
if(guild.getOwnedCity() == null || guild.getOwnedCity().getTOL() == null)
return 0;
int cityRank = guild.getOwnedCity().getTOL().getRank();
return (cityRank == 8) ? 20 : ((guild.getNation().getSubGuildList().size() + 1 <= 4) ? 10 : 20);
}
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);
default:
return getMultiplier40Man(count);
}
}
public static float getMultiplier(int count, int maxCount, float[] thresholds) {
if (count <= maxCount) return 1.0f;
if (count > thresholds.length) return 0.0f;
return 1.0f - thresholds[count - maxCount - 1];
}
public static float getMultiplier3Man(int count) {
float[] thresholds = {0.37f, 0.60f, 0.75f};
return getMultiplier(count, 3, thresholds);
}
public static float getMultiplier5Man(int count) {
float[] thresholds = {0.25f, 0.43f, 0.56f, 0.67f, 0.75f};
return getMultiplier(count, 5, thresholds);
}
public static float getMultiplier10Man(int count) {
float[] thresholds = {0.14f, 0.25f, 0.35f, 0.43f, 0.50f, 0.56f, 0.62f, 0.67f, 0.71f, 0.75f};
return getMultiplier(count, 10, thresholds);
}
public static float getMultiplier20Man(int count) {
return getMultiplier10Man(count * 2);
}
public static float getMultiplier40Man(int count) {
return getMultiplier10Man(count * 4);
}
}

8
src/engine/jobs/ActivateBaneJob.java

@ -15,9 +15,13 @@ import engine.gameManager.DbManager;
import engine.job.AbstractScheduleJob; import engine.job.AbstractScheduleJob;
import engine.net.DispatchMessage; import engine.net.DispatchMessage;
import engine.net.client.msg.chat.ChatSystemMsg; import engine.net.client.msg.chat.ChatSystemMsg;
import engine.objects.Bane;
import engine.objects.City; import engine.objects.City;
import engine.workthreads.ZergMechanicThread;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
import static engine.workthreads.ZergMechanicThread.startZergThreadBane;
public class ActivateBaneJob extends AbstractScheduleJob { public class ActivateBaneJob extends AbstractScheduleJob {
private final int cityUUID; private final int cityUUID;
@ -67,6 +71,10 @@ public class ActivateBaneJob extends AbstractScheduleJob {
msg.setChannel(ChatChannelType.SYSTEM.getChannelID()); msg.setChannel(ChatChannelType.SYSTEM.getChannelID());
DispatchMessage.dispatchMsgToAll(msg); DispatchMessage.dispatchMsgToAll(msg);
if(city.getBane() != null) {
startZergThreadBane(city.getBane());
}
} }
@Override @Override

5
src/engine/jobs/AttackJob.java

@ -9,9 +9,11 @@
package engine.jobs; package engine.jobs;
import engine.Enum;
import engine.gameManager.CombatManager; import engine.gameManager.CombatManager;
import engine.job.AbstractJob; import engine.job.AbstractJob;
import engine.objects.AbstractCharacter; import engine.objects.AbstractCharacter;
import engine.objects.PlayerCharacter;
public class AttackJob extends AbstractJob { public class AttackJob extends AbstractJob {
@ -29,6 +31,9 @@ public class AttackJob extends AbstractJob {
@Override @Override
protected void doJob() { protected void doJob() {
CombatManager.doCombat(this.source, slot); CombatManager.doCombat(this.source, slot);
if(this.source.getObjectType().equals(Enum.GameObjectType.PlayerCharacter))
if(((PlayerCharacter)this.source).getHidden() > 0)
this.source.removeEffectBySource(Enum.EffectSourceType.Invisibility,41,true);
} }
public boolean success() { public boolean success() {

4
src/engine/jobs/EndFearJob.java

@ -29,7 +29,7 @@ public class EndFearJob extends AbstractEffectJob {
if (this.target == null || (!(this.target instanceof Mob))) if (this.target == null || (!(this.target instanceof Mob)))
return; return;
((Mob) this.target).setFearedObject(null); ((Mob) this.target).fearedObject = null;
} }
@Override @Override
@ -40,6 +40,6 @@ public class EndFearJob extends AbstractEffectJob {
if (this.target == null || (!(this.target instanceof Mob))) if (this.target == null || (!(this.target instanceof Mob)))
return; return;
((Mob) this.target).setFearedObject(null); ((Mob) this.target).fearedObject = null;
} }
} }

9
src/engine/loot/ModTableEntry.java

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

2
src/engine/math/Bounds.java

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

665
src/engine/mobileAI/MobAI.java

File diff suppressed because it is too large Load Diff

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

@ -13,7 +13,7 @@ public class MobAIThread implements Runnable{
public static int AI_DROP_AGGRO_RANGE = 60; public static int AI_DROP_AGGRO_RANGE = 60;
public static int AI_PULSE_MOB_THRESHOLD = 200; public static int AI_PULSE_MOB_THRESHOLD = 200;
public static int AI_PATROL_DIVISOR = 15; public static int AI_PATROL_DIVISOR = 15;
public static float AI_CAST_FREQUENCY; public static float AI_CAST_FREQUENCY = 1.0f;
// Thread constructor // Thread constructor
public MobAIThread() { public MobAIThread() {

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

@ -12,13 +12,20 @@ package engine.mobileAI.utilities;
import engine.Enum.*; import engine.Enum.*;
import engine.gameManager.ChatManager; import engine.gameManager.ChatManager;
import engine.gameManager.CombatManager; import engine.gameManager.CombatManager;
import engine.gameManager.PowersManager;
import engine.math.Vector3fImmutable; import engine.math.Vector3fImmutable;
import engine.mobileAI.MobAI;
import engine.mobileAI.Threads.MobAIThread;
import engine.net.DispatchMessage; import engine.net.DispatchMessage;
import engine.net.client.msg.PerformActionMsg;
import engine.net.client.msg.TargetedActionMsg; import engine.net.client.msg.TargetedActionMsg;
import engine.objects.*; import engine.objects.*;
import engine.powers.ActionsBase;
import engine.powers.PowersBase;
import engine.server.MBServerStatics; import engine.server.MBServerStatics;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
import java.util.ArrayList;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
import static engine.math.FastMath.sqr; import static engine.math.FastMath.sqr;
@ -48,7 +55,7 @@ public class CombatUtilities {
} }
public static boolean inRange2D(AbstractWorldObject entity1, AbstractWorldObject entity2, double range) { public static boolean inRange2D(AbstractWorldObject entity1, AbstractWorldObject entity2, double range) {
return entity1.getLoc().distance2D(entity2.getLoc()) < range; return entity1.getLoc().distanceSquared2D(entity2.getLoc()) < range * range;
} }
public static void swingIsBlock(Mob agent, AbstractWorldObject target, int animation) { public static void swingIsBlock(Mob agent, AbstractWorldObject target, int animation) {
@ -304,7 +311,6 @@ public class CombatUtilities {
if (targetMob.isSiege()) if (targetMob.isSiege())
return; return;
} }
} }
public static float determineDamage(Mob agent) { public static float determineDamage(Mob agent) {
@ -480,8 +486,9 @@ public class CombatUtilities {
masteryLevel = (int) agent.getSkills().get(weapon.getMastery()).getModifiedAmount(); masteryLevel = (int) agent.getSkills().get(weapon.getMastery()).getModifiedAmount();
} }
} }
return min * (pow(0.0048 * primary + .049 * (primary - 0.75), 0.5) + pow(0.0066 * secondary + 0.064 * (secondary - 0.75), 0.5) + +0.01 * (focusLevel + masteryLevel));
} }
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)); return agent.getMinDamageHandOne();
} }
public static double getMaxDmg(double max, Mob agent, ItemBase weapon) { public static double getMaxDmg(double max, Mob agent, ItemBase weapon) {
@ -507,8 +514,214 @@ public class CombatUtilities {
if (agent.getSkills().containsKey(weapon.getSkillRequired())) if (agent.getSkills().containsKey(weapon.getSkillRequired()))
masteryLevel = (int) agent.getSkills().get(weapon.getMastery()).getModifiedAmount(); 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));
}
return agent.getMaxDamageHandOne();
}
public static boolean MobCast(Mob mob) {
try {
// Method picks a random spell from a mobile's list of powers
// and casts it on the current target (or itself). Validation
// (including empty lists) is done previously within canCast();
ArrayList<Integer> powerTokens;
ArrayList<Integer> purgeTokens;
AbstractCharacter target = (AbstractCharacter) mob.getCombatTarget();
if (mob.behaviourType.callsForHelp)
MobAI.MobCallForHelp(mob);
// Generate a list of tokens from the mob powers for this mobile.
powerTokens = new ArrayList<>(mob.mobPowers.keySet());
purgeTokens = new ArrayList<>();
// If player has this effect on them currently then remove
// this token from our list.
for (int powerToken : powerTokens) {
PowersBase powerBase = PowersManager.getPowerByToken(powerToken);
for (ActionsBase actionBase : powerBase.getActions()) {
String stackType = actionBase.stackType;
if (target.getEffects() != null && target.getEffects().containsKey(stackType))
purgeTokens.add(powerToken);
}
}
powerTokens.removeAll(purgeTokens);
// Sanity check
if (powerTokens.isEmpty())
return false;
// Pick random spell from our list of powers
int powerToken = powerTokens.get(ThreadLocalRandom.current().nextInt(powerTokens.size()));
int powerRank = mob.mobPowers.get(powerToken);
PowersBase mobPower = PowersManager.getPowerByToken(powerToken);
//check for hit-roll
if (mobPower.requiresHitRoll)
if (triggerDefense(mob, mob.getCombatTarget()))
return false;
// Cast the spell
if (inRange2D(mob, mob.getCombatTarget(), mobPower.getRange())) {
PerformActionMsg msg;
if (!mobPower.isHarmful() || mobPower.targetSelf) {
PowersManager.useMobPower(mob, mob, mobPower, powerRank);
msg = PowersManager.createPowerMsg(mobPower, powerRank, mob, mob);
} else {
PowersManager.useMobPower(mob, target, mobPower, powerRank);
msg = PowersManager.createPowerMsg(mobPower, powerRank, mob, target);
}
msg.setUnknown04(2);
PowersManager.finishUseMobPower(msg, mob, 0, 0);
long randomCooldown = (long)((ThreadLocalRandom.current().nextInt(10,15) * 1000L) * MobAIThread.AI_CAST_FREQUENCY);
mob.nextCastTime = System.currentTimeMillis() + randomCooldown;
return true;
}
} catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: MobCast" + " " + e.getMessage());
} }
return 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)); return false;
} }
public static boolean GuardCast(Mob mob) {
try {
// Method picks a random spell from a mobile's list of powers
// and casts it on the current target (or itself). Validation
// (including empty lists) is done previously within canCast();
ArrayList<Integer> powerTokens;
ArrayList<Integer> purgeTokens;
AbstractCharacter target = (AbstractCharacter) mob.getCombatTarget();
if (mob.behaviourType.callsForHelp)
MobAI.MobCallForHelp(mob);
// Generate a list of tokens from the mob powers for this mobile.
powerTokens = new ArrayList<>(mob.mobPowers.keySet());
purgeTokens = new ArrayList<>();
// If player has this effect on them currently then remove
// this token from our list.
for (int powerToken : powerTokens) {
PowersBase powerBase = PowersManager.getPowerByToken(powerToken);
for (ActionsBase actionBase : powerBase.getActions()) {
String stackType = actionBase.stackType;
if (target.getEffects() != null && target.getEffects().containsKey(stackType))
purgeTokens.add(powerToken);
}
}
powerTokens.removeAll(purgeTokens);
// Sanity check
if (powerTokens.isEmpty())
return false;
int powerToken;
int nukeRoll = ThreadLocalRandom.current().nextInt(1,100);
if (nukeRoll < 55) {
//use direct damage spell
powerToken = powerTokens.get(powerTokens.size() - 1);
} else {
//use random spell
powerToken = powerTokens.get(ThreadLocalRandom.current().nextInt(powerTokens.size()));
}
int powerRank = 1;
switch(mob.getRank()){
case 1:
powerRank = 10;
break;
case 2:
powerRank = 15;
break;
case 3:
powerRank = 20;
break;
case 4:
powerRank = 25;
break;
case 5:
powerRank = 30;
break;
case 6:
powerRank = 35;
break;
case 7:
powerRank = 40;
break;
}
PowersBase mobPower = PowersManager.getPowerByToken(powerToken);
//check for hit-roll
if (mobPower.requiresHitRoll)
if (triggerDefense(mob, mob.getCombatTarget()))
return false;
// Cast the spell
if (inRange2D(mob, mob.getCombatTarget(), mobPower.getRange())) {
PerformActionMsg msg;
if (!mobPower.isHarmful() || mobPower.targetSelf) {
if (mobPower.category.equals("DISPEL")) {
PowersManager.useMobPower(mob, target, mobPower, powerRank);
msg = PowersManager.createPowerMsg(mobPower, powerRank, mob, target);
} else {
PowersManager.useMobPower(mob, mob, mobPower, powerRank);
msg = PowersManager.createPowerMsg(mobPower, powerRank, mob, mob);
}
} else {
PowersManager.useMobPower(mob, target, mobPower, powerRank);
msg = PowersManager.createPowerMsg(mobPower, powerRank, mob, target);
}
msg.setUnknown04(2);
PowersManager.finishUseMobPower(msg, mob, 0, 0);
long randomCooldown = (long)((ThreadLocalRandom.current().nextInt(10,15) * 1000L) * MobAIThread.AI_CAST_FREQUENCY);
mob.nextCastTime = System.currentTimeMillis() + randomCooldown;
return true;
}
} catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: MobCast" + " " + e.getMessage());
}
return false;
}
} }

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

@ -13,10 +13,10 @@ import engine.Enum;
import engine.Enum.GameObjectType; import engine.Enum.GameObjectType;
import engine.Enum.ModType; import engine.Enum.ModType;
import engine.Enum.SourceType; import engine.Enum.SourceType;
import engine.mobileAI.Threads.MobAIThread;
import engine.exception.MsgSendException; import engine.exception.MsgSendException;
import engine.gameManager.MovementManager; import engine.gameManager.MovementManager;
import engine.math.Vector3fImmutable; import engine.math.Vector3fImmutable;
import engine.mobileAI.Threads.MobAIThread;
import engine.net.client.msg.MoveToPointMsg; import engine.net.client.msg.MoveToPointMsg;
import engine.objects.*; import engine.objects.*;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
@ -38,7 +38,7 @@ public class MovementUtilities {
if (agent.getContract() != null) if (agent.getContract() != null)
guardCaptain = agent; guardCaptain = agent;
else else
guardCaptain = (Mob) agent.npcOwner; guardCaptain = (Mob) agent.guardCaptain;
if (guardCaptain != null) { if (guardCaptain != null) {
Building barracks = guardCaptain.building; Building barracks = guardCaptain.building;
@ -115,39 +115,8 @@ public class MovementUtilities {
} }
public static Vector3fImmutable GetMoveLocation(Mob aiAgent, AbstractCharacter aggroTarget) {
// Player isnt moving and neither is mob. Just return
// the mobile's current location. Ain't goin nowhere!
// *** Refactor: Check to ensure methods calling us
// all don't sent move messages when not moving.
if ((aggroTarget.isMoving() == false))
return aggroTarget.getLoc();
if (aggroTarget.getEndLoc().x != 0) {
float aggroTargetDistanceSquared = aggroTarget.getLoc().distanceSquared2D(aggroTarget.getEndLoc());
float aiAgentDistanceSquared = aiAgent.getLoc().distanceSquared2D(aggroTarget.getEndLoc());
if (aiAgentDistanceSquared >= aggroTargetDistanceSquared)
return aggroTarget.getEndLoc();
else {
float distanceToMove = sqrt(aggroTargetDistanceSquared + aiAgentDistanceSquared) * .5f;
return aggroTarget.getFaceDir().scaleAdd(distanceToMove, aggroTarget.getLoc());
}
}
// One of us is moving so let's calculate our destination loc for this
// simulation frame. We will simply project our position onto the
// character's movement vector and return the closest point.
return aiAgent.getLoc().ClosestPointOnLine(aggroTarget.getLoc(), aggroTarget.getEndLoc());
}
public static void moveToLocation(Mob agent, Vector3fImmutable newLocation, float offset) { public static void moveToLocation(Mob agent, Vector3fImmutable newLocation, float offset) {
agent.resetLastSetLocUpdate();
try { try {
//don't move farther than 30 units from player. //don't move farther than 30 units from player.
@ -172,32 +141,8 @@ public class MovementUtilities {
return (agent.isAlive() && !agent.getBonuses().getBool(ModType.Stunned, SourceType.None) && !agent.getBonuses().getBool(ModType.CannotMove, SourceType.None)); return (agent.isAlive() && !agent.getBonuses().getBool(ModType.Stunned, SourceType.None) && !agent.getBonuses().getBool(ModType.CannotMove, SourceType.None));
} }
public static Vector3fImmutable randomPatrolLocation(Mob agent, Vector3fImmutable center, float radius) {
//Determing where I want to move.
return new Vector3fImmutable((center.x - radius) + ((ThreadLocalRandom.current().nextFloat() + .1f * 2) * radius),
center.y,
(center.z - radius) + ((ThreadLocalRandom.current().nextFloat() + .1f * 2) * radius));
}
public static Long estimateMovementTime(Mob agent) {
if (agent.getEndLoc().x == 0 && agent.getEndLoc().y == 0)
return 0L;
return (long) ((agent.getLoc().distance2D(agent.getEndLoc()) * 1000) / agent.getSpeed());
}
public static void aiMove(Mob agent, Vector3fImmutable vect, boolean isWalking) { public static void aiMove(Mob agent, Vector3fImmutable vect, boolean isWalking) {
//update our walk/run state.
if (isWalking && !agent.isWalk()) {
agent.setWalkMode(true);
MovementManager.sendRWSSMsg(agent);
} else if (!isWalking && agent.isWalk()) {
agent.setWalkMode(false);
MovementManager.sendRWSSMsg(agent);
}
MoveToPointMsg msg = new MoveToPointMsg(); MoveToPointMsg msg = new MoveToPointMsg();
@ -273,23 +218,4 @@ public class MovementUtilities {
return character.getLoc(); return character.getLoc();
} }
public static boolean updateMovementToCharacter(Mob aiAgent, AbstractCharacter aggroTarget) {
if (aiAgent.destination.equals(Vector3fImmutable.ZERO))
return true;
if (!aiAgent.isMoving())
return true;
if (aggroTarget.isMoving()) {
return !aiAgent.destination.equals(aggroTarget.getEndLoc()) && !aiAgent.destination.equals(aggroTarget.getLoc());
} else {
if (aiAgent.destination.equals(aggroTarget.getLoc()))
return false;
}
return false;
}
} }

2
src/engine/net/NetMsgFactory.java

@ -97,7 +97,7 @@ public class NetMsgFactory {
// if (MBServerStatics.worldServerName.equals("Grief")) // if (MBServerStatics.worldServerName.equals("Grief"))
Logger.error("Invalid protocol msg for player " + player.getFirstName() + " : " + opcode + " lastopcode: " + origin.lastProtocol.name() + " Error Code : " + errorCode); Logger.error("Invalid protocol msg for player " + player.getFirstName() + " : " + opcode + " lastopcode: " + origin.lastProtocol.name() + " Error Code : " + errorCode);
} else } else
Logger.error("Invalid protocol msg : " + opcode + " lastopcode: " + origin.lastProtocol.name() + " Error Code : " + errorCode); Logger.error("PROTOCOL ERROR: Player: " + ((ClientConnection) origin).getPlayerCharacter().getName() + " Account: " + ((ClientConnection) origin).getPlayerCharacter().getAccount().getUname() + "Invalid protocol msg : " + opcode + " lastopcode: " + origin.lastProtocol.name() + " Error Code : " + errorCode);
} }

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

@ -9,6 +9,7 @@
package engine.net.client; package engine.net.client;
import engine.Enum;
import engine.Enum.*; import engine.Enum.*;
import engine.InterestManagement.WorldGrid; import engine.InterestManagement.WorldGrid;
import engine.exception.MsgSendException; import engine.exception.MsgSendException;
@ -122,6 +123,7 @@ public class ClientMessagePump implements NetMsgHandler {
if (pc.isSit()) { if (pc.isSit()) {
pc.setCombat(false); pc.setCombat(false);
pc.cancelOnSit(); pc.cancelOnSit();
pc.stopMovement(pc.loc);
} }
UpdateStateMsg rwss = new UpdateStateMsg(); UpdateStateMsg rwss = new UpdateStateMsg();
@ -222,6 +224,11 @@ public class ClientMessagePump implements NetMsgHandler {
return; return;
} }
if(msg.getSlotNumber() == 11 && pc.getRaceID() == 1999){
forceTransferFromEquipToInventory(msg, origin, "Saetor cannot wear shoes.");
return;
}
int uuid = msg.getUUID(); int uuid = msg.getUUID();
int slot = msg.getSlotNumber(); int slot = msg.getSlotNumber();
//System.out.println("loading to slot: " + slot); //System.out.println("loading to slot: " + slot);
@ -554,18 +561,32 @@ public class ClientMessagePump implements NetMsgHandler {
if (i == null) if (i == null)
return; return;
if(i.getItemBaseID() == 7)
return; //cant delete gold
if (!itemManager.doesCharOwnThisItem(i.getObjectUUID())) if (!itemManager.doesCharOwnThisItem(i.getObjectUUID()))
return; return;
if (!itemManager.inventoryContains(i)) if (!itemManager.inventoryContains(i))
return; return;
if (i.isCanDestroy()) if(i.getItemBaseID() == 980066)
return;
if (i.canDestroy) {
int value = i.getItemBase().value;
if(i.getItemBase().isRune())
value = 500000;
if(sourcePlayer.getCharItemManager().getGoldInventory().getNumOfItems() + value > 10000000){
return;
}
if (itemManager.delete(i) == true) { if (itemManager.delete(i) == true) {
sourcePlayer.getCharItemManager().addGoldToInventory(value,false);
sourcePlayer.getCharItemManager().updateInventory();
Dispatch dispatch = Dispatch.borrow(sourcePlayer, msg); Dispatch dispatch = Dispatch.borrow(sourcePlayer, msg);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
} }
}
} }
private static void ackBankWindowOpened(AckBankWindowOpenedMsg msg, ClientConnection origin) { private static void ackBankWindowOpened(AckBankWindowOpenedMsg msg, ClientConnection origin) {
@ -1358,219 +1379,171 @@ public class ClientMessagePump implements NetMsgHandler {
} }
private static void buyFromNPC(BuyFromNPCMsg msg, ClientConnection origin) { private static void buyFromNPC(BuyFromNPCMsg msg, ClientConnection origin) {
PlayerCharacter sourcePlayer = SessionManager.getPlayerCharacter(origin); PlayerCharacter sourcePlayer = SessionManager.getPlayerCharacter(origin);
if (sourcePlayer == null) if (sourcePlayer == null)
return; return;
if (origin.buyLock.tryLock()) { if (origin.buyLock.tryLock()) {
try { try {
CharacterItemManager itemMan = sourcePlayer.getCharItemManager(); CharacterItemManager itemMan = sourcePlayer.getCharItemManager();
if (itemMan == null) {
if (itemMan == null)
return; return;
}
NPC npc = NPC.getFromCache(msg.getNPCID()); NPC npc = NPC.getFromCache(msg.getNPCID());
if (npc == null) {
if (npc == null)
return; return;
}
Item gold = itemMan.getGoldInventory(); Item gold = itemMan.getGoldInventory();
if (gold == null) {
if (gold == null)
return; return;
}
Item buy = null; Item buy = null;
if (msg.getItemType() == GameObjectType.MobEquipment.ordinal()) { if (msg.getItemType() == GameObjectType.MobEquipment.ordinal()) {
ArrayList<MobEquipment> sellInventory = npc.getContract().getSellInventory(); ArrayList<MobEquipment> sellInventory = npc.getContract().getSellInventory();
if (sellInventory == null) if (sellInventory == null) {
return; return;
}
for (MobEquipment me : sellInventory) { for (MobEquipment me : sellInventory) {
if (me.getObjectUUID() == msg.getItemID()) { if (me.getObjectUUID() == msg.getItemID()) {
ItemBase ib = me.getItemBase(); ItemBase ib = me.getItemBase();
if (ib == null) if (ib == null) {
return; return;
}
//test room available for item //test room available for item
if (!itemMan.hasRoomInventory(ib.getWeight())) if (!itemMan.hasRoomInventory(ib.getWeight())) {
return; return;
}
int cost = me.getMagicValue(); int cost = me.magicValue;
if(npc.getContractID() == 1201 && me.getItemBase().getName().equals("Prospector"))
cost = 50;
float bargain = sourcePlayer.getBargain(); float bargain = sourcePlayer.getBargain();
float profit = npc.getSellPercent(sourcePlayer) - bargain; float profit = npc.getSellPercent(sourcePlayer) - bargain;
if(me.getItemBase().getType().equals(ItemType.POTION))
profit -= 1.0f;
if (profit < 1) if (profit < 1)
profit = 1; profit = 1;
if(npc.getContractID() == 900){
cost = Warehouse.getCostForResource(ib.getUUID()) * Warehouse.getSellStackSize(ib.getUUID());
}
cost *= profit; cost *= profit;
if (gold.getNumOfItems() - cost < 0) { if (gold.getNumOfItems() - cost < 0) {
//dont' have enough goldItem exit! //dont' have enough goldItem exit!
// chatMan.chatSystemInfo(pc, "" + "You dont have enough gold."); // chatMan.chatSystemInfo(pc, "" + "You dont have enough gold.");
return; return;
} }
Building b = (!npc.isStatic()) ? npc.getBuilding() : null; Building b = (!npc.isStatic()) ? npc.getBuilding() : null;
if (b != null && b.getProtectionState().equals(ProtectionState.NPC)) if (b != null && b.getProtectionState().equals(ProtectionState.NPC))
b = null; b = null;
int buildingDeposit = cost - me.getMagicValue(); int buildingDeposit = cost - me.getMagicValue();
if (b != null && (b.getStrongboxValue() + buildingDeposit) > b.getMaxGold()) { if (b != null && (b.getStrongboxValue() + buildingDeposit) > b.getMaxGold() && !b.isOwnerIsNPC()) {
ErrorPopupMsg.sendErrorPopup(sourcePlayer, 206); ErrorPopupMsg.sendErrorPopup(sourcePlayer, 206);
return; return;
} }
if (!itemMan.buyFromNPC(b, cost, buildingDeposit)) { if (!itemMan.buyFromNPC(b, cost, buildingDeposit)) {
// chatMan.chatSystemInfo(pc, "" + "You Failed to buy the item."); // chatMan.chatSystemInfo(pc, "" + "You Failed to buy the item.");
ChatManager.chatSystemError(sourcePlayer, "Failed To Buy Item");
return; return;
} }
if(me.getItemBase().getType().equals(ItemType.RESOURCE) && npc.getContractID() == 900){
buy = Item.createItemForPlayer(sourcePlayer, ib); handleResourcePurchase(me,itemMan,npc,buy,sourcePlayer,ib);
}else {
if (buy != null) { buy = Item.createItemForPlayer(sourcePlayer, ib);
me.transferEnchants(buy); if (buy != null) {
itemMan.addItemToInventory(buy); me.transferEnchants(buy);
//itemMan.updateInventory(); itemMan.addItemToInventory(buy);
if(npc.contractUUID == 900 && buy.getItemBaseID() == 1705032){
buy.setNumOfItems(10);
DbManager.ItemQueries.UPDATE_NUM_ITEMS(buy,buy.getNumOfItems());
}
//itemMan.updateInventory();
}
} }
} }
} }
} else if (msg.getItemType() == GameObjectType.Item.ordinal()) { } else if (msg.getItemType() == GameObjectType.Item.ordinal()) {
CharacterItemManager npcCim = npc.getCharItemManager(); CharacterItemManager npcCim = npc.getCharItemManager();
if (npcCim == null) if (npcCim == null)
return; return;
buy = Item.getFromCache(msg.getItemID()); buy = Item.getFromCache(msg.getItemID());
if (buy == null) if (buy == null)
return; return;
ItemBase ib = buy.getItemBase(); ItemBase ib = buy.getItemBase();
if (ib == null) if (ib == null)
return; return;
if (!npcCim.inventoryContains(buy)) if (!npcCim.inventoryContains(buy))
return; return;
//test room available for item //test room available for item
if (!itemMan.hasRoomInventory(ib.getWeight())) if (!itemMan.hasRoomInventory(ib.getWeight()))
return; return;
//TODO test cost and subtract goldItem //TODO test cost and subtract goldItem
//TODO CHnage this if we ever put NPc city npcs in buildings. //TODO CHnage this if we ever put NPc city npcs in buildings.
int cost = buy.getBaseValue(); int cost = buy.getBaseValue();
if (buy.isID() || buy.isCustomValue()) if (buy.isID() || buy.isCustomValue())
cost = buy.getMagicValue(); cost = buy.getMagicValue();
float bargain = sourcePlayer.getBargain(); float bargain = sourcePlayer.getBargain();
float profit = npc.getSellPercent(sourcePlayer) - bargain; float profit = npc.getSellPercent(sourcePlayer) - bargain;
if (profit < 1) if (profit < 1)
profit = 1; profit = 1;
if (!buy.isCustomValue()) if (!buy.isCustomValue())
cost *= profit; cost *= profit;
else else
cost = buy.getValue(); cost = buy.getValue();
if (gold.getNumOfItems() - cost < 0) { if (gold.getNumOfItems() - cost < 0) {
ErrorPopupMsg.sendErrorPopup(sourcePlayer, 128); // Insufficient Gold ErrorPopupMsg.sendErrorPopup(sourcePlayer, 128); // Insufficient Gold
return; return;
} }
Building b = (!npc.isStatic()) ? npc.getBuilding() : null; Building b = (!npc.isStatic()) ? npc.getBuilding() : null;
if (b != null) if (b != null)
if (b.getProtectionState().equals(ProtectionState.NPC)) if (b.getProtectionState().equals(ProtectionState.NPC))
b = null; b = null;
int buildingDeposit = cost; int buildingDeposit = cost;
if (b != null && (b.getStrongboxValue() + buildingDeposit) > b.getMaxGold() && !b.isOwnerIsNPC()) {
if (b != null && (b.getStrongboxValue() + buildingDeposit) > b.getMaxGold()) {
ErrorPopupMsg.sendErrorPopup(sourcePlayer, 206); ErrorPopupMsg.sendErrorPopup(sourcePlayer, 206);
return; return;
} }
if (!itemMan.buyFromNPC(b, cost, buildingDeposit)) { if (!itemMan.buyFromNPC(b, cost, buildingDeposit)) {
ErrorPopupMsg.sendErrorPopup(sourcePlayer, 110); ErrorPopupMsg.sendErrorPopup(sourcePlayer, 110);
return; return;
} }
if (buy != null) if (buy != null)
itemMan.buyFromNPC(buy, npc); itemMan.buyFromNPC(buy, npc);
} else if (msg.getItemType() == GameObjectType.MobLoot.ordinal()) { } else if (msg.getItemType() == GameObjectType.MobLoot.ordinal()) {
CharacterItemManager npcCim = npc.getCharItemManager(); CharacterItemManager npcCim = npc.getCharItemManager();
if (npcCim == null) if (npcCim == null)
return; return;
buy = MobLoot.getFromCache(msg.getItemID()); buy = MobLoot.getFromCache(msg.getItemID());
if (buy == null) if (buy == null)
return; return;
ItemBase ib = buy.getItemBase(); ItemBase ib = buy.getItemBase();
if (ib == null) if (ib == null)
return; return;
if (!npcCim.inventoryContains(buy)) if (!npcCim.inventoryContains(buy))
return; return;
//test room available for item //test room available for item
if (!itemMan.hasRoomInventory(ib.getWeight())) if (!itemMan.hasRoomInventory(ib.getWeight()))
return; return;
//TODO test cost and subtract goldItem //TODO test cost and subtract goldItem
//TODO CHnage this if we ever put NPc city npcs in buildings. //TODO CHnage this if we ever put NPc city npcs in buildings.
int cost = buy.getMagicValue(); int cost = buy.getMagicValue();
cost *= npc.getSellPercent(sourcePlayer); cost *= npc.getSellPercent(sourcePlayer);
if (gold.getNumOfItems() - cost < 0) { if (gold.getNumOfItems() - cost < 0) {
ErrorPopupMsg.sendErrorPopup(sourcePlayer, 128); // Insufficient Gold ErrorPopupMsg.sendErrorPopup(sourcePlayer, 128); // Insufficient Gold
return; return;
} }
Building b = (!npc.isStatic()) ? npc.getBuilding() : null; Building b = (!npc.isStatic()) ? npc.getBuilding() : null;
if (b != null && b.getProtectionState().equals(ProtectionState.NPC)) if (b != null && b.getProtectionState().equals(ProtectionState.NPC))
b = null; b = null;
int buildingDeposit = cost; int buildingDeposit = cost;
if (b != null && (b.getStrongboxValue() + buildingDeposit) > b.getMaxGold() && !b.isOwnerIsNPC()) {
if (b != null && (b.getStrongboxValue() + buildingDeposit) > b.getMaxGold()) {
ErrorPopupMsg.sendErrorPopup(sourcePlayer, 206); ErrorPopupMsg.sendErrorPopup(sourcePlayer, 206);
return; return;
} }
if (!itemMan.buyFromNPC(b, cost, buildingDeposit)) if (!itemMan.buyFromNPC(b, cost, buildingDeposit))
return; return;
if (buy != null) if (buy != null)
itemMan.buyFromNPC(buy, npc); itemMan.buyFromNPC(buy, npc);
} else } else
return; return;
if (buy != null) { if (buy != null) {
msg.setItem(buy); msg.setItem(buy);
//send the buy message back to update player //send the buy message back to update player
// msg.setItemType(buy.getObjectType().ordinal()); // msg.setItemType(buy.getObjectType().ordinal());
@ -1579,16 +1552,44 @@ public class ClientMessagePump implements NetMsgHandler {
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
itemMan.updateInventory(); itemMan.updateInventory();
} }
} finally { } finally {
origin.buyLock.unlock(); origin.buyLock.unlock();
} }
} else { } else {
ErrorPopupMsg.sendErrorPopup(origin.getPlayerCharacter(), 12); // All production slots taken ErrorPopupMsg.sendErrorPopup(origin.getPlayerCharacter(), 12); // All production slots taken
} }
} }
public static void handleResourcePurchase(MobEquipment me, CharacterItemManager itemMan, NPC npc, Item buy, PlayerCharacter sourcePlayer, ItemBase ib){
boolean stacked = false;
int buystack = Warehouse.getSellStackSize(me.getItemBase().getUUID());
for(Item item : itemMan.getInventory()){
int itemID = item.getItemBaseID();
int meID = me.getItemBase().getUUID();
if(itemID == meID){
if(Warehouse.maxResources.isEmpty())
Warehouse.getMaxResources();
int maxStack = Warehouse.maxResources.get(itemID);
if(maxStack > item.getNumOfItems() + buystack){
item.setNumOfItems(item.getNumOfItems() + buystack);
stacked = true;
itemMan.updateInventory();
DbManager.ItemQueries.UPDATE_NUM_ITEMS(item,item.getNumOfItems());
break;
}
}
}
if(!stacked){
buy = Item.createItemForPlayer(sourcePlayer, ib);
if (buy != null) {
me.transferEnchants(buy);
itemMan.addItemToInventory(buy);
buy.setNumOfItems(buystack);
DbManager.ItemQueries.UPDATE_NUM_ITEMS(buy,buy.getNumOfItems());
}
}
itemMan.updateInventory();
}
private static void Repair(RepairMsg msg, ClientConnection origin) { private static void Repair(RepairMsg msg, ClientConnection origin) {
PlayerCharacter player = SessionManager.getPlayerCharacter(origin); PlayerCharacter player = SessionManager.getPlayerCharacter(origin);
@ -1631,8 +1632,8 @@ public class ClientMessagePump implements NetMsgHandler {
if (toRepair == null) if (toRepair == null)
return; return;
if (toRepair.getItemBase().isGlass()) //if (toRepair.getItemBase().isGlass())
return; // return;
//make sure item is in player's inventory or equipment //make sure item is in player's inventory or equipment
if (!itemMan.inventoryContains(toRepair) && !itemMan.equippedContains(toRepair)) if (!itemMan.inventoryContains(toRepair) && !itemMan.equippedContains(toRepair))
@ -1654,6 +1655,12 @@ public class ClientMessagePump implements NetMsgHandler {
} }
//TODO get cost to repair //TODO get cost to repair
int cost = (int) ((max - dur) * 80.1); int cost = (int) ((max - dur) * 80.1);
//glass costs 3x as much to repair
if (toRepair.getItemBase().isGlass()){
cost *= 3;
}
Building b = (!npc.isStatic()) ? npc.getBuilding() : null; Building b = (!npc.isStatic()) ? npc.getBuilding() : null;
if (b != null) if (b != null)
@ -1888,9 +1895,22 @@ public class ClientMessagePump implements NetMsgHandler {
break; break;
case LEAVEREQUEST: case LEAVEREQUEST:
origin.disconnect(); origin.disconnect();
ArrayList<PlayerCharacter> sameMachine = new ArrayList<>();
for (PlayerCharacter pc : SessionManager.getAllActivePlayers()) {
if(origin.machineID.equals(pc.getClientConnection().machineID))
sameMachine.add(pc);
}
if(sameMachine.isEmpty() == false){
if(sameMachine.get(0) != null) {
sameMachine.get(0).isBoxed = false;
sameMachine.get(0).removeEffectBySource(EffectSourceType.DeathShroud,41,true);
ChatManager.chatSystemInfo(sameMachine.get(0), "You Are No Longer Flagged 'Boxed'");
}
}
break; break;
case POWER: case POWER:
PowersManager.usePower((PerformActionMsg) msg, origin, false); PowersManager.usePower((PerformActionMsg) msg, origin, false);
//PowersManager.static_power_que.add(new PowersManager.PowerQueObject((PerformActionMsg) msg, origin, false));
break; break;
case REQUESTMELEEATTACK: case REQUESTMELEEATTACK:
CombatManager.setAttackTarget((AttackCmdMsg) msg, origin); CombatManager.setAttackTarget((AttackCmdMsg) msg, origin);

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

@ -57,6 +57,21 @@ public class ActivateNPCMsgHandler extends AbstractClientMsgHandler {
if (contract.canSlotinBuilding(building)) if (contract.canSlotinBuilding(building))
ItemLists.add(hirelings); ItemLists.add(hirelings);
if(building.getBlueprint().getBuildingGroup().equals(Enum.BuildingGroup.TOL)){
if(contract.getContractID() == 899)//alchemist
ItemLists.add(hirelings);
if(contract.getContractID() == 866)//banker
ItemLists.add(hirelings);
if(contract.getContractID() == 865)//siege engineer
ItemLists.add(hirelings);
}
if(building.getBlueprint().getBuildingGroup().equals(Enum.BuildingGroup.SIEGETENT)){
if(contract.getContractID() == 865)//siege engineer
ItemLists.add(hirelings);
}
} }
} }
@ -78,13 +93,20 @@ public class ActivateNPCMsgHandler extends AbstractClientMsgHandler {
return false; return false;
} }
if (building.getBlueprint().getMaxSlots() == building.getHirelings().size()) if (building.getBlueprint().getSlotsForRank(building.getRank()) == building.getHirelings().size())
return false; return false;
Item contractItem = Item.getFromCache(msg.getContractItem()); Item contractItem = Item.getFromCache(msg.getContractItem());
if (contractItem == null) if (contractItem == null)
return false; return false;
if (msg.getContractItem() == 850) {//runemaster
for (AbstractCharacter abs : building.getHirelings().keySet()) {
NPC npc = (NPC) abs;
if (npc.contract.getContractID() == 850)
return false; //can only have 1 runemaster
}
}
if (!player.getCharItemManager().doesCharOwnThisItem(contractItem.getObjectUUID())) { if (!player.getCharItemManager().doesCharOwnThisItem(contractItem.getObjectUUID())) {
Logger.error(player.getName() + "has attempted to place Hireling : " + contractItem.getName() + "without a valid contract!"); Logger.error(player.getName() + "has attempted to place Hireling : " + contractItem.getName() + "without a valid contract!");
@ -104,10 +126,33 @@ public class ActivateNPCMsgHandler extends AbstractClientMsgHandler {
return false; return false;
// Check if contract can be slotted in this building // Check if contract can be slotted in this building
//Logger.error("inserting contract: " + contract.getContractID());
if (contract.canSlotinBuilding(building) == false) if (contract.canSlotinBuilding(building) == false) {
return false; boolean override = false;
if (building.getBlueprint().getBuildingGroup().equals(Enum.BuildingGroup.TOL)) {
if (contract.getContractID() == 899)//alchemist
override = true;
if (contract.getContractID() == 866)//banker
override = true;
if (contract.getContractID() == 865)//siege engineer
override = true;
}
if (building.getBlueprint().getBuildingGroup().equals(Enum.BuildingGroup.SIEGETENT)) {
if (contract.getContractID() == 865)//siege engineer
override = true;
}
if(building.getBlueprint().getBuildingGroup().equals(Enum.BuildingGroup.SIEGETENT)){
if(contract.getContractID() == 865)//siege engineer
override = true;
}
if(override == false) {
Logger.error("failed at override with contract: " + contract.getContractID());
return false;
}
}
//Logger.error("override successful: " + contract.getContractID());
if (!BuildingManager.addHireling(building, player, zone, contract, contractItem)) if (!BuildingManager.addHireling(building, player, zone, contract, contractItem))
return false; return false;

5
src/engine/net/client/handlers/ArcLoginNotifyMsgHandler.java

@ -53,7 +53,7 @@ public class ArcLoginNotifyMsgHandler extends AbstractClientMsgHandler {
GroupManager.RefreshOthersGroupList(player); GroupManager.RefreshOthersGroupList(player);
} }
player.setEnteredWorld(true); player.enteredWorld = true;
// Set player active // Set player active
player.resetRegenUpdateTime(); player.resetRegenUpdateTime();
player.setActive(true); player.setActive(true);
@ -66,6 +66,9 @@ public class ArcLoginNotifyMsgHandler extends AbstractClientMsgHandler {
// Send Guild, Nation and IC MOTD // Send Guild, Nation and IC MOTD
GuildManager.enterWorldMOTD(player); GuildManager.enterWorldMOTD(player);
ChatManager.sendSystemMessage(player, ConfigManager.MB_WORLD_GREETING.getValue()); ChatManager.sendSystemMessage(player, ConfigManager.MB_WORLD_GREETING.getValue());
ChatManager.sendSystemMessage(player, "Gold Drop Rate: " + ConfigManager.MB_NORMAL_GOLD_RATE.getValue());
ChatManager.sendSystemMessage(player, "Loot Drop Rate: " + ConfigManager.MB_NORMAL_DROP_RATE.getValue());
ChatManager.sendSystemMessage(player, "Experience Rate: " + ConfigManager.MB_NORMAL_EXP_RATE.getValue());
// Send branch string if available from ConfigManager. // Send branch string if available from ConfigManager.

21
src/engine/net/client/handlers/BanishUnbanishHandler.java

@ -14,18 +14,17 @@ import engine.Enum.GuildHistoryType;
import engine.exception.MsgSendException; import engine.exception.MsgSendException;
import engine.gameManager.ChatManager; import engine.gameManager.ChatManager;
import engine.gameManager.DbManager; import engine.gameManager.DbManager;
import engine.gameManager.GroupManager;
import engine.gameManager.SessionManager; import engine.gameManager.SessionManager;
import engine.net.Dispatch; import engine.net.Dispatch;
import engine.net.DispatchMessage; import engine.net.DispatchMessage;
import engine.net.client.ClientConnection; import engine.net.client.ClientConnection;
import engine.net.client.msg.ClientNetMsg; import engine.net.client.msg.ClientNetMsg;
import engine.net.client.msg.ErrorPopupMsg; import engine.net.client.msg.ErrorPopupMsg;
import engine.net.client.msg.group.GroupUpdateMsg;
import engine.net.client.msg.guild.BanishUnbanishMsg; import engine.net.client.msg.guild.BanishUnbanishMsg;
import engine.net.client.msg.guild.GuildListMsg; import engine.net.client.msg.guild.GuildListMsg;
import engine.objects.Guild; import engine.objects.*;
import engine.objects.GuildHistory;
import engine.objects.GuildStatusController;
import engine.objects.PlayerCharacter;
import org.joda.time.DateTime; import org.joda.time.DateTime;
public class BanishUnbanishHandler extends AbstractClientMsgHandler { public class BanishUnbanishHandler extends AbstractClientMsgHandler {
@ -116,6 +115,20 @@ public class BanishUnbanishHandler extends AbstractClientMsgHandler {
GuildListMsg guildListMsg = new GuildListMsg(guild); GuildListMsg guildListMsg = new GuildListMsg(guild);
dispatch = Dispatch.borrow(source, guildListMsg); dispatch = Dispatch.borrow(source, guildListMsg);
DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.SECONDARY); DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.SECONDARY);
if(GroupManager.getGroup(target) != null) {
Group group = GroupManager.getGroup(target);
group.removeGroupMember(PlayerCharacter.getPlayerCharacter(target));
GroupManager.removeFromGroups(PlayerCharacter.getPlayerCharacter(target));
GroupUpdateMsg gim;
gim = new GroupUpdateMsg();
gim.setGroup(group);
gim.setMessageType(3);
gim.setPlayer(PlayerCharacter.getPlayerCharacter(target));
group.sendUpdate(gim);
String text = PlayerCharacter.getPlayerCharacter(target).getFirstName() + " has left your group.";
ChatManager.chatGroupInfo(source, text);
}
} else { } else {
ErrorPopupMsg.sendErrorPopup(source, 103); // You may not banish this char ErrorPopupMsg.sendErrorPopup(source, 103); // You may not banish this char
} }

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

@ -61,15 +61,6 @@ public class CityDataHandler extends AbstractClientMsgHandler {
dispatch = Dispatch.borrow(playerCharacter, cityDataMsg); dispatch = Dispatch.borrow(playerCharacter, cityDataMsg);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
// If the hotZone has changed then update the client's map accordingly.
if (playerCharacter.getTimeStamp("hotzoneupdate") <= ZoneManager.hotZoneLastUpdate.toEpochMilli() && ZoneManager.hotZone != null) {
HotzoneChangeMsg hotzoneChangeMsg = new HotzoneChangeMsg(Enum.GameObjectType.Zone.ordinal(), ZoneManager.hotZone.getObjectUUID());
dispatch = Dispatch.borrow(playerCharacter, hotzoneChangeMsg);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
playerCharacter.setTimeStamp("hotzoneupdate", System.currentTimeMillis() - 100);
}
// Serialize the realms for this map // Serialize the realms for this map
WorldRealmMsg worldRealmMsg = new WorldRealmMsg(); WorldRealmMsg worldRealmMsg = new WorldRealmMsg();

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

@ -62,7 +62,7 @@ public class DestroyBuildingHandler extends AbstractClientMsgHandler {
if (city != null) if (city != null)
bane = city.getBane(); bane = city.getBane();
if (bane != null && bane.getSiegePhase() == Enum.SiegePhase.WAR) { if (bane != null) {
ErrorPopupMsg.sendErrorPopup(pc, 171); ErrorPopupMsg.sendErrorPopup(pc, 171);
return true; return true;
} }
@ -71,9 +71,12 @@ public class DestroyBuildingHandler extends AbstractClientMsgHandler {
if (blueprint.getBuildingGroup() == BuildingGroup.TOL) if (blueprint.getBuildingGroup() == BuildingGroup.TOL)
return true; return true;
// Can't destroy a shrine // destorying a shrine will yield a rubble pile for looting
if (blueprint.getBuildingGroup() == BuildingGroup.SHRINE) if (blueprint.getBuildingGroup() == BuildingGroup.SHRINE) {
building.modifyHealth(-building.getHealth(), origin.getPlayerCharacter());
building.destroyOrDerank(origin.getPlayerCharacter());
return true; return true;
}
// Cannot destroy mines outside of normal mine mechanics // Cannot destroy mines outside of normal mine mechanics

7
src/engine/net/client/handlers/GroupInviteHandler.java

@ -21,6 +21,7 @@ import engine.net.client.msg.ClientNetMsg;
import engine.net.client.msg.group.GroupInviteMsg; import engine.net.client.msg.group.GroupInviteMsg;
import engine.net.client.msg.group.GroupUpdateMsg; import engine.net.client.msg.group.GroupUpdateMsg;
import engine.objects.Group; import engine.objects.Group;
import engine.objects.Guild;
import engine.objects.PlayerCharacter; import engine.objects.PlayerCharacter;
public class GroupInviteHandler extends AbstractClientMsgHandler { public class GroupInviteHandler extends AbstractClientMsgHandler {
@ -103,6 +104,12 @@ public class GroupInviteHandler extends AbstractClientMsgHandler {
if (target.isIgnoringPlayer(source)) if (target.isIgnoringPlayer(source))
return false; return false;
if(source.getGuild().getNation().equals(target.getGuild().getNation()) == false)
return false; // cannot group outside of nation
if(source.getGuild().getNation().equals(target.getGuild().getNation()) && source.getGuild().getNation().equals(Guild.getErrantGuild()))
if(source.getGuild().equals(target.getGuild()) == false)
return false; // cannot group as an errant guild with other errant guilds
// dont block invites to people already in a group and // dont block invites to people already in a group and
// dont check for pending invites, the client does it // dont check for pending invites, the client does it

21
src/engine/net/client/handlers/InviteToSubHandler.java

@ -25,6 +25,8 @@ import engine.objects.Guild;
import engine.objects.GuildStatusController; import engine.objects.GuildStatusController;
import engine.objects.PlayerCharacter; import engine.objects.PlayerCharacter;
import static engine.objects.Bane.getBaneByAttackerGuild;
public class InviteToSubHandler extends AbstractClientMsgHandler { public class InviteToSubHandler extends AbstractClientMsgHandler {
public InviteToSubHandler() { public InviteToSubHandler() {
@ -95,6 +97,25 @@ public class InviteToSubHandler extends AbstractClientMsgHandler {
if (sourceGuild.equals(targetGuild)) if (sourceGuild.equals(targetGuild))
return true; return true;
if(sourceGuild.getNation().getOwnedCity().getBane() != null)
return true; // cannot invite guilds to sub if you are baned
if(sourceGuild.getNation().getSubGuildList() != null){
for(Guild subGuild : sourceGuild.getNation().getSubGuildList()){
if(subGuild.getOwnedCity() != null)
if(subGuild.getOwnedCity().getBane() != null)
return true;//cannot invite guilds to sub if any tree in your nation has a bane on it
}
}
if(targetGuild.getOwnedCity() != null)
if(targetGuild.getOwnedCity().getBane() != null)
return true; // cannot be subbed if you have a bane placed on you
if(getBaneByAttackerGuild(targetGuild) != null)
return true; // cannot sub to a nation if they have a bane placed
//target must be GL or IC //target must be GL or IC
if (GuildStatusController.isInnerCouncil(target.getGuildStatus()) == false && GuildStatusController.isGuildLeader(target.getGuildStatus()) == false) { if (GuildStatusController.isInnerCouncil(target.getGuildStatus()) == false && GuildStatusController.isGuildLeader(target.getGuildStatus()) == false) {

22
src/engine/net/client/handlers/LeaveGuildHandler.java

@ -12,16 +12,15 @@ package engine.net.client.handlers;
import engine.Enum.GuildHistoryType; import engine.Enum.GuildHistoryType;
import engine.exception.MsgSendException; import engine.exception.MsgSendException;
import engine.gameManager.ChatManager; import engine.gameManager.ChatManager;
import engine.gameManager.GroupManager;
import engine.gameManager.SessionManager; import engine.gameManager.SessionManager;
import engine.net.Dispatch; import engine.net.Dispatch;
import engine.net.DispatchMessage; import engine.net.DispatchMessage;
import engine.net.client.ClientConnection; import engine.net.client.ClientConnection;
import engine.net.client.msg.ClientNetMsg; import engine.net.client.msg.ClientNetMsg;
import engine.net.client.msg.group.GroupUpdateMsg;
import engine.net.client.msg.guild.LeaveGuildMsg; import engine.net.client.msg.guild.LeaveGuildMsg;
import engine.objects.Guild; import engine.objects.*;
import engine.objects.GuildStatusController;
import engine.objects.Mine;
import engine.objects.PlayerCharacter;
public class LeaveGuildHandler extends AbstractClientMsgHandler { public class LeaveGuildHandler extends AbstractClientMsgHandler {
@ -61,6 +60,21 @@ public class LeaveGuildHandler extends AbstractClientMsgHandler {
return true; return true;
} }
if(GroupManager.getGroup(playerCharacter) != null) {
Group group = GroupManager.getGroup(playerCharacter);
group.removeGroupMember(playerCharacter);
GroupManager.removeFromGroups(playerCharacter);
GroupUpdateMsg gim;
gim = new GroupUpdateMsg();
gim.setGroup(group);
gim.setMessageType(3);
gim.setPlayer(playerCharacter);
group.sendUpdate(gim);
String text = playerCharacter.getFirstName() + " has left your group.";
ChatManager.chatGroupInfo(playerCharacter, text);
}
// Send left guild message to rest of guild // Send left guild message to rest of guild
ChatManager.chatGuildInfo(oldGuild, playerCharacter.getFirstName() + " has left the guild."); ChatManager.chatGuildInfo(oldGuild, playerCharacter.getFirstName() + " has left the guild.");

270
src/engine/net/client/handlers/ManageCityAssetMsgHandler.java

@ -5,6 +5,7 @@ import engine.Enum.DispatchChannel;
import engine.Enum.GameObjectType; import engine.Enum.GameObjectType;
import engine.exception.MsgSendException; import engine.exception.MsgSendException;
import engine.gameManager.BuildingManager; import engine.gameManager.BuildingManager;
import engine.gameManager.DbManager;
import engine.gameManager.SessionManager; import engine.gameManager.SessionManager;
import engine.gameManager.ZoneManager; import engine.gameManager.ZoneManager;
import engine.math.Bounds; import engine.math.Bounds;
@ -62,7 +63,6 @@ public class ManageCityAssetMsgHandler extends AbstractClientMsgHandler {
Building building; Building building;
msg = (ManageCityAssetsMsg) baseMsg; msg = (ManageCityAssetsMsg) baseMsg;
player = SessionManager.getPlayerCharacter(origin); player = SessionManager.getPlayerCharacter(origin);
if (player == null) if (player == null)
@ -72,34 +72,21 @@ public class ManageCityAssetMsgHandler extends AbstractClientMsgHandler {
if (building == null) { if (building == null) {
if (msg.actionType == 14) { if (msg.actionType == 14) {
Zone zone = ZoneManager.findSmallestZone(player.getLoc()); Zone zone = ZoneManager.findSmallestZone(player.getLoc());
if (!zone.isPlayerCity()) { if (!zone.isPlayerCity()) {
ErrorPopupMsg.sendErrorMsg(player, "Unable to find city to command."); ErrorPopupMsg.sendErrorMsg(player, "Unable to find city to command.");
return true; return true;
} }
City city = City.GetCityFromCache(zone.getPlayerCityUUID()); City city = City.GetCityFromCache(zone.getPlayerCityUUID());
if (city == null || !city.getGuild().equals(player.getGuild()) ||
if (city == null) { (!GuildStatusController.isInnerCouncil(player.getGuildStatus()) &&
ErrorPopupMsg.sendErrorMsg(player, "Unable to find city to command."); !GuildStatusController.isGuildLeader(player.getGuildStatus()))) {
return true;
}
if (!city.getGuild().equals(player.getGuild())) {
ErrorPopupMsg.sendErrorMsg(player, "You are not in the correct guild to command this city."); ErrorPopupMsg.sendErrorMsg(player, "You are not in the correct guild to command this city.");
return true; return true;
} }
if (!GuildStatusController.isInnerCouncil(player.getGuildStatus()) && !GuildStatusController.isGuildLeader(player.getGuildStatus())) {
ErrorPopupMsg.sendErrorMsg(player, "You must be an Inner Council or Guild leader to access city commands.");
return true;
}
ManageCityAssetsMsg mca = new ManageCityAssetsMsg(player, building); ManageCityAssetsMsg mca = new ManageCityAssetsMsg(player, building);
mca.actionType = 15; mca.actionType = 15;
Dispatch dispatch = Dispatch.borrow(player, mca); DispatchMessage.dispatchMsgDispatch(Dispatch.borrow(player, mca), DispatchChannel.SECONDARY);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
} }
return true; return true;
} }
@ -111,181 +98,126 @@ public class ManageCityAssetMsgHandler extends AbstractClientMsgHandler {
outMsg.setTargetType(building.getObjectType().ordinal()); outMsg.setTargetType(building.getObjectType().ordinal());
outMsg.setTargetID(building.getObjectUUID()); outMsg.setTargetID(building.getObjectUUID());
outMsg.setAssetName(building.getName()); outMsg.setAssetName(building.getName());
Dispatch dispatch = Dispatch.borrow(player, outMsg); DispatchMessage.dispatchMsgDispatch(Dispatch.borrow(player, outMsg), DispatchChannel.SECONDARY);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
return true; return true;
} }
if (msg.actionType == 2 || msg.actionType == 22) { switch (msg.actionType) {
case 2:
if (building.getBlueprint() != null && building.getBlueprint().getBuildingGroup() == engine.Enum.BuildingGroup.BANESTONE) { case 22:
if (building.getBlueprint() != null && building.getBlueprint().getBuildingGroup() == engine.Enum.BuildingGroup.BANESTONE) {
outMsg.actionType = 18; outMsg.actionType = 18;
outMsg.setTargetType(building.getObjectType().ordinal()); outMsg.setTargetType(building.getObjectType().ordinal());
outMsg.setTargetID(building.getObjectUUID()); outMsg.setTargetID(building.getObjectUUID());
} else if (BuildingManager.playerCanManage(player, building)) {
} else if (BuildingManager.playerCanManage(player, building)) { //TODO allow Friends list. configWindowState(player, building, outMsg);
configWindowState(player, building, outMsg); outMsg.actionType = 3;
outMsg.actionType = 3; outMsg.setTargetType(building.getObjectType().ordinal());
outMsg.setTargetType(building.getObjectType().ordinal()); outMsg.setTargetID(building.getObjectUUID());
outMsg.setTargetID(building.getObjectUUID()); outMsg.setTargetType3(building.getObjectType().ordinal());
outMsg.setTargetType3(building.getObjectType().ordinal()); outMsg.setTargetID3(building.getObjectUUID());
outMsg.setTargetID3(building.getObjectUUID()); outMsg.setUnknown54(1);
outMsg.setUnknown54(1); } else {
// Handle other cases
} else { if (building.getRank() == -1) {
if (!Bounds.collide(player.getLoc(), building)) {
if (building.getBlueprintUUID() != 0) ErrorPopupMsg.sendErrorPopup(player, 64);
switch (building.getBlueprint().getBuildingGroup()) { return true;
case SHRINE: }
if (building.getRank() == -1) { switch (building.getBlueprint().getBuildingGroup()) {
if (!Bounds.collide(player.getLoc(), building)) { case SHRINE:
ErrorPopupMsg.sendErrorPopup(player, 64);
return true;
}
Shrine shrine = Shrine.shrinesByBuildingUUID.get(building.getObjectUUID()); Shrine shrine = Shrine.shrinesByBuildingUUID.get(building.getObjectUUID());
if (shrine == null || shrine.getFavors() == 0) {
if (shrine == null)
return true;
if (shrine.getFavors() == 0) {
ErrorPopupMsg.sendErrorPopup(player, 166); // There is no more favor in this shrine to loot ErrorPopupMsg.sendErrorPopup(player, 166); // There is no more favor in this shrine to loot
return true; return true;
} }
//loot elan stones
BuildingManager.lootBuilding(player, building); MobLoot elanStones = new MobLoot(player,ItemBase.getItemBase(1705032),1,false);
return true; Item promotedItem = elanStones.promoteToItem(player);
} promotedItem.setNumOfItems(shrine.getFavors());
break; player.getCharItemManager().addItemToInventory(promotedItem);
case WAREHOUSE: DbManager.ItemQueries.UPDATE_NUM_ITEMS(promotedItem,promotedItem.getNumOfItems());
//TODO check player.getCharItemManager().updateInventory();
if (building.getRank() == -1) { shrine.setFavors(0);
if (!Bounds.collide(player.getLoc(), building)) { break;
ErrorPopupMsg.sendErrorPopup(player, 64); case WAREHOUSE:
return true;
}
Warehouse warehouse = Warehouse.warehouseByBuildingUUID.get(building.getObjectUUID()); Warehouse warehouse = Warehouse.warehouseByBuildingUUID.get(building.getObjectUUID());
if (warehouse == null || warehouse.isEmpty()) {
if (warehouse == null)
return true;
if (warehouse.isEmpty()) {
ErrorPopupMsg.sendErrorPopup(player, 167); // no more resources. ErrorPopupMsg.sendErrorPopup(player, 167); // no more resources.
return true; return true;
} }
break;
BuildingManager.lootBuilding(player, building); }
return true; }
} AbstractCharacter owner = building.getOwner();
if (owner == null) {
msg.actionType = 4;
DispatchMessage.dispatchMsgDispatch(Dispatch.borrow(player, msg), DispatchChannel.SECONDARY);
} else {
outMsg.actionType = 4;
outMsg.setTargetType(building.getObjectType().ordinal());
outMsg.setTargetID(building.getObjectUUID());
outMsg.setAssetName(building.getName());
} }
if (building.getRank() == -1)
return true;
AbstractCharacter owner = building.getOwner();
//no owner, send building info
if (owner == null) {
msg.actionType = 4;
Dispatch dispatch = Dispatch.borrow(player, msg);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
return true;
} }
outMsg.actionType = 4; DispatchMessage.dispatchMsgDispatch(Dispatch.borrow(player, outMsg), DispatchChannel.SECONDARY);
return true;
case 13:
outMsg.actionType = 13;
DispatchMessage.dispatchMsgDispatch(Dispatch.borrow(player, outMsg), DispatchChannel.SECONDARY);
return true;
case 5:
building.setName(msg.getAssetName());
configWindowState(player, building, outMsg);
outMsg.actionType = 3;
outMsg.setTargetType(building.getObjectType().ordinal()); outMsg.setTargetType(building.getObjectType().ordinal());
outMsg.setTargetID(building.getObjectUUID()); outMsg.setTargetID(building.getObjectUUID());
outMsg.setAssetName(building.getName()); outMsg.setTargetType3(GameObjectType.Building.ordinal());
outMsg.setTargetID3(building.getObjectUUID());
} outMsg.setAssetName1(building.getName());
Dispatch dispatch = Dispatch.borrow(player, outMsg); outMsg.setUnknown54(1);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); DispatchMessage.dispatchMsgDispatch(Dispatch.borrow(player, outMsg), DispatchChannel.SECONDARY);
return true; return true;
case 14:
ManageCityAssetsMsg mca = new ManageCityAssetsMsg(player, building);
mca.actionType = 15;
DispatchMessage.dispatchMsgDispatch(Dispatch.borrow(player, mca), DispatchChannel.SECONDARY);
return true;
case 20:
// Handle case 20
return handleCase20(player, outMsg, building, msg, origin);
default:
return true;
} }
}
if (msg.actionType == 13) { private boolean handleCase20(PlayerCharacter player, ManageCityAssetsMsg outMsg, Building building, ManageCityAssetsMsg msg, ClientConnection origin) throws MsgSendException {
outMsg.actionType = 13; Zone baneZone = building.getParentZone();
Dispatch dispatch = Dispatch.borrow(player, outMsg); if (baneZone == null)
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
return true; return true;
} City banedCity = City.getCity(baneZone.getPlayerCityUUID());
if (banedCity == null)
//Rename Building.
if (msg.actionType == 5) {
//TODO we need to check names before allowing
building.setName(msg.getAssetName());
configWindowState(player, building, outMsg);
outMsg.actionType = 3;
outMsg.setTargetType(building.getObjectType().ordinal());
outMsg.setTargetID(building.getObjectUUID());
outMsg.setTargetType3(GameObjectType.Building.ordinal());
outMsg.setTargetID3(building.getObjectUUID());
outMsg.setAssetName1(building.getName());
outMsg.setUnknown54(1);
Dispatch dispatch = Dispatch.borrow(player, outMsg);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
return true; return true;
Bane bane = banedCity.getBane();
//TOL, update city name also if (bane == null || bane.getLiveDate() != null || player.getGuild() != banedCity.getGuild() || !GuildStatusController.isInnerCouncil(player.getGuildStatus()))
//TODO update city and zone in database
//TODO update city map data in game server
}
if (msg.actionType == 14) {
ManageCityAssetsMsg mca = new ManageCityAssetsMsg(player, building);
mca.actionType = 15;
Dispatch dispatch = Dispatch.borrow(player, mca);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
return true; return true;
} int baneHour = msg.getBaneHour();
if (baneHour < 16 || baneHour > 24) {
if (msg.actionType == 20) { PlaceAssetMsg.sendPlaceAssetError(origin, 1, "A Serious error has occurred. Please post details for to ensure transaction integrity");
Zone baneZone = building.getParentZone();
if (baneZone == null)
return true;
City banedCity = City.getCity(baneZone.getPlayerCityUUID());
if (banedCity == null)
return true;
Bane bane = banedCity.getBane();
if (bane == null || bane.getLiveDate() != null || player.getGuild() != banedCity.getGuild() || GuildStatusController.isInnerCouncil(player.getGuildStatus()) == false)
return true;
int baneHour = msg.getBaneHour();
if (baneHour < 16 || baneHour > 24) {
PlaceAssetMsg.sendPlaceAssetError(origin, 1, "A Serious error has occurred. Please post details for to ensure transaction integrity");
return true;
}
DateTime baneLive = new DateTime(bane.getPlacementDate());
baneLive = baneHour == 24 ? baneLive.plusDays(3) : baneLive.plusDays(2);
baneLive = baneHour == 24 ? baneLive.hourOfDay().setCopy(0) : baneLive.hourOfDay().setCopy(baneHour);
baneLive = baneLive.minuteOfHour().setCopy(0);
baneLive = baneLive.secondOfMinute().setCopy(1);
bane.setLiveDate(baneLive);
outMsg.actionType = 18;
Dispatch dispatch = Dispatch.borrow(player, outMsg);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
return true; return true;
} }
DateTime baneLive = new DateTime(bane.getPlacementDate());
baneLive = baneHour == 24 ? baneLive.plusDays(3) : baneLive.plusDays(2);
baneLive = baneHour == 24 ? baneLive.hourOfDay().setCopy(0) : baneLive.hourOfDay().setCopy(baneHour);
baneLive = baneLive.minuteOfHour().setCopy(0);
baneLive = baneLive.secondOfMinute().setCopy(1);
bane.setLiveDate(baneLive);
outMsg.actionType = 18;
DispatchMessage.dispatchMsgDispatch(Dispatch.borrow(player, outMsg), DispatchChannel.SECONDARY);
return true; return true;
} }
public void configWindowState(PlayerCharacter player, Building building, ManageCityAssetsMsg manageCityAssetsMsg) { public void configWindowState(PlayerCharacter player, Building building, ManageCityAssetsMsg manageCityAssetsMsg) {
// Tests to turn on upgrade button if a building is not // Tests to turn on upgrade button if a building is not
@ -294,7 +226,7 @@ public class ManageCityAssetMsgHandler extends AbstractClientMsgHandler {
// Owner is obviously allowed to upgrade his own buildings // Owner is obviously allowed to upgrade his own buildings
if (building.getOwner().equals(player)) { if (building.getOwner() != null && building.getOwner().equals(player)) {
// Players cannot destroy or transfer a TOL. // Players cannot destroy or transfer a TOL.

20
src/engine/net/client/handlers/MerchantMsgHandler.java

@ -147,7 +147,7 @@ public class MerchantMsgHandler extends AbstractClientMsgHandler {
Building shrineBuilding; Building shrineBuilding;
Shrine shrine; Shrine shrine;
if (npc.getGuild() != player.getGuild()) if (npc.getGuild().getNation() != player.getGuild().getNation())
return; return;
shrineBuilding = npc.getBuilding(); shrineBuilding = npc.getBuilding();
@ -173,10 +173,10 @@ public class MerchantMsgHandler extends AbstractClientMsgHandler {
//already haz boon. //already haz boon.
if (player.containsEffect(shrine.getShrineType().getPowerToken())) { //if (player.containsEffect(shrine.getShrineType().getPowerToken())) {
ErrorPopupMsg.sendErrorPopup(player, 199); // ErrorPopupMsg.sendErrorPopup(player, 199);
return; // return;
} //}
if (!Shrine.canTakeFavor(player, shrine)) if (!Shrine.canTakeFavor(player, shrine))
return; return;
@ -191,12 +191,10 @@ public class MerchantMsgHandler extends AbstractClientMsgHandler {
return; return;
} }
int rank = shrine.getRank(); if(shrinePower.getName().equals("Boon: Nephilim"))
//R8 trees always get atleast rank 2 boons. rank uses index, where 0 is first place, 1 is second, etc... shrinePower.name = "Boon: Chaos";
if (shrineBuilding.getCity() != null && shrineBuilding.getCity().getTOL() != null && shrineBuilding.getCity().getTOL().getRank() == 8)
if (rank != 0) int trains = 5 * npc.getRank() + 5;//40 - (rank * 10);
rank = 1;
int trains = 40 - (rank * 10);
if (trains < 0) if (trains < 0)
trains = 0; trains = 0;

75
src/engine/net/client/handlers/MinionTrainingMsgHandler.java

@ -8,7 +8,6 @@ import engine.gameManager.BuildingManager;
import engine.gameManager.DbManager; import engine.gameManager.DbManager;
import engine.gameManager.NPCManager; import engine.gameManager.NPCManager;
import engine.gameManager.SessionManager; import engine.gameManager.SessionManager;
import engine.math.Vector3fImmutable;
import engine.net.Dispatch; import engine.net.Dispatch;
import engine.net.DispatchMessage; import engine.net.DispatchMessage;
import engine.net.client.ClientConnection; import engine.net.client.ClientConnection;
@ -42,7 +41,6 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler {
if (player == null) if (player == null)
return true; return true;
if (minionMsg.getNpcType() == Enum.GameObjectType.NPC.ordinal()) { if (minionMsg.getNpcType() == Enum.GameObjectType.NPC.ordinal()) {
NPC npc = NPC.getFromCache(minionMsg.getNpcID()); NPC npc = NPC.getFromCache(minionMsg.getNpcID());
@ -63,10 +61,10 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler {
Mob toRemove = Mob.getFromCache(minionMsg.getUUID()); Mob toRemove = Mob.getFromCache(minionMsg.getUUID());
if (!npc.getSiegeMinionMap().containsKey(toRemove)) if (!npc.siegeMinionMap.containsKey(toRemove))
return true; return true;
npc.getSiegeMinionMap().remove(toRemove); npc.siegeMinionMap.remove(toRemove);
WorldGrid.RemoveWorldObject(toRemove); WorldGrid.RemoveWorldObject(toRemove);
@ -74,14 +72,18 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler {
toRemove.getParentZone().zoneMobSet.remove(toRemove); toRemove.getParentZone().zoneMobSet.remove(toRemove);
DbManager.removeFromCache(toRemove); DbManager.removeFromCache(toRemove);
PlayerCharacter petOwner = toRemove.getOwner();
if (petOwner != null) { if(toRemove.guardCaptain.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) {
petOwner.setPet(null); PlayerCharacter petOwner = (PlayerCharacter) toRemove.guardCaptain;
toRemove.setOwner(null);
PetMsg petMsg = new PetMsg(5, null); if (petOwner != null) {
Dispatch dispatch = Dispatch.borrow(petOwner, petMsg); petOwner.setPet(null);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
toRemove.guardCaptain = null;
PetMsg petMsg = new PetMsg(5, null);
Dispatch dispatch = Dispatch.borrow(petOwner, petMsg);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
}
} }
// we Found the move to remove, lets break the for loop so it doesnt look for more. // we Found the move to remove, lets break the for loop so it doesnt look for more.
@ -115,7 +117,7 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler {
if (npc.getContractID() == 842) if (npc.getContractID() == 842)
maxSlots = 1; maxSlots = 1;
if (npc.getSiegeMinionMap().size() == maxSlots) if (npc.siegeMinionMap.size() == maxSlots)
return true; return true;
int mobBase; int mobBase;
@ -146,42 +148,10 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler {
if (mobBase == 0) if (mobBase == 0)
return true; return true;
Mob siegeMob = Mob.createSiegeMob(npc, mobBase, npc.getGuild(), zone, b.getLoc(), (short) 1); Mob siegeMob = Mob.createSiegeMinion(npc, mobBase);
if (siegeMob == null) if (siegeMob == null)
return true; return true;
if (siegeMob != null) {
siegeMob.setSpawnTime(60 * 15);
Building building = BuildingManager.getBuilding(((MinionTrainingMessage) baseMsg).getBuildingID());
siegeMob.building = building;
siegeMob.parentZone = zone;
// Slot siege minion
// Can be either corner tower or bulwark.
int slot;
if (building.getBlueprint().getBuildingGroup().equals(Enum.BuildingGroup.ARTYTOWER))
slot = 2;
else
slot = ((NPC) siegeMob.npcOwner).getSiegeMinionMap().get(siegeMob) + 1; // First slot is for the captain
BuildingLocation slotLocation = BuildingManager._slotLocations.get(building.meshUUID).get(slot);
siegeMob.bindLoc = building.getLoc().add(slotLocation.getLocation());
// Rotate slot position by the building rotation
siegeMob.bindLoc = Vector3fImmutable.rotateAroundPoint(building.getLoc(), siegeMob.bindLoc, building.getBounds().getQuaternion().angleY);
siegeMob.loc = new Vector3fImmutable(siegeMob.bindLoc);
siegeMob.endLoc = new Vector3fImmutable(siegeMob.bindLoc);
zone.zoneMobSet.add(siegeMob);
siegeMob.setLoc(siegeMob.bindLoc);
}
} }
ManageNPCMsg mnm = new ManageNPCMsg(npc); ManageNPCMsg mnm = new ManageNPCMsg(npc);
@ -228,11 +198,14 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler {
toRemove.getParentZone().zoneMobSet.remove(toRemove); toRemove.getParentZone().zoneMobSet.remove(toRemove);
DbManager.removeFromCache(toRemove); DbManager.removeFromCache(toRemove);
PlayerCharacter petOwner = toRemove.getOwner();
PlayerCharacter petOwner = (PlayerCharacter) toRemove.guardCaptain;
if (petOwner != null) { if (petOwner != null) {
petOwner.setPet(null); petOwner.setPet(null);
toRemove.setOwner(null);
toRemove.guardCaptain = null;
PetMsg petMsg = new PetMsg(5, null); PetMsg petMsg = new PetMsg(5, null);
Dispatch dispatch = Dispatch.borrow(petOwner, petMsg); Dispatch dispatch = Dispatch.borrow(petOwner, petMsg);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
@ -298,14 +271,14 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler {
String pirateName = NPCManager.getPirateName(mobBase); String pirateName = NPCManager.getPirateName(mobBase);
if (!DbManager.MobQueries.ADD_TO_GUARDS(npc.getObjectUUID(), mobBase, pirateName, npc.getSiegeMinionMap().size() + 1)) Mob toCreate = Mob.createGuardMinion(npc, npc.getLevel(), pirateName);
return true;
Mob toCreate = Mob.createGuardMob(npc, npc.getGuild(), zone, building.getLoc(), npc.getLevel(), pirateName);
if (toCreate == null) if (toCreate == null)
return true; return true;
if (!DbManager.MobQueries.ADD_TO_GUARDS(npc.getObjectUUID(), mobBase, pirateName, npc.getSiegeMinionMap().size() + 1))
return true;
if (toCreate != null) { if (toCreate != null) {
toCreate.setDeathTime(System.currentTimeMillis()); toCreate.setDeathTime(System.currentTimeMillis());
toCreate.parentZone.zoneMobSet.add(toCreate); toCreate.parentZone.zoneMobSet.add(toCreate);

14
src/engine/net/client/handlers/ObjectActionMsgHandler.java

@ -195,7 +195,9 @@ public class ObjectActionMsgHandler extends AbstractClientMsgHandler {
} }
hPMod = (building.getMaxHitPoints() * Realm.getRealmHealthMod(city)); hPMod = (building.getMaxHitPoints() * Realm.getRealmHealthMod(city));
float percentOfHealth = building.getCurrentHitpoints() / building.getHealthMax();
building.setMaxHitPoints(building.getMaxHitPoints() + hPMod); building.setMaxHitPoints(building.getMaxHitPoints() + hPMod);
building.setCurrentHitPoints(building.getMaxHitPoints() * percentOfHealth);
} }
} }
@ -439,8 +441,10 @@ public class ObjectActionMsgHandler extends AbstractClientMsgHandler {
// } // }
// break; // break;
//} //}
int i = 0;
LootManager.peddleFate(player,item); if(i != 0) {
LootManager.peddleFate(player, item);
}
break; break;
case 30: //water bucket case 30: //water bucket
@ -538,7 +542,11 @@ public class ObjectActionMsgHandler extends AbstractClientMsgHandler {
PowersManager.applyPower(player, target, Vector3fImmutable.ZERO, ib.getUseID(), ib.getUseAmount(), true); PowersManager.applyPower(player, target, Vector3fImmutable.ZERO, ib.getUseID(), ib.getUseAmount(), true);
itemMan.consume(item); itemMan.consume(item);
} else //just remove the item at this point } else if(ib.getUUID() > 252128 && ib.getUUID() < 252568){
if (ApplyRuneMsg.applyRune(uuid, origin, player)) {
itemMan.consume(item);
}
}else //just remove the item at this point
itemMan.consume(item); itemMan.consume(item);
dispatch = Dispatch.borrow(player, msg); dispatch = Dispatch.borrow(player, msg);

7
src/engine/net/client/handlers/OpenFriendsCondemnListMsgHandler.java

@ -44,6 +44,13 @@ public class OpenFriendsCondemnListMsgHandler extends AbstractClientMsgHandler {
return true; return true;
msg = (OpenFriendsCondemnListMsg) baseMsg; msg = (OpenFriendsCondemnListMsg) baseMsg;
sourceBuilding = BuildingManager.getBuildingFromCache(msg.getBuildingID());
if(sourceBuilding != null && sourceBuilding.getBlueprint().getBuildingGroup().equals(Enum.BuildingGroup.TOL)){
return true;
}
openFriendsCondemnListMsg = new OpenFriendsCondemnListMsg(msg); openFriendsCondemnListMsg = new OpenFriendsCondemnListMsg(msg);
friendListType = Enum.FriendListType.getListTypeByID(msg.getMessageType()); friendListType = Enum.FriendListType.getListTypeByID(msg.getMessageType());

10
src/engine/net/client/handlers/OrderNPCMsgHandler.java

@ -212,10 +212,6 @@ public class OrderNPCMsgHandler extends AbstractClientMsgHandler {
return; return;
} }
for (AbstractCharacter guard : building.getHirelings().keySet()) {
if (guard.getObjectType() == GameObjectType.Mob)
((Mob) guard).setPatrolPointIndex(0);
}
} else if (building.getPatrolPoints() != null) } else if (building.getPatrolPoints() != null)
ClearPatrolPoints(building.getObjectUUID()); ClearPatrolPoints(building.getObjectUUID());
@ -223,10 +219,6 @@ public class OrderNPCMsgHandler extends AbstractClientMsgHandler {
AddSentryPoints(building.getObjectUUID(), orderNpcMsg.getSentryPoints()); AddSentryPoints(building.getObjectUUID(), orderNpcMsg.getSentryPoints());
} else if (building.getSentryPoints() != null) } else if (building.getSentryPoints() != null)
ClearSentryPoints(building.getObjectUUID()); ClearSentryPoints(building.getObjectUUID());
// Dispatch dispatch = Dispatch.borrow(pc, msg);
// DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
} }
private static void processUpgradeNPC(PlayerCharacter player, AbstractCharacter abstractCharacter) { private static void processUpgradeNPC(PlayerCharacter player, AbstractCharacter abstractCharacter) {
@ -541,7 +533,7 @@ public class OrderNPCMsgHandler extends AbstractClientMsgHandler {
} else if (orderNPCMsg.getObjectType() == GameObjectType.Mob.ordinal()) { } else if (orderNPCMsg.getObjectType() == GameObjectType.Mob.ordinal()) {
mob = Mob.getFromCacheDBID(orderNPCMsg.getNpcUUID()); mob = Mob.getMob(orderNPCMsg.getNpcUUID());
if (mob == null) if (mob == null)
return true; return true;

10
src/engine/net/client/handlers/PlaceAssetMsgHandler.java

@ -412,6 +412,9 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
break; break;
if (!playerCharacter.getCharItemManager().doesCharOwnThisItem(contract.getObjectUUID())) if (!playerCharacter.getCharItemManager().doesCharOwnThisItem(contract.getObjectUUID()))
break; break;
if(contract.getItemBaseID() == 1035){//saetor shrine override
msg.getFirstPlacementInfo().setBlueprintUUID(1720000);
}
buildingCreated = placeShrine(playerCharacter, origin, msg); buildingCreated = placeShrine(playerCharacter, origin, msg);
break; break;
case BARRACK: case BARRACK:
@ -800,7 +803,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
treeObject.setObjectTypeMask(MBServerStatics.MASK_BUILDING); treeObject.setObjectTypeMask(MBServerStatics.MASK_BUILDING);
treeObject.setParentZone(zoneObject); treeObject.setParentZone(zoneObject);
MaintenanceManager.setMaintDateTime(treeObject, LocalDateTime.now().plusDays(7)); MaintenanceManager.setMaintDateTime(treeObject, LocalDateTime.now().plusDays(14));
// Update guild binds and tags // Update guild binds and tags
//load the new city on the clients //load the new city on the clients
@ -1210,7 +1213,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
private boolean createShrine(PlayerCharacter player, PlacementInfo buildingInfo, Zone currentZone) { private boolean createShrine(PlayerCharacter player, PlacementInfo buildingInfo, Zone currentZone) {
Blueprint blueprint; Blueprint blueprint;
Building newMesh; Building newMesh = null;
Shrine newShrine; Shrine newShrine;
City city; City city;
ShrineType shrineType; ShrineType shrineType;
@ -1271,6 +1274,9 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
break; break;
} }
} }
if(blueprint.getName().equals("Nephilim Shrine ") && newMesh != null){
newMesh.setName("Chaos Shrine");
}
return true; return true;
} }

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

@ -57,7 +57,7 @@ public class RequestEnterWorldHandler extends AbstractClientMsgHandler {
return true; return true;
} }
player.setEnteredWorld(false); player.enteredWorld = false;
Account acc = SessionManager.getAccount(origin); Account acc = SessionManager.getAccount(origin);

10
src/engine/net/client/handlers/TaxCityMsgHandler.java

@ -4,6 +4,7 @@ import engine.Enum;
import engine.InterestManagement.RealmMap; import engine.InterestManagement.RealmMap;
import engine.exception.MsgSendException; import engine.exception.MsgSendException;
import engine.gameManager.BuildingManager; import engine.gameManager.BuildingManager;
import engine.gameManager.ChatManager;
import engine.net.Dispatch; import engine.net.Dispatch;
import engine.net.DispatchMessage; import engine.net.DispatchMessage;
import engine.net.client.ClientConnection; import engine.net.client.ClientConnection;
@ -131,14 +132,15 @@ public class TaxCityMsgHandler extends AbstractClientMsgHandler {
TaxCityMsg msg; TaxCityMsg msg;
player = origin.getPlayerCharacter(); player = origin.getPlayerCharacter();
ChatManager.chatSystemInfo(player,"Taxing has been disabled");
return false;
//msg = (TaxCityMsg) baseMsg;
msg = (TaxCityMsg) baseMsg; //ViewTaxes(msg, player);
ViewTaxes(msg, player);
//return true;
return true;
} }

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

@ -66,6 +66,8 @@ public class UpgradeAssetMsgHandler extends AbstractClientMsgHandler {
Logger.error("Attempt to upgrade null building by " + player.getName()); Logger.error("Attempt to upgrade null building by " + player.getName());
return true; return true;
} }
if(buildingToRank.getBlueprint().getBuildingGroup().equals(Enum.BuildingGroup.WAREHOUSE))
return true;
// Early exit for building that is already ranking // Early exit for building that is already ranking

150
src/engine/net/client/msg/ApplyRuneMsg.java

@ -10,6 +10,7 @@
package engine.net.client.msg; package engine.net.client.msg;
import engine.Enum; import engine.Enum;
import engine.gameManager.ChatManager;
import engine.gameManager.DbManager; import engine.gameManager.DbManager;
import engine.net.*; import engine.net.*;
import engine.net.client.ClientConnection; import engine.net.client.ClientConnection;
@ -77,55 +78,98 @@ public class ApplyRuneMsg extends ClientNetMsg {
if (playerCharacter == null || origin == null || rb == null) { if (playerCharacter == null || origin == null || rb == null) {
return false; return false;
} }
int raceID = playerCharacter.getRaceID();
//Check race is met //Check race is met
ConcurrentHashMap<Integer, Boolean> races = rb.getRace(); ConcurrentHashMap<Integer, Boolean> races = rb.getRace();
if (races.size() > 0) { if(runeID != 3007 && runeID != 3014) {//bounty hunter and huntsman
int raceID = playerCharacter.getRaceID(); if (races.size() > 0) {
boolean valid = false;
for (int validID : races.keySet()) { boolean valid = false;
if (validID == raceID) { for (int validID : races.keySet()) {
if (validID == raceID) {
valid = true;
break;
}
}
if(runeID == 3040)
valid = true;
if(runeID == 2514 && raceID == 1999)
valid = true; valid = true;
break;
if(runeID == 3036 && raceID == 1999)
valid = true;
if(runeID == 3033 && raceID == 1999)
valid = true;
if (!valid) {
return false;
} }
} }
if (!valid) {
return false;
}
}
//Check base class is met //Check base class is met
ConcurrentHashMap<Integer, Boolean> baseClasses = rb.getBaseClass(); ConcurrentHashMap<Integer, Boolean> baseClasses = rb.getBaseClass();
if (baseClasses.size() > 0) { if (baseClasses.size() > 0) {
int baseClassID = playerCharacter.getBaseClassID(); int baseClassID = playerCharacter.getBaseClassID();
boolean valid = false; boolean valid = false;
for (int validID : baseClasses.keySet()) { for (int validID : baseClasses.keySet()) {
if (validID == baseClassID) { if (validID == baseClassID) {
valid = true;
break;
}
}
if(runeID == 3040)
valid = true;
if(runeID == 3036 && raceID == 1999)
valid = true;
if(runeID == 3033 && raceID == 1999)
valid = true;
if(runeID == 3035 && baseClassID == 2501)
valid = true; valid = true;
break;
if (!valid) {
return false;
} }
} }
if (!valid) {
return false;
}
}
//Check promotion class is met //Check promotion class is met
ConcurrentHashMap<Integer, Boolean> promotionClasses = rb.getPromotionClass(); ConcurrentHashMap<Integer, Boolean> promotionClasses = rb.getPromotionClass();
if (promotionClasses.size() > 0) { if (promotionClasses.size() > 0) {
int promotionClassID = playerCharacter.getPromotionClassID(); int promotionClassID = playerCharacter.getPromotionClassID();
boolean valid = false; boolean valid = false;
for (int validID : promotionClasses.keySet()) { for (int validID : promotionClasses.keySet()) {
if (validID == promotionClassID) { if (validID == promotionClassID) {
valid = true;
break;
}
}
if(runeID == 3040)
valid = true;
if(runeID == 3004 && (playerCharacter.getPromotionClassID() == 2505 || playerCharacter.getPromotionClassID() == 2510))
valid = true;
if(runeID == 3036 && raceID == 1999)
valid = true; valid = true;
break;
if(runeID == 3033 && raceID == 1999)
valid = true;
if (!valid) {
return false;
} }
} }
if (!valid) { } else{
if(playerCharacter.getPromotionClassID() == 2519){//priest
return false; return false;
} }
} }
//Check disciplines are met //Check disciplines are met
ArrayList<CharacterRune> runes = playerCharacter.getRunes(); ArrayList<CharacterRune> runes = playerCharacter.getRunes();
ConcurrentHashMap<Integer, Boolean> disciplines = rb.getDiscipline(); ConcurrentHashMap<Integer, Boolean> disciplines = rb.getDiscipline();
@ -174,7 +218,16 @@ public class ApplyRuneMsg extends ClientNetMsg {
int mod = rba.getModValue(); int mod = rba.getModValue();
switch (attrID) { switch (attrID) {
case MBServerStatics.RUNE_COST_ATTRIBUTE_ID: case MBServerStatics.RUNE_COST_ATTRIBUTE_ID:
switch (rb.getName()) {
case "Born of the Ethyri":
case "Born of the Taripontor":
case "Born of the Gwendannen":
case "Born of the Invorri":
case "Born of the Irydnu":
mod = 0;
}
if (mod > playerCharacter.getUnusedStatPoints()) { if (mod > playerCharacter.getUnusedStatPoints()) {
return false; return false;
} }
cost = mod; cost = mod;
@ -232,8 +285,29 @@ public class ApplyRuneMsg extends ClientNetMsg {
return false; return false;
} }
switch (rb.getName()) {
case "Born of the Ethyri":
case "Born of the Taripontor":
case "Born of the Gwendannen":
case "Born of the Invorri":
case "Born of the Irydnu":
for (CharacterRune charRune : playerCharacter.getRunes()) {
RuneBase rb2 = charRune.getRuneBase();
switch (rb2.getName()) {
case "Born of the Ethyri":
case "Born of the Taripontor":
case "Born of the Gwendannen":
case "Born of the Invorri":
case "Born of the Irydnu":
ChatManager.chatSystemError(playerCharacter, "You Have Already Applied A Blood Rune");
return false;
}
}
}
//if discipline, check number applied //if discipline, check number applied
if (isDiscipline(runeID)) { if (isDiscipline(runeID)) {
//if(playerCharacter.getLevel() == 80)
discCount -= 1; // level 80 characters get an extra disc rune
if (playerCharacter.getLevel() < 70) { if (playerCharacter.getLevel() < 70) {
if (discCount > 2) { if (discCount > 2) {
return false; return false;
@ -304,7 +378,15 @@ public class ApplyRuneMsg extends ClientNetMsg {
playerCharacter.recalculate(); playerCharacter.recalculate();
} }
} }
switch (rb.getName()) {
case "Born of the Ethyri":
case "Born of the Taripontor":
case "Born of the Gwendannen":
case "Born of the Invorri":
case "Born of the Irydnu":
cost = 0;
break;
}
if (cost > 0) { if (cost > 0) {
ModifyStatMsg msm = new ModifyStatMsg((0 - cost), 0, 3); ModifyStatMsg msm = new ModifyStatMsg((0 - cost), 0, 3);
dispatch = Dispatch.borrow(playerCharacter, msm); dispatch = Dispatch.borrow(playerCharacter, msm);

6
src/engine/net/client/msg/CityDataMsg.java

@ -87,7 +87,11 @@ public class CityDataMsg extends ClientNetMsg {
temp.putInt(cityList.size()); temp.putInt(cityList.size());
for (City city : cityList) for (City city : cityList)
City.serializeForClientMsg(city, temp); try {
City.serializeForClientMsg(city, temp);
}catch(Exception e){
continue;
}
temp.put((byte) 0); // PAD temp.put((byte) 0); // PAD
// Serialize runegates // Serialize runegates

5
src/engine/net/client/msg/CityZoneMsg.java

@ -9,6 +9,7 @@
package engine.net.client.msg; package engine.net.client.msg;
import engine.Enum;
import engine.Enum.GameObjectType; import engine.Enum.GameObjectType;
import engine.net.AbstractConnection; import engine.net.AbstractConnection;
import engine.net.ByteBufferReader; import engine.net.ByteBufferReader;
@ -42,8 +43,8 @@ public class CityZoneMsg extends ClientNetMsg {
this.locY = locY; this.locY = locY;
this.locZ = locZ; this.locZ = locZ;
this.name = name; this.name = name;
this.radiusX = radiusX; this.radiusX = Enum.CityBoundsType.ZONE.extents;
this.radiusZ = radiusZ; this.radiusZ = Enum.CityBoundsType.ZONE.extents;
this.unknown01 = 0; this.unknown01 = 0;
} }

6
src/engine/net/client/msg/ManageCityAssetsMsg.java

@ -9,6 +9,7 @@
package engine.net.client.msg; package engine.net.client.msg;
import engine.Enum;
import engine.Enum.*; import engine.Enum.*;
import engine.gameManager.BuildingManager; import engine.gameManager.BuildingManager;
import engine.gameManager.ZoneManager; import engine.gameManager.ZoneManager;
@ -531,7 +532,10 @@ public class ManageCityAssetsMsg extends ClientNetMsg {
else if (building.getRank() == building.getBlueprint().getMaxRank()) else if (building.getRank() == building.getBlueprint().getMaxRank())
this.upgradeCost = Integer.MAX_VALUE; this.upgradeCost = Integer.MAX_VALUE;
else else
this.upgradeCost = building.getBlueprint().getRankCost(Math.min(building.getRank() + 1, 7)); if(building.getBlueprint().getBuildingGroup().equals(Enum.BuildingGroup.WAREHOUSE))
this.upgradeCost = Integer.MAX_VALUE;
else
this.upgradeCost = building.getBlueprint().getRankCost(Math.min(building.getRank() + 1, 7));
writer.putInt(this.upgradeCost); writer.putInt(this.upgradeCost);
} else } else

8
src/engine/net/client/msg/ManageNPCMsg.java

@ -343,7 +343,7 @@ public class ManageNPCMsg extends ClientNetMsg {
writer.putInt(0); //runemaster list writer.putInt(0); //runemaster list
//artillery captain list //artillery captain list
ConcurrentHashMap<Mob, Integer> siegeMinions = npc.getSiegeMinionMap(); ConcurrentHashMap<Mob, Integer> siegeMinions = npc.siegeMinionMap;
writer.putInt(1 + siegeMinions.size()); writer.putInt(1 + siegeMinions.size());
serializeBulwarkList(writer, 1); //Trebuchet serializeBulwarkList(writer, 1); //Trebuchet
//serializeBulwarkList(writer, 2); //Ballista //serializeBulwarkList(writer, 2); //Ballista
@ -366,7 +366,7 @@ public class ManageNPCMsg extends ClientNetMsg {
long timeLife = upgradeTime - curTime; long timeLife = upgradeTime - curTime;
if (upgradeTime * 1000 > System.currentTimeMillis()) { if (upgradeTime * 1000 > System.currentTimeMillis()) {
if (mob.npcOwner.isAlive()) { if (mob.guardCaptain.isAlive()) {
writer.put((byte) 0);//shows respawning timer writer.put((byte) 0);//shows respawning timer
writer.putInt(mob.spawnTime); writer.putInt(mob.spawnTime);
writer.putInt(mob.spawnTime); writer.putInt(mob.spawnTime);
@ -557,7 +557,7 @@ public class ManageNPCMsg extends ClientNetMsg {
} else if (this.targetType == GameObjectType.Mob.ordinal()) { } else if (this.targetType == GameObjectType.Mob.ordinal()) {
mobA = Mob.getFromCacheDBID(this.targetID); mobA = Mob.getMob(this.targetID);
if (mobA == null) { if (mobA == null) {
Logger.error("Missing Mob of ID " + this.targetID); Logger.error("Missing Mob of ID " + this.targetID);
@ -689,7 +689,7 @@ public class ManageNPCMsg extends ClientNetMsg {
long timeLife = upgradeTime - curTime; long timeLife = upgradeTime - curTime;
if (upgradeTime * 1000 > System.currentTimeMillis()) { if (upgradeTime * 1000 > System.currentTimeMillis()) {
if (mob.npcOwner.isAlive()) { if (mob.guardCaptain.isAlive()) {
writer.put((byte) 0);//shows respawning timer writer.put((byte) 0);//shows respawning timer
writer.putInt(mob.spawnTime); writer.putInt(mob.spawnTime);
writer.putInt(mob.spawnTime); writer.putInt(mob.spawnTime);

3
src/engine/net/client/msg/PlaceAssetMsg.java

@ -601,6 +601,9 @@ public class PlaceAssetMsg extends ClientNetMsg {
public int getBlueprintUUID() { public int getBlueprintUUID() {
return this.blueprintUUID; return this.blueprintUUID;
} }
public void setBlueprintUUID(int id) {
this.blueprintUUID = id;
}
public Vector3fImmutable getLoc() { public Vector3fImmutable getLoc() {
return this.loc; return this.loc;

2
src/engine/net/client/msg/RefinerScreenMsg.java

@ -95,7 +95,7 @@ public class RefinerScreenMsg extends ClientNetMsg {
return this.unknown02; return this.unknown02;
} }
public void setUnknown02(int value) { public void setUnknown02(float value) {
this.unknown02 = value; this.unknown02 = value;
} }

1
src/engine/net/client/msg/TrainMsg.java

@ -94,7 +94,6 @@ public class TrainMsg extends ClientNetMsg {
if (sk == null) if (sk == null)
return; return;
if (sk.getSkillsBase().getToken() == 40661438) { if (sk.getSkillsBase().getToken() == 40661438) {
int maxValue = 15; int maxValue = 15;

66
src/engine/net/client/msg/VendorDialogMsg.java

@ -9,19 +9,19 @@
package engine.net.client.msg; package engine.net.client.msg;
import engine.Enum;
import engine.Enum.DispatchChannel; import engine.Enum.DispatchChannel;
import engine.Enum.GuildHistoryType; import engine.Enum.GuildHistoryType;
import engine.InterestManagement.InterestManager;
import engine.exception.MsgSendException; import engine.exception.MsgSendException;
import engine.gameManager.BuildingManager; import engine.gameManager.*;
import engine.gameManager.DbManager;
import engine.gameManager.GuildManager;
import engine.gameManager.SessionManager;
import engine.math.Vector3fImmutable; import engine.math.Vector3fImmutable;
import engine.net.*; import engine.net.*;
import engine.net.client.ClientConnection; import engine.net.client.ClientConnection;
import engine.net.client.Protocol; import engine.net.client.Protocol;
import engine.objects.*; import engine.objects.*;
import engine.server.MBServerStatics; import engine.server.MBServerStatics;
import engine.util.BoxTracker;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
@ -137,6 +137,29 @@ public class VendorDialogMsg extends ClientNetMsg {
msg.updateMessage(3, vd); msg.updateMessage(3, vd);
} }
if(contract.getObjectUUID() == 1502040){
if(!playerCharacter.getTimestamps().containsKey("lastBoxChange"))
playerCharacter.getTimestamps().put("lastBoxChange",System.currentTimeMillis() - 1000);
if(playerCharacter.getTimeStamp("lastBoxChange") + 30000L > System.currentTimeMillis()) {
ChatManager.chatSystemInfo(playerCharacter, "You Must Wait To Promote Again.");
return;
}
if(playerCharacter.isBoxed == false) {
ChatManager.chatSystemInfo(playerCharacter, "You Are Already The Active Character.");
return;
}
playerCharacter.getTimestamps().put("lastBoxChange",System.currentTimeMillis());
for(PlayerCharacter newlyBoxed : BoxTracker.getPlayers(playerCharacter.getClientConnection().machineID)){
newlyBoxed.isBoxed = true;
}
playerCharacter.isBoxed = false;
InterestManager.setObjectDirty(playerCharacter);
playerCharacter.removeEffectBySource(Enum.EffectSourceType.DeathShroud,50,true);
}
Dispatch dispatch = Dispatch.borrow(playerCharacter, msg); Dispatch dispatch = Dispatch.borrow(playerCharacter, msg);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
@ -548,23 +571,36 @@ public class VendorDialogMsg extends ClientNetMsg {
// verify race valid for profession // verify race valid for profession
Race race = pc.getRace(); Race race = pc.getRace();
if (race == null || !promo.isAllowedRune(race.getToken())) { if(race.getRaceRuneID() == 1999 && (promoID == 2512 || promoID == 2511)) {
// TODO send client promotion error
return; } else if(promo.getName().equals("Ranger")&& race.getName().equals("Saetor"))
} {
}else {
if (race == null || !promo.isAllowedRune(race.getToken())) {
// TODO send client promotion error
return;
}
}
// verify baseclass valid for profession // verify baseclass valid for profession
BaseClass bc = pc.getBaseClass(); BaseClass bc = pc.getBaseClass();
if (bc == null || !promo.isAllowedRune(bc.getToken())) { if(promo.getName().equals("Druid") && (bc.getName().equals("Rogue") || bc.getName().equals("Mage"))) { //allow rogue and mage druids
// TODO send client promotion error
return; }
else {
if (bc == null || !promo.isAllowedRune(bc.getToken())) {
// TODO send client promotion error
return;
}
} }
// verify gender // verify gender
if (promoID == 2511 && pc.isMale()) // Fury if(race.getName().equals("Saetor") == false) { //saetors can promote to huntress and fury
return; if (promoID == 2511 && pc.isMale()) // Fury
if (promoID == 2512 && pc.isMale()) // Huntress return;
return; if (promoID == 2512 && pc.isMale()) // Huntress
return;
}
if (promoID == 2517 && !pc.isMale()) // Warlock if (promoID == 2517 && !pc.isMale()) // Warlock
return; return;

3
src/engine/net/client/msg/login/CommitNewCharacterMsg.java

@ -15,6 +15,7 @@ import engine.net.ByteBufferReader;
import engine.net.ByteBufferWriter; import engine.net.ByteBufferWriter;
import engine.net.client.Protocol; import engine.net.client.Protocol;
import engine.net.client.msg.ClientNetMsg; import engine.net.client.msg.ClientNetMsg;
import engine.objects.Race;
public class CommitNewCharacterMsg extends ClientNetMsg { public class CommitNewCharacterMsg extends ClientNetMsg {
@ -175,7 +176,7 @@ public class CommitNewCharacterMsg extends ClientNetMsg {
public int getRace() { public int getRace() {
for (int i = 0; i < 23; i++) for (int i = 0; i < 23; i++)
if (this.runes[i] > 1999 && this.runes[i] < 2030) if(Race.getRace(this.runes[i]) != null)
return this.runes[i]; return this.runes[i];
return 0; return 0;
} }

114
src/engine/objects/AbstractCharacter.java

@ -52,8 +52,8 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
public int contractUUID; public int contractUUID;
public Contract contract; public Contract contract;
protected String firstName; public String firstName;
protected String lastName; public String lastName;
protected short statStrCurrent; protected short statStrCurrent;
protected short statDexCurrent; protected short statDexCurrent;
protected short statConCurrent; protected short statConCurrent;
@ -88,7 +88,7 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
protected AtomicFloat mana = new AtomicFloat(); protected AtomicFloat mana = new AtomicFloat();
protected float manaMax; // Health/Mana/Stamina protected float manaMax; // Health/Mana/Stamina
protected AtomicBoolean isAlive = new AtomicBoolean(true); protected AtomicBoolean isAlive = new AtomicBoolean(true);
protected Resists resists = new Resists("Genric"); protected Resists resists = null;
protected ConcurrentHashMap<String, JobContainer> timers; protected ConcurrentHashMap<String, JobContainer> timers;
protected ConcurrentHashMap<String, Long> timestamps; protected ConcurrentHashMap<String, Long> timestamps;
protected int atrHandOne; protected int atrHandOne;
@ -117,16 +117,33 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
protected boolean movingUp = false; protected boolean movingUp = false;
private float desiredAltitude = 0; private float desiredAltitude = 0;
private long takeOffTime = 0; private long takeOffTime = 0;
private float hateValue = 0;
private long lastHateUpdate = 0; private long lastHateUpdate = 0;
private boolean collided = false;
private byte aoecntr = 0; private byte aoecntr = 0;
public final ConcurrentHashMap<Mob, Integer> siegeMinionMap = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
public AbstractCharacter() { public AbstractCharacter() {
super(); super();
this.firstName = "";
this.lastName = "";
this.powers = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW); this.statStrCurrent = (short) 0;
this.skills = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW); this.statDexCurrent = (short) 0;
this.statConCurrent = (short) 0;
this.statIntCurrent = (short) 0;
this.statSpiCurrent = (short) 0;
this.unusedStatPoints = (short) 0;
this.level = (short) 0; // TODO get this from MobsBase later
this.exp = 1;
this.walkMode = true;
this.bindLoc = Vector3fImmutable.ZERO;
this.faceDir = Vector3fImmutable.ZERO;
this.runningTrains = (byte) 0;
this.skills = new ConcurrentHashMap<>();
this.powers = new ConcurrentHashMap<>();
this.initializeCharacter(); this.initializeCharacter();
} }
@ -214,8 +231,6 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
this.skills = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW); this.skills = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
this.initializeCharacter(); this.initializeCharacter();
// Dangerous to use THIS in a constructor!!!
this.charItemManager = new CharacterItemManager(this);
} }
/** /**
@ -258,8 +273,6 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
this.powers = new ConcurrentHashMap<>(); this.powers = new ConcurrentHashMap<>();
this.initializeCharacter(); this.initializeCharacter();
// Dangerous to use THIS in a constructor!!!
this.charItemManager = new CharacterItemManager(this);
} }
/** /**
@ -291,8 +304,6 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
this.powers = new ConcurrentHashMap<>(); this.powers = new ConcurrentHashMap<>();
initializeCharacter(); initializeCharacter();
// Dangerous to use THIS in a constructor!!!
this.charItemManager = new CharacterItemManager(this);
} }
/** /**
@ -342,9 +353,6 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
this.powers = new ConcurrentHashMap<>(); this.powers = new ConcurrentHashMap<>();
this.initializeCharacter(); this.initializeCharacter();
// Dangerous to use THIS in a constructor!!!
this.charItemManager = new CharacterItemManager(this);
} }
public static int getBankCapacity() { public static int getBankCapacity() {
@ -670,12 +678,22 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
} }
public final Resists getResists() { public final Resists getResists() {
if (this.resists == null)
return Resists.getResists(0); if(this.getObjectType().equals(GameObjectType.Mob)){
return this.resists; return ((Mob)this).mobResists;
}else {
if (this.resists == null)
return Resists.getResists(0);
return this.resists;
}
} }
public final void setResists(final Resists value) { public final void setResists(final Resists value) {
if(this.getObjectType().equals(GameObjectType.Mob))
return;
this.resists = value; this.resists = value;
} }
@ -986,7 +1004,7 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
if (this.takeOffTime != 0) if (this.takeOffTime != 0)
return super.getLoc(); return super.getLoc();
return super.getLoc().moveTowards(this.endLoc, this.getSpeed() * ((System.currentTimeMillis() - lastSetLocUpdate) * .001f)); return super.getLoc().moveTowards(this.endLoc, this.getSpeed() * ((System.currentTimeMillis() - this.lastSetLocUpdate) * .001f));
} }
@ -1096,23 +1114,6 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
} }
public final void setCombatTarget(final AbstractWorldObject value) { public final void setCombatTarget(final AbstractWorldObject value) {
if(this.getObjectTypeMask() == 2050) {//MOB?
if (value == null) {
if (this.isCombat()) {
this.setCombat(false);
UpdateStateMsg rwss = new UpdateStateMsg();
rwss.setPlayer(this);
DispatchMessage.sendToAllInRange(this, rwss);
}
}else {
if (!this.isCombat()) {
this.setCombat(true);
UpdateStateMsg rwss = new UpdateStateMsg();
rwss.setPlayer(this);
DispatchMessage.sendToAllInRange(this, rwss);
}
}
}
this.combatTarget = value; this.combatTarget = value;
} }
@ -1187,11 +1188,9 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
} }
} }
public final float modifyHealth( public final float modifyHealth(float value,final AbstractCharacter attacker,final boolean fromCost) {
final float value, if(attacker.getObjectType().equals(GameObjectType.PlayerCharacter))
final AbstractCharacter attacker, value *= ((PlayerCharacter)attacker).ZergMultiplier;
final boolean fromCost) {
try { try {
try { try {
@ -1247,9 +1246,11 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
} }
public final float modifyMana( public final float modifyMana(
final float value, float value,
final AbstractCharacter attacker final AbstractCharacter attacker
) { ) {
if(attacker.getObjectType().equals(GameObjectType.PlayerCharacter))
value *= ((PlayerCharacter)attacker).ZergMultiplier;
return this.modifyMana(value, attacker, false); return this.modifyMana(value, attacker, false);
} }
@ -1286,9 +1287,11 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
*/ */
public final float modifyStamina( public final float modifyStamina(
final float value, float value,
final AbstractCharacter attacker final AbstractCharacter attacker
) { ) {
if(attacker.getObjectType().equals(GameObjectType.PlayerCharacter))
value *= ((PlayerCharacter)attacker).ZergMultiplier;
return this.modifyStamina(value, attacker, false); return this.modifyStamina(value, attacker, false);
} }
@ -1758,29 +1761,6 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
this.inBuildingID = inBuildingID; this.inBuildingID = inBuildingID;
} }
public float getHateValue() {
if (this.hateValue <= 0) {
this.hateValue = 0;
return hateValue;
}
if (this.lastHateUpdate == 0) {
this.lastHateUpdate = System.currentTimeMillis();
return this.hateValue;
}
long duration = System.currentTimeMillis() - this.lastHateUpdate;
//convert duration to seconds and multiply Hate Delimiter.
float modAmount = duration / 1000 * MBServerStatics.PLAYER_HATE_DELIMITER;
this.hateValue -= modAmount;
this.lastHateUpdate = System.currentTimeMillis();
return this.hateValue;
}
public void setHateValue(float hateValue) {
this.lastHateUpdate = System.currentTimeMillis();
this.hateValue = hateValue;
}
public int getInFloorID() { public int getInFloorID() {
return inFloorID; return inFloorID;
} }

33
src/engine/objects/AbstractIntelligenceAgent.java

@ -9,11 +9,13 @@
package engine.objects; package engine.objects;
import ch.claude_martin.enumbitset.EnumBitSet;
import engine.Enum; import engine.Enum;
import engine.Enum.GameObjectType; import engine.Enum.GameObjectType;
import engine.Enum.ModType; import engine.Enum.ModType;
import engine.Enum.SourceType; import engine.Enum.SourceType;
import engine.InterestManagement.WorldGrid; import engine.InterestManagement.WorldGrid;
import engine.gameManager.DbManager;
import engine.gameManager.ZoneManager; import engine.gameManager.ZoneManager;
import engine.math.Vector3fImmutable; import engine.math.Vector3fImmutable;
import engine.mobileAI.Threads.MobAIThread; import engine.mobileAI.Threads.MobAIThread;
@ -31,7 +33,20 @@ public abstract class AbstractIntelligenceAgent extends AbstractCharacter {
protected Vector3fImmutable lastBindLoc; protected Vector3fImmutable lastBindLoc;
public boolean assist = false; public boolean assist = false;
public Enum.AIAgentType agentType = Enum.AIAgentType.MOBILE; public Enum.AIAgentType agentType = Enum.AIAgentType.MOBILE;
public boolean isPlayerGuard = false;
public AbstractCharacter guardCaptain;
public EnumBitSet<Enum.MonsterType> notEnemy = EnumBitSet.noneOf(Enum.MonsterType.class);
public EnumBitSet<Enum.MonsterType> enemy = EnumBitSet.noneOf(Enum.MonsterType.class);
;
public Enum.MobBehaviourType behaviourType;
public ArrayList<Vector3fImmutable> patrolPoints;
public int lastPatrolPointIndex = 0;
public long stopPatrolTime = 0;
public City guardedCity;
public AbstractIntelligenceAgent() {
super();
}
public AbstractIntelligenceAgent(ResultSet rs) throws SQLException { public AbstractIntelligenceAgent(ResultSet rs) throws SQLException {
super(rs); super(rs);
@ -87,7 +102,8 @@ public abstract class AbstractIntelligenceAgent extends AbstractCharacter {
this.agentType = Enum.AIAgentType.CHARMED; this.agentType = Enum.AIAgentType.CHARMED;
if (this.getObjectType().equals(GameObjectType.Mob)) { if (this.getObjectType().equals(GameObjectType.Mob)) {
((Mob) this).setOwner(owner);
((Mob) this).guardCaptain = owner;
} }
} }
@ -110,14 +126,6 @@ public abstract class AbstractIntelligenceAgent extends AbstractCharacter {
return 0; return 0;
} }
public PlayerCharacter getOwner() {
if (this.getObjectType().equals(GameObjectType.Mob))
return this.getOwner();
return null;
}
public boolean getSafeZone() { public boolean getSafeZone() {
ArrayList<Zone> allIn = ZoneManager.getAllZonesIn(this.getLoc()); ArrayList<Zone> allIn = ZoneManager.getAllZonesIn(this.getLoc());
@ -146,6 +154,7 @@ public abstract class AbstractIntelligenceAgent extends AbstractCharacter {
if ((this.agentType.equals(Enum.AIAgentType.PET))) { //delete summoned pet if ((this.agentType.equals(Enum.AIAgentType.PET))) { //delete summoned pet
WorldGrid.RemoveWorldObject(this); WorldGrid.RemoveWorldObject(this);
DbManager.removeFromCache(this);
if (this.getObjectType() == GameObjectType.Mob) if (this.getObjectType() == GameObjectType.Mob)
if (((Mob) this).getParentZone() != null) if (((Mob) this).getParentZone() != null)
@ -158,7 +167,7 @@ public abstract class AbstractIntelligenceAgent extends AbstractCharacter {
//clear owner //clear owner
PlayerCharacter owner = this.getOwner(); PlayerCharacter owner = (PlayerCharacter) this.guardCaptain;
//close pet window //close pet window
@ -174,7 +183,7 @@ public abstract class AbstractIntelligenceAgent extends AbstractCharacter {
owner.setPet(null); owner.setPet(null);
if (this.getObjectType().equals(GameObjectType.Mob)) if (this.getObjectType().equals(GameObjectType.Mob))
((Mob) this).setOwner(null); ((Mob) this).guardCaptain = null;
} }

6
src/engine/objects/AbstractWorldObject.java

@ -245,7 +245,7 @@ public abstract class AbstractWorldObject extends AbstractGameObject {
} }
JobContainer jc = new JobContainer(ntj); JobContainer jc = new JobContainer(ntj);
Effect eff = new Effect(jc, eb, trains); Effect eff = new Effect(jc, eb, trains,true);
if (isStatic) if (isStatic)
eff.setIsStatic(isStatic); eff.setIsStatic(isStatic);
this.effects.put(name, eff); this.effects.put(name, eff);
@ -357,7 +357,9 @@ public abstract class AbstractWorldObject extends AbstractGameObject {
Mob mob = (Mob) this; Mob mob = (Mob) this;
if (mob.isSiege()) { if (mob.isSiege()) {
if (mob.isPet()) { if (mob.isPet()) {
PlayerCharacter petOwner = mob.getOwner();
PlayerCharacter petOwner = (PlayerCharacter) mob.guardCaptain;
if (petOwner != null && source.equals(EffectSourceType.Effect)) { if (petOwner != null && source.equals(EffectSourceType.Effect)) {
petOwner.dismissPet(); petOwner.dismissPet();
return; return;

55
src/engine/objects/Bane.java

@ -17,10 +17,7 @@ import engine.InterestManagement.HeightMap;
import engine.InterestManagement.WorldGrid; import engine.InterestManagement.WorldGrid;
import engine.db.archive.BaneRecord; import engine.db.archive.BaneRecord;
import engine.db.archive.DataWarehouse; import engine.db.archive.DataWarehouse;
import engine.gameManager.BuildingManager; import engine.gameManager.*;
import engine.gameManager.ChatManager;
import engine.gameManager.DbManager;
import engine.gameManager.ZoneManager;
import engine.job.JobScheduler; import engine.job.JobScheduler;
import engine.jobs.ActivateBaneJob; import engine.jobs.ActivateBaneJob;
import engine.jobs.BaneDefaultTimeJob; import engine.jobs.BaneDefaultTimeJob;
@ -35,6 +32,8 @@ import org.pmw.tinylog.Logger;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.time.DayOfWeek;
import java.time.LocalDateTime;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
@ -52,6 +51,8 @@ public final class Bane {
// Internal cache for banes // Internal cache for banes
private ActivateBaneJob activateBaneJob; private ActivateBaneJob activateBaneJob;
public int capSize;
/** /**
* ResultSet Constructor * ResultSet Constructor
*/ */
@ -106,10 +107,17 @@ public final class Bane {
if (this.liveDate == null) if (this.liveDate == null)
setDefaultTime(); setDefaultTime();
this.capSize = ZergManager.getBaneCap(this.getCity().getGuild());
} }
public static boolean summonBanestone(PlayerCharacter player, ClientConnection origin, int rank) { public static boolean summonBanestone(PlayerCharacter player, ClientConnection origin, int rank) {
//if(LocalDateTime.now().getDayOfWeek().equals(DayOfWeek.WEDNESDAY) == false && LocalDateTime.now().getDayOfWeek().equals(DayOfWeek.THURSDAY) == false){
// ChatManager.chatSystemError(player, "You can only place banes on Wednesdays and Thursdays.");
// return false;
//}
Guild baningGuild; Guild baningGuild;
Zone cityZone; Zone cityZone;
City targetCity; City targetCity;
@ -203,18 +211,28 @@ public final class Bane {
return false; return false;
} }
for(Guild subGuild : baningGuild.getNation().getSubGuildList()) {
if (getBaneByAttackerGuild(subGuild) != null) {
PlaceAssetMsg.sendPlaceAssetError(player.getClientConnection(), 1, "Your Nation Already Has a Bane Placed");
return false;
}
}
if(targetCity.getGuild().getNation().getSubGuildList() != null) {
for (Guild subGuild : targetCity.getGuild().getNation().getSubGuildList()) {
if (getBaneByAttackerGuild(subGuild) != null) {
PlaceAssetMsg.sendPlaceAssetError(player.getClientConnection(), 1, "This Nation Already Has a Bane Placed On It");
return false;
}
}
}
Blueprint blueprint = Blueprint.getBlueprint(24300); // Banestone Blueprint blueprint = Blueprint.getBlueprint(24300); // Banestone
//Let's drop a banestone! //Let's drop a banestone!
Vector3fImmutable localLocation = ZoneManager.worldToLocal(player.getLoc(), cityZone); Vector3fImmutable localLocation = ZoneManager.worldToLocal(player.getLoc(), cityZone);
if (localLocation == null) {
PlaceAssetMsg.sendPlaceAssetError(player.getClientConnection(), 1, "A Serious error has occurred. Please post details for to ensure transaction integrity");
Logger.info("Failed to Convert World coordinates to local zone coordinates");
return false;
}
Building stone = DbManager.BuildingQueries.CREATE_BUILDING( Building stone = DbManager.BuildingQueries.CREATE_BUILDING(
cityZone.getObjectUUID(), player.getObjectUUID(), blueprint.getName(), blueprint.getBlueprintUUID(), cityZone.getObjectUUID(), player.getObjectUUID(), blueprint.getName(), blueprint.getBlueprintUUID(),
localLocation, 1.0f, blueprint.getMaxHealth(rank), ProtectionState.PROTECTED, 0, rank, localLocation, 1.0f, blueprint.getMaxHealth(rank), ProtectionState.PROTECTED, 0, rank,
@ -225,6 +243,7 @@ public final class Bane {
return false; return false;
} }
stone.addEffectBit((1 << 19)); stone.addEffectBit((1 << 19));
stone.setMaxHitPoints(stone.getBlueprint().getMaxHealth(stone.getRank())); stone.setMaxHitPoints(stone.getBlueprint().getMaxHealth(stone.getRank()));
stone.setCurrentHitPoints(stone.getMaxHitPoints()); stone.setCurrentHitPoints(stone.getMaxHitPoints());
@ -266,6 +285,12 @@ public final class Bane {
BaneRecord baneRecord = BaneRecord.borrow(bane, Enum.RecordEventType.PENDING); BaneRecord baneRecord = BaneRecord.borrow(bane, Enum.RecordEventType.PENDING);
DataWarehouse.pushToWarehouse(baneRecord); DataWarehouse.pushToWarehouse(baneRecord);
if(bane.getCity().getTOL().getRank() == 8)
bane.capSize = 40;
else
bane.capSize = 20;
bane.getCity().setSiegesWithstood(bane.capSize);
return true; return true;
} }
@ -342,6 +367,12 @@ public final class Bane {
newBane = DbManager.BaneQueries.LOAD_BANE(city.getObjectUUID()); newBane = DbManager.BaneQueries.LOAD_BANE(city.getObjectUUID());
if(newBane.getCity().getTOL().getRank() == 8)
newBane.capSize = 40;
else
newBane.capSize = 20;
newBane.getCity().setSiegesWithstood(newBane.capSize);
return newBane; return newBane;
} }
@ -576,6 +607,10 @@ public final class Bane {
DispatchMessage.dispatchMsgToAll(msg); DispatchMessage.dispatchMsgToAll(msg);
} }
for(AbstractWorldObject awo : WorldGrid.getObjectsInRangePartial(this.getCity().loc,1500,MBServerStatics.MASK_BUILDING)){
Building building = (Building)awo;
if(building.setOwner(this.getOwner()));
}
break; break;
case DESTROY: case DESTROY:

44
src/engine/objects/Blueprint.java

@ -30,15 +30,15 @@ public class Blueprint {
public static HashMap<Integer, Blueprint> _meshLookup = new HashMap<>(); public static HashMap<Integer, Blueprint> _meshLookup = new HashMap<>();
private static HashMap<Integer, Blueprint> _blueprints = new HashMap<>(); private static HashMap<Integer, Blueprint> _blueprints = new HashMap<>();
private static HashMap<Integer, Integer> _doorNumbers = new HashMap<>(); private static HashMap<Integer, Integer> _doorNumbers = new HashMap<>();
private final int blueprintUUID; private int blueprintUUID;
private final String name; private final String name;
private final BuildingGroup buildingGroup; private final BuildingGroup buildingGroup;
private final int icon; private final int icon;
private final int maxRank; private final int maxRank;
private final int maxSlots; private final int maxSlots;
private final int rank1UUID; public int rank1UUID;
private final int rank3UUID; public int rank3UUID;
private final int rank7UUID; public int rank7UUID;
private final int destroyedUUID; private final int destroyedUUID;
private Blueprint() { private Blueprint() {
@ -167,10 +167,7 @@ public class Blueprint {
// based upon the building's current rank // based upon the building's current rank
public static int getNpcMaintCost(int rank) { public static int getNpcMaintCost(int rank) {
int maintCost = Integer.MAX_VALUE; int maintCost = 0;
maintCost = (9730 * rank) + 1890;
return maintCost; return maintCost;
} }
@ -313,10 +310,14 @@ public class Blueprint {
// Early exit for buildings with single or no slots // Early exit for buildings with single or no slots
if (this.maxSlots <= 1) if(this.buildingGroup.isTrainerBuilding() && currentRank > 0){
return 3;
}
if (this.maxSlots <= 1 && this.buildingGroup.equals(BuildingGroup.TOL) == false)
return maxSlots; return maxSlots;
if (this.maxRank == 1 && currentRank == 1) if (this.maxRank == 1 && currentRank == 1&& this.buildingGroup.equals(BuildingGroup.TOL) == false)
return getMaxSlots(); return getMaxSlots();
switch (currentRank) { switch (currentRank) {
@ -328,20 +329,22 @@ public class Blueprint {
case 3: case 3:
case 4: case 4:
case 5: case 5:
case 6:
availableSlots = 2; availableSlots = 2;
break; break;
case 6:
case 7: case 7:
availableSlots = 3; availableSlots = 3;
break; break;
case 8: case 8:
availableSlots = 1; availableSlots = 3;
break; break;
default: default:
availableSlots = 0; availableSlots = 0;
break; break;
} }
if(this.buildingGroup.equals(BuildingGroup.TOL)){
availableSlots += 1;
}
return availableSlots; return availableSlots;
} }
@ -584,7 +587,9 @@ public class Blueprint {
public int getBlueprintUUID() { public int getBlueprintUUID() {
return blueprintUUID; return blueprintUUID;
} }
public void setBlueprintUUID(int id) {
this.blueprintUUID = id;
}
@Override @Override
public boolean equals(Object object) { public boolean equals(Object object) {
@ -609,17 +614,10 @@ public class Blueprint {
switch (this.buildingGroup) { switch (this.buildingGroup) {
case TOL: case TOL:
case BARRACK: maintCost = 3000000;
maintCost = (61500 * rank) + 19500;
break;
case SPIRE:
maintCost = (4800 * rank) + 1200;
break; break;
default: default:
if (maxRank == 1) maintCost = 0;
maintCost = 22500;
else
maintCost = (15900 * rank) + 3300;
break; break;
} }

22
src/engine/objects/Building.java

@ -12,6 +12,7 @@ package engine.objects;
import engine.Enum; import engine.Enum;
import engine.Enum.*; import engine.Enum.*;
import engine.InterestManagement.HeightMap; import engine.InterestManagement.HeightMap;
import engine.InterestManagement.InterestManager;
import engine.InterestManagement.RealmMap; import engine.InterestManagement.RealmMap;
import engine.InterestManagement.WorldGrid; import engine.InterestManagement.WorldGrid;
import engine.db.archive.CityRecord; import engine.db.archive.CityRecord;
@ -394,7 +395,7 @@ public class Building extends AbstractWorldObject {
this.rank = newRank; this.rank = newRank;
// New rank means new mesh // New rank means new mesh
int oldMeshID = this.meshUUID;
newMeshUUID = this.getBlueprint().getMeshForRank(this.rank); newMeshUUID = this.getBlueprint().getMeshForRank(this.rank);
this.meshUUID = newMeshUUID; this.meshUUID = newMeshUUID;
@ -428,6 +429,15 @@ public class Building extends AbstractWorldObject {
BuildingManager.cleanupHirelings(this); BuildingManager.cleanupHirelings(this);
this.isDeranking.compareAndSet(true, false); this.isDeranking.compareAndSet(true, false);
if(oldMeshID != this.meshUUID) {
//move NPCs to new slot locations if the mesh was changed and force reload them
int index = 0;
for (AbstractCharacter hireling : this.hirelings.keySet()) {
hireling.setLoc(BuildingManager._slotLocations.get(newMeshUUID).get(index).getLocation());
InterestManager.reloadCharacter(hireling,false);
}
}
} }
public final int getOwnerUUID() { public final int getOwnerUUID() {
@ -1000,7 +1010,10 @@ public class Building extends AbstractWorldObject {
public final boolean setStrongboxValue(int newValue) { public final boolean setStrongboxValue(int newValue) {
boolean success = true; boolean success = true;
if(this.isOwnerIsNPC()) {
newValue = 0;
this.setStrongboxValue(0);
}
try { try {
DbManager.BuildingQueries.SET_PROPERTY(this, "currentGold", newValue); DbManager.BuildingQueries.SET_PROPERTY(this, "currentGold", newValue);
this._strongboxValue = newValue; this._strongboxValue = newValue;
@ -1035,13 +1048,14 @@ public class Building extends AbstractWorldObject {
// *** Refactor: Can't we just use setRank() for this? // *** Refactor: Can't we just use setRank() for this?
public final void rebuildMine() { public final void rebuildMine(int maxHP) {
this.setRank(1); this.setRank(1);
this.meshUUID = this.getBlueprint().getMeshForRank(this.rank); this.meshUUID = this.getBlueprint().getMeshForRank(this.rank);
// New rank mean new max hitpoints. // New rank mean new max hitpoints.
this.healthMax = this.getBlueprint().getMaxHealth(this.rank); //this.healthMax = this.getBlueprint().getMaxHealth(this.rank);
this.healthMax = maxHP;
this.setCurrentHitPoints(this.healthMax); this.setCurrentHitPoints(this.healthMax);
this.getBounds().setBounds(this); this.getBounds().setBounds(this);
} }

79
src/engine/objects/CharacterItemManager.java

@ -12,16 +12,14 @@ package engine.objects;
import engine.Enum; import engine.Enum;
import engine.Enum.GameObjectType; import engine.Enum.GameObjectType;
import engine.Enum.ItemType; import engine.Enum.ItemType;
import engine.gameManager.BuildingManager; import engine.gameManager.*;
import engine.gameManager.ChatManager;
import engine.gameManager.ConfigManager;
import engine.gameManager.DbManager;
import engine.math.Vector3fImmutable; import engine.math.Vector3fImmutable;
import engine.net.Dispatch; import engine.net.Dispatch;
import engine.net.DispatchMessage; import engine.net.DispatchMessage;
import engine.net.client.ClientConnection; import engine.net.client.ClientConnection;
import engine.net.client.ClientMessagePump; import engine.net.client.ClientMessagePump;
import engine.net.client.msg.*; import engine.net.client.msg.*;
import engine.powers.poweractions.AbstractPowerAction;
import engine.server.MBServerStatics; import engine.server.MBServerStatics;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
@ -72,6 +70,8 @@ public class CharacterItemManager {
*/ */
private byte equipVer = (byte) 0; private byte equipVer = (byte) 0;
public boolean updateLock = false;
public CharacterItemManager(AbstractCharacter ac) { public CharacterItemManager(AbstractCharacter ac) {
super(); super();
this.absCharacter = ac; this.absCharacter = ac;
@ -641,6 +641,7 @@ public class CharacterItemManager {
dispatch = Dispatch.borrow(other, utwm); dispatch = Dispatch.borrow(other, utwm);
DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.PRIMARY); DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.PRIMARY);
stripTempEnchants(i);
return true; return true;
} }
@ -1056,7 +1057,7 @@ public class CharacterItemManager {
i.addToCache(); i.addToCache();
calculateWeights(); calculateWeights();
stripTempEnchants(i);
return true; return true;
} }
@ -1201,10 +1202,19 @@ public class CharacterItemManager {
i.addToCache(); i.addToCache();
calculateWeights(); calculateWeights();
stripTempEnchants(i);
return true; return true;
} }
private static void stripTempEnchants(Item i) {
//i.clearEffects();
for (String name : i.getEffects().keySet()) {
Effect eff = i.getEffects().get(name);
if (!eff.isStatic())
i.endEffect(name);
}
}
//Used for buying MobEquipment from NPC //Used for buying MobEquipment from NPC
//Handles the gold transfer aspect //Handles the gold transfer aspect
@ -1233,7 +1243,7 @@ public class CharacterItemManager {
// This adds item to inventory for loot. Validity checks already handled // This adds item to inventory for loot. Validity checks already handled
public synchronized boolean addItemToInventory(Item i) { public synchronized boolean addItemToInventory(Item i) {
if (i.getItemBase().getType().equals(ItemType.GOLD)) if (i.getItemBase().getType().equals(ItemType.GOLD)) {
if (this.absCharacter.getObjectType() == GameObjectType.Mob) { if (this.absCharacter.getObjectType() == GameObjectType.Mob) {
if (this.goldInventory == null) if (this.goldInventory == null)
loadGoldItems(); loadGoldItems();
@ -1244,19 +1254,39 @@ public class CharacterItemManager {
updateInventory(); updateInventory();
return true; return true;
} }
return false; return false;
} }
} //else if (i.getItemBase().getType().equals(ItemType.RESOURCE)) {
// if(this.inventoryContainsResource(i)){
// Item resource = getResource(i);
// if(resource != null){
// resource.setNumOfItems(resource.getNumOfItems() + i.getNumOfItems());
// return true;
// }
//}
// }
this.inventory.add(i); this.inventory.add(i);
this.itemIDtoType.put(i.getObjectUUID(), i.getObjectType().ordinal()); this.itemIDtoType.put(i.getObjectUUID(), i.getObjectType().ordinal());
ItemBase ib = i.getItemBase();
if (ib != null)
this.inventoryWeight += ib.getWeight();
return true; return true;
} }
private boolean inventoryContainsResource(Item resource) {
for(Item i : this.inventory){
if(i.getItemBaseID() == resource.getItemBaseID())
return true;
}
return false;
}
private Item getResource(Item resource) {
for(Item i : this.inventory){
if(i.getItemBaseID() == resource.getItemBaseID())
return i;
}
return null;
}
//called for adding gold of a specified amount //called for adding gold of a specified amount
public synchronized boolean addItemToInventory(Item i, int amount) { public synchronized boolean addItemToInventory(Item i, int amount) {
if (i.getItemBase().getType().equals(ItemType.GOLD)) if (i.getItemBase().getType().equals(ItemType.GOLD))
@ -1330,8 +1360,10 @@ public class CharacterItemManager {
Item gold = this.getGoldInventory(); Item gold = this.getGoldInventory();
if (cost <= 0 || (gold.getNumOfItems() - cost) < 0) if (cost <= 0 || (gold.getNumOfItems() - cost) < 0){
ChatManager.chatSystemError((PlayerCharacter)this.getOwner(),"Not Enough Gold: " + "COST: " + cost);
return false; return false;
}
if (this.getOwner() != null && this.getOwner().getObjectType().equals(GameObjectType.PlayerCharacter)) { if (this.getOwner() != null && this.getOwner().getObjectType().equals(GameObjectType.PlayerCharacter)) {
@ -1345,7 +1377,6 @@ public class CharacterItemManager {
// if the NPC is not slotted. // if the NPC is not slotted.
if (vendorBuilding == null) { if (vendorBuilding == null) {
return this.modifyInventoryGold(-cost); return this.modifyInventoryGold(-cost);
} }
@ -1357,31 +1388,31 @@ public class CharacterItemManager {
if (pc.getClientConnection() != null) if (pc.getClientConnection() != null)
ErrorPopupMsg.sendErrorPopup(pc, 206); ErrorPopupMsg.sendErrorPopup(pc, 206);
} }
return false; return false;
} }
// Update strongbox and inventory gold // Update strongbox and inventory gold
if (!this.modifyInventoryGold(-cost)) if (!this.modifyInventoryGold(-cost)) {
return false; return false;
}
City buildingCity = vendorBuilding.getCity(); City buildingCity = vendorBuilding.getCity();
if (buildingCity != null) { if (buildingCity != null) {
buildingCity.transactionLock.writeLock().lock(); buildingCity.transactionLock.writeLock().lock();
try { try {
if (!vendorBuilding.transferGold(buildingDeposit, true)) if (!vendorBuilding.isOwnerIsNPC() && !vendorBuilding.transferGold(buildingDeposit, true)) {
return false; return false;
}
} catch (Exception e) { } catch (Exception e) {
Logger.error(e); Logger.error(e);
return false; return false;
} finally { } finally {
buildingCity.transactionLock.writeLock().unlock(); buildingCity.transactionLock.writeLock().unlock();
} }
} else if (!vendorBuilding.transferGold(buildingDeposit, true)) } else if (!vendorBuilding.isOwnerIsNPC() && !vendorBuilding.transferGold(buildingDeposit, true)) {
return false; return false;
}
return true; return true;
} }
@ -2257,6 +2288,8 @@ public class CharacterItemManager {
if (this.absCharacter.getObjectType().equals(GameObjectType.PlayerCharacter) == false) if (this.absCharacter.getObjectType().equals(GameObjectType.PlayerCharacter) == false)
return; return;
if(this.updateLock)
return;
PlayerCharacter pc = (PlayerCharacter) this.absCharacter; PlayerCharacter pc = (PlayerCharacter) this.absCharacter;
UpdateInventoryMsg updateInventoryMsg = new UpdateInventoryMsg(inventory, this.getBank(), this.getGoldInventory(), add); UpdateInventoryMsg updateInventoryMsg = new UpdateInventoryMsg(inventory, this.getBank(), this.getGoldInventory(), add);
@ -2426,7 +2459,7 @@ public class CharacterItemManager {
i.setOwnerID(0); i.setOwnerID(0);
calculateWeights(); calculateWeights();
stripTempEnchants(i);
return true; return true;
} }
@ -2435,6 +2468,10 @@ public class CharacterItemManager {
if (item == null || amount < 1 || amount > 5) if (item == null || amount < 1 || amount > 5)
return; return;
if(ZoneManager.findSmallestZone(this.getOwner().loc).getSafeZone() == 1){
return;
}
//verify the item is equipped by this player //verify the item is equipped by this player
int slot = item.getEquipSlot(); int slot = item.getEquipSlot();
if (!this.equipped.containsKey(slot)) if (!this.equipped.containsKey(slot))

14
src/engine/objects/CharacterSkill.java

@ -489,7 +489,6 @@ public class CharacterSkill extends AbstractGameObject {
return; return;
ConcurrentHashMap<String, CharacterSkill> skills = pc.getSkills(); ConcurrentHashMap<String, CharacterSkill> skills = pc.getSkills();
//First add skills that don't exist //First add skills that don't exist
Race race = pc.getRace(); Race race = pc.getRace();
if (race != null) { if (race != null) {
@ -538,6 +537,10 @@ public class CharacterSkill extends AbstractGameObject {
continue; continue;
} }
} }
if (pc.getRace().getName().equals("Saetor")) {
if (cs.getSkillsBase().getName().equals("Parry") || cs.getSkillsBase().getName().equals("Staff") || cs.getSkillsBase().getName().equals("Staff Mastery"))
valid = true;
}
//if skill doesn't belong to any runes, then remove it //if skill doesn't belong to any runes, then remove it
if (!valid) { if (!valid) {
DbManager.CharacterSkillQueries.DELETE_SKILL(cs.getObjectUUID()); DbManager.CharacterSkillQueries.DELETE_SKILL(cs.getObjectUUID());
@ -557,6 +560,15 @@ public class CharacterSkill extends AbstractGameObject {
if (skills == null) if (skills == null)
return; return;
//if (pc.getRace().getName().equals("Saetor")) {
// SkillReq parry = new SkillReq(95961104, (short) 1);
// SkillReq staff = new SkillReq(71438003, (short) 15);
// SkillReq staffMastery = new SkillReq(-61022283, (short) 1);
// skillsGranted.add(parry);
// skillsGranted.add(staff);
// skillsGranted.add(staffMastery);
//}
for (SkillReq skillreq : skillsGranted) { for (SkillReq skillreq : skillsGranted) {
SkillsBase skillsBase = skillreq.getSkillsBase(); SkillsBase skillsBase = skillreq.getSkillsBase();

5
src/engine/objects/CharacterTitle.java

@ -21,7 +21,8 @@ public enum CharacterTitle {
CSR_3(255, 0, 0, "CCR"), CSR_3(255, 0, 0, "CCR"),
CSR_4(251, 181, 13, "CCR"), CSR_4(251, 181, 13, "CCR"),
DEVELOPER(166, 153, 114, "Programmer"), DEVELOPER(166, 153, 114, "Programmer"),
QA(88, 250, 244, "GIRLFRIEND"); QA(88, 250, 244, "GIRLFRIEND"),
BOX(255, 0, 0, "");
int headerLength, footerLength; int headerLength, footerLength;
private ByteBuffer header; private ByteBuffer header;
@ -32,7 +33,7 @@ public enum CharacterTitle {
(((_r < 100) ? ((_r < 10) ? "00" : "0") : "") + ((byte) _r & 0xFF)) + (((_r < 100) ? ((_r < 10) ? "00" : "0") : "") + ((byte) _r & 0xFF)) +
(((_g < 100) ? ((_g < 10) ? "00" : "0") : "") + ((byte) _g & 0xFF)) + (((_g < 100) ? ((_g < 10) ? "00" : "0") : "") + ((byte) _g & 0xFF)) +
(((_b < 100) ? ((_b < 10) ? "00" : "0") : "") + ((byte) _b & 0xFF)) + (((_b < 100) ? ((_b < 10) ? "00" : "0") : "") + ((byte) _b & 0xFF)) +
'<' + _prefix + "> ").toCharArray(); _prefix).toCharArray();
char[] str_footer = ("^\\c255255255").toCharArray(); char[] str_footer = ("^\\c255255255").toCharArray();

277
src/engine/objects/City.java

@ -32,6 +32,7 @@ import engine.server.MBServerStatics;
import engine.server.world.WorldServer; import engine.server.world.WorldServer;
import engine.workthreads.DestroyCityThread; import engine.workthreads.DestroyCityThread;
import engine.workthreads.TransferCityThread; import engine.workthreads.TransferCityThread;
import org.joda.time.DateTime;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
import java.sql.ResultSet; import java.sql.ResultSet;
@ -39,6 +40,7 @@ import java.sql.SQLException;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.ZoneId; import java.time.ZoneId;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
@ -88,6 +90,9 @@ public class City extends AbstractWorldObject {
private boolean reverseKOS = false; private boolean reverseKOS = false;
private String hash; private String hash;
public final HashMap<Integer,Long> _recentMemory = new HashMap<>();
HashMap<Guild,ArrayList<Integer>> dividedPlayers;
public Integer totalPlayers;
/** /**
* ResultSet Constructor * ResultSet Constructor
*/ */
@ -194,137 +199,132 @@ public class City extends AbstractWorldObject {
} }
public static void serializeForClientMsg(City city, ByteBufferWriter writer) { public static void serializeForClientMsg(City city, ByteBufferWriter writer) {
AbstractCharacter guildRuler; AbstractCharacter guildRuler;
Guild rulingGuild; Guild rulingGuild;
Guild rulingNation; Guild rulingNation;
java.time.LocalDateTime dateTime1900; java.time.LocalDateTime dateTime1900;
// Cities aren't a city without a TOL. Time to early exit. // Cities aren't a city without a TOL. Time to early exit.
// No need to spam the log here as non-existant TOL's are indicated // No need to spam the log here as non-existant TOL's are indicated
// during bootstrap routines. // during bootstrap routines.
if (city.getTOL() == null) { if (city.getTOL() == null) {
Logger.error("NULL TOL FOR " + city.cityName); Logger.error("NULL TOL FOR " + city.cityName);
} }
// Assign city owner // Assign city owner
if (city.getTOL() != null) if (city.getTOL() != null)
guildRuler = city.getTOL().getOwner(); guildRuler = city.getTOL().getOwner();
else else
guildRuler = null; guildRuler = null;
// If is an errant tree, use errant guild for serialization.
// otherwise we serialize the soverign guild
if (guildRuler == null) // If is an errant tree, use errant guild for serialization.
rulingGuild = Guild.getErrantGuild(); // otherwise we serialize the soverign guild
else
rulingGuild = guildRuler.getGuild();
rulingNation = rulingGuild.getNation(); if (guildRuler == null)
rulingGuild = Guild.getErrantGuild();
else
rulingGuild = guildRuler.getGuild();
// Begin Serialzing soverign guild data rulingNation = rulingGuild.getNation();
writer.putInt(city.getObjectType().ordinal());
writer.putInt(city.getObjectUUID());
writer.putString(city.cityName);
writer.putInt(rulingGuild.getObjectType().ordinal());
writer.putInt(rulingGuild.getObjectUUID());
writer.putString(rulingGuild.getName()); // Begin Serialzing soverign guild data
writer.putString(city.motto); writer.putInt(city.getObjectType().ordinal());
writer.putString(rulingGuild.getLeadershipType()); writer.putInt(city.getObjectUUID());
writer.putString(city.cityName);
writer.putInt(rulingGuild.getObjectType().ordinal());
writer.putInt(rulingGuild.getObjectUUID());
// Serialize guild ruler's name writer.putString(rulingGuild.getName());
// If tree is abandoned blank out the name writer.putString(city.motto);
// to allow them a rename. writer.putString(rulingGuild.getLeadershipType());
if (guildRuler == null) // Serialize guild ruler's name
writer.putString(""); // If tree is abandoned blank out the name
else // to allow them a rename.
writer.putString(guildRuler.getFirstName() + ' ' + guildRuler.getLastName());
writer.putInt(rulingGuild.getCharter()); if (guildRuler == null)
writer.putInt(0); // always 00000000 writer.putString("");
else
writer.putString(guildRuler.getFirstName() + ' ' + guildRuler.getLastName());
writer.put(city.isSafeHold); writer.putInt(rulingGuild.getCharter());
writer.putInt(0); // always 00000000
writer.put((byte) 1); writer.put(city.isSafeHold);
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); writer.put((byte) 1);
GuildTag._serializeForDisplay(rulingNation.getGuildTag(), writer); writer.put((byte) 1); // *** Refactor: What are these flags?
writer.put((byte) 1);
writer.put((byte) 1);
writer.put((byte) 1);
writer.putInt(0);// TODO Implement description text GuildTag._serializeForDisplay(rulingGuild.getGuildTag(), writer);
GuildTag._serializeForDisplay(rulingNation.getGuildTag(), writer);
writer.put((byte) 1); writer.putInt(0);// TODO Implement description text
if (city.isCapital > 0)
writer.put((byte) 1); writer.put((byte) 1);
else
writer.put((byte) 0);
writer.put((byte) 1);
// Begin serializing nation guild info if (city.isCapital > 0)
writer.put((byte) 1);
if (rulingNation.isEmptyGuild()) { else
writer.putInt(rulingGuild.getObjectType().ordinal()); writer.put((byte) 0);
writer.putInt(rulingGuild.getObjectUUID());
} else {
writer.putInt(rulingNation.getObjectType().ordinal());
writer.putInt(rulingNation.getObjectUUID());
}
writer.put((byte) 1);
// Serialize nation name // Begin serializing nation guild info
if (rulingNation.isEmptyGuild()) if (rulingNation.isEmptyGuild()) {
writer.putString("None"); writer.putInt(rulingGuild.getObjectType().ordinal());
else writer.putInt(rulingGuild.getObjectUUID());
writer.putString(rulingNation.getName()); } else {
writer.putInt(rulingNation.getObjectType().ordinal());
writer.putInt(rulingNation.getObjectUUID());
}
writer.putInt(city.getTOL().getRank());
if (city.isNoobIsle > 0) // Serialize nation name
writer.putInt(1);
else
writer.putInt(0xFFFFFFFF);
writer.putInt(city.population); if (rulingNation.isEmptyGuild())
writer.putString("None");
else
writer.putString(rulingNation.getName());
if (rulingNation.isEmptyGuild()) if(city.getTOL() != null) {
writer.putString(" "); writer.putInt(city.getTOL().getRank());
else }else{
writer.putString(Guild.GetGL(rulingNation).getFirstName() + ' ' + Guild.GetGL(rulingNation).getLastName()); writer.putInt(-1);
}
if (city.isNoobIsle > 0)
writer.putInt(1);
else
writer.putInt(0xFFFFFFFF);
writer.putLocalDateTime(city.established); writer.putInt(city.population);
// writer.put((byte) city.established.getDayOfMonth()); if (rulingNation.isEmptyGuild())
// writer.put((byte) city.established.minusMonths(1).getMonth().getValue()); writer.putString(" ");
// writer.putInt((int) years); else
// writer.put((byte) hours); writer.putString(Guild.GetGL(rulingNation).getFirstName() + ' ' + Guild.GetGL(rulingNation).getLastName());
// writer.put((byte) minutes);
// writer.put((byte) seconds);
writer.putFloat(city.location.x);
writer.putFloat(city.location.y);
writer.putFloat(city.location.z);
writer.putInt(city.siegesWithstood); writer.putLocalDateTime(city.established);
writer.put((byte) 1); writer.putFloat(city.location.x);
writer.put((byte) 0); writer.putFloat(city.location.y);
writer.putInt(0x64); writer.putFloat(city.location.z);
writer.put((byte) 0); writer.putInt(ZergManager.getBaneCap(city.getGuild()));
writer.put((byte) 0); writer.put((byte) 1);
writer.put((byte) 0); writer.put((byte) 0);
writer.putInt(0x64);
writer.put((byte) 0);
writer.put((byte) 0);
writer.put((byte) 0);
} }
public static Vector3fImmutable getBindLoc(int cityID) { public static Vector3fImmutable getBindLoc(int cityID) {
@ -980,23 +980,12 @@ public class City extends AbstractWorldObject {
public void onEnter() { public void onEnter() {
HashSet<AbstractWorldObject> currentPlayers; for (Integer id : this._playerMemory) {
HashSet<Integer> currentMemory;
PlayerCharacter player;
// Gather current list of players within the zone bounds
currentPlayers = WorldGrid.getObjectsInRangePartial(this.location, CityBoundsType.ZONE.extents, MBServerStatics.MASK_PLAYER);
currentMemory = new HashSet<>();
for (AbstractWorldObject playerObject : currentPlayers) {
if (playerObject == null) PlayerCharacter player = PlayerCharacter.getFromCache(id);
if (player == null)
continue; continue;
player = (PlayerCharacter) playerObject;
currentMemory.add(player.getObjectUUID());
// Player is already in our memory // Player is already in our memory
if (_playerMemory.contains(player.getObjectUUID())) if (_playerMemory.contains(player.getObjectUUID()))
@ -1012,62 +1001,6 @@ public class City extends AbstractWorldObject {
//add spire effects. //add spire effects.
if (this.getEffects().size() > 0) if (this.getEffects().size() > 0)
this.applyAllCityEffects(player); this.applyAllCityEffects(player);
// Add player to our city's memory
_playerMemory.add(player.getObjectUUID());
// ***For debugging
// Logger.info("PlayerMemory for ", this.getCityName() + ": " + _playerMemory.size());
}
try {
onExit(currentMemory);
} catch (Exception e) {
Logger.error(e.getMessage());
}
}
private void onExit(HashSet<Integer> currentMemory) {
PlayerCharacter player;
int playerUUID = 0;
HashSet<Integer> toRemove = new HashSet<>();
Iterator<Integer> iter = _playerMemory.iterator();
while (iter.hasNext()) {
playerUUID = iter.next();
player = PlayerCharacter.getFromCache(playerUUID);
if (this.isLocationWithinSiegeBounds(player.getLoc()))
continue;
// Remove players safezone status if warranted
// they can assumed to be not on the citygrid at
// this point.
player.setSafeZone(false);
this.removeAllCityEffects(player, false);
// We will remove this player after iteration is complete
// so store it in a temporary collection
toRemove.add(playerUUID);
// ***For debugging
// Logger.info("PlayerMemory for ", this.getCityName() + ": " + _playerMemory.size());
}
// Remove players from city memory
_playerMemory.removeAll(toRemove);
for (Integer removalUUID : toRemove) {
if (this.cityOutlaws.contains(removalUUID))
this.cityOutlaws.remove(removalUUID);
} }
} }
@ -1086,7 +1019,15 @@ public class City extends AbstractWorldObject {
destroyCityThread.setName("deestroyCity:" + this.getName()); destroyCityThread.setName("deestroyCity:" + this.getName());
destroyCityThread.start(); destroyCityThread.start();
} }
public static void destroyAllCityAssets(City city){
if(city == null)
Logger.error("Maintenance Failed To Find City To Destroy");
for(Building building : city.getParent().zoneBuildingSet){
building.setRank(-1);
DbManager.removeFromCache(building);
}
city.getParent().zoneBuildingSet.clear();
}
public final void transfer(AbstractCharacter newOwner) { public final void transfer(AbstractCharacter newOwner) {
Thread transferCityThread = new Thread(new TransferCityThread(this, newOwner)); Thread transferCityThread = new Thread(new TransferCityThread(this, newOwner));

11
src/engine/objects/Contract.java

@ -30,7 +30,7 @@ public class Contract extends AbstractGameObject {
public int inventorySet = 0; public int inventorySet = 0;
private int vendorID; private int vendorID;
private boolean isTrainer; private boolean isTrainer;
private VendorDialog vendorDialog; public VendorDialog vendorDialog;
private ArrayList<Integer> npcMenuOptions = new ArrayList<>(); private ArrayList<Integer> npcMenuOptions = new ArrayList<>();
private ArrayList<Integer> npcModTypeTable = new ArrayList<>(); private ArrayList<Integer> npcModTypeTable = new ArrayList<>();
private ArrayList<Integer> npcModSuffixTable = new ArrayList<>(); private ArrayList<Integer> npcModSuffixTable = new ArrayList<>();
@ -198,6 +198,15 @@ public class Contract extends AbstractGameObject {
} }
public ArrayList<MobEquipment> getSellInventory() { public ArrayList<MobEquipment> getSellInventory() {
if(this.getObjectUUID() == 900){
for (MobEquipment me : this.sellInventory) {
if(me.getItemBase().getUUID() == 1705032) {
me.magicValue = 1000000; //elan stones
}else{
me.magicValue = (Warehouse.getSellStackSize(me.getItemBase().getUUID()) * Warehouse.getCostForResource(me.getItemBase().getUUID()));
}
}
}
return this.sellInventory; return this.sellInventory;
} }

3
src/engine/objects/Corpse.java

@ -63,7 +63,8 @@ public class Corpse extends AbstractWorldObject {
this.inBuilding = belongsTo.getInBuilding(); this.inBuilding = belongsTo.getInBuilding();
this.inFloorID = belongsTo.getInFloorID(); this.inFloorID = belongsTo.getInFloorID();
this.inBuildingID = belongsTo.getInBuildingID(); this.inBuildingID = belongsTo.getInBuildingID();
this.setLoc(belongsTo.getLoc()); belongsTo.stopMovement(belongsTo.getMovementLoc());
this.setLoc(belongsTo.getMovementLoc());
} else { } else {
Logger.error("No player passed in for corpse"); Logger.error("No player passed in for corpse");
this.firstName = ""; this.firstName = "";

51
src/engine/objects/Experience.java

@ -9,7 +9,9 @@
package engine.objects; package engine.objects;
import engine.Enum;
import engine.Enum.TargetColor; import engine.Enum.TargetColor;
import engine.gameManager.LootManager;
import engine.gameManager.ZoneManager; import engine.gameManager.ZoneManager;
import engine.math.Vector3fImmutable; import engine.math.Vector3fImmutable;
import engine.server.MBServerStatics; import engine.server.MBServerStatics;
@ -117,6 +119,11 @@ public class Experience {
159932666, // Level 74 159932666, // Level 74
169707808, // Level 75 169707808, // Level 75
179921247, // Level 76 179921247, // Level 76
190548651, // Level 77
201590020, // Level 78
213045354, // Level 79
224914653, // Level 80
237197917 // Level 81
}; };
@ -214,9 +221,21 @@ public class Experience {
235166.21f, // Level 72 235166.21f, // Level 72
246039.34f, // Level 73 246039.34f, // Level 73
257240.58f, // Level 74 257240.58f, // Level 74
1 // 268774.71 //Level 75 268765.03f, // Level 75
280612.69f, // Level 76
292783.56f, // Level 77
305277.64f, // Level 78
318094.93f, // Level 79
1, // Level 80
};
};
// Used to calcuate the amount of experience a monster grants in the // Used to calcuate the amount of experience a monster grants in the
// following formula // following formula
// expGranted = a(moblevel)^2 + b(moblevel) + c // expGranted = a(moblevel)^2 + b(moblevel) + c
@ -268,8 +287,8 @@ public class Experience {
if (level < 1) if (level < 1)
level = 1; level = 1;
if (level > 75) if (level > MBServerStatics.LEVELCAP)
level = 75; level = MBServerStatics.LEVELCAP;
return MaxExpPerLevel[level]; return MaxExpPerLevel[level];
} }
@ -354,8 +373,8 @@ public class Experience {
if (leaderskill != null) if (leaderskill != null)
leadership = leaderskill.getNumTrains(); leadership = leaderskill.getNumTrains();
if (leadership > 90) //if (leadership > 90)
leadership = 90; // leadership caps at 90% // leadership = 90; // leadership caps at 90%
} }
// Check every group member for distance to see if they get xp // Check every group member for distance to see if they get xp
@ -393,6 +412,8 @@ public class Experience {
// Process XP for this member // Process XP for this member
grantedExperience *= (1/giveEXPTo.size()+0.9);
penalty = getGroupMemberPenalty(leadership, playerCharacter, giveEXPTo, penalty = getGroupMemberPenalty(leadership, playerCharacter, giveEXPTo,
highestLevel); highestLevel);
@ -423,8 +444,14 @@ public class Experience {
if (grantedExperience == 0) if (grantedExperience == 0)
grantedExperience = 1; grantedExperience = 1;
grantedExperience *= LootManager.NORMAL_EXP_RATE;
// Grant the player the EXP // Grant the player the EXP
playerCharacter.grantXP((int) Math.floor(grantedExperience)); if(mob.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) {
if (((PlayerCharacter) mob).pvpDeaths.contains(killer.getObjectUUID()) == false)
playerCharacter.grantXP((int) Math.floor(grantedExperience), true);
}else {
playerCharacter.grantXP((int) Math.floor(grantedExperience), false);
}
} }
} else { // Give EXP to a single character } else { // Give EXP to a single character
@ -435,7 +462,8 @@ public class Experience {
return; return;
// Get XP and adjust for Mob Level with world xp modifier taken into account // Get XP and adjust for Mob Level with world xp modifier taken into account
grantedExperience = (double) LOOTMANAGER.NORMAL_EXP_RATE * maxXPPerKill(killer.getLevel()); float mdofier = LOOTMANAGER.NORMAL_EXP_RATE;
grantedExperience = maxXPPerKill(killer.getLevel());
grantedExperience *= getConMod(killer, mob); grantedExperience *= getConMod(killer, mob);
// Modify for hotzone // Modify for hotzone
@ -448,7 +476,12 @@ public class Experience {
grantedExperience *= .6; grantedExperience *= .6;
// Grant XP // Grant XP
killer.grantXP((int) Math.floor(grantedExperience)); if(mob.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) {
if (((PlayerCharacter) mob).pvpDeaths.contains(killer.getObjectUUID()) == false)
killer.grantXP((int) Math.floor(grantedExperience), true);
}else {
killer.grantXP((int) Math.floor(grantedExperience), false);
}
} }
} }
} }

22
src/engine/objects/Guild.java

@ -667,6 +667,9 @@ public class Guild extends AbstractWorldObject {
pc.incVer(); pc.incVer();
DispatchMessage.sendToAllInRange(pc, new GuildInfoMsg(pc, Guild.getErrantGuild(), 2)); DispatchMessage.sendToAllInRange(pc, new GuildInfoMsg(pc, Guild.getErrantGuild(), 2));
if(GroupManager.getGroup(pc) != null)
GroupManager.getGroup(pc).removeGroupMember(pc);
} }
public void upgradeGuildState(boolean nation) { public void upgradeGuildState(boolean nation) {
@ -730,32 +733,29 @@ public class Guild extends AbstractWorldObject {
public boolean canSubAGuild(Guild toSub) { public boolean canSubAGuild(Guild toSub) {
boolean canSub; boolean canSubToNation;
boolean canAcceptSub;
if (this.equals(toSub)) if (this.equals(toSub))
return false; return false;
switch (this.guildState) { switch (this.guildState) {
case Nation: case Nation:
case Sovereign: case Sovereign:
canSub = true; canAcceptSub = true;
break; break;
default: default:
canSub = false; canAcceptSub = false;
} }
switch (toSub.guildState) { switch (toSub.guildState) {
case Errant: case Errant:
case Sovereign: case Sovereign:
canSub = true; canSubToNation = true;
break; break;
default: default:
canSub = false; canSubToNation = false;
} }
City nationCap = City.getCity(nation.cityUUID);
if (nation.getSubGuildList().size() >= nationCap.getRank()) { return canAcceptSub && canSubToNation;
canSub = false;
}
return canSub;
} }
public int getRealmsOwnedFlag() { public int getRealmsOwnedFlag() {

24
src/engine/objects/Item.java

@ -51,7 +51,7 @@ public class Item extends AbstractWorldObject {
private short durabilityCurrent; private short durabilityCurrent;
private byte chargesRemaining; private byte chargesRemaining;
private byte equipSlot; private byte equipSlot;
private boolean canDestroy; public boolean canDestroy;
private boolean rentable; private boolean rentable;
private boolean isRandom = false; private boolean isRandom = false;
private int value; private int value;
@ -61,7 +61,7 @@ public class Item extends AbstractWorldObject {
private ArrayList<EnchantmentBase> enchants = new ArrayList<>(); private ArrayList<EnchantmentBase> enchants = new ArrayList<>();
private long dateToUpgrade; private long dateToUpgrade;
private String customName = ""; private String customName = "";
private int magicValue; public int magicValue;
/** /**
* No Id Constructor * No Id Constructor
@ -233,7 +233,6 @@ public class Item extends AbstractWorldObject {
this.value = rs.getInt("item_value"); this.value = rs.getInt("item_value");
this.customName = rs.getString("item_name"); this.customName = rs.getString("item_name");
} }
public static void _serializeForClientMsg(Item item, ByteBufferWriter writer) public static void _serializeForClientMsg(Item item, ByteBufferWriter writer)
@ -666,7 +665,6 @@ public class Item extends AbstractWorldObject {
} }
return item; return item;
} }
public static Item getFromCache(int id) { public static Item getFromCache(int id) {
return (Item) DbManager.getFromCache(GameObjectType.Item, id); return (Item) DbManager.getFromCache(GameObjectType.Item, id);
} }
@ -889,6 +887,8 @@ public class Item extends AbstractWorldObject {
} }
public boolean isCanDestroy() { public boolean isCanDestroy() {
if(this.getItemBaseID() == 7)//gold
return false;
return canDestroy; return canDestroy;
} }
@ -1230,18 +1230,18 @@ public class Item extends AbstractWorldObject {
return; return;
if (this.getItemBase() != null) if (this.getItemBase() != null)
for (Integer token : this.getItemBase().getBakedInStats().keySet()) {
for (Integer token : this.getItemBase().getBakedInStats().keySet()) { effect = PowersManager.getEffectByToken(token);
effect = PowersManager.getEffectByToken(token); if (effect == null) {
Logger.error("missing effect of token " + token);
continue;
}
AbstractPowerAction apa = PowersManager.getPowerActionByIDString(effect.getIDString());
apa.applyBakedInStatsForItem(this, this.getItemBase().getBakedInStats().get(token));
if (effect == null) {
Logger.error("missing effect of token " + token);
continue;
} }
AbstractPowerAction apa = PowersManager.getPowerActionByIDString(effect.getIDString());
apa.applyBakedInStatsForItem(this, this.getItemBase().getBakedInStats().get(token));
}
} }
public final void loadEnchantments() { public final void loadEnchantments() {

82
src/engine/objects/ItemBase.java

@ -13,6 +13,7 @@ import engine.Enum.DamageType;
import engine.Enum.GameObjectType; import engine.Enum.GameObjectType;
import engine.Enum.ItemType; import engine.Enum.ItemType;
import engine.gameManager.DbManager; import engine.gameManager.DbManager;
import engine.gameManager.LootManager;
import engine.server.MBServerStatics; import engine.server.MBServerStatics;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
@ -23,7 +24,7 @@ import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
public class ItemBase { public class ItemBase{
public static final byte GOLD_BASE_TYPE = 4; public static final byte GOLD_BASE_TYPE = 4;
public static ItemBase GOLD_ITEM_BASE = null; public static ItemBase GOLD_ITEM_BASE = null;
@ -35,10 +36,10 @@ public class ItemBase {
private static HashMap<Integer, Integer> itemHashIDMap = new HashMap<>(); private static HashMap<Integer, Integer> itemHashIDMap = new HashMap<>();
private static HashMap<String, Integer> _IDsByNames = new HashMap<>(); private static HashMap<String, Integer> _IDsByNames = new HashMap<>();
private static ArrayList<ItemBase> _resourceList = new ArrayList<>(); private static ArrayList<ItemBase> _resourceList = new ArrayList<>();
private final int uuid; private int uuid;
private final String name; private String name;
private float durability; private float durability;
private int value; public int value;
private short weight; private short weight;
private short color; private short color;
private ItemType type; private ItemType type;
@ -722,7 +723,12 @@ public class ItemBase {
public final int getUUID() { public final int getUUID() {
return uuid; return uuid;
} }
public void setUUID(int id) {
this.uuid = id;
}
public void setName(String name) {
this.name = name;
}
public boolean isRing() { public boolean isRing() {
return ((this.equipFlag & (64 | 128 | 192)) != 0); return ((this.equipFlag & (64 | 128 | 192)) != 0);
} }
@ -914,4 +920,70 @@ public class ItemBase {
public void setAutoID(boolean autoID) { public void setAutoID(boolean autoID) {
this.autoID = autoID; this.autoID = autoID;
} }
public boolean isVorg(){
return LootManager.vorg_ha_uuids.contains(this.uuid) || LootManager.vorg_ma_uuids.contains(this.uuid) || LootManager.vorg_la_uuids.contains(this.uuid) || LootManager.vorg_cloth_uuids.contains(this.uuid);
}
public String[] getVorgStats() {
return new String[]{};
}
public static int getPriceCeilingForRune(int runeID){
switch(runeID){
case 250001: //5 stats
case 250010:
case 250019:
case 250028:
case 250037:
return 3000000;
case 250002: //10 stats
case 250011:
case 250020:
case 250029:
case 250038:
return 4000000;
case 250003: //15 stats
case 250012:
case 250021:
case 250030:
case 250039:
return 5000000;
case 250004: //20 stats
case 250013:
case 250022:
case 250031:
case 250040:
return 6000000;
case 250005: //25 stats
case 250014:
case 250023:
case 250032:
case 250041:
return 7000000;
case 250006: //30 stats
case 250015:
case 250024:
case 250033:
case 250042:
return 8000000;
case 250007: //35 stats
case 250016:
case 250025:
case 250034:
case 250043:
return 9000000;
case 250008: //40 stats
case 250017:
case 250026:
case 250035:
case 250044:
return 10000000;
case 3040: //prospector
case 3021: //traveller
return 500000;
}
return 10000000;
}
} }

4
src/engine/objects/ItemFactory.java

@ -707,7 +707,7 @@ public class ItemFactory {
if (rollPrefix < 80) { if (rollPrefix < 80) {
int randomPrefix = LootManager.TableRoll(vendor.getLevel(), false); int randomPrefix = LootManager.TableRoll(vendor.getLevel());
prefixEntry = ModTableEntry.rollTable(prefixTypeTable.modTableID, randomPrefix); prefixEntry = ModTableEntry.rollTable(prefixTypeTable.modTableID, randomPrefix);
if (prefixEntry != null) if (prefixEntry != null)
@ -722,7 +722,7 @@ public class ItemFactory {
if (rollSuffix < 80 || prefixEntry == null) { if (rollSuffix < 80 || prefixEntry == null) {
int randomSuffix = LootManager.TableRoll(vendor.getLevel(), false); int randomSuffix = LootManager.TableRoll(vendor.getLevel());
suffixEntry = ModTableEntry.rollTable(suffixTypeTable.modTableID, randomSuffix); suffixEntry = ModTableEntry.rollTable(suffixTypeTable.modTableID, randomSuffix);
if (suffixEntry != null) if (suffixEntry != null)

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

Loading…
Cancel
Save