Compare commits

...

364 Commits

Author SHA1 Message Date
MagicBot 44b9ba911d Indices added to command output. 2 years ago
MagicBot c24f8fc85b Login check modified for testing. 2 years ago
MagicBot 75c56cbeee Devcmd output updated. 2 years ago
MagicBot 15f42c9658 Devcmd output updated. 2 years ago
MagicBot 525d0c21bb Devcmd output updated. 2 years ago
MagicBot cbf05cfe5b Devcmd output updated. 2 years ago
MagicBot aaa506a581 Divisor testing. 2 years ago
MagicBot a2fbfad00e Revert initialize. 2 years ago
MagicBot 031c52e25a Divisor test. 2 years ago
MagicBot 693dfd827c Updated dev cmd output 2 years ago
MagicBot d26a2d35bf Multiple not divide 2 years ago
MagicBot 9839de128c Variable initialized. 2 years ago
MagicBot 12872ee51e Variable initialized. 2 years ago
MagicBot 2af08d6823 Reformat file. 2 years ago
MagicBot f646075311 Static method to save memory. 2 years ago
MagicBot dfca767476 Multiple not divide. 2 years ago
MagicBot fd7b5952c2 Dev command updated 2 years ago
MagicBot 4b46eddc47 Dev command updated 2 years ago
MagicBot e26121177f World altitude set in setparent. 2 years ago
MagicBot 91eb0c314f SeAudit command created 2 years ago
MagicBot 1d7a2d4eae Added sea level info to command. 2 years ago
MagicBot e4235d4d75 Bugfix in setparent. 2 years ago
FatBoy-DOTC 41a83115be safehold guard exclusion from equipment dropping 2 years ago
FatBoy-DOTC 3ce887cb34 NPC are immune to all 2 years ago
FatBoy-DOTC 874eb6189e NPC apply runes 2 years ago
FatBoy-DOTC 5c5c491597 debug code 2 years ago
FatBoy-DOTC ff78c1443c null check 2 years ago
FatBoy-DOTC cdc1c2d776 region assignment 2 years ago
FatBoy-DOTC a004c247ab abstract character cleanup 2 years ago
FatBoy-DOTC 048e90fb8f NPC all apply "shopkeeper" rune 2 years ago
FatBoy-DOTC c1498145e6 NPC rune work 2 years ago
FatBoy-DOTC 7654d5183a region lookup and height offset for AbstractCharacters when setLoc is called 2 years ago
FatBoy-DOTC 9b7fc0a93b region height work 2 years ago
FatBoy-DOTC 200318ddcf add region height to world height in setLoc 2 years ago
FatBoy-DOTC 1fdd0a1b32 initialize runes array list for NPC 2 years ago
FatBoy-DOTC 8869772fa4 print effects command 2 years ago
FatBoy-DOTC 96bc894962 print runes command 2 years ago
FatBoy-DOTC 5a9f5f2eca NPCs apply runes from set 2 years ago
FatBoy-DOTC bd9dbcbb42 NPCs load rune sets 2 years ago
FatBoy-DOTC f8269bb764 character runes moved form PlayerCharacter to AbstractCharacter 2 years ago
FatBoy-DOTC c215047c00 teleport method removed form PLayerCharacter to use AbstractCharacter.teleport instead 2 years ago
FatBoy-DOTC a313e3f364 setRegion removal 2 years ago
FatBoy-DOTC b34be1184e null region assignment 2 years ago
FatBoy-DOTC e23c5527da null region assignment 2 years ago
FatBoy-DOTC 847e62dd27 setLoc now handles region assignment 2 years ago
MagicBot f5d83aa259 Class cleanup of bonus code and unused methods. 2 years ago
MagicBot 4a5c0ae5a0 Cities don't actually have a location. They are a property of a zone. Let's start here. 2 years ago
MagicBot b4a4323906 Minor formatting cleanup. 2 years ago
MagicBot 48fc5af5f7 Removed unused variables from class. 2 years ago
MagicBot a1753a28ec Player cities write correct offset. 2 years ago
MagicBot fa4039cf63 Add y offset to zone altitude. 2 years ago
MagicBot 4b0814c0a1 Add y offset to zone altitude. 2 years ago
MagicBot 78d0b06b36 Revert for testing. 2 years ago
MagicBot 426bdf5df3 Removed yoffset from world altitude. 2 years ago
MagicBot 5dbad7ebd0 Player cities set to white. 2 years ago
MagicBot 6ef33c5b7f Update to world altitude calculation 2 years ago
MagicBot 3737a6eace Sea level logic updated. 2 years ago
MagicBot 967e129724 Sea level logic updated. 2 years ago
MagicBot e9d549377e Sea level logic updated. 2 years ago
MagicBot 924b8af827 Sea level logic updated. 2 years ago
MagicBot 045ee73b61 rework of world altitude calculation. 2 years ago
MagicBot 5d9d13ce07 Any argument rebuilds world altitude. 2 years ago
MagicBot 5a1347ec50 Devcmd updated 2 years ago
MagicBot c705f45856 Devcmd updated 2 years ago
MagicBot 83fc129d05 Dev command output update. 2 years ago
MagicBot d7cde3a77f Grid flip testing 2 years ago
MagicBot afb1ad8e94 Grid flip testing 2 years ago
MagicBot 15a79ee9bd devcmd output updated with grid. 2 years ago
MagicBot 68794c170b Removed usless method: added grid to cmd output. 2 years ago
MagicBot a9d84749ba Removed worthless command. 2 years ago
MagicBot dd5fc323ef bugfix in array loading 2 years ago
MagicBot cf1547d077 DevCmd Updated 2 years ago
MagicBot 9664c99e06 DevCmd Updated 2 years ago
MagicBot 17b7fb6999 Unused method 2 years ago
MagicBot 21a4db8a81 Pixels set to 0 2 years ago
MagicBot eabdabcfcd No insane bucket widths. 2 years ago
MagicBot c548383a4c Should not be putting empty maps into the collection with id 0. 2 years ago
MagicBot 7337f4be1e DevCmd update. 2 years ago
MagicBot d84f223b9d DevCmd update. 2 years ago
MagicBot 5431112186 DevCmd update. 2 years ago
MagicBot ff743151c6 DevCmd update. 2 years ago
MagicBot b923392b53 DevCmd update. 2 years ago
MagicBot 15d272c621 DevCmd update. 2 years ago
MagicBot eefa50b2c3 DevCmd update. 2 years ago
MagicBot ecc7a152f7 DevCmd update. 2 years ago
MagicBot 7bf31f9a47 Rework of class interface. 2 years ago
MagicBot 7dc970ff53 Rework of dev command; junk deleted. 2 years ago
FatBoy-DOTC 97d71ec361 move to point handler revert 2 years ago
FatBoy-DOTC 003b939d33 Move to point message variable naming and handler cleanup 2 years ago
FatBoy-DOTC 9989cbff24 pc.teleport uneeded 2 years ago
FatBoy-DOTC 426ef989f8 can no longer run to invalid targets 2 years ago
FatBoy-DOTC ca6e079053 fresh start 2 years ago
FatBoy-DOTC 13644fd308 use target from message in move to point 2 years ago
FatBoy-DOTC 1ec76ae3fc use target from message in move to point 2 years ago
FatBoy-DOTC 51d75146cc NPC added to attack message handler switch 2 years ago
FatBoy-DOTC bc4222646d combat target usage 2 years ago
FatBoy-DOTC c3e206e3b1 null check 2 years ago
FatBoy-DOTC 04147e11cc logic for moveToPoint message handler 2 years ago
FatBoy-DOTC 545cb4cddf null check for building pulled 2 years ago
FatBoy-DOTC 0f948d4e2a removed redundant setCombatTarget 2 years ago
FatBoy-DOTC 5fb3e0fe14 switch for target type in attack message handler 2 years ago
MagicBot fb87dfd91e TargetType declared. 2 years ago
FatBoy-DOTC be8967b05f null set for target 2 years ago
FatBoy-DOTC 8acfff7faa null check for target 2 years ago
FatBoy-DOTC 18e1f4bd28 early exits for attack message handler 2 years ago
MagicBot 74f88a6643 Unused variable removed 2 years ago
FatBoy-DOTC 47fe764cb0 early exits for attack message handler 2 years ago
MagicBot 9e53770e6c Handler added to protocol class. 2 years ago
MagicBot a9cc001791 Handler added to protocol class. 2 years ago
MagicBot c24913d124 Handler filled in with logic. 2 years ago
MagicBot 63bf0b6070 Handler created for AttackMsg 2 years ago
FatBoy-DOTC 50792327a4 moveToPoint attack handling 2 years ago
FatBoy-DOTC 46e67be8ca player character attacks added to city outlaws 2 years ago
FatBoy-DOTC e7c3ba5eba guards and siege engines ignore idle state with no players loaded 2 years ago
FatBoy-DOTC ea86ab2300 guards will revert cmbat target to null if its a player and is no longer loaded 2 years ago
FatBoy-DOTC 501e8c937f guards use city player memory to determine whether they go idle or not 2 years ago
FatBoy-DOTC cae5c36d84 guards will aggro siege equipment not belonging to the guild 2 years ago
FatBoy-DOTC 1b92fa76e1 characters that attack city friendly buildings are added to cityOutlaws 2 years ago
FatBoy-DOTC bbdb683061 players who attack buildinsg added to cityOutlaw list 2 years ago
FatBoy-DOTC 2d04547c74 display seeInvis level in aiInfo command 2 years ago
FatBoy-DOTC 5192c801f7 CombatUtilities cleanup 2 years ago
FatBoy-DOTC d966d50bd5 removed duplicate variables in MobBase 2 years ago
FatBoy-DOTC 7e20db33f2 final guard stat revisions 2 years ago
FatBoy-DOTC 669ee7215b added range modification for guards 2 years ago
FatBoy-DOTC 6fa00a43a4 removed unused method 2 years ago
FatBoy-DOTC 4edf740179 finished modifications for guards 2 years ago
FatBoy-DOTC c7abb4c920 stance modifiers for guards 2 years ago
FatBoy-DOTC df3964110a stances for guards 2 years ago
FatBoy-DOTC 96231260bc consolidated all guards to GuardLogic 2 years ago
FatBoy-DOTC 967303d2de outlaw and hate value moved to modifyHealth 2 years ago
FatBoy-DOTC 955481773d wall archer early exit for canCast 2 years ago
FatBoy-DOTC d66a7049e8 guard walking bug fix 2 years ago
MagicBot e73b8d2826 Harden against null 2 years ago
MagicBot ea23003807 Hirelings removed from zone mob set 2 years ago
MagicBot 23f41f8ae7 Minions always have offset not determined by captain being alive. 2 years ago
MagicBot 3f416f83d3 Patrol points only set once. 2 years ago
MagicBot 931d1992b6 Patrol points are reset each patrol. 2 years ago
MagicBot fd927a7052 New method implemented. 2 years ago
MagicBot dd46224afe New method implemented. 2 years ago
MagicBot be2b29ccc7 New method implemented. 2 years ago
MagicBot c93e3bc947 Update to ordering of logic 2 years ago
MagicBot 7d49395c41 New method implemented. 2 years ago
MagicBot f4c9e6d7b8 Remove hireling method defined in manager. 2 years ago
MagicBot b7a907c8c8 db method to support removing all minions 2 years ago
MagicBot 36485a0f01 Formation enforced when captain is dead. 2 years ago
MagicBot efec1b4444 Load data only. 2 years ago
MagicBot bdf6500260 Outlaw moved before guild check. 2 years ago
MagicBot db4eb0579e Aggro code removed from check to send mob home. 2 years ago
MagicBot 76f33534d4 Captains force march minions 2 years ago
MagicBot 39fea5bc2f Captains order minions to patrol 2 years ago
MagicBot 660d5c1270 Captains order minions to patrol 2 years ago
MagicBot 781e2fc9b2 Comment adjusted 2 years ago
MagicBot c2a2464fe8 Errant delimiter removed. 2 years ago
MagicBot beb3c15eb3 Miniond patrol on own if captain is dead. 2 years ago
MagicBot 553010bb7b Minions get marching orders from captain 2 years ago
MagicBot 8d12bbf453 Formation offset for minions. 2 years ago
MagicBot fa7588826a Pets set to not alive when dismissing. 2 years ago
MagicBot 332f191e19 Merged switch cases. 2 years ago
MagicBot 8151382a6b Patrol points inherited from barracks not captain. 2 years ago
MagicBot ae44a21be1 Duplicate range check removed. 2 years ago
MagicBot b0ff0995de Start consolidation of guard logic 2 years ago
MagicBot e711095ecd Start consolidation of guard logic 2 years ago
MagicBot 08de97a2a8 Guild check removed from outlaw condition. 2 years ago
MagicBot 5eb6302d2a Null check is made before this method call. 2 years ago
MagicBot 2e346ae7fd Rework of combat deference to captain. 2 years ago
MagicBot 1285d12915 Consolidated cast methods. 2 years ago
MagicBot 8b5cb9258e dd roll removed 2 years ago
MagicBot ef3e3a0392 .contains check needed. 2 years ago
MagicBot 8fca6572f9 Typo in comment fixed. 2 years ago
MagicBot 33eaf0e583 Outlaws added to aiinfo. 2 years ago
MagicBot 16acd1c08c Simplify logic; variable is provided. 2 years ago
MagicBot a8e8804ce3 Attacking guard flags you as an outlaw. 2 years ago
MagicBot b8c0f997f6 Fix typo in thread name. 2 years ago
MagicBot 11e63f38b1 Update to mob retaliate logic. 2 years ago
MagicBot ff36d8f3db Modification to minion retaliate. 2 years ago
MagicBot 975542d8af sql column update. 2 years ago
MagicBot d71a9415b4 Integer object not int signature. 2 years ago
MagicBot e948da95b5 Column name updated. 2 years ago
MagicBot 9a6510c320 Minions now use copyonwrite collection. Slot agnostic. 2 years ago
MagicBot 57ff1ede97 Name is all that's needed. 2 years ago
MagicBot 7c0f2563f7 Already added to collection at this point. 2 years ago
FatBoy-DOTC d11a954b40 remove test block 2 years ago
FatBoy-DOTC f354339af1 null checks 2 years ago
FatBoy-DOTC 89658bb77a null checks 2 years ago
FatBoy-DOTC 1ff0238b6e skill loading bypass for guards 2 years ago
FatBoy-DOTC e777434d57 Mob specific rune skill loading 2 years ago
FatBoy-DOTC ee6efc30a3 rune skill loading broken into static method in NPCManager 2 years ago
FatBoy-DOTC 0758bb5f38 SkillsBase are now cached when missing for mobs 2 years ago
FatBoy-DOTC 299d5725a6 lookup using name 2 years ago
FatBoy-DOTC d7c9b31ec7 indentation and comment 2 years ago
FatBoy-DOTC 6c78bee5c1 null check 2 years ago
FatBoy-DOTC dba0cbd5f9 skill type not name used 2 years ago
FatBoy-DOTC 0752e780f2 mobs load skills 2 years ago
MagicBot c43919ce01 Level loaded into object. 2 years ago
MagicBot 0d95510b72 captain uuid added to aiInfoCmd 2 years ago
MagicBot 60fb2571a2 Support for loading of skill adjustment map. 2 years ago
MagicBot 90cbe90492 Merge remote-tracking branch 'origin/mobile-effects' into magicbox-1.5.2 2 years ago
FatBoy-DOTC 95c203b0ed load and apply mobbaseSkill 2 years ago
FatBoy-DOTC 449c5c5c77 infrastructure for mob skills loading 2 years ago
FatBoy-DOTC 9aff208403 guard captains to move tot heir first patrol point right away 2 years ago
FatBoy-DOTC 4318849127 minion relatiate handled inside retaliate function 2 years ago
FatBoy-DOTC 29e8cdf699 attacking guard minion will no longer be ignored 2 years ago
MagicBot 4427dbdcad Fix in exception for werwolf/werebear (magic numbers) 2 years ago
MagicBot af4c3819b9 contract added to aiInfoCmd 2 years ago
MagicBot 39379e1ac0 Sight check moved out of cancast. 2 years ago
MagicBot 71eeb3f6b8 Variable hidden elevated to abschar. 2 years ago
MagicBot d409ef49af Can cast added to aiinfo. 2 years ago
MagicBot e7a80e9280 Comment cleanup 2 years ago
MagicBot 65c2d2ea0b Logic cleanup when dealing with contracts. 2 years ago
MagicBot 92666dca21 Invis check precedes power check. 2 years ago
MagicBot 3e1a79c248 AI info dev command updated. 2 years ago
MagicBot 73a1ce083a Unused method removed. 2 years ago
MagicBot 22dacebc5e Override unnecessary. 2 years ago
MagicBot 80d0948e24 Contract power handling now additive. 2 years ago
MagicBot 58b427b977 Contract support added to mobile ai when gathering powers. 2 years ago
MagicBot a4cab3565a Value cannot be null. Set early in runafterload. 2 years ago
MagicBot 205c9580e3 sql column name fix. 2 years ago
MagicBot 70a0ed135b Refactored mob powers to rune powers. Now uses rune_id to call into system which is derived in the getter to support minions. 2 years ago
FatBoy-DOTC f556181d77 guardlist serialization displays correct minion rank 2 years ago
FatBoy-DOTC d48e26904e revert last commit 2 years ago
FatBoy-DOTC 19232ac405 archers added to human guards as minions 2 years ago
FatBoy-DOTC 9ee2ccc8af werebear and werewolf guard can use powers 2 years ago
FatBoy-DOTC 7079bb6a63 resist loading refactored as static method to NPCManager 2 years ago
FatBoy-DOTC 0ab5827ee5 mobs to load equipment resists 2 years ago
FatBoy-DOTC c5443f622c utilization and assignment of aiAgentType 2 years ago
FatBoy-DOTC e4aa276cca cleanup old code 2 years ago
FatBoy-DOTC 90ff2d679e create and use applyMobbaseEffects method, remove old unused methods 2 years ago
FatBoy-DOTC da26c35d5a mobbase loads effectsList 2 years ago
MagicBot 779e3da74e Cleanup of clear minion logic. 2 years ago
MagicBot e358c08773 Removed msg from handler. 2 years ago
MagicBot 2945fa3a47 Class reformat and removal of try block. 2 years ago
MagicBot ab1541e741 Class not needed on login server. 2 years ago
MagicBot 3aeaa709a5 Comment cleanup 2 years ago
MagicBot 91e627df6b AI moved to top of runafterload. 2 years ago
MagicBot d0795e9e1c Rework of agent type init in runafterload. Only used for 2 instances from disk. 2 years ago
MagicBot 0e12dd4874 Contract powers loaded first to preserve ordering. 2 years ago
MagicBot 25c0e48181 Loot bypass now uses agent type. 2 years ago
MagicBot 0d43c3620d Value is set earlier. 2 years ago
MagicBot 2f6137f8df Minion agent type set properly. 2 years ago
FatBoy-DOTC 2843b86a93 Moved agent type to top of constructor. 2 years ago
MagicBot 8235de07ff Updated output of devcmd. 2 years ago
MagicBot e2f9a4c7f0 Guard minions inherit powers from captain. 2 years ago
MagicBot 55c6e3cf93 Refactored out duplicate power collection. 2 years ago
MagicBot 11c154e564 Assignment fix and comment cleanup. 2 years ago
MagicBot 7fc0d27c3c Siege engine agent type set properly. 2 years ago
MagicBot 1ac76cfcd8 isPlayerguard refactored to derive from agenttype. 2 years ago
MagicBot c8ed04aaaf Refactor to separate persistence and write fsm to table. 2 years ago
MagicBot 6641651f3c Unused method removed. 2 years ago
MagicBot dbf164bfb2 bonus code removal 2 years ago
MagicBot 8a617c3008 Siege minion spawn time set to 15m. 2 years ago
FatBoy-DOTC a50a2430ba hate value for chants to affect mobs in range 2 years ago
FatBoy-DOTC 5c3c552288 usage of AIAgentType for default patrol points 2 years ago
FatBoy-DOTC 69fdddfc71 hate value fix 2 years ago
FatBoy-DOTC db5b988275 usage of AIAgentType for pet checks in run after load 2 years ago
FatBoy-DOTC 4284757035 pet level set in run after load removed 2 years ago
FatBoy-DOTC b93a47acc0 pet death and dismissal fix 2 years ago
MagicBot d59f9857ce Cleanup in pet minion 2 years ago
FatBoy-DOTC 8ce212b74b Merge remote-tracking branch 'origin/mob-refactor2' into mob-refactor2 2 years ago
FatBoy-DOTC e78aea5735 Assign patrol points added as static method to NPC manager 2 years ago
MagicBot 9a3c5c3f40 Siege minion assigned UUID. 2 years ago
FatBoy-DOTC 60ca3f9c34 remove siege minion 2 years ago
FatBoy-DOTC e7e740dff1 blocked player character specific block in minion training message handler 2 years ago
MagicBot 8343a98d77 Minion added to map after runafterload. 2 years ago
MagicBot 5862039a00 Minion added to map after runafterload. 2 years ago
MagicBot 8af989b75f Fix is patrol logic bloc conditional. 2 years ago
MagicBot 08d0e5ff75 Logic isn't needed here. 2 years ago
MagicBot 5196d10e5c Logic isn't needed here. 2 years ago
MagicBot 3392ec463d Removed unused methods. 2 years ago
MagicBot 33529404cf Logic fix in siege minions. 2 years ago
MagicBot 00e7a36013 Logic fix in siege minions. 2 years ago
FatBoy-DOTC 3060b394ab removed siegeminion map from NPC 2 years ago
MagicBot a43d9022fe Siege engine slot override. 2 years ago
FatBoy-DOTC 6abdc68ca5 removed un-needed cast to player character for pets 2 years ago
FatBoy-DOTC 61c66b0e96 trebs slot in proper locations 2 years ago
FatBoy-DOTC 36cc23457a optimized slot for siege engines 2 years ago
FatBoy-DOTC d573b238de refactored mob get/set owner 2 years ago
FatBoy-DOTC 8afe25fe85 siege minions added to arty captain minion map 2 years ago
MagicBot f80647ff0d Spawn time set to 15s for debug. 2 years ago
MagicBot 7e64cbabf8 Update to slotting logic. 2 years ago
MagicBot 14a06410ae Update to slotting logic. 2 years ago
MagicBot 85c2a4f4f0 Add all as hirelings 2 years ago
FatBoy-DOTC da9e211ec7 SiegeEngine enum and logic added 2 years ago
MagicBot a81070c471 Pet level += 20 to conform to 24.3 2 years ago
MagicBot e3ad7efa4f Method renamed for new convention. 2 years ago
MagicBot a4dafd7155 Unused variable in signature. 2 years ago
MagicBot 645aec853e Bindloc not adjusted for pets. 2 years ago
MagicBot d8d5e4a3c4 Name set to default. 2 years ago
MagicBot 7a48c04057 Mobbase set properly. 2 years ago
MagicBot 64aaaa707e Behaviour type set for pets. 2 years ago
MagicBot 445d40dc5f Bonus code removed. 2 years ago
MagicBot ebdcb531f2 AI methods moved to ai class. 2 years ago
MagicBot c9cdb891d6 Cleanup of ownerNPC mess. 2 years ago
MagicBot f5c6c002a8 Unused method removed. 2 years ago
MagicBot d171c6bb9a Unused method removed. 2 years ago
MagicBot 1c81a4faed Wall archers static reverted. 2 years ago
MagicBot e7d1d5cb71 Constructor removed. 2 years ago
MagicBot 060d831d50 Comment for clarity. 2 years ago
MagicBot 316bd6dd01 Siege engines use slot system. 2 years ago
MagicBot 34081e5903 Ordinal comparison fix. 2 years ago
MagicBot e2d843b65e Signature refactor. 2 years ago
MagicBot a796f5fe4b More siege engine work. 2 years ago
MagicBot 51ee41c773 use of SiegeEngine Behaviour Type 2 years ago
MagicBot 7e5ed3efe5 sqrMagnitude not sqrRoot 2 years ago
MagicBot 8dd25ac315 Minions inherit patrol points form barracks. 2 years ago
MagicBot 1cdaa58e7a Wall archers set to static grid type. 2 years ago
MagicBot fa3aa24a3d Update to minion building/location mechanic. 2 years ago
MagicBot 091431d95b Dynamic set in all constructors. 2 years ago
MagicBot 1ecf0122ab Unused variable removed. 2 years ago
MagicBot 79980a1725 NoID constructor removed. 2 years ago
MagicBot 8badcc3f6e Refactored out redundant stat-xyz variables. 2 years ago
MagicBot 4d6e57257c Unused methods removed. 2 years ago
MagicBot a7a93b8500 Tweak to bindloc for minions. 2 years ago
MagicBot 85cc34fb4c AIinfo updated. 2 years ago
MagicBot 772a996b6e Tweak to behavior type setup. 2 years ago
MagicBot e67eff822d Propagate guardedCity. 2 years ago
MagicBot c39ed6120f Cleanup of bind/loc logic. 2 years ago
MagicBot c38f4e6543 Mask only needs be set once. 2 years ago
MagicBot 098433b697 Needs contract null check 2 years ago
MagicBot c8e20c905b Add to cache before setloc 2 years ago
MagicBot bd2446ba0a Minion uuid set pre configure 2 years ago
MagicBot c179e4aaf3 Don't override level or name for minions. 2 years ago
MagicBot 2f8de2a919 Worthless collection only used in 2 places. 2 years ago
MagicBot 338110973d Mobbase cannot be null. 2 years ago
MagicBot 3c9c4495bc playerGuard = true. 2 years ago
MagicBot 93476f782c Bind loc not overwritten. 2 years ago
MagicBot 3aec6ee578 More minion setup work. 2 years ago
MagicBot 3bca76d4c8 Setloc to spawn minion. 2 years ago
MagicBot b9d6f35aac Unused variable. 2 years ago
MagicBot 9b6959414a More flushing out minion support. 2 years ago
MagicBot 400dd6aa5e More granular error reporting. 2 years ago
MagicBot 14af2f6efd Minion spawning re-enabled for refactoring. 2 years ago
MagicBot 0a2de9e0d5 Contract handling cleanup. 2 years ago
MagicBot 89bfad78a6 Contract handling cleanup. 2 years ago
MagicBot 52486fa278 Contract handling cleanup. 2 years ago
MagicBot dc0e14eb21 AI added earlier in sequence for availability. 2 years ago
MagicBot 70278374e7 manager init moved to the top of method. 2 years ago
MagicBot ac3588c76a manager init moved to the top of method. 2 years ago
MagicBot ab335aef2a Enums are fragile. 2 years ago
MagicBot 719c855bdb Cleanup of inventoryManager usage. 2 years ago
MagicBot f283e50018 Disabled minions for now. 2 years ago
MagicBot 99b952ee28 Refactor towards new constructor. 2 years ago
MagicBot 24639b62c0 Refactor towards new constructor. 2 years ago
MagicBot 573cc531bf Refactor towards new constructor. 2 years ago
MagicBot 29e24bae93 Unused constructor removed. 2 years ago
MagicBot 22e4cc07c0 Separate pet and siege behaviour types. 2 years ago
MagicBot 9264347698 Minions inherit enemy/notenemy from captain. 2 years ago
MagicBot 579c26ac59 InitializeMob removed. 2 years ago
MagicBot ef577dd313 Removed catch to propagate error. 2 years ago
MagicBot 62c7e52487 Starting to whittle away at initmob method. 2 years ago
MagicBot 3534ac6477 Starting to whittle away at initmob method. 2 years ago
MagicBot 1738f7b311 Starting to whittle away at initmob method. 2 years ago
MagicBot eb25caec81 Object creation moved out of rs const. 2 years ago
MagicBot a6c60e2c04 Merge remote-tracking branch 'origin/master' into mobile-cleanup 2 years ago
MagicBot adafbdf6d3 Duplicate building and building ID values. 2 years ago
MagicBot 7eab14938d Exception for siege when slotting. 2 years ago
MagicBot 039e55673b Exception for siege when slotting. 2 years ago
MagicBot ec3a9b6cb4 Minions don't have contracts. 2 years ago
MagicBot 17a6494b2b Unused code. 2 years ago
MagicBot 0b05c7074f Slot all agents but true mobiles. 2 years ago
MagicBot 876ccc7cbf New constructor created. 2 years ago
MagicBot bdf14b8f24 Ordinal comparisons refactored. 2 years ago
MagicBot 43375a6f5b Only mobiles with contracts can be slotted. 2 years ago
MagicBot e00328ae13 Siege pets use slotting mechanic. 2 years ago
MagicBot 07c553294b Mobiles use new slotting mechanic. 2 years ago
  1. 20
      src/engine/Enum.java
  2. 363
      src/engine/InterestManagement/HeightMap.java
  3. 12
      src/engine/InterestManagement/InterestManager.java
  4. 73
      src/engine/db/handlers/dbMobHandler.java
  5. 45
      src/engine/db/handlers/dbPowerHandler.java
  6. 80
      src/engine/db/handlers/dbRuneBaseHandler.java
  7. 5
      src/engine/devcmd/cmds/AddMobCmd.java
  8. 70
      src/engine/devcmd/cmds/AuditHeightMapCmd.java
  9. 226
      src/engine/devcmd/cmds/GetHeightCmd.java
  10. 4
      src/engine/devcmd/cmds/InfoCmd.java
  11. 67
      src/engine/devcmd/cmds/PrintEffectsCmd.java
  12. 67
      src/engine/devcmd/cmds/PrintRunesCmd.java
  13. 22
      src/engine/devcmd/cmds/PrintStatsCmd.java
  14. 21
      src/engine/devcmd/cmds/PurgeObjectsCmd.java
  15. 41
      src/engine/devcmd/cmds/RegionCmd.java
  16. 52
      src/engine/devcmd/cmds/RemoveObjectCmd.java
  17. 43
      src/engine/devcmd/cmds/SeaAuditCmd.java
  18. 2
      src/engine/devcmd/cmds/SetSubRaceCmd.java
  19. 3
      src/engine/devcmd/cmds/SplatMobCmd.java
  20. 2
      src/engine/devcmd/cmds/ZoneInfoCmd.java
  21. 96
      src/engine/devcmd/cmds/aiInfoCmd.java
  22. 140
      src/engine/gameManager/BuildingManager.java
  23. 2
      src/engine/gameManager/ChatManager.java
  24. 269
      src/engine/gameManager/CombatManager.java
  25. 5
      src/engine/gameManager/DevCmdManager.java
  26. 2
      src/engine/gameManager/LootManager.java
  27. 23
      src/engine/gameManager/MovementManager.java
  28. 426
      src/engine/gameManager/NPCManager.java
  29. 21
      src/engine/gameManager/PowersManager.java
  30. 28
      src/engine/gameManager/ZoneManager.java
  31. 4
      src/engine/jobs/EndFearJob.java
  32. 2
      src/engine/jobs/FinishSummonsJob.java
  33. 569
      src/engine/mobileAI/MobAI.java
  34. 189
      src/engine/mobileAI/utilities/CombatUtilities.java
  35. 14
      src/engine/mobileAI/utilities/MovementUtilities.java
  36. 2
      src/engine/net/DispatchMessage.java
  37. 5
      src/engine/net/client/ClientMessagePump.java
  38. 2
      src/engine/net/client/Protocol.java
  39. 86
      src/engine/net/client/handlers/AttackCmdMsgHandler.java
  40. 136
      src/engine/net/client/handlers/MinionTrainingMsgHandler.java
  41. 12
      src/engine/net/client/handlers/MoveToPointHandler.java
  42. 59
      src/engine/net/client/handlers/OrderNPCMsgHandler.java
  43. 26
      src/engine/net/client/handlers/PlaceAssetMsgHandler.java
  44. 1
      src/engine/net/client/handlers/RequestEnterWorldHandler.java
  45. 33
      src/engine/net/client/msg/ManageNPCMsg.java
  46. 111
      src/engine/net/client/msg/MoveToPointMsg.java
  47. 133
      src/engine/objects/AbstractCharacter.java
  48. 33
      src/engine/objects/AbstractIntelligenceAgent.java
  49. 15
      src/engine/objects/AbstractWorldObject.java
  50. 12
      src/engine/objects/Building.java
  51. 120
      src/engine/objects/CharacterSkill.java
  52. 195
      src/engine/objects/City.java
  53. 17
      src/engine/objects/ItemBase.java
  54. 1305
      src/engine/objects/Mob.java
  55. 31
      src/engine/objects/MobBase.java
  56. 10
      src/engine/objects/MobBaseStats.java
  57. 40
      src/engine/objects/NPC.java
  58. 73
      src/engine/objects/PlayerCharacter.java
  59. 96
      src/engine/objects/Zone.java
  60. 17
      src/engine/powers/MobPowerEntry.java
  61. 29
      src/engine/powers/RunePowerEntry.java
  62. 31
      src/engine/powers/RuneSkillAdjustEntry.java
  63. 24
      src/engine/powers/poweractions/ApplyEffectPowerAction.java
  64. 36
      src/engine/powers/poweractions/CreateMobPowerAction.java
  65. 2
      src/engine/powers/poweractions/FearPowerAction.java
  66. 2
      src/engine/powers/poweractions/MobRecallPowerAction.java
  67. 2
      src/engine/powers/poweractions/RecallPowerAction.java
  68. 2
      src/engine/powers/poweractions/TeleportPowerAction.java
  69. 24
      src/engine/server/login/LoginServerMsgHandler.java
  70. 88
      src/engine/server/world/WorldServer.java

20
src/engine/Enum.java

@ -2822,7 +2822,6 @@ public class Enum { @@ -2822,7 +2822,6 @@ public class Enum {
public enum MobBehaviourType {
None(null, false, false, false, false, false),
//Power
Power(null, false, true, true, true, false),
PowerHelpee(Power, false, true, true, false, true),
PowerHelpeeWimpy(Power, true, false, true, false, false),
@ -2847,6 +2846,7 @@ public class Enum { @@ -2847,6 +2846,7 @@ public class Enum {
//Independent Types
SimpleStandingGuard(null, false, false, false, false, false),
Pet1(null, false, false, true, false, false),
SiegeEngine(null, false, false, false, false, false),
Simple(null, false, false, true, false, false),
Helpee(null, false, true, true, false, true),
HelpeeWimpy(null, true, false, true, false, false),
@ -2857,13 +2857,12 @@ public class Enum { @@ -2857,13 +2857,12 @@ public class Enum {
HamletGuard(null, false, true, false, false, false),
AggroWanderer(null, false, false, true, false, false);
private static HashMap<Integer, MobBehaviourType> _behaviourTypes = new HashMap<>();
public MobBehaviourType BehaviourHelperType;
public boolean isWimpy;
public boolean isAgressive;
public boolean canRoam;
public boolean callsForHelp;
public boolean respondsToCallForHelp;
public final MobBehaviourType BehaviourHelperType;
public final boolean isWimpy;
public final boolean isAgressive;
public final boolean canRoam;
public final boolean callsForHelp;
public final boolean respondsToCallForHelp;
MobBehaviourType(MobBehaviourType helpeebehaviourType, boolean wimpy, boolean agressive, boolean canroam, boolean callsforhelp, boolean respondstocallforhelp) {
this.BehaviourHelperType = helpeebehaviourType;
@ -2878,8 +2877,11 @@ public class Enum { @@ -2878,8 +2877,11 @@ public class Enum {
public enum AIAgentType {
MOBILE,
GUARDCAPTAIN,
GUARDMINION,
GUARDWALLARCHER,
PET,
CHARMED,
GUARD;
SIEGEENGINE;
}
}

363
src/engine/InterestManagement/HeightMap.java

@ -14,9 +14,7 @@ import engine.gameManager.DbManager; @@ -14,9 +14,7 @@ import engine.gameManager.DbManager;
import engine.gameManager.ZoneManager;
import engine.math.Vector2f;
import engine.math.Vector3fImmutable;
import engine.objects.AbstractWorldObject;
import engine.objects.Zone;
import engine.util.MapLoader;
import org.pmw.tinylog.Logger;
import javax.imageio.ImageIO;
@ -32,6 +30,7 @@ public class HeightMap { @@ -32,6 +30,7 @@ public class HeightMap {
// Class variables
public static float SCALEVALUE = 1.0f / 256;
// Heightmap data for all zones.
public static final HashMap<Integer, HeightMap> heightmapByLoadNum = new HashMap<>();
@ -45,17 +44,17 @@ public class HeightMap { @@ -45,17 +44,17 @@ public class HeightMap {
public BufferedImage heightmapImage;
private int heightMapID;
private int maxHeight;
private int fullExtentsX;
private int fullExtentsY;
private final int heightMapID;
private final int maxHeight;
private final int fullExtentsX;
private final int fullExtentsY;
private float bucketWidthX;
private float bucketWidthY;
private int zoneLoadID;
private final int zoneLoadID;
private float seaLevel = 0;
private float outsetX;
private float outsetZ;
private final float outsetX;
private final float outsetZ;
private int[][] pixelColorValues;
public HeightMap(ResultSet rs) throws SQLException {
@ -88,12 +87,12 @@ public class HeightMap { @@ -88,12 +87,12 @@ public class HeightMap {
try {
this.heightmapImage = ImageIO.read(imageFile);
} catch (IOException e) {
Logger.error("***Error loading heightmap data for heightmap " + this.heightMapID + e.toString());
Logger.error("***Error loading heightmap data for heightmap " + this.heightMapID + e);
}
// We needed to flip the image as OpenGL and Shadowbane both use the bottom left corner as origin.
this.heightmapImage = MapLoader.flipImage(this.heightmapImage);
// this.heightmapImage = MapLoader.flipImage(this.heightmapImage);
// Calculate the data we do not load from table
@ -104,7 +103,7 @@ public class HeightMap { @@ -104,7 +103,7 @@ public class HeightMap {
// Generate pixel array from image data
generatePixelData();
generatePixelData(this);
HeightMap.heightmapByLoadNum.put(this.zoneLoadID, this);
@ -123,35 +122,26 @@ public class HeightMap { @@ -123,35 +122,26 @@ public class HeightMap {
this.outsetX = 128;
this.outsetZ = 128;
// Cache the full extents to avoid the calculation
this.fullExtentsX = halfExtentsX * 2;
this.fullExtentsY = halfExtentsY * 2;
// load the heightmap image.
// We needed to flip the image as OpenGL and Shadowbane both use the bottom left corner as origin.
this.heightmapImage = null;
// Calculate the data we do not load from table
this.bucketWidthX = 1;
this.bucketWidthY = 1;
this.bucketWidthX = halfExtentsX;
this.bucketWidthY = halfExtentsY;
this.pixelColorValues = new int[this.fullExtentsX + 1][this.fullExtentsY + 1];
this.pixelColorValues = new int[this.fullExtentsX][this.fullExtentsY];
for (int y = 0; y <= this.fullExtentsY; y++) {
for (int x = 0; x <= this.fullExtentsX; x++) {
for (int y = 0; y < this.fullExtentsY; y++) {
for (int x = 0; x < this.fullExtentsX; x++) {
pixelColorValues[x][y] = 255;
}
}
HeightMap.heightmapByLoadNum.put(this.zoneLoadID, this);
}
public HeightMap(Zone zone) {
@ -170,26 +160,21 @@ public class HeightMap { @@ -170,26 +160,21 @@ public class HeightMap {
this.fullExtentsX = halfExtentsX * 2;
this.fullExtentsY = halfExtentsY * 2;
// We needed to flip the image as OpenGL and Shadowbane both use the bottom left corner as origin.
this.heightmapImage = null;
// Calculate the data we do not load from table
this.bucketWidthX = 1;
this.bucketWidthY = 1;
this.bucketWidthX = halfExtentsX;
this.bucketWidthY = halfExtentsY;
this.pixelColorValues = new int[this.fullExtentsX + 1][this.fullExtentsY + 1];
this.pixelColorValues = new int[this.fullExtentsX][this.fullExtentsY];
for (int y = 0; y <= this.fullExtentsY; y++) {
for (int x = 0; x <= this.fullExtentsX; x++) {
pixelColorValues[x][y] = 255;
for (int y = 0; y < this.fullExtentsY; y++) {
for (int x = 0; x < this.fullExtentsX; x++) {
pixelColorValues[x][y] = 0;
}
}
HeightMap.heightmapByLoadNum.put(this.zoneLoadID, this);
}
public static void GeneratePlayerCityHeightMap() {
@ -222,113 +207,9 @@ public class HeightMap { @@ -222,113 +207,9 @@ public class HeightMap {
return nextZone;
}
public static float getWorldHeight(AbstractWorldObject worldObject) {
public static float getWorldHeight(Zone currentZone, Vector3fImmutable worldLoc) {
Vector2f parentLoc = new Vector2f(-1, -1);
Zone currentZone = ZoneManager.findSmallestZone(worldObject.getLoc());
if (currentZone == null)
return worldObject.getAltitude();
currentZone = getNextZoneWithTerrain(currentZone);
if (currentZone == ZoneManager.getSeaFloor())
return currentZone.getAbsY() + worldObject.getAltitude();
Zone parentZone = getNextZoneWithTerrain(currentZone.getParent());
HeightMap heightMap = currentZone.getHeightMap();
Vector2f zoneLoc = ZoneManager.worldToZoneSpace(worldObject.getLoc(), currentZone);
Vector3fImmutable localLocFromCenter = ZoneManager.worldToLocal(worldObject.getLoc(), currentZone);
if ((parentZone != null) && (parentZone.getHeightMap() != null))
parentLoc = ZoneManager.worldToZoneSpace(worldObject.getLoc(), parentZone);
float interaltitude = currentZone.getHeightMap().getInterpolatedTerrainHeight(zoneLoc);
float worldAltitude = currentZone.getWorldAltitude();
float realWorldAltitude = interaltitude + worldAltitude;
//OUTSET
if (parentZone != null) {
float parentXRadius = currentZone.getBounds().getHalfExtents().x;
float parentZRadius = currentZone.getBounds().getHalfExtents().y;
float offsetX = Math.abs((localLocFromCenter.x / parentXRadius));
float offsetZ = Math.abs((localLocFromCenter.z / parentZRadius));
float bucketScaleX = heightMap.outsetX / parentXRadius;
float bucketScaleZ = heightMap.outsetZ / parentZRadius;
if (bucketScaleX <= 0.40000001)
bucketScaleX = heightMap.outsetZ / parentXRadius;
if (bucketScaleX > 0.40000001)
bucketScaleX = 0.40000001f;
if (bucketScaleZ <= 0.40000001)
bucketScaleZ = heightMap.outsetX / parentZRadius;
if (bucketScaleZ > 0.40000001)
bucketScaleZ = 0.40000001f;
float outsideGridSizeX = 1 - bucketScaleX; //32/256
float outsideGridSizeZ = 1 - bucketScaleZ;
float weight;
double scale;
if (offsetX > outsideGridSizeX && offsetX > offsetZ) {
weight = (offsetX - outsideGridSizeX) / bucketScaleX;
scale = Math.atan2((.5 - weight) * 3.1415927, 1);
float scaleChild = (float) ((scale + 1) * .5);
float scaleParent = 1 - scaleChild;
float parentAltitude = parentZone.getHeightMap().getInterpolatedTerrainHeight(parentLoc);
float parentCenterAltitude = parentZone.getHeightMap().getInterpolatedTerrainHeight(ZoneManager.worldToZoneSpace(currentZone.getLoc(), parentZone));
parentCenterAltitude += currentZone.getYCoord();
parentCenterAltitude += interaltitude;
float firstScale = parentAltitude * scaleParent;
float secondScale = parentCenterAltitude * scaleChild;
float outsetALt = firstScale + secondScale;
outsetALt += currentZone.getParent().getWorldAltitude();
realWorldAltitude = outsetALt;
} else if (offsetZ > outsideGridSizeZ) {
weight = (offsetZ - outsideGridSizeZ) / bucketScaleZ;
scale = Math.atan2((.5 - weight) * 3.1415927, 1);
float scaleChild = (float) ((scale + 1) * .5);
float scaleParent = 1 - scaleChild;
float parentAltitude = parentZone.getHeightMap().getInterpolatedTerrainHeight(parentLoc);
float parentCenterAltitude = parentZone.getHeightMap().getInterpolatedTerrainHeight(ZoneManager.worldToZoneSpace(currentZone.getLoc(), parentZone));
parentCenterAltitude += currentZone.getYCoord();
parentCenterAltitude += interaltitude;
float firstScale = parentAltitude * scaleParent;
float secondScale = parentCenterAltitude * scaleChild;
float outsetALt = firstScale + secondScale;
outsetALt += currentZone.getParent().getWorldAltitude();
realWorldAltitude = outsetALt;
}
}
return realWorldAltitude;
}
public static float getWorldHeight(Vector3fImmutable worldLoc) {
Vector2f parentLoc = new Vector2f(-1, -1);
Zone currentZone = ZoneManager.findSmallestZone(worldLoc);
if (currentZone == null)
return 0;
@ -352,7 +233,7 @@ public class HeightMap { @@ -352,7 +233,7 @@ public class HeightMap {
float interaltitude = currentZone.getHeightMap().getInterpolatedTerrainHeight(zoneLoc);
float worldAltitude = currentZone.getWorldAltitude();
float worldAltitude = currentZone.worldAltitude;
float realWorldAltitude = interaltitude + worldAltitude;
@ -360,9 +241,6 @@ public class HeightMap { @@ -360,9 +241,6 @@ public class HeightMap {
if (parentZone != null) {
// if (currentZone.getHeightMap() != null && parentZone.getHeightMap() != null && parentZone.getParent() != null && parentZone.getParent().getHeightMap() != null)
// return realWorldAltitude;
float parentXRadius = currentZone.getBounds().getHalfExtents().x;
float parentZRadius = currentZone.getBounds().getHalfExtents().y;
@ -378,7 +256,6 @@ public class HeightMap { @@ -378,7 +256,6 @@ public class HeightMap {
double scale;
if (offsetX > outsideGridSizeX && offsetX > offsetZ) {
weight = (offsetX - outsideGridSizeX) / bucketScaleX;
scale = Math.atan2((.5 - weight) * 3.1415927, 1);
@ -396,7 +273,7 @@ public class HeightMap { @@ -396,7 +273,7 @@ public class HeightMap {
float secondScale = parentCenterAltitude * scaleChild;
float outsetALt = firstScale + secondScale;
outsetALt += currentZone.getParent().getWorldAltitude();
outsetALt += currentZone.getParent().worldAltitude;
realWorldAltitude = outsetALt;
} else if (offsetZ > outsideGridSizeZ) {
@ -415,7 +292,7 @@ public class HeightMap { @@ -415,7 +292,7 @@ public class HeightMap {
float secondScale = parentCenterAltitude * scaleChild;
float outsetALt = firstScale + secondScale;
outsetALt += currentZone.getParent().getWorldAltitude();
outsetALt += currentZone.getParent().worldAltitude;
realWorldAltitude = outsetALt;
}
}
@ -423,85 +300,13 @@ public class HeightMap { @@ -423,85 +300,13 @@ public class HeightMap {
return realWorldAltitude;
}
public static float getOutsetHeight(float interpolatedAltitude, Zone zone, Vector3fImmutable worldLocation) {
Vector2f parentLoc;
float outsetALt = 0;
if (zone.getParent() == null || zone.getParent().getHeightMap() == null)
return interpolatedAltitude + zone.getWorldAltitude();
if (zone.getParent() != null && zone.getParent().getHeightMap() != null) {
parentLoc = ZoneManager.worldToZoneSpace(worldLocation, zone.getParent());
Vector3fImmutable localLocFromCenter = ZoneManager.worldToLocal(worldLocation, zone);
float parentXRadius = zone.getBounds().getHalfExtents().x;
float parentZRadius = zone.getBounds().getHalfExtents().y;
float bucketScaleX = zone.getHeightMap().outsetX / parentXRadius;
float bucketScaleZ = zone.getHeightMap().outsetZ / parentZRadius;
float outsideGridSizeX = 1 - bucketScaleX; //32/256
float outsideGridSizeZ = 1 - bucketScaleZ;
float weight;
double scale;
float offsetX = Math.abs((localLocFromCenter.x / parentXRadius));
float offsetZ = Math.abs((localLocFromCenter.z / parentZRadius));
if (offsetX > outsideGridSizeX && offsetX > offsetZ) {
weight = (offsetX - outsideGridSizeX) / bucketScaleX;
scale = Math.atan2((.5 - weight) * 3.1415927, 1);
float scaleChild = (float) ((scale + 1) * .5);
float scaleParent = 1 - scaleChild;
float parentAltitude = zone.getParent().getHeightMap().getInterpolatedTerrainHeight(parentLoc);
float parentCenterAltitude = zone.getParent().getHeightMap().getInterpolatedTerrainHeight(ZoneManager.worldToZoneSpace(zone.getLoc(), zone.getParent()));
parentCenterAltitude += zone.getYCoord();
parentCenterAltitude += interpolatedAltitude;
float firstScale = parentAltitude * scaleParent;
float secondScale = parentCenterAltitude * scaleChild;
outsetALt = firstScale + secondScale;
outsetALt += zone.getParent().getAbsY();
} else if (offsetZ > outsideGridSizeZ) {
weight = (offsetZ - outsideGridSizeZ) / bucketScaleZ;
scale = Math.atan2((.5 - weight) * 3.1415927, 1);
float scaleChild = (float) ((scale + 1) * .5);
float scaleParent = 1 - scaleChild;
float parentAltitude = zone.getParent().getHeightMap().getInterpolatedTerrainHeight(parentLoc);
float parentCenterAltitude = zone.getHeightMap().getInterpolatedTerrainHeight(ZoneManager.worldToZoneSpace(zone.getLoc(), zone));
parentCenterAltitude += zone.getYCoord();
parentCenterAltitude += interpolatedAltitude;
float firstScale = parentAltitude * scaleParent;
float secondScale = parentCenterAltitude * scaleChild;
outsetALt = firstScale + secondScale;
outsetALt += zone.getParent().getAbsY();
}
}
return outsetALt;
}
public static Vector2f getGridOffset(Vector2f gridSquare) {
public static float getWorldHeight(Vector3fImmutable worldLoc) {
int floorX = (int) gridSquare.x;
int floorY = (int) gridSquare.y;
Zone currentZone = ZoneManager.findSmallestZone(worldLoc);
return new Vector2f(gridSquare.x - floorX, gridSquare.y - floorY);
if (currentZone == null)
return 0;
return getWorldHeight(currentZone, worldLoc);
}
@ -515,7 +320,6 @@ public class HeightMap { @@ -515,7 +320,6 @@ public class HeightMap {
HeightMap.GeneratePlayerCityHeightMap();
// Clear all heightmap image data as it's no longer needed.
for (HeightMap heightMap : HeightMap.heightmapByLoadNum.values()) {
@ -530,10 +334,25 @@ public class HeightMap { @@ -530,10 +334,25 @@ public class HeightMap {
float localAltitude = HeightMap.getWorldHeight(currentLoc);
Zone zone = ZoneManager.findSmallestZone(currentLoc);
if (localAltitude < zone.getSeaLevel())
return true;
return localAltitude < zone.getSeaLevel();
}
private static void generatePixelData(HeightMap heightMap) {
Color color;
// Generate altitude lookup table for this heightmap
heightMap.pixelColorValues = new int[heightMap.heightmapImage.getWidth()][heightMap.heightmapImage.getHeight()];
for (int y = 0; y < heightMap.heightmapImage.getHeight(); y++) {
for (int x = 0; x < heightMap.heightmapImage.getWidth(); x++) {
color = new Color(heightMap.heightmapImage.getRGB(x, y));
heightMap.pixelColorValues[x][y] = color.getRed();
}
}
return false;
}
public Vector2f getGridSquare(Vector2f zoneLoc) {
@ -541,14 +360,18 @@ public class HeightMap { @@ -541,14 +360,18 @@ public class HeightMap {
if (zoneLoc.x < 0)
zoneLoc.setX(0);
if (zoneLoc.x > this.fullExtentsX - 1)
zoneLoc.setX((this.fullExtentsX - 1) + .9999999f);
if (zoneLoc.x >= this.fullExtentsX)
zoneLoc.setX(this.fullExtentsX);
if (zoneLoc.y < 0)
zoneLoc.setY(0);
if (zoneLoc.y > this.fullExtentsY - 1)
zoneLoc.setY((this.fullExtentsY - 1) + .9999999f);
if (zoneLoc.y > this.fullExtentsY)
zoneLoc.setY(this.fullExtentsY);
// Flip Y coordinates
zoneLoc.setY(this.fullExtentsY - zoneLoc.y);
float xBucket = (zoneLoc.x / this.bucketWidthX);
float yBucket = (zoneLoc.y / this.bucketWidthY);
@ -569,13 +392,10 @@ public class HeightMap { @@ -569,13 +392,10 @@ public class HeightMap {
int maxX = (int) (this.fullExtentsX / this.bucketWidthX);
int maxY = (int) (this.fullExtentsY / this.bucketWidthY);
//flip the Y so it grabs from the bottom left instead of top left.
//zoneLoc.setY(maxZoneHeight - zoneLoc.y);
gridSquare = getGridSquare(zoneLoc);
int gridX = (int) gridSquare.x;
int gridY = (int) (gridSquare.y);
int gridY = (int) gridSquare.y;
if (gridX > maxX)
gridX = maxX;
@ -613,76 +433,11 @@ public class HeightMap { @@ -613,76 +433,11 @@ public class HeightMap {
interpolatedHeight += (bottomLeftHeight * (1 - offsetX) * offsetY);
interpolatedHeight += (topLeftHeight * (1 - offsetX) * (1 - offsetY));
interpolatedHeight *= (float) this.maxHeight / 256; // Scale height
return interpolatedHeight;
}
public float getInterpolatedTerrainHeight(Vector3fImmutable zoneLoc3f) {
Vector2f zoneLoc = new Vector2f(zoneLoc3f.x, zoneLoc3f.z);
Vector2f gridSquare;
if (zoneLoc.x < 0 || zoneLoc.x > this.fullExtentsX)
return -1;
if (zoneLoc.y < 0 || zoneLoc.y > this.fullExtentsY)
return -1;
//flip the Y so it grabs from the bottom left instead of top left.
//zoneLoc.setY(maxZoneHeight - zoneLoc.y);
gridSquare = getGridSquare(zoneLoc);
int gridX = (int) gridSquare.x;
int gridY = (int) (gridSquare.y);
float offsetX = (gridSquare.x - gridX);
float offsetY = gridSquare.y - gridY;
//get height of the 4 vertices.
float topLeftHeight = pixelColorValues[gridX][gridY];
float topRightHeight = pixelColorValues[gridX + 1][gridY];
float bottomLeftHeight = pixelColorValues[gridX][gridY + 1];
float bottomRightHeight = pixelColorValues[gridX + 1][gridY + 1];
float interpolatedHeight;
interpolatedHeight = topRightHeight * (1 - offsetY) * (offsetX);
interpolatedHeight += (bottomRightHeight * offsetY * offsetX);
interpolatedHeight += (bottomLeftHeight * (1 - offsetX) * offsetY);
interpolatedHeight += (topLeftHeight * (1 - offsetX) * (1 - offsetY));
interpolatedHeight *= (float) this.maxHeight / 256; // Scale height
interpolatedHeight *= (float) this.maxHeight * SCALEVALUE; // Scale height
return interpolatedHeight;
}
private void generatePixelData() {
Color color;
// Generate altitude lookup table for this heightmap
this.pixelColorValues = new int[this.heightmapImage.getWidth()][this.heightmapImage.getHeight()];
for (int y = 0; y < this.heightmapImage.getHeight(); y++) {
for (int x = 0; x < this.heightmapImage.getWidth(); x++) {
color = new Color(this.heightmapImage.getRGB(x, y));
pixelColorValues[x][y] = color.getRed();
}
}
}
public float getScaledHeightForColor(float color) {
return (color / 256) * this.maxHeight;
}
public float getBucketWidthX() {
return bucketWidthX;
}

12
src/engine/InterestManagement/InterestManager.java

@ -140,7 +140,7 @@ public enum InterestManager implements Runnable { @@ -140,7 +140,7 @@ public enum InterestManager implements Runnable {
else {
if (pc != null)
if (pcc.getSeeInvis() < pc.getHidden())
if (pcc.getSeeInvis() < pc.hidden)
continue;
if (!cc.sendMsg(uom)) {
@ -340,7 +340,7 @@ public enum InterestManager implements Runnable { @@ -340,7 +340,7 @@ public enum InterestManager implements Runnable {
if (loadedPlayer.getObjectUUID() == player.getObjectUUID())
continue;
if (player.getSeeInvis() < loadedPlayer.getHidden())
if (player.getSeeInvis() < loadedPlayer.hidden)
continue;
if (loadedPlayer.safemodeInvis())
@ -372,7 +372,7 @@ public enum InterestManager implements Runnable { @@ -372,7 +372,7 @@ public enum InterestManager implements Runnable {
if (playerLoadedObject.getObjectType().equals(GameObjectType.PlayerCharacter)) {
PlayerCharacter loadedPlayer = (PlayerCharacter) playerLoadedObject;
if (player.getSeeInvis() < loadedPlayer.getHidden())
if (player.getSeeInvis() < loadedPlayer.hidden)
toRemove.add(playerLoadedObject);
else if (loadedPlayer.safemodeInvis())
toRemove.add(playerLoadedObject);
@ -437,7 +437,7 @@ public enum InterestManager implements Runnable { @@ -437,7 +437,7 @@ public enum InterestManager implements Runnable {
// dont load if invis
if (player.getSeeInvis() < awopc.getHidden())
if (player.getSeeInvis() < awopc.hidden)
continue;
lcm = new LoadCharacterMsg(awopc, PlayerCharacter.hideNonAscii());
@ -467,7 +467,7 @@ public enum InterestManager implements Runnable { @@ -467,7 +467,7 @@ public enum InterestManager implements Runnable {
if (awonpc.despawned == true)
continue;
awonpc.playerAgroMap.put(player.getObjectUUID(), false);
awonpc.playerAgroMap.put(player.getObjectUUID(), 0f);
((Mob) awonpc).setCombatTarget(null);
lcm = new LoadCharacterMsg(awonpc, PlayerCharacter.hideNonAscii());
@ -480,7 +480,7 @@ public enum InterestManager implements Runnable { @@ -480,7 +480,7 @@ public enum InterestManager implements Runnable {
if (!awonpc.isAlive())
continue;
awonpc.playerAgroMap.put(player.getObjectUUID(), false);
awonpc.playerAgroMap.put(player.getObjectUUID(), 0f);
if ((awonpc.agentType.equals(Enum.AIAgentType.MOBILE)))
((Mob) awonpc).setCombatTarget(null);

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

@ -28,31 +28,27 @@ public class dbMobHandler extends dbHandlerBase { @@ -28,31 +28,27 @@ public class dbMobHandler extends dbHandlerBase {
this.localObjectType = engine.Enum.GameObjectType.valueOf(this.localClass.getSimpleName());
}
public Mob ADD_MOB(Mob toAdd) {
public Mob PERSIST(Mob toAdd) {
Mob mobile = null;
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("CALL `mob_CREATE`(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);")) {
preparedStatement.setLong(1, toAdd.getParentZoneID());
preparedStatement.setInt(2, toAdd.getMobBaseID());
preparedStatement.setInt(3, toAdd.getGuildUUID());
preparedStatement.setFloat(4, toAdd.getSpawnX());
preparedStatement.setFloat(5, toAdd.getSpawnY());
preparedStatement.setFloat(6, toAdd.getSpawnZ());
PreparedStatement preparedStatement = connection.prepareStatement("CALL `mob_CREATE`(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);")) {
preparedStatement.setLong(1, toAdd.parentZoneUUID);
preparedStatement.setInt(2, toAdd.loadID);
preparedStatement.setInt(3, toAdd.guildUUID);
preparedStatement.setFloat(4, toAdd.bindLoc.x);
preparedStatement.setFloat(5, toAdd.bindLoc.y);
preparedStatement.setFloat(6, toAdd.bindLoc.z);
preparedStatement.setInt(7, 0);
preparedStatement.setFloat(8, toAdd.getSpawnRadius());
preparedStatement.setInt(9, toAdd.getTrueSpawnTime());
if (toAdd.getContract() != null)
preparedStatement.setInt(10, toAdd.getContract().getContractID());
else
preparedStatement.setInt(10, 0);
preparedStatement.setInt(11, toAdd.getBuildingID());
preparedStatement.setInt(12, toAdd.getLevel());
preparedStatement.setString(13, toAdd.getFirstName());
preparedStatement.setFloat(8, toAdd.spawnRadius);
preparedStatement.setInt(9, toAdd.spawnTime);
preparedStatement.setInt(10, toAdd.contractUUID);
preparedStatement.setInt(11, toAdd.buildingUUID);
preparedStatement.setInt(12, toAdd.level);
preparedStatement.setString(13, toAdd.firstName);
preparedStatement.setString(14, toAdd.behaviourType.toString());
ResultSet rs = preparedStatement.executeQuery();
@ -106,17 +102,17 @@ public class dbMobHandler extends dbHandlerBase { @@ -106,17 +102,17 @@ public class dbMobHandler extends dbHandlerBase {
return row_count;
}
public void LOAD_PATROL_POINTS(Mob captain) {
public void LOAD_GUARD_MINIONS(Mob guardCaptain) {
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM `dyn_guards` WHERE `captainUID` = ?")) {
preparedStatement.setInt(1, captain.getObjectUUID());
preparedStatement.setInt(1, guardCaptain.getObjectUUID());
ResultSet rs = preparedStatement.executeQuery();
while (rs.next()) {
String name = rs.getString("name");
Mob toCreate = Mob.createGuardMob(captain, captain.getGuild(), captain.getParentZone(), captain.building.getLoc(), captain.getLevel(), name);
String minionName = rs.getString("minionName");
Mob toCreate = Mob.createGuardMinion(guardCaptain, guardCaptain.getLevel(), minionName);
if (toCreate == null)
return;
@ -131,15 +127,13 @@ public class dbMobHandler extends dbHandlerBase { @@ -131,15 +127,13 @@ public class dbMobHandler extends dbHandlerBase {
}
}
public boolean ADD_TO_GUARDS(final long captainUID, final int mobBaseID, final String name, final int slot) {
public boolean ADD_GUARD_MINION(final long captainUID, final String minionName) {
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("INSERT INTO `dyn_guards` (`captainUID`, `mobBaseID`,`name`, `slot`) VALUES (?,?,?,?)")) {
PreparedStatement preparedStatement = connection.prepareStatement("INSERT INTO `dyn_guards` (`captainUID`, `minionName`) VALUES (?,?)")) {
preparedStatement.setLong(1, captainUID);
preparedStatement.setInt(2, mobBaseID);
preparedStatement.setString(3, name);
preparedStatement.setInt(4, slot);
preparedStatement.setString(2, minionName);
return (preparedStatement.executeUpdate() > 0);
@ -149,14 +143,13 @@ public class dbMobHandler extends dbHandlerBase { @@ -149,14 +143,13 @@ public class dbMobHandler extends dbHandlerBase {
}
}
public boolean REMOVE_FROM_GUARDS(final long captainUID, final int mobBaseID, final int slot) {
public boolean REMOVE_GUARD_MINION(final long captainUID, final String minionName) {
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("DELETE FROM `dyn_guards` WHERE `captainUID`=? AND `mobBaseID`=? AND `slot` =?")) {
PreparedStatement preparedStatement = connection.prepareStatement("DELETE FROM `dyn_guards` WHERE `captainUID`=? AND `minionName`=? LIMIT 1;")) {
preparedStatement.setLong(1, captainUID);
preparedStatement.setInt(2, mobBaseID);
preparedStatement.setInt(3, slot);
preparedStatement.setString(2, minionName);
return (preparedStatement.executeUpdate() > 0);
@ -166,6 +159,20 @@ public class dbMobHandler extends dbHandlerBase { @@ -166,6 +159,20 @@ public class dbMobHandler extends dbHandlerBase {
}
}
public boolean REMOVE_ALL_MINIONS(final long captainUID) {
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("DELETE FROM `dyn_guards` WHERE `captainUID`=?;")) {
preparedStatement.setLong(1, captainUID);
return (preparedStatement.executeUpdate() > 0);
} catch (SQLException e) {
Logger.error(e);
return false;
}
}
public ArrayList<Mob> GET_ALL_MOBS_FOR_ZONE(Zone zone) {

45
src/engine/db/handlers/dbPowerHandler.java

@ -15,15 +15,9 @@ import engine.gameManager.PowersManager; @@ -15,15 +15,9 @@ import engine.gameManager.PowersManager;
import engine.objects.Mob;
import engine.objects.PreparedStatementShared;
import engine.powers.EffectsBase;
import engine.powers.MobPowerEntry;
import org.pmw.tinylog.Logger;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
public class dbPowerHandler extends dbHandlerBase {
@ -86,43 +80,4 @@ public class dbPowerHandler extends dbHandlerBase { @@ -86,43 +80,4 @@ public class dbPowerHandler extends dbHandlerBase {
}
}
public static HashMap<Integer, ArrayList<MobPowerEntry>> LOAD_MOB_POWERS() {
HashMap<Integer, ArrayList<MobPowerEntry>> mobPowers = new HashMap<>();
MobPowerEntry mobPowerEntry;
int mobbaseID;
int recordsRead = 0;
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_npc_mobbase_powers ORDER BY `id` ASC;")) {
ResultSet rs = preparedStatement.executeQuery();
while (rs.next()) {
recordsRead++;
mobbaseID = rs.getInt("mobbaseUUID");
mobPowerEntry = new MobPowerEntry(rs);
if (mobPowers.get(mobbaseID) == null) {
ArrayList<MobPowerEntry> powerList = new ArrayList<>();
powerList.add(mobPowerEntry);
mobPowers.put(mobbaseID, powerList);
} else {
ArrayList<MobPowerEntry> powerList = mobPowers.get(mobbaseID);
powerList.add(mobPowerEntry);
mobPowers.put(mobbaseID, powerList);
}
}
} catch (SQLException e) {
Logger.error(e);
return mobPowers;
}
Logger.info("read: " + recordsRead + " cached: " + mobPowers.size());
return mobPowers;
}
}

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

@ -11,6 +11,8 @@ package engine.db.handlers; @@ -11,6 +11,8 @@ package engine.db.handlers;
import engine.gameManager.DbManager;
import engine.objects.RuneBase;
import engine.powers.RunePowerEntry;
import engine.powers.RuneSkillAdjustEntry;
import org.pmw.tinylog.Logger;
import java.sql.Connection;
@ -27,6 +29,84 @@ public class dbRuneBaseHandler extends dbHandlerBase { @@ -27,6 +29,84 @@ public class dbRuneBaseHandler extends dbHandlerBase {
this.localObjectType = engine.Enum.GameObjectType.valueOf(this.localClass.getSimpleName());
}
public static HashMap<Integer, ArrayList<RunePowerEntry>> LOAD_RUNE_POWERS() {
HashMap<Integer, ArrayList<RunePowerEntry>> mobPowers = new HashMap<>();
RunePowerEntry runePowerEntry;
int rune_id;
int recordsRead = 0;
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_rune_powers")) {
ResultSet rs = preparedStatement.executeQuery();
while (rs.next()) {
recordsRead++;
rune_id = rs.getInt("rune_id");
runePowerEntry = new RunePowerEntry(rs);
if (mobPowers.get(rune_id) == null) {
ArrayList<RunePowerEntry> runePowerList = new ArrayList<>();
runePowerList.add(runePowerEntry);
mobPowers.put(rune_id, runePowerList);
} else {
ArrayList<RunePowerEntry> powerList = mobPowers.get(rune_id);
powerList.add(runePowerEntry);
mobPowers.put(rune_id, powerList);
}
}
} catch (SQLException e) {
Logger.error(e);
return mobPowers;
}
Logger.info("read: " + recordsRead + " cached: " + mobPowers.size());
return mobPowers;
}
public static HashMap<Integer, ArrayList<RuneSkillAdjustEntry>> LOAD_RUNE_SKILL_ADJUSTS() {
HashMap<Integer, ArrayList<RuneSkillAdjustEntry>> runeSkillAdjusts = new HashMap<>();
RuneSkillAdjustEntry runeSkillAdjustEntry;
int rune_id;
int recordsRead = 0;
try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM static_rune_skill_adjusts")) {
ResultSet rs = preparedStatement.executeQuery();
while (rs.next()) {
recordsRead++;
rune_id = rs.getInt("rune_id");
runeSkillAdjustEntry = new RuneSkillAdjustEntry(rs);
if (runeSkillAdjusts.get(rune_id) == null) {
ArrayList<RuneSkillAdjustEntry> skillAdjustList = new ArrayList<>();
skillAdjustList.add(runeSkillAdjustEntry);
runeSkillAdjusts.put(rune_id, skillAdjustList);
} else {
ArrayList<RuneSkillAdjustEntry> powerList = runeSkillAdjusts.get(rune_id);
powerList.add(runeSkillAdjustEntry);
runeSkillAdjusts.put(rune_id, powerList);
}
}
} catch (SQLException e) {
Logger.error(e);
return runeSkillAdjusts;
}
Logger.info("read: " + recordsRead + " cached: " + runeSkillAdjusts.size());
return runeSkillAdjusts;
}
public void GET_RUNE_REQS(final RuneBase rb) {
try (Connection connection = DbManager.getConnection();

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

@ -9,6 +9,7 @@ @@ -9,6 +9,7 @@
package engine.devcmd.cmds;
import engine.Enum;
import engine.Enum.GameObjectType;
import engine.devcmd.AbstractDevCmd;
import engine.gameManager.ChatManager;
@ -43,7 +44,7 @@ public class AddMobCmd extends AbstractDevCmd { @@ -43,7 +44,7 @@ public class AddMobCmd extends AbstractDevCmd {
MobBase mb = (MobBase) mobbaseAGO;
int loadID = mb.getObjectUUID();
Mob mob = Mob.createMob(loadID, Vector3fImmutable.getRandomPointInCircle(pc.getLoc(), 100),
null, true, zone, null, 0, "", 1);
null, zone, null, null, "", 1, Enum.AIAgentType.MOBILE);
if (mob != null) {
mob.updateDatabase();
this.setResult(String.valueOf(mob.getDBID()));
@ -84,7 +85,7 @@ public class AddMobCmd extends AbstractDevCmd { @@ -84,7 +85,7 @@ public class AddMobCmd extends AbstractDevCmd {
Mob mob = Mob.createMob(loadID, pc.getLoc(),
null, true, zone, null, 0, "", 1);
null, zone, null, null, "", 1, Enum.AIAgentType.MOBILE);
if (mob != null) {
mob.updateDatabase();
ChatManager.chatSayInfo(pc,

70
src/engine/devcmd/cmds/AuditHeightMapCmd.java

@ -1,70 +0,0 @@ @@ -1,70 +0,0 @@
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
package engine.devcmd.cmds;
import engine.InterestManagement.HeightMap;
import engine.devcmd.AbstractDevCmd;
import engine.gameManager.ZoneManager;
import engine.math.Vector2f;
import engine.math.Vector3fImmutable;
import engine.objects.AbstractGameObject;
import engine.objects.PlayerCharacter;
import engine.objects.Zone;
public class AuditHeightMapCmd extends AbstractDevCmd {
public AuditHeightMapCmd() {
super("auditheightmap");
}
@Override
protected void _doCmd(PlayerCharacter pcSender, String[] words,
AbstractGameObject target) {
int count = Integer.parseInt(words[0]);
long start = System.currentTimeMillis();
for (int i = 0; i < count; i++) {
Zone currentZone = ZoneManager.findSmallestZone(pcSender.getLoc());
Vector3fImmutable currentLoc = Vector3fImmutable.getRandomPointInCircle(currentZone.getLoc(), currentZone.getBounds().getHalfExtents().x < currentZone.getBounds().getHalfExtents().y ? currentZone.getBounds().getHalfExtents().x : currentZone.getBounds().getHalfExtents().y);
Vector2f zoneLoc = ZoneManager.worldToZoneSpace(currentLoc, currentZone);
if (currentZone != null && currentZone.getHeightMap() != null) {
float altitude = currentZone.getHeightMap().getInterpolatedTerrainHeight(zoneLoc);
float outsetAltitude = HeightMap.getOutsetHeight(altitude, currentZone, pcSender.getLoc());
}
}
long end = System.currentTimeMillis();
long delta = end - start;
this.throwbackInfo(pcSender, "Audit Heightmap took " + delta + " ms to run " + count + " times!");
}
@Override
protected String _getUsageString() {
return "' /auditmobs [zone.UUID]'";
}
@Override
protected String _getHelpString() {
return "Audits all the mobs in a zone.";
}
}

226
src/engine/devcmd/cmds/GetHeightCmd.java

@ -13,7 +13,6 @@ import engine.InterestManagement.HeightMap; @@ -13,7 +13,6 @@ import engine.InterestManagement.HeightMap;
import engine.devcmd.AbstractDevCmd;
import engine.gameManager.ZoneManager;
import engine.math.Vector2f;
import engine.math.Vector3fImmutable;
import engine.objects.AbstractGameObject;
import engine.objects.PlayerCharacter;
import engine.objects.Zone;
@ -22,205 +21,58 @@ public class GetHeightCmd extends AbstractDevCmd { @@ -22,205 +21,58 @@ public class GetHeightCmd extends AbstractDevCmd {
public GetHeightCmd() {
super("getHeight");
this.addCmdString("height");
}
@Override
protected void _doCmd(PlayerCharacter pc, String[] words,
protected void _doCmd(PlayerCharacter playerCharacter, String[] words,
AbstractGameObject target) {
boolean end = true;
float height = HeightMap.getWorldHeight(pc);
this.throwbackInfo(pc, "Altitude : " + height);
this.throwbackInfo(pc, "Character Height: " + pc.getCharacterHeight());
this.throwbackInfo(pc, "Character Height to start swimming: " + pc.centerHeight);
Zone zone = ZoneManager.findSmallestZone(pc.getLoc());
this.throwbackInfo(pc, "Water Level : " + zone.getSeaLevel());
this.throwbackInfo(pc, "Character Water Level Above : " + (pc.getCharacterHeight() + height - zone.getSeaLevel()));
if (end)
return;
Vector2f gridSquare;
Vector2f gridOffset;
Vector2f parentGrid;
Vector2f parentLoc = new Vector2f(-1, -1);
Zone currentZone = ZoneManager.findSmallestZone(pc.getLoc());
if (currentZone == null)
return;
Zone parentZone = currentZone.getParent();
HeightMap heightMap = currentZone.getHeightMap();
//find the next parents heightmap if the currentzone heightmap is null.
while (heightMap == null) {
if (currentZone == ZoneManager.getSeaFloor()) {
this.throwbackInfo(pc, "Could not find a heightmap to get height.");
break;
}
this.throwbackError(pc, "Heightmap does not exist for " + currentZone.getName());
this.throwbackInfo(pc, "Using parent zone instead: ");
currentZone = currentZone.getParent();
heightMap = currentZone.getHeightMap();
}
if ((heightMap == null) || (currentZone == ZoneManager.getSeaFloor())) {
this.throwbackInfo(pc, currentZone.getName() + " has no heightmap ");
this.throwbackInfo(pc, "Current altitude: " + currentZone.absY);
return;
}
Vector2f zoneLoc = ZoneManager.worldToZoneSpace(pc.getLoc(), currentZone);
Vector3fImmutable seaFloorLocalLoc = ZoneManager.worldToLocal(pc.getLoc(), ZoneManager.getSeaFloor());
this.throwbackInfo(pc, "SeaFloor Local : " + seaFloorLocalLoc.x + " , " + seaFloorLocalLoc.y);
this.throwbackInfo(pc, "Local Zone Location : " + zoneLoc.x + " , " + zoneLoc.y);
Vector3fImmutable localLocFromCenter = ZoneManager.worldToLocal(pc.getLoc(), currentZone);
Vector3fImmutable parentLocFromCenter = ZoneManager.worldToLocal(pc.getLoc(), currentZone.getParent());
this.throwbackInfo(pc, "Local Zone Location from center : " + localLocFromCenter);
this.throwbackInfo(pc, "parent Zone Location from center : " + parentLocFromCenter);
Vector2f parentZoneLoc = ZoneManager.worldToZoneSpace(pc.getLoc(), currentZone.getParent());
this.throwbackInfo(pc, "Parent Zone Location from Bottom Left : " + parentZoneLoc);
if ((parentZone != null) && (parentZone.getHeightMap() != null)) {
parentLoc = ZoneManager.worldToZoneSpace(pc.getLoc(), parentZone);
parentGrid = parentZone.getHeightMap().getGridSquare(parentLoc);
} else
parentGrid = new Vector2f(-1, -1);
gridSquare = heightMap.getGridSquare(zoneLoc);
gridOffset = HeightMap.getGridOffset(gridSquare);
float interaltitude = currentZone.getHeightMap().getInterpolatedTerrainHeight(zoneLoc);
this.throwbackInfo(pc, currentZone.getName());
this.throwbackInfo(pc, "Current Grid Square: " + gridSquare.x + " , " + gridSquare.y);
this.throwbackInfo(pc, "Grid Offset: " + gridOffset.x + " , " + gridOffset.y);
this.throwbackInfo(pc, "Parent Grid: " + parentGrid.x + " , " + parentGrid.y);
if (parentGrid.x != -1) {
float parentAltitude = parentZone.getHeightMap().getInterpolatedTerrainHeight(parentLoc);
this.throwbackInfo(pc, "Parent ALTITUDE: " + (parentAltitude));
this.throwbackInfo(pc, "Parent Interpolation: " + (parentAltitude + parentZone.getWorldAltitude()));
}
this.throwbackInfo(pc, "interpolated height: " + interaltitude);
this.throwbackInfo(pc, "interpolated height with World: " + (interaltitude + currentZone.getWorldAltitude()));
float realWorldAltitude = interaltitude + currentZone.getWorldAltitude();
//OUTSET
if (parentZone != null) {
float parentXRadius = currentZone.getBounds().getHalfExtents().x;
float parentZRadius = currentZone.getBounds().getHalfExtents().y;
float offsetX = Math.abs((localLocFromCenter.x / parentXRadius));
float offsetZ = Math.abs((localLocFromCenter.z / parentZRadius));
float bucketScaleX = 100 / parentXRadius;
float bucketScaleZ = 200 / parentZRadius;
float outsideGridSizeX = 1 - bucketScaleX; //32/256
float outsideGridSizeZ = 1 - bucketScaleZ;
float weight;
double scale;
if (offsetX > outsideGridSizeX && offsetX > offsetZ) {
weight = (offsetX - outsideGridSizeX) / bucketScaleX;
scale = Math.atan2((.5 - weight) * 3.1415927, 1);
float scaleChild = (float) ((scale + 1) * .5);
float scaleParent = 1 - scaleChild;
float parentAltitude = parentZone.getHeightMap().getInterpolatedTerrainHeight(parentLoc);
float parentCenterAltitude = parentZone.getHeightMap().getInterpolatedTerrainHeight(ZoneManager.worldToZoneSpace(currentZone.getLoc(), parentZone));
parentCenterAltitude += currentZone.getYCoord();
parentCenterAltitude += interaltitude;
float firstScale = parentAltitude * scaleParent;
float secondScale = parentCenterAltitude * scaleChild;
float outsetALt = firstScale + secondScale;
outsetALt += currentZone.getParent().getAbsY();
realWorldAltitude = outsetALt;
} else if (offsetZ > outsideGridSizeZ) {
weight = (offsetZ - outsideGridSizeZ) / bucketScaleZ;
scale = Math.atan2((.5 - weight) * 3.1415927, 1);
float scaleChild = (float) ((scale + 1) * .5);
float scaleParent = 1 - scaleChild;
float parentAltitude = parentZone.getHeightMap().getInterpolatedTerrainHeight(parentLoc);
float parentCenterAltitude = parentZone.getHeightMap().getInterpolatedTerrainHeight(ZoneManager.worldToZoneSpace(currentZone.getLoc(), parentZone));
parentCenterAltitude += currentZone.getYCoord();
parentCenterAltitude += interaltitude;
float firstScale = parentAltitude * scaleParent;
float secondScale = parentCenterAltitude * scaleChild;
float outsetALt = firstScale + secondScale;
outsetALt += currentZone.getParent().getAbsY();
realWorldAltitude = outsetALt;
}
}
float strMod = pc.statStrBase - 40;
strMod *= .00999999998f;
strMod += 1f;
float radius = 0;
switch (pc.getRaceID()) {
case 2017:
radius = 3.1415927f;
case 2000:
}
strMod *= 1.5707964f;
strMod += 3.1415927f;
strMod -= .5f;
realWorldAltitude += strMod;
this.throwbackInfo(pc, "interpolated height with World: " + realWorldAltitude);
Zone currentZone;
Zone parentZone;
Zone heightmapZone;
currentZone = ZoneManager.findSmallestZone(playerCharacter.getLoc());
heightmapZone = HeightMap.getNextZoneWithTerrain(currentZone);
parentZone = HeightMap.getNextZoneWithTerrain(currentZone.getParent());
float currentHeight = HeightMap.getWorldHeight(currentZone, playerCharacter.getLoc());
float parentHeight = HeightMap.getWorldHeight(parentZone, playerCharacter.getLoc());
Vector2f zoneLoc = ZoneManager.worldToZoneSpace(playerCharacter.getLoc(), heightmapZone);
Vector2f gridSquare = heightmapZone.getHeightMap().getGridSquare(zoneLoc);
this.throwbackInfo(playerCharacter, "Current Zone : " + currentZone.getName());
this.throwbackInfo(playerCharacter, "Heightmap Zone : " + heightmapZone.getName());
this.throwbackInfo(playerCharacter, "Zone Height: " + heightmapZone.worldAltitude);
this.throwbackInfo(playerCharacter, "Sea Level: " + heightmapZone.getSeaLevel());
this.throwbackInfo(playerCharacter, "Grid : " + (int) gridSquare.x + "x" + (int) gridSquare.y);
this.throwbackInfo(playerCharacter, "*** 256: " + currentHeight);
this.throwbackInfo(playerCharacter, "***Adjusted Height: " + (currentHeight + playerCharacter.getCharacterHeight()));
HeightMap.SCALEVALUE = 1f / 255f;
currentHeight = HeightMap.getWorldHeight(currentZone, playerCharacter.getLoc());
HeightMap.SCALEVALUE = 1f / 256f;
this.throwbackInfo(playerCharacter, "***255 Adjusted: " + (currentHeight + playerCharacter.getCharacterHeight()));
this.throwbackInfo(playerCharacter, "Drowning Height: " + (heightmapZone.getSeaLevel() + playerCharacter.getCharacterHeight()));
this.throwbackInfo(playerCharacter, "------------");
this.throwbackInfo(playerCharacter, "Parent : " + parentZone.getName());
this.throwbackInfo(playerCharacter, "Height returned : " + parentHeight);
this.throwbackInfo(playerCharacter, "[" + (gridSquare.x) + "][" + (gridSquare.y) + "]");
this.throwbackInfo(playerCharacter, "[" + (gridSquare.x + 1) + "][" + (gridSquare.y) + "]");
this.throwbackInfo(playerCharacter, "[" + (gridSquare.x) + "][" + (gridSquare.y + 1) + "]");
this.throwbackInfo(playerCharacter, "[" + (gridSquare.x + 1) + "][" + (gridSquare.y + 1) + "]");
}
@Override
protected String _getHelpString() {
return "Temporarily Changes SubRace";
return "Queries heightmap engine";
}
@Override
protected String _getUsageString() {
return "' /subrace mobBaseID";
return "' /getheight";
}
}

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

@ -440,7 +440,9 @@ public class InfoCmd extends AbstractDevCmd { @@ -440,7 +440,9 @@ public class InfoCmd extends AbstractDevCmd {
output += "isSummonedPet: true";
else
output += "isSummonedPet: false";
PlayerCharacter owner = targetMob.getOwner();
PlayerCharacter owner = (PlayerCharacter) targetMob.guardCaptain;
if (owner != null)
output += " owner: " + owner.getObjectUUID();
output += newline;

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

@ -0,0 +1,67 @@ @@ -0,0 +1,67 @@
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
package engine.devcmd.cmds;
import engine.devcmd.AbstractDevCmd;
import engine.objects.*;
import java.util.HashMap;
/**
*
*/
public class PrintEffectsCmd extends AbstractDevCmd {
public PrintEffectsCmd() {
super("printeffects");
// super("printstats", MBServerStatics.ACCESS_LEVEL_ADMIN);
}
public static ItemBase getWeaponBase(int slot, HashMap<Integer, MobEquipment> equip) {
if (equip.containsKey(slot)) {
MobEquipment item = equip.get(slot);
if (item != null && item.getItemBase() != null) {
return item.getItemBase();
}
}
return null;
}
@Override
protected void _doCmd(PlayerCharacter pc, String[] words,
AbstractGameObject target) {
AbstractCharacter tar;
if (target != null && target instanceof AbstractCharacter) {
tar = (AbstractCharacter) target;
String newline = "\r\n ";
String output = "Effects For Character: " + tar.getName() + newline;
for(String effect : tar.effects.keySet()){
output += effect + newline;
}
throwbackInfo(pc, output);
}
}
@Override
protected String _getHelpString() {
return "Returns the player's current stats";
}
@Override
protected String _getUsageString() {
return "' /printstats'";
}
}

67
src/engine/devcmd/cmds/PrintRunesCmd.java

@ -0,0 +1,67 @@ @@ -0,0 +1,67 @@
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
package engine.devcmd.cmds;
import engine.devcmd.AbstractDevCmd;
import engine.objects.*;
import java.util.HashMap;
/**
*
*/
public class PrintRunesCmd extends AbstractDevCmd {
public PrintRunesCmd() {
super("printrunes");
// super("printstats", MBServerStatics.ACCESS_LEVEL_ADMIN);
}
public static ItemBase getWeaponBase(int slot, HashMap<Integer, MobEquipment> equip) {
if (equip.containsKey(slot)) {
MobEquipment item = equip.get(slot);
if (item != null && item.getItemBase() != null) {
return item.getItemBase();
}
}
return null;
}
@Override
protected void _doCmd(PlayerCharacter pc, String[] words,
AbstractGameObject target) {
AbstractCharacter tar;
if (target != null && target instanceof AbstractCharacter) {
tar = (AbstractCharacter) target;
String newline = "\r\n ";
String output = "Applied Runes For Character: " + ((AbstractCharacter) target).getName() + newline;
for(CharacterRune rune : ((AbstractCharacter)target).runes){
output += rune.getRuneBaseID() + " " + rune.getRuneBase().getName() + newline;
}
throwbackInfo(pc, output);
}
}
@Override
protected String _getHelpString() {
return "Returns the player's current stats";
}
@Override
protected String _getUsageString() {
return "' /printstats'";
}
}

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

@ -103,15 +103,19 @@ public class PrintStatsCmd extends AbstractDevCmd { @@ -103,15 +103,19 @@ public class PrintStatsCmd extends AbstractDevCmd {
main = getWeaponBase(1, equip);
ItemBase off = null;
if (equip != null)
getWeaponBase(2, equip);
if (main == null && off == null) {
out += "Main Hand: atr: " + tar.getAtrHandOne() + ", damage: " + tar.getMinDamageHandOne() + " to " + tar.getMaxDamageHandOne() + ", speed: " + tar.getSpeedHandOne() + ", range: 6" + newline;
} else {
if (main != null)
out += "Main Hand: atr: " + tar.getAtrHandOne() + ", damage: " + tar.getMinDamageHandOne() + " to " + tar.getMaxDamageHandOne() + ", speed: " + tar.getSpeedHandOne() + ", range: " + main.getRange() + newline;
if (off != null)
out += "Main Hand: atr: " + tar.getAtrHandTwo() + ", damage: " + tar.getMinDamageHandTwo() + " to " + tar.getMaxDamageHandTwo() + ", speed: " + tar.getSpeedHandTwo() + ", range: " + off.getRange() + newline;
if(equip != null){
if(equip.get(2) != null && !equip.get(2).getItemBase().isShield()){
//off hand weapon
out += "Attack Rating: " + tar.atrHandTwo + newline;
out += "Damage: " + tar.minDamageHandTwo + " - " + tar.maxDamageHandTwo + newline;
out += "Range: " + tar.rangeHandTwo + newline;
out += "Attack Speed: " + tar.speedHandTwo + newline;
} else{
out += "Attack Rating: " + tar.atrHandOne + newline;
out += "Damage: " + tar.minDamageHandOne + " - " + tar.maxDamageHandOne + newline;
out += "Range: " + tar.rangeHandOne + newline;
out += "Attack Speed: " + tar.speedHandOne + newline;
}
}
out += "isAlive: " + tar.isAlive() + ", Combat: " + tar.isCombat() + newline;

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

@ -59,22 +59,25 @@ public class PurgeObjectsCmd extends AbstractDevCmd { @@ -59,22 +59,25 @@ public class PurgeObjectsCmd extends AbstractDevCmd {
if (npc != null) {
for (Mob mob : npc.getSiegeMinionMap().keySet()) {
for (Integer minionUUID : npc.minions) {
Mob mob = Mob.getMob(minionUUID);
WorldGrid.RemoveWorldObject(mob);
WorldGrid.removeObject(mob, pc);
//Mob.getRespawnMap().remove(mob);
if (mob.getParentZone() != null)
mob.getParentZone().zoneMobSet.remove(mob);
}
DbManager.NPCQueries.DELETE_NPC(npc);
DbManager.removeFromCache(GameObjectType.NPC,
npc.getObjectUUID());
WorldGrid.RemoveWorldObject(npc);
} else if (mobA != null) {
for (Mob mob : mobA.getSiegeMinionMap().keySet()) {
for (Integer minionUUID : mobA.minions) {
Mob mob = Mob.getMob(minionUUID);
WorldGrid.RemoveWorldObject(mob);
WorldGrid.removeObject(mob, pc);
//Mob.getRespawnMap().remove(mob);
if (mob.getParentZone() != null)
mob.getParentZone().zoneMobSet.remove(mob);
}
@ -151,10 +154,11 @@ public class PurgeObjectsCmd extends AbstractDevCmd { @@ -151,10 +154,11 @@ public class PurgeObjectsCmd extends AbstractDevCmd {
if (npc != null) {
for (Mob mob : npc.getSiegeMinionMap().keySet()) {
for (Integer minionUUID : npc.minions) {
Mob mob = Mob.getMob(minionUUID);
WorldGrid.RemoveWorldObject(mob);
WorldGrid.removeObject(mob, pc);
//Mob.getRespawnMap().remove(mob);
if (mob.getParentZone() != null)
mob.getParentZone().zoneMobSet.remove(mob);
}
@ -163,10 +167,11 @@ public class PurgeObjectsCmd extends AbstractDevCmd { @@ -163,10 +167,11 @@ public class PurgeObjectsCmd extends AbstractDevCmd {
npc.getObjectUUID());
WorldGrid.RemoveWorldObject(npc);
} else if (mobA != null) {
for (Mob mob : mobA.getSiegeMinionMap().keySet()) {
for (Integer minionUUID : mobA.minions) {
Mob mob = Mob.getMob(minionUUID);
WorldGrid.RemoveWorldObject(mob);
WorldGrid.removeObject(mob, pc);
//Mob.getRespawnMap().remove(mob);
if (mob.getParentZone() != null)
mob.getParentZone().zoneMobSet.remove(mob);
}

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

@ -9,9 +9,9 @@ @@ -9,9 +9,9 @@
package engine.devcmd.cmds;
import engine.Enum;
import engine.devcmd.AbstractDevCmd;
import engine.objects.AbstractGameObject;
import engine.objects.PlayerCharacter;
import engine.objects.*;
import java.lang.reflect.Field;
@ -25,42 +25,17 @@ public class RegionCmd extends AbstractDevCmd { @@ -25,42 +25,17 @@ public class RegionCmd extends AbstractDevCmd {
protected void _doCmd(PlayerCharacter pc, String[] words,
AbstractGameObject target) {
if (pc.region == null) {
Regions region = ((AbstractCharacter)target).region;
if (region == null) {
this.throwbackInfo(pc, "No Region Found.");
return;
}
String newLine = System.getProperty("line.separator");
String result = "";
result += (pc.region.getClass().getSimpleName());
result += (" {");
result += (newLine);
Field[] fields = pc.region.getClass().getDeclaredFields();
//print field names paired with their values
for (Field field : fields) {
field.setAccessible(true);
result += (" ");
try {
if (field.getName().contains("Furniture"))
continue;
result += (field.getName());
result += (": ");
//requires access to private field:
result += (field.get(pc.region).toString());
} catch (IllegalAccessException ex) {
System.out.println(ex);
}
result.trim();
result += (newLine);
if(region != null) {
this.throwbackInfo(pc, "Region Info: " + ((AbstractCharacter) target).getName());
this.throwbackInfo(pc, "Region Name: " + region);
this.throwbackInfo(pc, "Region Height: " + region.lerpY((AbstractCharacter)target));
}
result += ("}");
this.throwbackInfo(pc, result.toString());
}

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

@ -11,7 +11,6 @@ package engine.devcmd.cmds; @@ -11,7 +11,6 @@ package engine.devcmd.cmds;
import engine.Enum.BuildingGroup;
import engine.Enum.DbObjectType;
import engine.Enum.GameObjectType;
import engine.InterestManagement.WorldGrid;
import engine.devcmd.AbstractDevCmd;
import engine.gameManager.BuildingManager;
@ -138,49 +137,16 @@ public class RemoveObjectCmd extends AbstractDevCmd { @@ -138,49 +137,16 @@ public class RemoveObjectCmd extends AbstractDevCmd {
Warehouse.warehouseByBuildingUUID.remove(building.getObjectUUID());
}
//remove cached shrines.
if ((building.getBlueprintUUID() != 0)
&& (building.getBlueprint().getBuildingGroup() == BuildingGroup.SHRINE))
Shrine.RemoveShrineFromCacheByBuilding(building);
for (AbstractCharacter ac : building.getHirelings().keySet()) {
NPC npc = null;
Mob mobA = null;
if (ac.getObjectType() == GameObjectType.NPC)
npc = (NPC) ac;
else if (ac.getObjectType() == GameObjectType.Mob)
mobA = (Mob) ac;
if (npc != null) {
for (Mob mob : npc.getSiegeMinionMap().keySet()) {
WorldGrid.RemoveWorldObject(mob);
WorldGrid.removeObject(mob, pc);
//Mob.getRespawnMap().remove(mob);
if (mob.getParentZone() != null)
mob.getParentZone().zoneMobSet.remove(mob);
}
DbManager.NPCQueries.DELETE_NPC(npc);
DbManager.removeFromCache(npc);
WorldGrid.RemoveWorldObject(npc);
WorldGrid.removeObject(npc, pc);
} else if (mobA != null) {
for (Mob mob : mobA.getSiegeMinionMap().keySet()) {
WorldGrid.RemoveWorldObject(mob);
WorldGrid.removeObject(mob, pc);
//Mob.getRespawnMap().remove(mob);
if (mob.getParentZone() != null)
mob.getParentZone().zoneMobSet.remove(mob);
}
DbManager.MobQueries.DELETE_MOB(mobA);
DbManager.removeFromCache(mobA);
WorldGrid.RemoveWorldObject(mobA);
WorldGrid.removeObject(mobA, pc);
}
// Remove hirelings for this building
for (AbstractCharacter abstractCharacter : building.getHirelings().keySet())
BuildingManager.removeHireling(building, abstractCharacter);
}
Zone zone = building.getParentZone();
DbManager.BuildingQueries.DELETE_FROM_DATABASE(building);
DbManager.removeFromCache(building);
@ -209,11 +175,13 @@ public class RemoveObjectCmd extends AbstractDevCmd { @@ -209,11 +175,13 @@ public class RemoveObjectCmd extends AbstractDevCmd {
if (npc.building != null)
npc.building.getHirelings().remove(npc);
for (Mob mob : npc.getSiegeMinionMap().keySet()) {
WorldGrid.RemoveWorldObject(mob);
WorldGrid.removeObject(mob, pc);
if (mob.getParentZone() != null)
mob.getParentZone().zoneMobSet.remove(mob);
for (Integer minionUUID : npc.minions) {
Mob minionMob = Mob.getMob(minionUUID);
WorldGrid.RemoveWorldObject(minionMob);
WorldGrid.removeObject(minionMob, pc);
if (minionMob.getParentZone() != null)
minionMob.getParentZone().zoneMobSet.remove(minionMob);
}
DbManager.NPCQueries.DELETE_NPC(npc);

43
src/engine/devcmd/cmds/SeaAuditCmd.java

@ -0,0 +1,43 @@ @@ -0,0 +1,43 @@
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
package engine.devcmd.cmds;
import engine.devcmd.AbstractDevCmd;
import engine.gameManager.ZoneManager;
import engine.objects.AbstractGameObject;
import engine.objects.PlayerCharacter;
import engine.objects.Zone;
public class SeaAuditCmd extends AbstractDevCmd {
public SeaAuditCmd() {
super("seaaudit");
}
@Override
protected void _doCmd(PlayerCharacter playerCharacter, String[] words,
AbstractGameObject target) {
for (Zone zone : ZoneManager.getAllZones())
if (zone.getSeaLevel() > zone.worldAltitude)
this.throwbackInfo(playerCharacter, zone.getObjectUUID() + zone.getName());
}
@Override
protected String _getHelpString() {
return "Queries heightmap engine";
}
@Override
protected String _getUsageString() {
return "' /getheight";
}
}

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

@ -159,7 +159,7 @@ public class SetSubRaceCmd extends AbstractDevCmd { @@ -159,7 +159,7 @@ public class SetSubRaceCmd extends AbstractDevCmd {
// pum.setEffectID(token);
// pum.setSourceType(pc.getObjectType().ordinal());
// pum.setSourceID(pc.getObjectUUID());
// pum.setTargetType(pc.getObjectType().ordinal());
// pum.setStartLocType(pc.getObjectType().ordinal());
// pum.setTargetID(pc.getObjectUUID());
// pum.setNumTrains(40);
// pum.setDuration(-1);

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

@ -1,5 +1,6 @@ @@ -1,5 +1,6 @@
package engine.devcmd.cmds;
import engine.Enum;
import engine.devcmd.AbstractDevCmd;
import engine.gameManager.ZoneManager;
import engine.math.Vector3fImmutable;
@ -110,7 +111,7 @@ public class SplatMobCmd extends AbstractDevCmd { @@ -110,7 +111,7 @@ public class SplatMobCmd extends AbstractDevCmd {
mobile = Mob.createMob(_mobileUUID,
Vector3fImmutable.getRandomPointInCircle(_currentLocation, _targetRange),
null, true, serverZone, null, 0, "", 1);
null, serverZone, null, null, "", 1, Enum.AIAgentType.MOBILE);
if (mobile != null) {
mobile.updateDatabase();

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

@ -104,7 +104,7 @@ public class ZoneInfoCmd extends AbstractDevCmd { @@ -104,7 +104,7 @@ public class ZoneInfoCmd extends AbstractDevCmd {
output += newline;
output += "Sea Level = " + zone.getSeaLevel();
output += newline;
output += "World Altitude = " + zone.getWorldAltitude();
output += "World Altitude = " + zone.worldAltitude;
throwbackInfo(player, output);
City city = ZoneManager.getCityAtLocation(player.getLoc());

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

@ -9,12 +9,17 @@ @@ -9,12 +9,17 @@
package engine.devcmd.cmds;
import engine.Enum;
import engine.Enum.GameObjectType;
import engine.devcmd.AbstractDevCmd;
import engine.gameManager.PowersManager;
import engine.mobileAI.MobAI;
import engine.objects.AbstractGameObject;
import engine.objects.Mob;
import engine.objects.PlayerCharacter;
import engine.powers.RunePowerEntry;
import java.util.ArrayList;
import java.util.Map;
@ -56,36 +61,95 @@ public class aiInfoCmd extends AbstractDevCmd { @@ -56,36 +61,95 @@ public class aiInfoCmd extends AbstractDevCmd {
Mob mob = (Mob) target;
output = "Mob AI Information:" + newline;
output += mob.getName() + newline;
if (mob.BehaviourType != null) {
output += "BehaviourType: " + mob.BehaviourType.toString() + newline;
if (mob.BehaviourType.BehaviourHelperType != null) {
output += "Behaviour Helper Type: " + mob.BehaviourType.BehaviourHelperType.toString() + newline;
output += mob.agentType.toString() + newline;
int contractID = 0;
if (mob.isPlayerGuard() == true) {
if (mob.agentType.equals(Enum.AIAgentType.GUARDMINION))
contractID = mob.guardCaptain.contract.getContractID();
else
contractID = mob.contract.getContractID();
}
if (contractID != 0) {
if (mob.agentType.equals(Enum.AIAgentType.GUARDMINION)) {
output += "Captain Contract: " + contractID + newline;
output += "Captain UUID: " + mob.guardCaptain.getObjectUUID() + newline;
} else
output += "Contract: " + contractID + newline;
}
if (mob.behaviourType != null) {
output += "BehaviourType: " + mob.behaviourType.toString() + newline;
if (mob.behaviourType.BehaviourHelperType != null) {
output += "Behaviour Helper Type: " + mob.behaviourType.BehaviourHelperType.toString() + newline;
} else {
output += "Behaviour Helper Type: NULL" + newline;
}
output += "Wimpy: " + mob.BehaviourType.isWimpy + newline;
output += "Agressive: " + mob.BehaviourType.isAgressive + newline;
output += "Can Roam: " + mob.BehaviourType.canRoam + newline;
output += "Calls For Help: " + mob.BehaviourType.callsForHelp + newline;
output += "Responds To Call For Help: " + mob.BehaviourType.respondsToCallForHelp + newline;
} else {
output += "BehaviourType: NULL" + newline;
}
output += "Wimpy: " + mob.behaviourType.isWimpy + newline;
output += "Agressive: " + mob.behaviourType.isAgressive + newline;
output += "Can Roam: " + mob.behaviourType.canRoam + newline;
output += "Calls For Help: " + mob.behaviourType.callsForHelp + newline;
output += "Responds To Call For Help: " + mob.behaviourType.respondsToCallForHelp + newline;
} else {
output += "BehaviourType: NULL" + newline;
}
output += "Aggro Range: " + mob.getAggroRange() + newline;
output += "Player Aggro Map Size: " + mob.playerAgroMap.size() + newline;
if (mob.playerAgroMap.size() > 0) {
output += "Players Loaded:" + newline;
}
for (Map.Entry<Integer, Boolean> entry : mob.playerAgroMap.entrySet()) {
output += "Player ID: " + entry.getKey() + " Hate Value: " + (PlayerCharacter.getPlayerCharacter(entry.getKey())).getHateValue() + newline;
for (Map.Entry<Integer, Float> entry : mob.playerAgroMap.entrySet()) {
output += "Player ID: " + entry.getKey() + " Hate Value: " + entry.getValue() + newline;
}
if (mob.getCombatTarget() != null)
output += "Current Target: " + mob.getCombatTarget().getName() + newline;
else
output += "Current Target: NULL" + newline;
for (int token : mob.mobPowers.keySet())
output += token + newline;
if (mob.guardedCity != null)
output += "Patrolling: " + mob.guardedCity.getCityName() + newline;
output += "See Invis Level: " + mob.mobBase.getSeeInvis() + newline;
output += "Can Cast: " + MobAI.canCast(mob) + newline;
output += "Powers:" + newline;
ArrayList<RunePowerEntry> powerEntries = new ArrayList<>(PowersManager.getPowersForRune(mob.getMobBaseID()));
// Additional powers may come from the contract ID. This is to support
// powers for player guards irrespective of the mobbase used.
if (mob.isPlayerGuard()) {
ArrayList<RunePowerEntry> contractEntries = new ArrayList<>();
if (mob.contract != null)
contractEntries = new ArrayList<>(PowersManager.getPowersForRune(mob.contractUUID));
if (mob.agentType.equals(Enum.AIAgentType.GUARDMINION))
contractEntries = new ArrayList<>(PowersManager.getPowersForRune(mob.guardCaptain.contractUUID));
powerEntries.addAll(contractEntries);
}
for (RunePowerEntry runePowerEntry : powerEntries)
output += PowersManager.getPowerByToken(runePowerEntry.token).getName() + newline;
// List outlaws defined for this player guard's city
if (mob.isPlayerGuard()) {
ArrayList<Integer> outlaws = new ArrayList(mob.guardedCity.cityOutlaws);
if (outlaws.isEmpty() == false)
output += "Outlaws: " + newline;
for (Integer outlawUUID : outlaws)
output += outlawUUID + newline;
}
throwbackInfo(playerCharacter, output);
}

140
src/engine/gameManager/BuildingManager.java

@ -308,6 +308,72 @@ public enum BuildingManager { @@ -308,6 +308,72 @@ public enum BuildingManager {
}
public static void removeHireling(Building building, AbstractCharacter hireling) {
if (hireling.getObjectType().equals(GameObjectType.Mob)) {
Mob guardCaptain = (Mob) hireling;
// Clear minions from database if a guard captain
if (guardCaptain.agentType.equals(Enum.AIAgentType.GUARDCAPTAIN))
DbManager.MobQueries.REMOVE_ALL_MINIONS(hireling.getObjectUUID());
}
// Clear minions from world
for (Integer minionUUID : hireling.minions) {
Mob minionMob = Mob.getMob(minionUUID);
DbManager.removeFromCache(minionMob);
WorldGrid.RemoveWorldObject(minionMob);
WorldGrid.unloadObject(minionMob);
if (minionMob.getParentZone() != null)
minionMob.getParentZone().zoneMobSet.remove(minionMob);
}
// Remove hireling from building
building.getHirelings().remove(hireling);
// Remove from zone mob set
if (hireling.getObjectType().equals(GameObjectType.Mob)) {
Mob hirelingMob = (Mob) hireling;
if (hirelingMob.getParentZone() != null)
if (hirelingMob.getParentZone().zoneMobSet.contains(hirelingMob))
hirelingMob.getParentZone().zoneMobSet.remove(hireling);
}
if (hireling.getObjectType().equals(GameObjectType.NPC)) {
NPC hirelingNPC = (NPC) hireling;
if (hirelingNPC.getParentZone() != null)
if (hirelingNPC.getParentZone().zoneNPCSet.contains(hirelingNPC))
hirelingNPC.getParentZone().zoneNPCSet.remove(hireling);
}
// Unload hireling from world
DbManager.removeFromCache(hireling);
WorldGrid.RemoveWorldObject(hireling);
WorldGrid.removeObject(hireling);
// Delete hireling from database
if (hireling.getObjectType().equals(GameObjectType.Mob))
DbManager.MobQueries.DELETE_MOB((Mob) hireling);
else
DbManager.NPCQueries.DELETE_NPC((NPC) hireling);
}
public static void cleanupHirelings(Building building) {
// Early exit: Cannot have hirelings in a building
@ -320,42 +386,18 @@ public enum BuildingManager { @@ -320,42 +386,18 @@ public enum BuildingManager {
if (building.getRank() < 1) {
for (AbstractCharacter slottedNPC : building.getHirelings().keySet()) {
for (AbstractCharacter slottedNPC : building.getHirelings().keySet())
BuildingManager.removeHireling(building, slottedNPC);
if (slottedNPC.getObjectType() == Enum.GameObjectType.NPC)
((NPC) slottedNPC).remove();
else if (slottedNPC.getObjectType() == Enum.GameObjectType.Mob)
NPCManager.removeMobileFromBuilding(((Mob) slottedNPC), building);
}
return;
}
// Delete hireling if building has deranked.
for (AbstractCharacter hireling : building.getHirelings().keySet()) {
NPC npc = null;
Mob mob = null;
if (hireling.getObjectType() == Enum.GameObjectType.NPC)
npc = (NPC) hireling;
else if (hireling.getObjectType() == Enum.GameObjectType.Mob)
mob = (Mob) hireling;
for (AbstractCharacter hireling : building.getHirelings().keySet()) {
if (building.getHirelings().get(hireling) > building.getBlueprint().getSlotsForRank(building.getRank()))
if (npc != null) {
if (!npc.remove())
Logger.error("Failed to remove npc " + npc.getObjectUUID()
+ "from Building " + building.getObjectUUID());
else
building.getHirelings().remove(npc);
} else if (mob != null) {
if (!NPCManager.removeMobileFromBuilding(mob, building))
Logger.error("Failed to remove npc " + npc.getObjectUUID()
+ "from Building " + building.getObjectUUID());
else
building.getHirelings().remove(npc);
}
BuildingManager.removeHireling(building, hireling);
}
@ -530,41 +572,63 @@ public enum BuildingManager { @@ -530,41 +572,63 @@ public enum BuildingManager {
else
rank = 10;
Mob mob;
Mob mobile;
NPC npc;
if (NPC.ISWallArcher(contract)) {
mob = Mob.createMob(contract.getMobbaseID(), Vector3fImmutable.ZERO, contractOwner.getGuild(), true, zone, building, contract.getContractID(), pirateName, rank);
mobile = Mob.createMob(contract.getMobbaseID(), Vector3fImmutable.ZERO, contractOwner.getGuild(), zone, building, contract, pirateName, rank, Enum.AIAgentType.GUARDWALLARCHER);
if (mob == null)
if (mobile == null)
return false;
mob.setLoc(mob.getLoc());
// Configure AI and write new mobile to disk
mobile.behaviourType = Enum.MobBehaviourType.GuardWallArcher;
mobile = DbManager.MobQueries.PERSIST(mobile);
// Spawn new mobile
mobile.setLoc(mobile.getLoc());
return true;
}
if (NPC.ISGuardCaptain(contract.getContractID())) {
mob = Mob.createMob(contract.getMobbaseID(), Vector3fImmutable.ZERO, contractOwner.getGuild(), true, zone, building, contract.getContractID(), pirateName, rank);
mobile = Mob.createMob(contract.getMobbaseID(), Vector3fImmutable.ZERO, contractOwner.getGuild(), zone, building, contract, pirateName, rank, Enum.AIAgentType.GUARDCAPTAIN);
if (mob == null)
if (mobile == null)
return false;
mob.setLoc(mob.getLoc());
// Configure AI and write new mobile to disk
mobile.behaviourType = Enum.MobBehaviourType.GuardCaptain;
mobile = DbManager.MobQueries.PERSIST(mobile);
// Spawn new mobile
mobile.setLoc(mobile.getLoc());
return true;
}
if (contract.getContractID() == 910) {
//guard dog
mob = Mob.createMob(contract.getMobbaseID(), Vector3fImmutable.ZERO, contractOwner.getGuild(), true, zone, building, contract.getContractID(), pirateName, rank);
mobile = Mob.createMob(contract.getMobbaseID(), Vector3fImmutable.ZERO, contractOwner.getGuild(), zone, building, contract, pirateName, rank, Enum.AIAgentType.GUARDCAPTAIN);
if (mob == null)
if (mobile == null)
return false;
mob.setLoc(mob.getLoc());
// Configure AI and write new mobile to disk
mobile.behaviourType = Enum.MobBehaviourType.GuardCaptain;
mobile = DbManager.MobQueries.PERSIST(mobile);
// Spawn new mobile
mobile.setLoc(mobile.getLoc());
return true;
}

2
src/engine/gameManager/ChatManager.java

@ -788,7 +788,7 @@ public enum ChatManager { @@ -788,7 +788,7 @@ public enum ChatManager {
it.remove();
else {
PlayerCharacter pcc = (PlayerCharacter) awo;
if (pcc.getSeeInvis() < pc.getHidden())
if (pcc.getSeeInvis() < pc.hidden)
it.remove();
}
}

269
src/engine/gameManager/CombatManager.java

@ -30,8 +30,6 @@ import java.util.HashSet; @@ -30,8 +30,6 @@ import java.util.HashSet;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ThreadLocalRandom;
import static engine.math.FastMath.sqr;
public enum CombatManager {
COMBATMANAGER;
@ -41,63 +39,6 @@ public enum CombatManager { @@ -41,63 +39,6 @@ public enum CombatManager {
/**
* Message sent by player to attack something.
*/
public static void setAttackTarget(AttackCmdMsg msg, ClientConnection origin) throws MsgSendException {
PlayerCharacter player;
int targetType;
AbstractWorldObject target;
if (TargetedActionMsg.un2cnt == 60 || TargetedActionMsg.un2cnt == 70)
return;
player = SessionManager.getPlayerCharacter(origin);
if (player == null)
return;
//source must match player this account belongs to
if (player.getObjectUUID() != msg.getSourceID() || player.getObjectType().ordinal() != msg.getSourceType()) {
Logger.error("Msg Source ID " + msg.getSourceID() + " Does not Match Player ID " + player.getObjectUUID());
return;
}
targetType = msg.getTargetType();
if (targetType == GameObjectType.PlayerCharacter.ordinal()) {
target = PlayerCharacter.getFromCache(msg.getTargetID());
} else if (targetType == GameObjectType.Building.ordinal()) {
target = BuildingManager.getBuildingFromCache(msg.getTargetID());
} else if (targetType == GameObjectType.Mob.ordinal()) {
target = Mob.getFromCache(msg.getTargetID());
} else {
player.setCombatTarget(null);
return; //not valid type to attack
}
// quit of the combat target is already the current combat target
// or there is no combat target
if (target == null)
return;
//set sources target
player.setCombatTarget(target);
//put in combat if not already
if (!player.isCombat())
toggleCombat(true, origin);
//make character stand if sitting
if (player.isSit())
toggleSit(false, origin);
AttackTarget(player, target);
}
public static void AttackTarget(PlayerCharacter playerCharacter, AbstractWorldObject target) {
@ -141,11 +82,6 @@ public enum CombatManager { @@ -141,11 +82,6 @@ public enum CombatManager {
if (off == null)
CombatManager.createTimer(playerCharacter, MBServerStatics.SLOT_OFFHAND, 1, true); // attack in 0.1 of a second
}
City playerCity = ZoneManager.getCityAtLocation(playerCharacter.getLoc());
if (playerCity != null && playerCity.getGuild().getNation().equals(playerCharacter.getGuild().getNation()) == false && playerCity.cityOutlaws.contains(playerCharacter.getObjectUUID()) == false)
playerCity.cityOutlaws.add(playerCharacter.getObjectUUID());
}
public static void setAttackTarget(PetAttackMsg msg, ClientConnection origin) throws MsgSendException {
@ -523,7 +459,7 @@ public enum CombatManager { @@ -523,7 +459,7 @@ public enum CombatManager {
/**
* Attempt to attack target
*/
private static void attack(AbstractCharacter ac, AbstractWorldObject target, Item weapon, ItemBase wb, boolean mainHand) {
private static void attack(AbstractCharacter attacker, AbstractWorldObject target, Item weapon, ItemBase wb, boolean mainHand) {
float atr;
int minDamage, maxDamage;
@ -531,20 +467,20 @@ public enum CombatManager { @@ -531,20 +467,20 @@ public enum CombatManager {
try {
if (ac == null)
if (attacker == null)
return;
if (target == null)
return;
if (mainHand) {
atr = ac.getAtrHandOne();
minDamage = ac.getMinDamageHandOne();
maxDamage = ac.getMaxDamageHandOne();
atr = attacker.getAtrHandOne();
minDamage = attacker.getMinDamageHandOne();
maxDamage = attacker.getMaxDamageHandOne();
} else {
atr = ac.getAtrHandTwo();
minDamage = ac.getMinDamageHandTwo();
maxDamage = ac.getMaxDamageHandTwo();
atr = attacker.getAtrHandTwo();
minDamage = attacker.getMinDamageHandTwo();
maxDamage = attacker.getMaxDamageHandTwo();
}
boolean tarIsRat = false;
@ -563,9 +499,9 @@ public enum CombatManager { @@ -563,9 +499,9 @@ public enum CombatManager {
//Dont think we need to do this anymore.
if (tarIsRat)
if (ac.getBonuses().getFloatPercentAll(ModType.Slay, SourceType.Rat) != 0) { //strip away current % dmg buffs then add with rat %
if (attacker.getBonuses().getFloatPercentAll(ModType.Slay, SourceType.Rat) != 0) { //strip away current % dmg buffs then add with rat %
float percent = 1 + ac.getBonuses().getFloatPercentAll(ModType.Slay, SourceType.Rat);
float percent = 1 + attacker.getBonuses().getFloatPercentAll(ModType.Slay, SourceType.Rat);
minDamage *= percent;
maxDamage *= percent;
@ -576,24 +512,24 @@ public enum CombatManager { @@ -576,24 +512,24 @@ public enum CombatManager {
//subtract stamina
if (wb == null)
ac.modifyStamina(-0.5f, ac, true);
attacker.modifyStamina(-0.5f, attacker, true);
else {
float stam = wb.getWeight() / 3;
stam = (stam < 1) ? 1 : stam;
ac.modifyStamina(-(stam), ac, true);
attacker.modifyStamina(-(stam), attacker, true);
}
ac.cancelOnAttackSwing();
attacker.cancelOnAttackSwing();
errorTrack = 2;
//set last time this player has attacked something.
if (target.getObjectType().equals(GameObjectType.PlayerCharacter) && target.getObjectUUID() != ac.getObjectUUID() && ac.getObjectType() == GameObjectType.PlayerCharacter) {
ac.setTimeStamp("LastCombatPlayer", System.currentTimeMillis());
if (target.getObjectType().equals(GameObjectType.PlayerCharacter) && target.getObjectUUID() != attacker.getObjectUUID() && attacker.getObjectType() == GameObjectType.PlayerCharacter) {
attacker.setTimeStamp("LastCombatPlayer", System.currentTimeMillis());
((PlayerCharacter) target).setTimeStamp("LastCombatPlayer", System.currentTimeMillis());
} else
ac.setTimeStamp("LastCombatMob", System.currentTimeMillis());
attacker.setTimeStamp("LastCombatMob", System.currentTimeMillis());
errorTrack = 3;
@ -604,42 +540,16 @@ public enum CombatManager { @@ -604,42 +540,16 @@ public enum CombatManager {
if (target.getObjectType().equals(GameObjectType.Building)) {
if (BuildingManager.getBuildingFromCache(target.getObjectUUID()) == null) {
ac.setCombatTarget(null);
attacker.setCombatTarget(null);
return;
}
defense = 0;
Building building = (Building) target;
if (building.getParentZone() != null && building.getParentZone().isPlayerCity()) {
if (System.currentTimeMillis() > building.getTimeStamp("CallForHelp")) {
building.getTimestamps().put("CallForHelp", System.currentTimeMillis() + 15000);
for (Mob mob : building.getParentZone().zoneMobSet) {
if (!mob.isPlayerGuard())
continue;
if (mob.getCombatTarget() != null)
continue;
if (mob.getGuild() != null && building.getGuild() != null)
if (!Guild.sameGuild(mob.getGuild().getNation(), building.getGuild().getNation()))
continue;
if (mob.getLoc().distanceSquared2D(building.getLoc()) > sqr(300))
continue;
mob.setCombatTarget(ac);
}
}
}
} else {
AbstractCharacter tar = (AbstractCharacter) target;
defense = tar.getDefenseRating();
handleRetaliate(tar, ac); //Handle target attacking back if in combat and has no other target
handleRetaliate(tar, attacker); //Handle target attacking back if in combat and has no other target
}
errorTrack = 4;
@ -665,11 +575,11 @@ public enum CombatManager { @@ -665,11 +575,11 @@ public enum CombatManager {
if (roll < chance) {
if (ac.getObjectType().equals(GameObjectType.PlayerCharacter))
updateAttackTimers((PlayerCharacter) ac, target, true);
if (attacker.getObjectType().equals(GameObjectType.PlayerCharacter))
updateAttackTimers((PlayerCharacter) attacker, target, true);
boolean skipPassives = false;
PlayerBonuses bonuses = ac.getBonuses();
PlayerBonuses bonuses = attacker.getBonuses();
if (bonuses != null && bonuses.getBool(ModType.IgnorePassiveDefense, SourceType.None))
skipPassives = true;
@ -684,26 +594,26 @@ public enum CombatManager { @@ -684,26 +594,26 @@ public enum CombatManager {
// Apply Weapon power effect if any. don't try to apply twice if
// dual wielding. Perform after passive test for sync purposes.
if (ac.getObjectType().equals(GameObjectType.PlayerCharacter) && (mainHand || wb.isTwoHanded())) {
if (attacker.getObjectType().equals(GameObjectType.PlayerCharacter) && (mainHand || wb.isTwoHanded())) {
dpj = ((PlayerCharacter) ac).getWeaponPower();
dpj = ((PlayerCharacter) attacker).getWeaponPower();
if (dpj != null) {
PlayerBonuses bonus = ac.getBonuses();
PlayerBonuses bonus = attacker.getBonuses();
float attackRange = getWeaponRange(wb, bonus);
dpj.attack(target, attackRange);
if (dpj.getPower() != null && (dpj.getPowerToken() == -1851459567 || dpj.getPowerToken() == -1851489518))
((PlayerCharacter) ac).setWeaponPower(dpj);
((PlayerCharacter) attacker).setWeaponPower(dpj);
}
}
//check to apply second backstab.
if (ac.getObjectType().equals(GameObjectType.PlayerCharacter) && !mainHand) {
if (attacker.getObjectType().equals(GameObjectType.PlayerCharacter) && !mainHand) {
dpj = ((PlayerCharacter) ac).getWeaponPower();
dpj = ((PlayerCharacter) attacker).getWeaponPower();
if (dpj != null && dpj.getPower() != null && (dpj.getPowerToken() == -1851459567 || dpj.getPowerToken() == -1851489518)) {
float attackRange = getWeaponRange(wb, bonuses);
@ -723,24 +633,24 @@ public enum CombatManager { @@ -723,24 +633,24 @@ public enum CombatManager {
//Handle Block passive
if (testPassive(ac, tarAc, "Block") && canTestBlock(ac, target)) {
if (testPassive(attacker, tarAc, "Block") && canTestBlock(attacker, target)) {
if (!target.isAlive())
return;
sendPassiveDefenseMessage(ac, wb, target, MBServerStatics.COMBAT_SEND_BLOCK, dpj, mainHand);
sendPassiveDefenseMessage(attacker, wb, target, MBServerStatics.COMBAT_SEND_BLOCK, dpj, mainHand);
passiveFired = true;
}
//Handle Parry passive
if (!passiveFired)
if (canTestParry(ac, target) && testPassive(ac, tarAc, "Parry")) {
if (canTestParry(attacker, target) && testPassive(attacker, tarAc, "Parry")) {
if (!target.isAlive())
return;
sendPassiveDefenseMessage(ac, wb, target, MBServerStatics.COMBAT_SEND_PARRY, dpj, mainHand);
sendPassiveDefenseMessage(attacker, wb, target, MBServerStatics.COMBAT_SEND_PARRY, dpj, mainHand);
passiveFired = true;
}
@ -751,12 +661,12 @@ public enum CombatManager { @@ -751,12 +661,12 @@ public enum CombatManager {
//Handle Dodge passive
if (!passiveFired)
if (testPassive(ac, tarAc, "Dodge")) {
if (testPassive(attacker, tarAc, "Dodge")) {
if (!target.isAlive())
return;
sendPassiveDefenseMessage(ac, wb, target, MBServerStatics.COMBAT_SEND_DODGE, dpj, mainHand);
sendPassiveDefenseMessage(attacker, wb, target, MBServerStatics.COMBAT_SEND_DODGE, dpj, mainHand);
passiveFired = true;
}
}
@ -772,7 +682,7 @@ public enum CombatManager { @@ -772,7 +682,7 @@ public enum CombatManager {
//if target is player, set last attack timestamp
if (target.getObjectType().equals(GameObjectType.PlayerCharacter))
updateAttackTimers((PlayerCharacter) target, ac, false);
updateAttackTimers((PlayerCharacter) target, attacker, false);
//Get damage Type
@ -780,7 +690,7 @@ public enum CombatManager { @@ -780,7 +690,7 @@ public enum CombatManager {
if (wb != null)
damageType = wb.getDamageType();
else if (ac.getObjectType().equals(GameObjectType.Mob) && ((Mob) ac).isSiege())
else if (attacker.getObjectType().equals(GameObjectType.Mob) && ((Mob) attacker).isSiege())
damageType = DamageType.Siege;
else
damageType = DamageType.Crush;
@ -799,7 +709,7 @@ public enum CombatManager { @@ -799,7 +709,7 @@ public enum CombatManager {
//make sure target is not immune to damage type;
if (resists != null && resists.immuneTo(damageType)) {
sendCombatMessage(ac, target, 0f, wb, dpj, mainHand);
sendCombatMessage(attacker, target, 0f, wb, dpj, mainHand);
return;
}
@ -810,9 +720,9 @@ public enum CombatManager { @@ -810,9 +720,9 @@ public enum CombatManager {
float damage;
if (wb != null)
damage = calculateDamage(ac, tarAc, minDamage, maxDamage, damageType, resists);
damage = calculateDamage(attacker, tarAc, minDamage, maxDamage, damageType, resists);
else
damage = calculateDamage(ac, tarAc, minDamage, maxDamage, damageType, resists);
damage = calculateDamage(attacker, tarAc, minDamage, maxDamage, damageType, resists);
float d = 0f;
@ -825,40 +735,35 @@ public enum CombatManager { @@ -825,40 +735,35 @@ public enum CombatManager {
if (tarAc.isSit())
damage *= 2.5f; //increase damage if sitting
if (tarAc.getObjectType() == GameObjectType.Mob) {
ac.setHateValue(damage * MBServerStatics.PLAYER_COMBAT_HATE_MODIFIER);
((Mob) tarAc).handleDirectAggro(ac);
}
if (tarAc.getHealth() > 0)
d = tarAc.modifyHealth(-damage, ac, false);
d = tarAc.modifyHealth(-damage, attacker, false);
} else if (target.getObjectType().equals(GameObjectType.Building)) {
if (BuildingManager.getBuildingFromCache(target.getObjectUUID()) == null) {
ac.setCombatTarget(null);
attacker.setCombatTarget(null);
return;
}
if (target.getHealth() > 0)
d = ((Building) target).modifyHealth(-damage, ac);
d = ((Building) target).modifyHealth(-damage, attacker);
}
errorTrack = 13;
//Test to see if any damage needs done to weapon or armor
testItemDamage(ac, target, weapon, wb);
testItemDamage(attacker, target, weapon, wb);
// if target is dead, we got the killing blow, remove attack timers on our weapons
if (tarAc != null && !tarAc.isAlive())
removeAttackTimers(ac);
removeAttackTimers(attacker);
//test double death fix
if (d != 0)
sendCombatMessage(ac, target, damage, wb, dpj, mainHand); //send damage message
sendCombatMessage(attacker, target, damage, wb, dpj, mainHand); //send damage message
errorTrack = 14;
@ -885,7 +790,7 @@ public enum CombatManager { @@ -885,7 +790,7 @@ public enum CombatManager {
int procChance = ThreadLocalRandom.current().nextInt(100);
if (procChance < MBServerStatics.PROC_CHANCE)
((WeaponProcEffectModifier) aem).applyProc(ac, target);
((WeaponProcEffectModifier) aem).applyProc(attacker, target);
}
}
@ -897,52 +802,52 @@ public enum CombatManager { @@ -897,52 +802,52 @@ public enum CombatManager {
//handle damage shields
if (ac.isAlive() && tarAc != null && tarAc.isAlive())
handleDamageShields(ac, tarAc, damage);
if (attacker.isAlive() && tarAc != null && tarAc.isAlive())
handleDamageShields(attacker, tarAc, damage);
} else {
// Apply Weapon power effect if any.
// don't try to apply twice if dual wielding.
if (ac.getObjectType().equals(GameObjectType.PlayerCharacter) && (mainHand || wb.isTwoHanded())) {
dpj = ((PlayerCharacter) ac).getWeaponPower();
if (attacker.getObjectType().equals(GameObjectType.PlayerCharacter) && (mainHand || wb.isTwoHanded())) {
dpj = ((PlayerCharacter) attacker).getWeaponPower();
if (dpj != null) {
PowersBase wp = dpj.getPower();
if (wp.requiresHitRoll() == false) {
PlayerBonuses bonus = ac.getBonuses();
PlayerBonuses bonus = attacker.getBonuses();
float attackRange = getWeaponRange(wb, bonus);
dpj.attack(target, attackRange);
} else
((PlayerCharacter) ac).setWeaponPower(null);
((PlayerCharacter) attacker).setWeaponPower(null);
}
}
if (target.getObjectType() == GameObjectType.Mob)
((Mob) target).handleDirectAggro(ac);
((Mob) target).handleDirectAggro(attacker);
errorTrack = 17;
//miss, Send miss message
sendCombatMessage(ac, target, 0f, wb, dpj, mainHand);
sendCombatMessage(attacker, target, 0f, wb, dpj, mainHand);
//if attacker is player, set last attack timestamp
if (ac.getObjectType().equals(GameObjectType.PlayerCharacter))
updateAttackTimers((PlayerCharacter) ac, target, true);
if (attacker.getObjectType().equals(GameObjectType.PlayerCharacter))
updateAttackTimers((PlayerCharacter) attacker, target, true);
}
errorTrack = 18;
//cancel effects that break on attack or attackSwing
ac.cancelOnAttack();
attacker.cancelOnAttack();
} catch (Exception e) {
Logger.error(ac.getName() + ' ' + errorTrack + ' ' + e);
Logger.error(attacker.getName() + ' ' + errorTrack + ' ' + e);
}
}
@ -1220,7 +1125,7 @@ public enum CombatManager { @@ -1220,7 +1125,7 @@ public enum CombatManager {
toggleCombat(msg.getToggle(), origin);
}
private static void toggleCombat(boolean toggle, ClientConnection origin) {
public static void toggleCombat(boolean toggle, ClientConnection origin) {
PlayerCharacter pc = SessionManager.getPlayerCharacter(origin);
@ -1237,7 +1142,7 @@ public enum CombatManager { @@ -1237,7 +1142,7 @@ public enum CombatManager {
DispatchMessage.dispatchMsgToInterestArea(pc, rwss, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, false, false);
}
private static void toggleSit(boolean toggle, ClientConnection origin) {
public static void toggleSit(boolean toggle, ClientConnection origin) {
PlayerCharacter pc = SessionManager.getPlayerCharacter(origin);
@ -1267,61 +1172,69 @@ public enum CombatManager { @@ -1267,61 +1172,69 @@ public enum CombatManager {
}
//Called when character takes damage.
public static void handleRetaliate(AbstractCharacter tarAc, AbstractCharacter ac) {
public static void handleRetaliate(AbstractCharacter target, AbstractCharacter attacker) {
if (ac == null || tarAc == null)
if (attacker == null || target == null)
return;
if (ac.equals(tarAc))
if (attacker.equals(target))
return;
if (tarAc.isMoving() && tarAc.getObjectType().equals(GameObjectType.PlayerCharacter))
if (target.isMoving() && target.getObjectType().equals(GameObjectType.PlayerCharacter))
return;
if (!tarAc.isAlive() || !ac.isAlive())
if (!target.isAlive() || !attacker.isAlive())
return;
boolean isCombat = tarAc.isCombat();
boolean isCombat = target.isCombat();
//If target in combat and has no target, then attack back
AbstractWorldObject awoCombTar = tarAc.getCombatTarget();
AbstractWorldObject awoCombTar = target.getCombatTarget();
if ((tarAc.isCombat() && awoCombTar == null) || (isCombat && awoCombTar != null && (!awoCombTar.isAlive() || tarAc.isCombat() && NotInRange(tarAc, awoCombTar, tarAc.getRange()))) || (tarAc != null && tarAc.getObjectType() == GameObjectType.Mob && ((Mob) tarAc).isSiege()))
if (tarAc.getObjectType().equals(GameObjectType.PlayerCharacter)) { // we are in combat with no valid target
if ((target.isCombat() && awoCombTar == null) || (isCombat && awoCombTar != null && (!awoCombTar.isAlive() || target.isCombat() && NotInRange(target, awoCombTar, target.getRange()))) || (target != null && target.getObjectType() == GameObjectType.Mob && ((Mob) target).isSiege()))
if (target.getObjectType().equals(GameObjectType.PlayerCharacter)) { // we are in combat with no valid target
PlayerCharacter pc = (PlayerCharacter) tarAc;
tarAc.setCombatTarget(ac);
pc.setLastTarget(ac.getObjectType(), ac.getObjectUUID());
PlayerCharacter pc = (PlayerCharacter) target;
target.setCombatTarget(attacker);
pc.setLastTarget(attacker.getObjectType(), attacker.getObjectUUID());
if (tarAc.getTimers() != null)
if (!tarAc.getTimers().containsKey("Attack" + MBServerStatics.SLOT_MAINHAND))
CombatManager.AttackTarget((PlayerCharacter) tarAc, tarAc.getCombatTarget());
if (target.getTimers() != null)
if (!target.getTimers().containsKey("Attack" + MBServerStatics.SLOT_MAINHAND))
CombatManager.AttackTarget((PlayerCharacter) target, target.getCombatTarget());
}
//Handle pet retaliate if assist is on and pet doesn't have a target.
if (tarAc.getObjectType().equals(GameObjectType.PlayerCharacter)) {
if (target.getObjectType().equals(GameObjectType.PlayerCharacter)) {
Mob pet = ((PlayerCharacter) tarAc).getPet();
Mob pet = ((PlayerCharacter) target).getPet();
if (pet != null && pet.assist && pet.getCombatTarget() == null)
pet.setCombatTarget(ac);
pet.setCombatTarget(attacker);
}
//Handle Mob Retaliate.
if (tarAc.getObjectType() == GameObjectType.Mob) {
if (target.getObjectType() == GameObjectType.Mob) {
Mob retaliater = (Mob) tarAc;
Mob attackedMobile = (Mob) target;
if (retaliater.getCombatTarget() != null && !retaliater.isSiege())
return;
//handle minion informing his captain of an attack
if (attackedMobile.agentType.equals(AIAgentType.GUARDMINION) && attackedMobile.guardCaptain != null && attackedMobile.guardCaptain.isAlive()) {
if (attackedMobile.guardCaptain.combatTarget == null)
attackedMobile.guardCaptain.setCombatTarget(attacker);
}
// Mobile already has a target; don't switch.
if (ac.getObjectType() == GameObjectType.Mob && retaliater.isSiege())
if (attackedMobile.getCombatTarget() != null && !attackedMobile.isSiege())
return;
retaliater.setCombatTarget(ac);
attackedMobile.setCombatTarget(attacker);
}
}

5
src/engine/gameManager/DevCmdManager.java

@ -46,9 +46,11 @@ public enum DevCmdManager { @@ -46,9 +46,11 @@ public enum DevCmdManager {
DevCmdManager.registerDevCmd(new GetZoneCmd());
DevCmdManager.registerDevCmd(new ZoneSetCmd());
DevCmdManager.registerDevCmd(new PrintBankCmd());
DevCmdManager.registerDevCmd(new PrintEffectsCmd());
DevCmdManager.registerDevCmd(new PrintEquipCmd());
DevCmdManager.registerDevCmd(new PrintInventoryCmd());
DevCmdManager.registerDevCmd(new PrintVaultCmd());
DevCmdManager.registerDevCmd(new PrintRunesCmd());
DevCmdManager.registerDevCmd(new PrintStatsCmd());
DevCmdManager.registerDevCmd(new PrintSkillsCmd());
DevCmdManager.registerDevCmd(new PrintPowersCmd());
@ -128,7 +130,6 @@ public enum DevCmdManager { @@ -128,7 +130,6 @@ public enum DevCmdManager {
DevCmdManager.registerDevCmd(new SetForceRenameCityCmd());
DevCmdManager.registerDevCmd(new GotoObj());
DevCmdManager.registerDevCmd(new convertLoc());
DevCmdManager.registerDevCmd(new AuditHeightMapCmd());
DevCmdManager.registerDevCmd(new UnloadFurnitureCmd());
DevCmdManager.registerDevCmd(new SetNpcEquipSetCmd());
DevCmdManager.registerDevCmd(new SetBuildingAltitudeCmd());
@ -143,7 +144,7 @@ public enum DevCmdManager { @@ -143,7 +144,7 @@ public enum DevCmdManager {
DevCmdManager.registerDevCmd(new ApplyBonusCmd());
DevCmdManager.registerDevCmd(new AuditFailedItemsCmd());
DevCmdManager.registerDevCmd(new SlotTestCmd());
DevCmdManager.registerDevCmd(new SeaAuditCmd());
}
private static void registerDevCmd(AbstractDevCmd cmd) {

2
src/engine/gameManager/LootManager.java

@ -330,6 +330,8 @@ public enum LootManager { @@ -330,6 +330,8 @@ public enum LootManager {
public static void GenerateEquipmentDrop(Mob mob) {
if(mob.behaviourType.equals(Enum.MobBehaviourType.HamletGuard))
return; // safehold guards don't drop their equipment
//do equipment here
int dropCount = 0;
if (mob.getEquip() != null)

23
src/engine/gameManager/MovementManager.java

@ -116,8 +116,8 @@ public enum MovementManager { @@ -116,8 +116,8 @@ public enum MovementManager {
// if inside a building, convert both locations from the building local reference frame to the world reference frame
if (msg.getTargetID() > 0) {
Building building = BuildingManager.getBuildingFromCache(msg.getTargetID());
if (msg.getInBuildingUUID() > 0) {
Building building = BuildingManager.getBuildingFromCache(msg.getInBuildingUUID());
if (building != null) {
Vector3fImmutable convertLocEnd = new Vector3fImmutable(ZoneManager.convertLocalToWorld(building, endLocation));
@ -128,8 +128,8 @@ public enum MovementManager { @@ -128,8 +128,8 @@ public enum MovementManager {
// }
// else {
toMove.setInBuilding(msg.getInBuilding());
toMove.setInFloorID(msg.getUnknown01());
toMove.setInBuildingID(msg.getTargetID());
toMove.setInFloorID(msg.getInBuildingFloor());
toMove.setInBuildingID(msg.getInBuildingUUID());
msg.setStartCoord(ZoneManager.convertWorldToLocal(building, toMove.getLoc()));
if (toMove.getObjectType() == GameObjectType.PlayerCharacter) {
@ -174,9 +174,9 @@ public enum MovementManager { @@ -174,9 +174,9 @@ public enum MovementManager {
msg.setStartCoord(ZoneManager.convertWorldToLocal(Regions.GetBuildingForRegion(toMove.region), toMove.getLoc()));
msg.setEndCoord(ZoneManager.convertWorldToLocal(regionBuilding, endLocation));
msg.setInBuilding(toMove.region.level);
msg.setUnknown01(toMove.region.room);
msg.setTargetType(GameObjectType.Building.ordinal());
msg.setTargetID(regionBuilding.getObjectUUID());
msg.setInBuildingFloor(toMove.region.room);
msg.setStartLocType(GameObjectType.Building.ordinal());
msg.setInBuildingUUID(regionBuilding.getObjectUUID());
}
} else {
@ -185,8 +185,8 @@ public enum MovementManager { @@ -185,8 +185,8 @@ public enum MovementManager {
toMove.setInBuilding(-1);
msg.setStartCoord(toMove.getLoc());
msg.setEndCoord(endLocation);
msg.setTargetType(0);
msg.setTargetID(0);
msg.setStartLocType(0);
msg.setInBuildingUUID(0);
}
//checks sync between character and server, if out of sync, teleport player to original position and return.
@ -233,7 +233,7 @@ public enum MovementManager { @@ -233,7 +233,7 @@ public enum MovementManager {
toMove.cancelOnMove();
//cancel any attacks for manual move.
if ((toMove.getObjectType() == GameObjectType.PlayerCharacter) && msg.getUnknown02() == 0)
if ((toMove.getObjectType() == GameObjectType.PlayerCharacter) && msg.getInitiatedFromAttack() == 0)
toMove.setCombatTarget(null);
@ -464,7 +464,7 @@ public enum MovementManager { @@ -464,7 +464,7 @@ public enum MovementManager {
}
}
public static void translocate(AbstractCharacter teleporter, Vector3fImmutable targetLoc, Regions region) {
public static void translocate(AbstractCharacter teleporter, Vector3fImmutable targetLoc) {
if (targetLoc == null)
@ -473,7 +473,6 @@ public enum MovementManager { @@ -473,7 +473,6 @@ public enum MovementManager {
Vector3fImmutable oldLoc = new Vector3fImmutable(teleporter.getLoc());
teleporter.stopMovement(targetLoc);
teleporter.setRegion(region);
//mobs ignore region sets for now.
if (teleporter.getObjectType().equals(GameObjectType.Mob)) {

426
src/engine/gameManager/NPCManager.java

@ -5,13 +5,17 @@ import engine.InterestManagement.WorldGrid; @@ -5,13 +5,17 @@ import engine.InterestManagement.WorldGrid;
import engine.math.Quaternion;
import engine.math.Vector3f;
import engine.math.Vector3fImmutable;
import engine.mobileAI.MobAI;
import engine.net.Dispatch;
import engine.net.DispatchMessage;
import engine.net.client.msg.PetMsg;
import engine.objects.*;
import engine.powers.EffectsBase;
import engine.powers.PowersBase;
import engine.powers.RuneSkillAdjustEntry;
import org.pmw.tinylog.Logger;
import javax.smartcardio.ATR;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.concurrent.ThreadLocalRandom;
@ -23,92 +27,6 @@ public enum NPCManager { @@ -23,92 +27,6 @@ public enum NPCManager {
NPC_MANAGER;
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) {
// Early exit
if (mob.runeSet == 0)
return;
//Apply all rune effects.
if (NPCManager._runeSetMap.get(mob.runeSet).contains(252623)) {
mob.isPlayerGuard = true;
}
// Only captains have contracts
if (mob.contract != null || mob.isPlayerGuard)
applyEffectsForRune(mob, 252621);
// Apply effects from RuneSet
if (mob.runeSet != 0)
for (int runeID : _runeSetMap.get(mob.runeSet))
applyEffectsForRune(mob, runeID);
// Not sure why but apply Warrior effects for some reason?
applyEffectsForRune(mob, 2518);
}
public static void applyEffectsForRune(AbstractCharacter character, int runeID) {
EffectsBase effectsBase;
RuneBase sourceRune = RuneBase.getRuneBase(runeID);
// Race runes are in the runeset but not in runebase for some reason
if (sourceRune == null)
return;
for (MobBaseEffects mbe : sourceRune.getEffectsList()) {
effectsBase = PowersManager.getEffectByToken(mbe.getToken());
if (effectsBase == null) {
Logger.info("Mob: " + character.getObjectUUID() + " EffectsBase Null for Token " + mbe.getToken());
continue;
}
//check to upgrade effects if needed.
if (character.effects.containsKey(Integer.toString(effectsBase.getUUID()))) {
if (mbe.getReqLvl() > (int) character.level)
continue;
Effect eff = character.effects.get(Integer.toString(effectsBase.getUUID()));
if (eff == null)
continue;
//Current effect is a higher rank, dont apply.
if (eff.getTrains() > mbe.getRank())
continue;
//new effect is of a higher rank. remove old effect and apply new one.
eff.cancelJob();
character.addEffectNoTimer(Integer.toString(effectsBase.getUUID()), effectsBase, mbe.getRank(), true);
} else {
if (mbe.getReqLvl() > (int) character.level)
continue;
character.addEffectNoTimer(Integer.toString(effectsBase.getUUID()), effectsBase, mbe.getRank(), true);
}
}
}
public static void dismissNecroPet(Mob necroPet, boolean updateOwner) {
necroPet.setCombatTarget(null);
@ -127,10 +45,12 @@ public enum NPCManager { @@ -127,10 +45,12 @@ public enum NPCManager {
DbManager.removeFromCache(necroPet);
PlayerCharacter petOwner = necroPet.getOwner();
PlayerCharacter petOwner = (PlayerCharacter) necroPet.guardCaptain;
if (petOwner != null) {
necroPet.setOwner(null);
necroPet.guardCaptain = null;
petOwner.setPet(null);
if (updateOwner == false)
@ -202,78 +122,6 @@ public enum NPCManager { @@ -202,78 +122,6 @@ public enum NPCManager {
playerCharacter.necroPets.clear();
}
public static void removeSiegeMinions(Mob mobile) {
for (Mob toRemove : mobile.siegeMinionMap.keySet()) {
if (mobile.isMoving()) {
mobile.stopMovement(mobile.getLoc());
if (toRemove.parentZone != null)
toRemove.parentZone.zoneMobSet.remove(toRemove);
}
try {
toRemove.clearEffects();
} catch (Exception e) {
Logger.error(e.getMessage());
}
if (toRemove.parentZone != null)
toRemove.parentZone.zoneMobSet.remove(toRemove);
WorldGrid.RemoveWorldObject(toRemove);
WorldGrid.removeObject(toRemove);
DbManager.removeFromCache(toRemove);
PlayerCharacter petOwner = toRemove.getOwner();
if (petOwner != null) {
petOwner.setPet(null);
toRemove.setOwner(null);
PetMsg petMsg = new PetMsg(5, null);
Dispatch dispatch = Dispatch.borrow(petOwner, petMsg);
DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.PRIMARY);
}
}
}
public static boolean removeMobileFromBuilding(Mob mobile, Building building) {
// Remove npc from it's building
try {
mobile.clearEffects();
} catch (Exception e) {
Logger.error(e.getMessage());
}
if (mobile.parentZone != null)
mobile.parentZone.zoneMobSet.remove(mobile);
if (building != null) {
building.getHirelings().remove(mobile);
removeSiegeMinions(mobile);
}
// Delete npc from database
if (DbManager.MobQueries.DELETE_MOB(mobile) == 0)
return false;
// Remove npc from the simulation
mobile.removeFromCache();
DbManager.removeFromCache(mobile);
WorldGrid.RemoveWorldObject(mobile);
WorldGrid.removeObject(mobile);
return true;
}
public static void loadAllPirateNames() {
DbManager.NPCQueries.LOAD_PIRATE_NAMES();
@ -340,10 +188,19 @@ public enum NPCManager { @@ -340,10 +188,19 @@ public enum NPCManager {
else
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.minions.size() + 2;
}
if (buildingSlot == -1)
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
// from BuildingManager slot location data.
@ -370,4 +227,251 @@ public enum NPCManager { @@ -370,4 +227,251 @@ public enum NPCManager {
return buildingSlot;
}
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.setLoc(newPatrolPoint);
mob.endLoc = newPatrolPoint;
}
}
}
public static void applyGuardStanceModifiers(Mob guard){
float damageModifier = 1;
float attackRatingModifier = 1;
float defenseModifier = 1;
float attackSpeedModifier = 1;
float powerDamageModifier = 1;
//handle stance modifiers for guard mob
if(guard.agentType.equals(Enum.AIAgentType.GUARDWALLARCHER)){
//apply rogue bonuses
attackRatingModifier += 0.5f;
defenseModifier += 0.5f;
damageModifier += 0.5f;
attackSpeedModifier -= 0.36f;
}else {
Integer contractID;
if (guard.agentType.equals(Enum.AIAgentType.GUARDMINION)) {
contractID = guard.guardCaptain.contract.getContractID();
} else{
contractID = guard.contract.getContractID();
}
if (Enum.MinionType.ContractToMinionMap.get(contractID) != null && Enum.MinionType.ContractToMinionMap.get(contractID).isMage()){
//apply mage offensive Stance
powerDamageModifier += 0.5f;
} else{
//apply fighter offensive stance
damageModifier += 0.5f;
attackSpeedModifier -= 0.36f;
}
}
guard.minDamageHandOne *= damageModifier;
guard.minDamageHandTwo *= damageModifier;
guard.maxDamageHandOne *= damageModifier;
guard.maxDamageHandTwo *= damageModifier;
guard.atrHandOne *= attackRatingModifier;
guard.atrHandTwo *= attackRatingModifier;
guard.defenseRating *= defenseModifier;
guard.speedHandOne *= attackSpeedModifier;
guard.speedHandTwo *= attackSpeedModifier;
//TODO figure out how to apply +50% powerdamage to mage guards
}
public static void setDamageAndSpeedForGuard(Mob guard){
float rankModifier = 1 + (guard.getRank() * 0.1f);
int primaryStat = 0;
if(guard.equip == null) {
guard.minDamageHandOne = (int)((guard.mobBase.getDamageMin()) * rankModifier);
guard.maxDamageHandOne = (int)((guard.mobBase.getDamageMax()) * rankModifier);
guard.speedHandOne = 30.0f;
}else{
if(guard.equip.containsKey(1)){
//has main hand weapon
ItemBase weapon = guard.equip.get(1).getItemBase();
if(weapon.isStrBased())
primaryStat = guard.getStatStrCurrent();
else
primaryStat = guard.getStatDexCurrent();
guard.minDamageHandOne = (int)((guard.mobBase.getDamageMin() + weapon.getMinDamage()) * rankModifier) + primaryStat;
guard.maxDamageHandOne = (int)((guard.mobBase.getDamageMax() + weapon.getMaxDamage()) * rankModifier) + primaryStat;
guard.speedHandOne = weapon.getSpeed();
guard.rangeHandOne = weapon.getRange();
} else if(guard.equip.containsKey(2) && !guard.equip.get(2).getItemBase().isShield()){
//has off hand weapon
ItemBase weapon = guard.equip.get(2).getItemBase();
if(weapon.isStrBased())
primaryStat = guard.getStatStrCurrent();
else
primaryStat = guard.getStatDexCurrent();
guard.minDamageHandTwo = (int)((guard.mobBase.getDamageMin() + weapon.getMinDamage()) * rankModifier) + primaryStat;
guard.maxDamageHandTwo = (int)((guard.mobBase.getDamageMax() + weapon.getMaxDamage()) * rankModifier) + primaryStat;
guard.speedHandTwo = weapon.getSpeed();
guard.rangeHandTwo = weapon.getRange();
} else {
primaryStat = guard.getStatStrCurrent();
guard.minDamageHandOne = (int)((guard.mobBase.getDamageMin()) * rankModifier) + primaryStat;
guard.maxDamageHandOne = (int)((guard.mobBase.getDamageMax()) * rankModifier) + primaryStat;
guard.speedHandOne = 30.0f;
guard.rangeHandOne = 3;
}
}
}
public static void setDefenseForGuard(Mob guard){
int dexterity = guard.getStatDexCurrent();
if(dexterity < 1)
dexterity = 1;
int baseDef = guard.mobBase.getDefenseRating();
int armorDefense = 0;
for(MobEquipment equipped : guard.equip.values())
if(equipped.getItemBase().isArmor() || equipped.getItemBase().isShield())
armorDefense += equipped.getItemBase().getDefense();
guard.defenseRating = dexterity + baseDef + armorDefense;
}
public static void setAttackRatingForGuard(Mob guard) {
int strength = guard.getStatStrCurrent();
int baseAtr = guard.mobBase.getAttackRating();
if (guard.equip.get(1) != null)
guard.atrHandOne = baseAtr + (int) ((strength * 0.5f) + (guard.equip.get(1).getItemBase().getPercentRequired() * 4) + (guard.equip.get(1).getItemBase().getPercentRequired() * 3));
else if (guard.equip.get(2) != null && !guard.equip.get(2).getItemBase().isShield())
guard.atrHandTwo = baseAtr + (int) ((strength * 0.5f) + (guard.equip.get(2).getItemBase().getPercentRequired() * 4) + (guard.equip.get(2).getItemBase().getPercentRequired() * 3));
else
guard.atrHandOne = baseAtr;
}
public static void setMaxHealthForGuard(Mob guard){
//values derived fom reading memory address for health on client when selecting player guards
switch(guard.getRank()){
default:
guard.healthMax = 750; //rank 1
break;
case 2:
guard.healthMax = 2082;
break;
case 3:
guard.healthMax = 2740;
break;
case 4:
guard.healthMax = 3414;
break;
case 5:
guard.healthMax = 4080;
break;
case 6:
guard.healthMax = 4746;
break;
case 7:
guard.healthMax = 5412;
break;
}
}
public static void applyMobbaseEffects(Mob mob) {
EffectsBase effectsBase;
for (MobBaseEffects mbe : mob.mobBase.effectsList) {
effectsBase = PowersManager.getEffectByToken(mbe.getToken());
if (effectsBase == null) {
Logger.info("Mob: " + mob.getObjectUUID() + " EffectsBase Null for Token " + mbe.getToken());
continue;
}
//check to upgrade effects if needed.
if (mob.effects.containsKey(Integer.toString(effectsBase.getUUID()))) {
if (mbe.getReqLvl() > (int) mob.level)
continue;
Effect eff = mob.effects.get(Integer.toString(effectsBase.getUUID()));
if (eff == null)
continue;
//Current effect is a higher rank, dont apply.
if (eff.getTrains() > mbe.getRank())
continue;
//new effect is of a higher rank. remove old effect and apply new one.
eff.cancelJob();
mob.addEffectNoTimer(Integer.toString(effectsBase.getUUID()), effectsBase, mbe.getRank(), true);
} else {
if (mbe.getReqLvl() > (int) mob.level)
continue;
mob.addEffectNoTimer(Integer.toString(effectsBase.getUUID()), effectsBase, mbe.getRank(), true);
}
}
}
public static void applyEquipmentResists(Mob mob){
if(mob.equip != null){
for(MobEquipment equipped : mob.equip.values()){
ItemBase itemBase = equipped.getItemBase();
if(itemBase.isHeavyArmor() || itemBase.isLightArmor() || itemBase.isMediumArmor()){
mob.resists.setResist(Enum.DamageType.Crush, mob.resists.getResist(Enum.DamageType.Crush,0) + itemBase.getCrushResist());
mob.resists.setResist(Enum.DamageType.Slash, mob.resists.getResist(Enum.DamageType.Slash,0) + itemBase.getCrushResist());
mob.resists.setResist(Enum.DamageType.Pierce, mob.resists.getResist(Enum.DamageType.Pierce,0) + itemBase.getCrushResist());
}
}
}
}
public static void applyMobbaseSkill(Mob mob) {
SkillsBase baseSkill = DbManager.SkillsBaseQueries.GET_BASE_BY_TOKEN(mob.mobBase.getMobBaseStats().getBaseSkill());
if(baseSkill != null)
mob.getSkills().put(baseSkill.getName(),new CharacterSkill(baseSkill,mob,mob.mobBase.getMobBaseStats().getBaseSkillAmount()));
}
public static void applyRuneSkills(Mob mob, int runeID){
//load mob skill adjustments from mobbase rune
if(PowersManager._allRuneSkillAdjusts.containsKey(runeID))
for(RuneSkillAdjustEntry entry : PowersManager._allRuneSkillAdjusts.get(runeID)) {
if(SkillsBase.getFromCache(entry.skill_type) == null)
SkillsBase.putInCache(DbManager.SkillsBaseQueries.GET_BASE_BY_NAME(entry.skill_type));
SkillsBase skillBase = SkillsBase.getFromCache(entry.skill_type);
if(skillBase == null)
continue;
if (entry.level <= mob.level)
if (mob.skills.containsKey(entry.name) == false)
mob.skills.put(entry.skill_type, new CharacterSkill(skillBase, mob, entry.rank));
else
mob.skills.put(entry.skill_type, new CharacterSkill(skillBase, mob, entry.rank + mob.skills.get(entry.skill_type).getNumTrains()));
}
}
public static void applyRunesForNPC(NPC npc){
npc.runes = new ArrayList<>();
RuneBase shopkeeperBase = RuneBase.getRuneBase(252620);
CharacterRune shopkeeper = new CharacterRune(shopkeeperBase,npc.getObjectUUID());
npc.runes.add(shopkeeper);
if(NPCManager._runeSetMap.containsKey(npc.runeSetID)) {
for (int runeID : _runeSetMap.get(npc.runeSetID)) {
RuneBase rb = RuneBase.getRuneBase(runeID);
if(rb != null) {
CharacterRune toApply = new CharacterRune(rb, npc.getObjectUUID());
npc.runes.add(toApply);
}
}
}
}
}

21
src/engine/gameManager/PowersManager.java

@ -53,13 +53,10 @@ public enum PowersManager { @@ -53,13 +53,10 @@ public enum PowersManager {
public static HashMap<Integer, AbstractPowerAction> powerActionsByID = new HashMap<>();
public static HashMap<String, Integer> ActionTokenByIDString = new HashMap<>();
public static HashMap<String, Integer> AnimationOverrides = new HashMap<>();
public static HashMap<Integer, ArrayList<MobPowerEntry>> AllMobPowers;
public static HashMap<Integer, ArrayList<RunePowerEntry>> _allRunePowers;
public static HashMap<Integer, ArrayList<RuneSkillAdjustEntry>> _allRuneSkillAdjusts;
private static JobScheduler js;
private PowersManager() {
}
public static void initPowersManager(boolean fullPowersLoad) {
if (fullPowersLoad)
@ -103,6 +100,16 @@ public enum PowersManager { @@ -103,6 +100,16 @@ public enum PowersManager {
}
}
public static ArrayList<RunePowerEntry> getPowersForRune(int rune_id) {
ArrayList<RunePowerEntry> powerEntries = PowersManager._allRunePowers.get(rune_id);
if (powerEntries == null)
powerEntries = new ArrayList<>();
return powerEntries;
}
// This pre-loads all powers and effects
public static void InitializePowers() {
@ -839,8 +846,6 @@ public enum PowersManager { @@ -839,8 +846,6 @@ public enum PowersManager {
return;
}
playerCharacter.setHateValue(pb.getHateValue(trains));
//Send Cast Message.
// PerformActionMsg castMsg = new PerformActionMsg(msg);
// castMsg.setNumTrains(9999);
@ -891,8 +896,6 @@ public enum PowersManager { @@ -891,8 +896,6 @@ public enum PowersManager {
//Power is aiding a target, handle aggro if combat target is a Mob.
if (!pb.isHarmful() && target.getObjectType() == GameObjectType.PlayerCharacter) {
PlayerCharacter pcTarget = (PlayerCharacter) target;
if (!pb.isHarmful())
Mob.HandleAssistedAggro(playerCharacter, pcTarget);
}
// update target of used power timer

28
src/engine/gameManager/ZoneManager.java

@ -9,6 +9,7 @@ @@ -9,6 +9,7 @@
package engine.gameManager;
import engine.Enum;
import engine.InterestManagement.HeightMap;
import engine.db.archive.CityRecord;
import engine.db.archive.DataWarehouse;
import engine.math.Bounds;
@ -453,4 +454,31 @@ public enum ZoneManager { @@ -453,4 +454,31 @@ public enum ZoneManager {
}
}
}
public static float caclulateWorldAltitude(Zone zone) {
float worldAlttitude = MBServerStatics.SEA_FLOOR_ALTITUDE;
// Seafloor
if (zone.getParent() == null)
return worldAlttitude;
Zone parentZone = zone.getParent();
// Children of seafloor
if (parentZone.getParent() == null)
return worldAlttitude + zone.getYCoord();
// return height from heightmap engine at zone location
worldAlttitude = HeightMap.getWorldHeight(parentZone, zone.getLoc());
// Add zone offset to value
worldAlttitude += zone.getYCoord();
return worldAlttitude;
}
}

4
src/engine/jobs/EndFearJob.java

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

2
src/engine/jobs/FinishSummonsJob.java

@ -61,8 +61,6 @@ public class FinishSummonsJob extends AbstractScheduleJob { @@ -61,8 +61,6 @@ public class FinishSummonsJob extends AbstractScheduleJob {
return;
}
if (this.source.region != null)
this.target.setRegion(this.source.region);
//teleport target to source
target.teleport(source.getLoc());
}

569
src/engine/mobileAI/MobAI.java

@ -23,6 +23,7 @@ import engine.net.client.msg.PowerProjectileMsg; @@ -23,6 +23,7 @@ import engine.net.client.msg.PowerProjectileMsg;
import engine.objects.*;
import engine.powers.ActionsBase;
import engine.powers.PowersBase;
import engine.powers.RunePowerEntry;
import engine.server.MBServerStatics;
import org.pmw.tinylog.Logger;
@ -49,17 +50,19 @@ public class MobAI { @@ -49,17 +50,19 @@ public class MobAI {
return;
}
if (target.getObjectType().equals(Enum.GameObjectType.PlayerCharacter) &&
!mob.canSee((AbstractCharacter) target)) {
mob.setCombatTarget(null);
return;
}
if (target.getObjectType() == Enum.GameObjectType.PlayerCharacter && canCast(mob)) {
if (mob.isPlayerGuard() == false && MobCast(mob)) {
if (MobCast(mob)) {
mob.updateLocation();
return;
}
if (mob.isPlayerGuard() == true && GuardCast(mob)) {
mob.updateLocation();
return;
}
}
if (!CombatUtilities.inRangeToAttack(mob, target))
@ -96,7 +99,7 @@ public class MobAI { @@ -96,7 +99,7 @@ public class MobAI {
return;
}
if (mob.BehaviourType.callsForHelp)
if (mob.behaviourType.callsForHelp)
MobCallForHelp(mob);
if (!MovementUtilities.inRangeDropAggro(mob, target)) {
@ -165,7 +168,7 @@ public class MobAI { @@ -165,7 +168,7 @@ public class MobAI {
if (playercity != null)
for (Mob guard : playercity.getParent().zoneMobSet)
if (guard.BehaviourType != null && guard.BehaviourType.ordinal() == Enum.MobBehaviourType.GuardCaptain.ordinal())
if (guard.agentType.equals(Enum.AIAgentType.GUARDCAPTAIN))
if (guard.getCombatTarget() == null && !guard.getGuild().equals(mob.getGuild()))
guard.setCombatTarget(mob);
@ -249,50 +252,58 @@ public class MobAI { @@ -249,50 +252,58 @@ public class MobAI {
try {
//make sure mob is out of combat stance
int patrolDelay = ThreadLocalRandom.current().nextInt((int) (MobAIThread.AI_PATROL_DIVISOR * 0.5f), MobAIThread.AI_PATROL_DIVISOR) + MobAIThread.AI_PATROL_DIVISOR;
//early exit while waiting to patrol again
// early exit while waiting to patrol again.
// Minions are force marched if captain is alive
boolean forced = mob.agentType.equals(Enum.AIAgentType.GUARDMINION) &&
mob.guardCaptain.isAlive();
if (mob.stopPatrolTime + (patrolDelay * 1000) > System.currentTimeMillis())
return;
if (!forced)
return;
//guard captains inherit barracks patrol points dynamically
//guards inherit barracks patrol points dynamically
if (mob.BehaviourType.ordinal() == Enum.MobBehaviourType.GuardCaptain.ordinal()) {
if (mob.patrolPoints == null || mob.patrolPoints.isEmpty())
if (mob.agentType.equals(Enum.AIAgentType.GUARDCAPTAIN) || mob.agentType.equals(Enum.AIAgentType.GUARDMINION)) {
Building barracks = mob.building;
Building barracks = mob.building;
if (barracks != null && barracks.patrolPoints != null && !barracks.getPatrolPoints().isEmpty()) {
mob.patrolPoints = barracks.patrolPoints;
} else {
randomGuardPatrolPoint(mob);
return;
if (barracks != null && barracks.patrolPoints != null && !barracks.getPatrolPoints().isEmpty()) {
mob.patrolPoints = barracks.patrolPoints;
} else {
randomGuardPatrolPoint(mob);
return;
}
}
}
if (mob.lastPatrolPointIndex > mob.patrolPoints.size() - 1)
mob.lastPatrolPointIndex = 0;
mob.destination = mob.patrolPoints.get(mob.lastPatrolPointIndex);
mob.lastPatrolPointIndex += 1;
// Minions are given marching orders by the captain if he is alive
MovementUtilities.aiMove(mob, mob.destination, true);
if (mob.agentType.equals(Enum.AIAgentType.GUARDMINION)) {
Mob captain = (Mob) mob.guardCaptain;
mob.destination = captain.destination.add(Formation.getOffset(2, mob.guardCaptain.minions.indexOf(mob.getObjectUUID()) + 3));
mob.lastPatrolPointIndex = captain.lastPatrolPointIndex;
} else {
mob.destination = mob.patrolPoints.get(mob.lastPatrolPointIndex);
mob.lastPatrolPointIndex += 1;
}
if (mob.BehaviourType.equals(Enum.MobBehaviourType.GuardCaptain))
for (Entry<Mob, Integer> minion : mob.siegeMinionMap.entrySet())
// Captain orders minions to patrol
//make sure mob is out of combat stance
if (mob.agentType.equals(Enum.AIAgentType.GUARDCAPTAIN))
for (Integer minionUUID : mob.minions) {
Mob minion = Mob.getMob(minionUUID);
if (minion.isAlive() && minion.combatTarget == null)
MobAI.Patrol(minion);
}
MovementUtilities.aiMove(mob, mob.destination, true);
if (minion.getKey().despawned == false) {
if (MovementUtilities.canMove(minion.getKey())) {
Vector3f minionOffset = Formation.getOffset(2, minion.getValue() + 3);
minion.getKey().updateLocation();
Vector3fImmutable formationPatrolPoint = new Vector3fImmutable(mob.destination.x + minionOffset.x, mob.destination.y, mob.destination.z + minionOffset.z);
MovementUtilities.aiMove(minion.getKey(), formationPatrolPoint, true);
}
}
} catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: AttackTarget" + " " + e.getMessage());
}
@ -300,6 +311,8 @@ public class MobAI { @@ -300,6 +311,8 @@ public class MobAI {
public static boolean canCast(Mob mob) {
int contractID = 0;
try {
// Performs validation to determine if a
@ -308,26 +321,27 @@ public class MobAI { @@ -308,26 +321,27 @@ public class MobAI {
if (mob == null)
return false;
if(mob.isPlayerGuard == true){
if (mob.isPlayerGuard() == true) {
int contractID;
if(mob.BehaviourType.equals(Enum.MobBehaviourType.GuardMinion))
contractID = mob.npcOwner.contract.getContractID();
else
if(mob.agentType.equals(Enum.AIAgentType.GUARDWALLARCHER))
return false; //wall archers don't cast
if (mob.agentType.equals(Enum.AIAgentType.GUARDMINION))
contractID = mob.guardCaptain.contract.getContractID();
else
contractID = mob.contract.getContractID();
if(Enum.MinionType.ContractToMinionMap.get(contractID).isMage() == false)
// exception allowing werewolf and werebear guard captains to cast
if (Enum.MinionType.ContractToMinionMap.get(contractID).isMage() == false && contractID != 980103 && contractID != 980104)
return false;
}
if (mob.mobPowers.isEmpty())
return false;
// Mobile has no powers defined in mobbase or contract..
if (!mob.canSee((PlayerCharacter) mob.getCombatTarget())) {
mob.setCombatTarget(null);
if (PowersManager.getPowersForRune(mob.getMobBaseID()).isEmpty() &&
PowersManager.getPowersForRune(contractID).isEmpty())
return false;
}
if (mob.nextCastTime == 0)
mob.nextCastTime = System.currentTimeMillis();
@ -346,164 +360,67 @@ public class MobAI { @@ -346,164 +360,67 @@ public class MobAI {
// and casts it on the current target (or itself). Validation
// (including empty lists) is done previously within canCast();
ArrayList<Integer> powerTokens;
ArrayList<Integer> purgeTokens;
ArrayList<RunePowerEntry> powerEntries;
ArrayList<RunePowerEntry> purgeEntries;
AbstractCharacter target = (AbstractCharacter) mob.getCombatTarget();
if (mob.BehaviourType.callsForHelp)
if (mob.behaviourType.callsForHelp)
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);
powerEntries = new ArrayList<>(PowersManager.getPowersForRune(mob.getMobBaseID()));
purgeEntries = new ArrayList<>();
// 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 (CombatUtilities.triggerDefense(mob, mob.getCombatTarget()))
return false;
// Additional powers may come from the contract ID. This is to support
// powers for player guards irrespective of the mobbase used.
// Cast the spell
if (mob.isPlayerGuard()) {
if (CombatUtilities.inRange2D(mob, mob.getCombatTarget(), mobPower.getRange())) {
ArrayList<RunePowerEntry> contractEntries = new ArrayList<>();
PerformActionMsg msg;
if (mob.contract != null)
contractEntries = PowersManager.getPowersForRune(mob.contractUUID);
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);
}
if (mob.agentType.equals(Enum.AIAgentType.GUARDMINION))
contractEntries = PowersManager.getPowersForRune(mob.guardCaptain.contractUUID);
msg.setUnknown04(2);
PowersManager.finishUseMobPower(msg, mob, 0, 0);
long randomCooldown = (long)((ThreadLocalRandom.current().nextInt(10,15) * 1000) * MobAIThread.AI_CAST_FREQUENCY);
powerEntries.addAll(contractEntries);
mob.nextCastTime = System.currentTimeMillis() + randomCooldown;
return true;
}
} catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: MobCast" + " " + e.getMessage());
}
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)
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) {
for (RunePowerEntry runePowerEntry : powerEntries) {
PowersBase powerBase = PowersManager.getPowerByToken(powerToken);
PowersBase powerBase = PowersManager.getPowerByToken(runePowerEntry.token);
for (ActionsBase actionBase : powerBase.getActions()) {
String stackType = actionBase.stackType;
if (target.getEffects() != null && target.getEffects().containsKey(stackType))
purgeTokens.add(powerToken);
purgeEntries.add(runePowerEntry);
}
}
powerTokens.removeAll(purgeTokens);
powerEntries.removeAll(purgeEntries);
// Sanity check
if (powerTokens.isEmpty())
if (powerEntries.isEmpty())
return false;
int powerToken = 0;
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()));
}
// Pick random spell from our list of powers
int powerRank = 1;
RunePowerEntry runePowerEntry = powerEntries.get(ThreadLocalRandom.current().nextInt(powerEntries.size()));
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(runePowerEntry.token);
int powerRank = runePowerEntry.rank;
PowersBase mobPower = PowersManager.getPowerByToken(powerToken);
if (mob.isPlayerGuard())
powerRank = getGuardPowerRank(mob);
//check for hit-roll
@ -518,14 +435,8 @@ public class MobAI { @@ -518,14 +435,8 @@ public class MobAI {
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);
}
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);
@ -534,8 +445,8 @@ public class MobAI { @@ -534,8 +445,8 @@ public class MobAI {
msg.setUnknown04(2);
PowersManager.finishUseMobPower(msg, mob, 0, 0);
long randomCooldown = (long) ((ThreadLocalRandom.current().nextInt(10, 15) * 1000) * MobAIThread.AI_CAST_FREQUENCY);
long randomCooldown = (long)((ThreadLocalRandom.current().nextInt(10,15) * 1000) * MobAIThread.AI_CAST_FREQUENCY);
mob.nextCastTime = System.currentTimeMillis() + randomCooldown;
return true;
}
@ -545,6 +456,35 @@ public class MobAI { @@ -545,6 +456,35 @@ public class MobAI {
return false;
}
public static int getGuardPowerRank(Mob mob) {
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;
}
return powerRank;
}
public static void MobCallForHelp(Mob mob) {
try {
@ -564,7 +504,7 @@ public class MobAI { @@ -564,7 +504,7 @@ public class MobAI {
Zone mobCamp = mob.getParentZone();
for (Mob helper : mobCamp.zoneMobSet) {
if (helper.BehaviourType.respondsToCallForHelp && helper.BehaviourType.BehaviourHelperType.equals(mob.BehaviourType)) {
if (helper.behaviourType.respondsToCallForHelp && helper.behaviourType.BehaviourHelperType.equals(mob.behaviourType)) {
helper.setCombatTarget(mob.getCombatTarget());
callGotResponse = true;
}
@ -606,10 +546,10 @@ public class MobAI { @@ -606,10 +546,10 @@ public class MobAI {
//override for guards
if (mob.despawned && mob.isPlayerGuard) {
if (mob.despawned && mob.isPlayerGuard()) {
if (mob.BehaviourType.ordinal() == Enum.MobBehaviourType.GuardMinion.ordinal()) {
if (mob.npcOwner.isAlive() == false || ((Mob) mob.npcOwner).despawned == true) {
if (mob.agentType.equals(Enum.AIAgentType.GUARDMINION)) {
if (mob.guardCaptain.isAlive() == false || ((Mob) mob.guardCaptain).despawned == true) {
//minions don't respawn while guard captain is dead
@ -625,7 +565,7 @@ public class MobAI { @@ -625,7 +565,7 @@ public class MobAI {
//check to send mob home for player guards to prevent exploit of dragging guards away and then teleporting
if (mob.BehaviourType.ordinal() != Enum.MobBehaviourType.Pet1.ordinal())
if (!mob.agentType.equals(Enum.AIAgentType.PET))
CheckToSendMobHome(mob);
return;
@ -638,15 +578,23 @@ public class MobAI { @@ -638,15 +578,23 @@ public class MobAI {
return;
}
//no players loaded, no need to proceed
//no players loaded, no need to proceed unless it's a player guard
boolean bypassLoadedPlayerCheck = false;
if(mob.isPlayerGuard() || mob.isSiege()) {
bypassLoadedPlayerCheck = true;
if(mob.combatTarget != null && mob.combatTarget.getObjectType().equals(Enum.GameObjectType.PlayerCharacter))
if(mob.combatTarget.loc.distanceSquared(mob.loc) > 10000)
mob.setCombatTarget(null);
}
if (mob.playerAgroMap.isEmpty()) {
if(mob.getCombatTarget() != null)
if (mob.playerAgroMap.isEmpty() && !bypassLoadedPlayerCheck) {
if (mob.getCombatTarget() != null)
mob.setCombatTarget(null);
return;
}
if (mob.BehaviourType.ordinal() != Enum.MobBehaviourType.Pet1.ordinal())
if (mob.agentType.equals(Enum.AIAgentType.PET) == false)
CheckToSendMobHome(mob);
if (mob.getCombatTarget() != null) {
@ -673,17 +621,14 @@ public class MobAI { @@ -673,17 +621,14 @@ public class MobAI {
}
}
switch (mob.BehaviourType) {
switch (mob.behaviourType) {
case GuardCaptain:
GuardCaptainLogic(mob);
break;
case GuardMinion:
GuardMinionLogic(mob);
break;
case GuardWallArcher:
GuardWallArcherLogic(mob);
GuardLogic(mob);
break;
case Pet1:
case SiegeEngine:
PetLogic(mob);
break;
case HamletGuard:
@ -707,7 +652,7 @@ public class MobAI { @@ -707,7 +652,7 @@ public class MobAI {
if (!aiAgent.isAlive())
return;
ConcurrentHashMap<Integer, Boolean> loadedPlayers = aiAgent.playerAgroMap;
ConcurrentHashMap<Integer, Float> loadedPlayers = aiAgent.playerAgroMap;
for (Entry playerEntry : loadedPlayers.entrySet()) {
@ -747,7 +692,6 @@ public class MobAI { @@ -747,7 +692,6 @@ public class MobAI {
aiAgent.setCombatTarget(loadedPlayer);
return;
}
}
if (aiAgent.getCombatTarget() == null) {
@ -782,47 +726,45 @@ public class MobAI { @@ -782,47 +726,45 @@ public class MobAI {
mob.updateLocation();
switch (mob.BehaviourType) {
switch (mob.behaviourType) {
case Pet1:
if (mob.getOwner() == null)
return;
if (!mob.playerAgroMap.containsKey(mob.getOwner().getObjectUUID())) {
if (mob.guardCaptain == null)
return;
//mob no longer has its owner loaded, translocate pet to owner
//mob no longer has its owner loaded, translate pet to owner
MovementManager.translocate(mob, mob.getOwner().getLoc(), null);
if (!mob.playerAgroMap.containsKey(mob.guardCaptain.getObjectUUID())) {
MovementManager.translocate(mob, mob.guardCaptain.getLoc());
return;
}
if (mob.getCombatTarget() == null) {
//move back to owner
if (CombatUtilities.inRange2D(mob, mob.getOwner(), 6))
if (CombatUtilities.inRange2D(mob, mob.guardCaptain, 6))
return;
mob.destination = mob.getOwner().getLoc();
MovementUtilities.moveToLocation(mob, mob.destination, 5);
mob.destination = mob.guardCaptain.getLoc();
MovementUtilities.moveToLocation(mob, mob.destination, 5, false);
} else
chaseTarget(mob);
break;
case GuardMinion:
if (!mob.npcOwner.isAlive() || ((Mob) mob.npcOwner).despawned)
randomGuardPatrolPoint(mob);
else {
if (mob.getCombatTarget() != null) {
chaseTarget(mob);
}
}
break;
default:
if (mob.getCombatTarget() == null) {
if (!mob.isMoving())
Patrol(mob);
else {
if (!mob.isMoving()) {
// Minions only patrol on their own if captain is dead.
if (mob.agentType.equals(Enum.AIAgentType.GUARDMINION) == false)
Patrol(mob);
else if (mob.guardCaptain.isAlive() == false)
Patrol(mob);
} else
mob.stopPatrolTime = System.currentTimeMillis();
}
} else {
chaseTarget(mob);
}
@ -893,7 +835,8 @@ public class MobAI { @@ -893,7 +835,8 @@ public class MobAI {
if (mob.getCombatTarget() == null)
return;
if (mob.getCombatTarget().getObjectType().equals(Enum.GameObjectType.PlayerCharacter) && MovementUtilities.inRangeDropAggro(mob, (PlayerCharacter) mob.getCombatTarget()) == false && mob.BehaviourType.ordinal() != Enum.MobBehaviourType.Pet1.ordinal()) {
if (mob.getCombatTarget().getObjectType().equals(Enum.GameObjectType.PlayerCharacter) && MovementUtilities.inRangeDropAggro(mob, (PlayerCharacter) mob.getCombatTarget()) == false &&
mob.agentType.equals(Enum.AIAgentType.PET) == false) {
mob.setCombatTarget(null);
return;
@ -909,15 +852,6 @@ public class MobAI { @@ -909,15 +852,6 @@ public class MobAI {
private static void CheckToSendMobHome(Mob mob) {
try {
if (mob.BehaviourType.isAgressive) {
if (mob.isPlayerGuard()) {
if (mob.BehaviourType.ordinal() == Enum.MobBehaviourType.GuardCaptain.ordinal())
CheckForPlayerGuardAggro(mob);
} else {
CheckForAggro(mob);
}
}
if (mob.getCombatTarget() != null && CombatUtilities.inRange2D(mob, mob.getCombatTarget(), MobAIThread.AI_BASE_AGGRO_RANGE * 0.5f))
return;
@ -932,13 +866,15 @@ public class MobAI { @@ -932,13 +866,15 @@ public class MobAI {
PowersManager.useMobPower(mob, mob, recall, 40);
mob.setCombatTarget(null);
if (mob.BehaviourType.ordinal() == Enum.MobBehaviourType.GuardCaptain.ordinal() && mob.isAlive()) {
if (mob.agentType.equals(Enum.AIAgentType.GUARDCAPTAIN) && mob.isAlive()) {
//guard captain pulls his minions home with him
for (Entry<Mob, Integer> minion : mob.siegeMinionMap.entrySet()) {
PowersManager.useMobPower(minion.getKey(), minion.getKey(), recall, 40);
minion.getKey().setCombatTarget(null);
for (Integer minionUUID : mob.minions) {
Mob minion = Mob.getMob(minionUUID);
PowersManager.useMobPower(minion, minion, recall, 40);
minion.setCombatTarget(null);
}
}
}
@ -948,8 +884,8 @@ public class MobAI { @@ -948,8 +884,8 @@ public class MobAI {
PowersManager.useMobPower(mob, mob, recall, 40);
mob.setCombatTarget(null);
for (Entry playerEntry : mob.playerAgroMap.entrySet())
PlayerCharacter.getFromCache((int) playerEntry.getKey()).setHateValue(0);
for (Integer playerEntry : mob.playerAgroMap.keySet())
mob.playerAgroMap.put(playerEntry, 0f);
}
} catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: CheckToSendMobHome" + " " + e.getMessage());
@ -960,16 +896,10 @@ public class MobAI { @@ -960,16 +896,10 @@ public class MobAI {
try {
float rangeSquared = mob.getRange() * mob.getRange();
float distanceSquared = mob.getLoc().distanceSquared2D(mob.getCombatTarget().getLoc());
if(mob.isMoving() == true && distanceSquared < rangeSquared - 50) {
mob.destination = mob.getLoc();
MovementUtilities.moveToLocation(mob, mob.destination, 0);
} else if (CombatUtilities.inRange2D(mob, mob.getCombatTarget(), mob.getRange()) == false) {
if (CombatUtilities.inRange2D(mob, mob.getCombatTarget(), mob.getRange()) == false) {
if (mob.getRange() > 15) {
mob.destination = mob.getCombatTarget().getLoc();
MovementUtilities.moveToLocation(mob, mob.destination, 0);
MovementUtilities.moveToLocation(mob, mob.destination, 0, false);
} else {
//check if building
@ -978,11 +908,11 @@ public class MobAI { @@ -978,11 +908,11 @@ public class MobAI {
case PlayerCharacter:
case Mob:
mob.destination = MovementUtilities.GetDestinationToCharacter(mob, (AbstractCharacter) mob.getCombatTarget());
MovementUtilities.moveToLocation(mob, mob.destination, mob.getRange() + 1);
MovementUtilities.moveToLocation(mob, mob.destination, mob.getRange() + 1, false);
break;
case Building:
mob.destination = mob.getCombatTarget().getLoc();
MovementUtilities.moveToLocation(mob, mob.getCombatTarget().getLoc(), 0);
MovementUtilities.moveToLocation(mob, mob.getCombatTarget().getLoc(), 0, false);
break;
}
}
@ -1003,17 +933,17 @@ public class MobAI { @@ -1003,17 +933,17 @@ public class MobAI {
//dont scan self.
if (mob.equals(awoMob) || (mob.agentType.equals(Enum.AIAgentType.GUARD)) == true)
if (mob.equals(awoMob) || (mob.agentType.equals(Enum.AIAgentType.GUARDCAPTAIN)) == true)
continue;
Mob aggroMob = (Mob) awoMob;
//don't attack other guards
if ((aggroMob.agentType.equals(Enum.AIAgentType.GUARD)))
if ((aggroMob.agentType.equals(Enum.AIAgentType.GUARDCAPTAIN)))
continue;
if(aggroMob.BehaviourType.equals(Enum.MobBehaviourType.Pet1))
if (aggroMob.agentType.equals(Enum.AIAgentType.PET))
continue;
if (mob.getLoc().distanceSquared2D(aggroMob.getLoc()) > sqr(50))
@ -1026,75 +956,33 @@ public class MobAI { @@ -1026,75 +956,33 @@ public class MobAI {
}
}
public static void GuardCaptainLogic(Mob mob) {
public static void GuardLogic(Mob mob) {
try {
if (mob.getCombatTarget() == null)
if (mob.getCombatTarget() == null) {
CheckForPlayerGuardAggro(mob);
} else {
//do not need to look to change target if target is already null
AbstractWorldObject newTarget = ChangeTargetFromHateValue(mob);
AbstractWorldObject newTarget = ChangeTargetFromHateValue(mob);
if (newTarget != null) {
if (newTarget.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) {
if (GuardCanAggro(mob, (PlayerCharacter) newTarget))
mob.setCombatTarget(newTarget);
} else
mob.setCombatTarget(newTarget);
}
CheckMobMovement(mob);
CheckForAttack(mob);
} catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: GuardCaptainLogic" + " " + e.getMessage());
}
}
public static void GuardMinionLogic(Mob mob) {
try {
if (!mob.npcOwner.isAlive()) {
if (mob.getCombatTarget() == null) {
CheckForPlayerGuardAggro(mob);
} else {
AbstractWorldObject newTarget = ChangeTargetFromHateValue(mob);
if (newTarget != null) {
if (newTarget != null) {
if (newTarget.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) {
if (GuardCanAggro(mob, (PlayerCharacter) newTarget))
mob.setCombatTarget(newTarget);
} else
if (newTarget.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) {
if (GuardCanAggro(mob, (PlayerCharacter) newTarget))
mob.setCombatTarget(newTarget);
}
} else
mob.setCombatTarget(newTarget);
}
}else {
if (mob.npcOwner.getCombatTarget() != null)
mob.setCombatTarget(mob.npcOwner.getCombatTarget());
else
if (mob.getCombatTarget() != null)
mob.setCombatTarget(null);
}
CheckMobMovement(mob);
CheckForAttack(mob);
} catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: GuardMinionLogic" + " " + e.getMessage());
}
}
public static void GuardWallArcherLogic(Mob mob) {
if(mob.behaviourType.canRoam)
CheckMobMovement(mob);//all guards that can move check to move
if(mob.combatTarget != null)
CheckForAttack(mob); //only check to attack if combat target is not null
try {
if (mob.getCombatTarget() == null)
CheckForPlayerGuardAggro(mob);
else
CheckForAttack(mob);
} catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: GuardWallArcherLogic" + " " + e.getMessage());
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: GuardLogic" + " " + e.getMessage());
}
}
@ -1102,11 +990,11 @@ public class MobAI { @@ -1102,11 +990,11 @@ public class MobAI {
try {
if (mob.getOwner() == null && mob.isNecroPet() == false && mob.isSiege() == false)
if (mob.guardCaptain == null && mob.isNecroPet() == false && mob.isSiege() == false)
if (ZoneManager.getSeaFloor().zoneMobSet.contains(mob))
mob.killCharacter("no owner");
if (MovementUtilities.canMove(mob) && mob.BehaviourType.canRoam)
if (MovementUtilities.canMove(mob) && mob.behaviourType.canRoam)
CheckMobMovement(mob);
CheckForAttack(mob);
@ -1156,7 +1044,7 @@ public class MobAI { @@ -1156,7 +1044,7 @@ public class MobAI {
if (mob.getCombatTarget() != null && mob.playerAgroMap.containsKey(mob.getCombatTarget().getObjectUUID()) == false)
mob.setCombatTarget(null);
if (mob.BehaviourType.isAgressive) {
if (mob.behaviourType.isAgressive) {
AbstractWorldObject newTarget = ChangeTargetFromHateValue(mob);
@ -1164,7 +1052,7 @@ public class MobAI { @@ -1164,7 +1052,7 @@ public class MobAI {
mob.setCombatTarget(newTarget);
else {
if (mob.getCombatTarget() == null) {
if (mob.BehaviourType == Enum.MobBehaviourType.HamletGuard)
if (mob.behaviourType == Enum.MobBehaviourType.HamletGuard)
SafeGuardAggro(mob); //safehold guard
else
CheckForAggro(mob); //normal aggro
@ -1174,12 +1062,12 @@ public class MobAI { @@ -1174,12 +1062,12 @@ public class MobAI {
//check if mob can move for patrol or moving to target
if (mob.BehaviourType.canRoam)
if (mob.behaviourType.canRoam)
CheckMobMovement(mob);
//check if mob can attack if it isn't wimpy
if (!mob.BehaviourType.isWimpy && mob.getCombatTarget() != null)
if (!mob.behaviourType.isWimpy && mob.getCombatTarget() != null)
CheckForAttack(mob);
} catch (Exception e) {
@ -1196,7 +1084,16 @@ public class MobAI { @@ -1196,7 +1084,16 @@ public class MobAI {
if (!mob.isAlive())
return;
ConcurrentHashMap<Integer, Boolean> loadedPlayers = mob.playerAgroMap;
// Defer to captain if possible for current target
if (mob.agentType.equals(Enum.AIAgentType.GUARDMINION) &&
mob.guardCaptain.isAlive()
&& mob.guardCaptain.combatTarget != null) {
mob.setCombatTarget(mob.guardCaptain.combatTarget);
return;
}
ConcurrentHashMap<Integer, Float> loadedPlayers = mob.playerAgroMap;
for (Entry playerEntry : loadedPlayers.entrySet()) {
@ -1231,27 +1128,39 @@ public class MobAI { @@ -1231,27 +1128,39 @@ public class MobAI {
mob.setCombatTarget(loadedPlayer);
return;
}
}
if (mob.getCombatTarget() == null) {
//look for siege equipment to aggro if no players found to aggro
HashSet<AbstractWorldObject> awoList = WorldGrid.getObjectsInRangePartial(mob, MobAIThread.AI_BASE_AGGRO_RANGE, MBServerStatics.MASK_SIEGE);
for (AbstractWorldObject awoMob : awoList) {
Mob aggroMob = (Mob) awoMob;
if(GuardCanAggro(mob,aggroMob)) {
mob.setCombatTarget(aggroMob);
return;
}
}
}
} catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: CheckForPlayerGuardAggro" + e.getMessage());
}
}
public static Boolean GuardCanAggro(Mob mob, PlayerCharacter target) {
public static Boolean GuardCanAggro(Mob mob, AbstractCharacter target) {
try {
if (mob.guardedCity.cityOutlaws.contains(target.getObjectUUID()) == true)
return true;
if (mob.getGuild().getNation().equals(target.getGuild().getNation()))
return false;
if (mob.BehaviourType.ordinal() == Enum.MobBehaviourType.GuardMinion.ordinal()) {
if (((Mob) mob.npcOwner).building.getCity().cityOutlaws.contains(target.getObjectUUID()) == true) {
return true;
}
} else if (mob.building.getCity().cityOutlaws.contains(target.getObjectUUID()) == true) {
return true;
}
//first check condemn list for aggro allowed (allies button is checked)
if (ZoneManager.getCityAtLocation(mob.getLoc()).getTOL().reverseKOS) {
@ -1329,17 +1238,19 @@ public class MobAI { @@ -1329,17 +1238,19 @@ public class MobAI {
MovementUtilities.aiMove(mob, mob.destination, true);
if (mob.BehaviourType.ordinal() == Enum.MobBehaviourType.GuardCaptain.ordinal()) {
for (Entry<Mob, Integer> minion : mob.siegeMinionMap.entrySet()) {
if (mob.agentType.equals(Enum.AIAgentType.GUARDCAPTAIN)) {
for (Integer minionUUID : mob.minions) {
Mob minion = Mob.getMob(minionUUID);
//make sure mob is out of combat stance
if (minion.getKey().despawned == false) {
if (MovementUtilities.canMove(minion.getKey())) {
Vector3f minionOffset = Formation.getOffset(2, minion.getValue() + 3);
minion.getKey().updateLocation();
if (minion.despawned == false) {
if (MovementUtilities.canMove(minion)) {
Vector3f minionOffset = Formation.getOffset(2, mob.minions.indexOf(minionUUID) + 3);
minion.updateLocation();
Vector3fImmutable formationPatrolPoint = new Vector3fImmutable(mob.destination.x + minionOffset.x, mob.destination.y, mob.destination.z + minionOffset.z);
MovementUtilities.aiMove(minion.getKey(), formationPatrolPoint, true);
MovementUtilities.aiMove(minion, formationPatrolPoint, true);
}
}
}
@ -1356,7 +1267,7 @@ public class MobAI { @@ -1356,7 +1267,7 @@ public class MobAI {
float CurrentHateValue = 0;
if (mob.getCombatTarget() != null && mob.getCombatTarget().getObjectType().equals(Enum.GameObjectType.PlayerCharacter))
CurrentHateValue = ((PlayerCharacter) mob.getCombatTarget()).getHateValue();
CurrentHateValue = mob.playerAgroMap.get(mob.combatTarget.getObjectUUID()).floatValue();
AbstractWorldObject mostHatedTarget = null;
@ -1367,8 +1278,8 @@ public class MobAI { @@ -1367,8 +1278,8 @@ public class MobAI {
if (potentialTarget.equals(mob.getCombatTarget()))
continue;
if (potentialTarget != null && potentialTarget.getHateValue() > CurrentHateValue && MovementUtilities.inRangeToAggro(mob, potentialTarget)) {
CurrentHateValue = potentialTarget.getHateValue();
if (potentialTarget != null && mob.playerAgroMap.get(potentialTarget.getObjectUUID()).floatValue() > CurrentHateValue && MovementUtilities.inRangeToAggro(mob, potentialTarget)) {
CurrentHateValue = mob.playerAgroMap.get(potentialTarget.getObjectUUID()).floatValue();
mostHatedTarget = potentialTarget;
}

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

@ -48,7 +48,7 @@ public class CombatUtilities { @@ -48,7 +48,7 @@ public class CombatUtilities {
}
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) {
@ -264,19 +264,9 @@ public class CombatUtilities { @@ -264,19 +264,9 @@ public class CombatUtilities {
swingIsBlock(agent, target, passiveAnim);
return;
}
if (agent.getEquip().get(1) != null && agent.getEquip().get(2) != null && agent.getEquip().get(2).getItemBase().isShield() == false) {
//mob is duel wielding and should conduct an attack for each hand
ItemBase weapon1 = agent.getEquip().get(1).getItemBase();
double range1 = getMaxDmg(weapon1.getMinDamage(), agent, weapon1) - getMinDmg(weapon1.getMinDamage(), agent, weapon1);
double damage1 = getMinDmg(weapon1.getMinDamage(), agent, weapon1) + ((ThreadLocalRandom.current().nextFloat() * range1) + (ThreadLocalRandom.current().nextFloat() * range1)) / 2;
swingIsDamage(agent, target, (float) damage1, CombatManager.getSwingAnimation(weapon1, null, true));
ItemBase weapon2 = agent.getEquip().get(2).getItemBase();
double range2 = getMaxDmg(weapon2.getMinDamage(), agent, weapon2) - getMinDmg(weapon2.getMinDamage(), agent, weapon2);
double damage2 = getMinDmg(weapon2.getMinDamage(), agent, weapon2) + ((ThreadLocalRandom.current().nextFloat() * range2) + (ThreadLocalRandom.current().nextFloat() * range2)) / 2;
swingIsDamage(agent, target, (float) damage2, CombatManager.getSwingAnimation(weapon1, null, false));
} else {
swingIsDamage(agent, target, determineDamage(agent), anim);
}
swingIsDamage(agent, target, determineDamage(agent), anim);
if (agent.getWeaponPower() != null)
agent.getWeaponPower().attack(target, MBServerStatics.ONE_MINUTE);
@ -319,19 +309,10 @@ public class CombatUtilities { @@ -319,19 +309,10 @@ public class CombatUtilities {
if (target == null)
return 0;
float damage = 0;
int damage = 0;
DamageType dt = getDamageType(agent);
if ((agent.agentType.equals(AIAgentType.PET)) == true || agent.isPet() == true || agent.isNecroPet() == true) {
damage = calculatePetDamage(agent);
} else if (agent.isPlayerGuard() == true) {
//damage = calculateGuardDamage(agent);
damage = calculateMobDamage(agent);
} else if (agent.getLevel() > 80) {
damage = calculateEpicDamage(agent);
} else {
damage = calculateMobDamage(agent);
}
damage = ThreadLocalRandom.current().nextInt((int)getMinDmg(agent), (int)getMaxDmg(agent) + 1);
if (AbstractWorldObject.IsAbstractCharacter(target)) {
if (((AbstractCharacter) target).isSit()) {
damage *= 2.5f; //increase damage if sitting
@ -357,158 +338,16 @@ public class CombatUtilities { @@ -357,158 +338,16 @@ public class CombatUtilities {
return dt;
}
public static int calculatePetDamage(Mob agent) {
//damage calc for pet
float range;
float damage;
float min = 40;
float max = 60;
float dmgMultiplier = 1 + agent.getBonuses().getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None);
double minDmg = getMinDmg(min, agent, null);
double maxDmg = getMaxDmg(max, agent, null);
dmgMultiplier += agent.getLevel() * 0.1f;
range = (float) (maxDmg - minDmg);
damage = min + ((ThreadLocalRandom.current().nextFloat() * range) + (ThreadLocalRandom.current().nextFloat() * range)) / 2;
return (int) (damage * dmgMultiplier);
}
public static int calculateGuardDamage(Mob agent) {
//damage calc for guard
ItemBase weapon = agent.getEquip().get(1).getItemBase();
AbstractWorldObject target = agent.getCombatTarget();
float dmgMultiplier = 1 + agent.getBonuses().getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None);
double minDmg = weapon.getMinDamage();
double maxDmg = weapon.getMaxDamage();
double min = getMinDmg(minDmg, agent, weapon);
double max = getMaxDmg(maxDmg, agent, weapon);
DamageType dt = weapon.getDamageType();
double range = max - min;
double damage = min + ((ThreadLocalRandom.current().nextFloat() * range) + (ThreadLocalRandom.current().nextFloat() * range)) / 2;
if (AbstractWorldObject.IsAbstractCharacter(target))
if (((AbstractCharacter) target).isSit())
damage *= 2.5f; //increase damage if sitting
if (AbstractWorldObject.IsAbstractCharacter(target))
return (int) (((AbstractCharacter) target).getResists().getResistedDamage(agent, (AbstractCharacter) target, dt, (float) damage, 0) * dmgMultiplier);
return 0;
}
public static int calculateEpicDamage(Mob agent) {
//handle r8 mob damage
DamageType dt = DamageType.Crush;
AbstractWorldObject target = agent.getCombatTarget();
float dmgMultiplier = 1 + agent.getBonuses().getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None);
double min = agent.getMinDamageHandOne();
double max = agent.getMaxDamageHandOne();
if (agent.getEquip().get(1) != null) {
if (agent.getEquip().get(1).getItemBase() != null) {
dt = agent.getEquip().get(1).getItemBase().getDamageType();
min = agent.getMinDamageHandOne();
max = agent.getMaxDamageHandOne();
} else if (agent.getEquip().get(2).getItemBase() != null && agent.getEquip().get(2).getItemBase().isShield() == false) {
dt = agent.getEquip().get(2).getItemBase().getDamageType();
min = agent.getMinDamageHandTwo();
max = agent.getMaxDamageHandTwo();
}
}
double range = max - min;
double damage = min + ((ThreadLocalRandom.current().nextFloat() * range) + (ThreadLocalRandom.current().nextFloat() * range)) / 2;
return (int) (((AbstractCharacter) target).getResists().getResistedDamage(agent, (AbstractCharacter) target, dt, (float) damage, 0) * dmgMultiplier);
}
public static int calculateMobDamage(Mob agent) {
ItemBase weapon = null;
double minDmg;
double maxDmg;
DamageType dt;
//main hand or offhand damage
if (agent.getEquip().get(1) != null)
weapon = agent.getEquip().get(1).getItemBase();
else if (agent.getEquip().get(2) != null)
weapon = agent.getEquip().get(2).getItemBase();
if (weapon != null) {
minDmg = getMinDmg(weapon.getMinDamage(), agent, weapon);
maxDmg = getMaxDmg(weapon.getMaxDamage(), agent, weapon);
dt = weapon.getDamageType();
} else {
minDmg = agent.getMobBase().getDamageMin();
maxDmg = agent.getMobBase().getDamageMax();
dt = DamageType.Crush;
}
AbstractWorldObject target = agent.getCombatTarget();
float dmgMultiplier = 1 + agent.getBonuses().getFloatPercentAll(ModType.MeleeDamageModifier, SourceType.None);
double range = maxDmg - minDmg;
double damage = minDmg + ((ThreadLocalRandom.current().nextFloat() * range) + (ThreadLocalRandom.current().nextFloat() * range)) / 2;
if (AbstractWorldObject.IsAbstractCharacter(target))
if (((AbstractCharacter) target).isSit())
damage *= 2.5f; //increase damage if sitting
if (AbstractWorldObject.IsAbstractCharacter(target))
return (int) (((AbstractCharacter) target).getResists().getResistedDamage(agent, (AbstractCharacter) target, dt, (float) damage, 0) * dmgMultiplier);
return 0;
public static double getMinDmg(Mob agent) {
if(agent.equip.get(2) != null && !agent.equip.get(2).getItemBase().isShield())
return agent.minDamageHandTwo;
else return agent.minDamageHandOne;
}
public static double getMinDmg(double min, Mob agent, ItemBase weapon) {
int primary = agent.getStatStrCurrent();
int secondary = agent.getStatDexCurrent();
int focusLevel = 0;
int masteryLevel = 0;
if (weapon != null) {
if (weapon.isStrBased() == true) {
primary = agent.getStatStrCurrent();
secondary = agent.getStatDexCurrent();
} else {
primary = agent.getStatDexCurrent();
secondary = agent.getStatStrCurrent();
if (agent.getSkills().containsKey(weapon.getSkillRequired())) {
focusLevel = (int) agent.getSkills().get(weapon.getSkillRequired()).getModifiedAmount();
}
if (agent.getSkills().containsKey(weapon.getMastery())) {
masteryLevel = (int) agent.getSkills().get(weapon.getMastery()).getModifiedAmount();
}
}
}
return min * (pow(0.0048 * primary + .049 * (primary - 0.75), 0.5) + pow(0.0066 * secondary + 0.064 * (secondary - 0.75), 0.5) + +0.01 * (focusLevel + masteryLevel));
}
public static double getMaxDmg(double max, Mob agent, ItemBase weapon) {
int primary = agent.getStatStrCurrent();
int secondary = agent.getStatDexCurrent();
int focusLevel = 0;
int masteryLevel = 0;
if (weapon != null) {
if (weapon.isStrBased() == true) {
primary = agent.getStatStrCurrent();
secondary = agent.getStatDexCurrent();
} else {
primary = agent.getStatDexCurrent();
secondary = agent.getStatStrCurrent();
}
if (agent.getSkills().containsKey(weapon.getSkillRequired()))
focusLevel = (int) agent.getSkills().get(weapon.getSkillRequired()).getModifiedAmount();
if (agent.getSkills().containsKey(weapon.getSkillRequired()))
masteryLevel = (int) agent.getSkills().get(weapon.getMastery()).getModifiedAmount();
}
return max * (pow(0.0124 * primary + 0.118 * (primary - 0.75), 0.5) + pow(0.0022 * secondary + 0.028 * (secondary - 0.75), 0.5) + 0.0075 * (focusLevel + masteryLevel));
public static double getMaxDmg(Mob agent) {
if(agent.equip.get(2) != null && !agent.equip.get(2).getItemBase().isShield())
return agent.maxDamageHandTwo;
else return agent.maxDamageHandOne;
}
}

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

@ -13,10 +13,10 @@ import engine.Enum; @@ -13,10 +13,10 @@ import engine.Enum;
import engine.Enum.GameObjectType;
import engine.Enum.ModType;
import engine.Enum.SourceType;
import engine.mobileAI.Threads.MobAIThread;
import engine.exception.MsgSendException;
import engine.gameManager.MovementManager;
import engine.math.Vector3fImmutable;
import engine.mobileAI.Threads.MobAIThread;
import engine.net.client.msg.MoveToPointMsg;
import engine.objects.*;
import org.pmw.tinylog.Logger;
@ -38,7 +38,7 @@ public class MovementUtilities { @@ -38,7 +38,7 @@ public class MovementUtilities {
if (agent.getContract() != null)
guardCaptain = agent;
else
guardCaptain = (Mob) agent.npcOwner;
guardCaptain = (Mob) agent.guardCaptain;
if (guardCaptain != null) {
Building barracks = guardCaptain.building;
@ -147,7 +147,7 @@ public class MovementUtilities { @@ -147,7 +147,7 @@ public class MovementUtilities {
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, boolean isWalking) {
try {
//don't move farther than 30 units from player.
@ -158,7 +158,7 @@ public class MovementUtilities { @@ -158,7 +158,7 @@ public class MovementUtilities {
agent.setFaceDir(newLoc.subtract2D(agent.getLoc()).normalize());
aiMove(agent, newLoc, false);
aiMove(agent, newLoc, isWalking);
} catch (Exception e) {
Logger.error(e.toString());
}
@ -244,10 +244,10 @@ public class MovementUtilities { @@ -244,10 +244,10 @@ public class MovementUtilities {
msg.setSourceID(agent.getObjectUUID());
msg.setStartCoord(startLoc);
msg.setEndCoord(endLoc);
msg.setUnknown01(-1);
msg.setInBuildingFloor(-1);
msg.setInBuilding(-1);
msg.setTargetType(0);
msg.setTargetID(0);
msg.setStartLocType(0);
msg.setInBuildingUUID(0);
try {

2
src/engine/net/DispatchMessage.java

@ -28,7 +28,7 @@ import static engine.net.MessageDispatcher.maxRecipients; @@ -28,7 +28,7 @@ import static engine.net.MessageDispatcher.maxRecipients;
/*
* Dispatch Message is the main interface to Magicbane's threaded
* asynch message delivery system.
* async message delivery system.
*/
public class DispatchMessage {

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

@ -643,7 +643,7 @@ public class ClientMessagePump implements NetMsgHandler { @@ -643,7 +643,7 @@ public class ClientMessagePump implements NetMsgHandler {
moveMsg.setStartCoord(sourcePlayer.getLoc());
moveMsg.setEndCoord(sourcePlayer.getLoc());
moveMsg.setInBuilding(-1);
moveMsg.setUnknown01(-1);
moveMsg.setInBuildingFloor(-1);
dispatch = Dispatch.borrow(sourcePlayer, moveMsg);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY);
@ -1892,9 +1892,6 @@ public class ClientMessagePump implements NetMsgHandler { @@ -1892,9 +1892,6 @@ public class ClientMessagePump implements NetMsgHandler {
case POWER:
PowersManager.usePower((PerformActionMsg) msg, origin, false);
break;
case REQUESTMELEEATTACK:
CombatManager.setAttackTarget((AttackCmdMsg) msg, origin);
break;
case READYTOENTER:
break;
case OPENVAULT:

2
src/engine/net/client/Protocol.java

@ -173,7 +173,7 @@ public enum Protocol { @@ -173,7 +173,7 @@ public enum Protocol {
REPAIROBJECT(0x782219CE, RepairMsg.class, null), //Repair Window Req/Ack, RepairObject item Req/Ack
REQUESTCONTENTS(0xA786B0A2, LootWindowRequestMsg.class, null), // MoveObjectToContainer Window Request
REQUESTGUILDLIST(0x85DCC6D7, ReqGuildListMsg.class, RequestGuildListHandler.class),
REQUESTMELEEATTACK(0x98C71545, AttackCmdMsg.class, null), // Attack
REQUESTMELEEATTACK(0x98C71545, AttackCmdMsg.class, AttackCmdMsgHandler.class), // Attack
REQUESTMEMBERLIST(0x3235E5EA, GuildControlMsg.class, GuildControlHandler.class), // Part of Promote/Demote, Also Player History
REQUESTTOOPENBANK(0xF26E453F, null, null), // RequestToOpenBankMsg
REQUESTTOTRADE(0x4D84259B, TradeRequestMsg.class, null), // Trade Request

86
src/engine/net/client/handlers/AttackCmdMsgHandler.java

@ -0,0 +1,86 @@ @@ -0,0 +1,86 @@
package engine.net.client.handlers;
import engine.Enum;
import engine.exception.MsgSendException;
import engine.gameManager.BuildingManager;
import engine.gameManager.CombatManager;
import engine.net.client.ClientConnection;
import engine.net.client.msg.AttackCmdMsg;
import engine.net.client.msg.ClientNetMsg;
import engine.net.client.msg.TargetedActionMsg;
import engine.objects.*;
/*
* @Author:
* @Summary: Processes application protocol message which keeps
* client's tcp connection open.
*/
public class AttackCmdMsgHandler extends AbstractClientMsgHandler {
public AttackCmdMsgHandler() {
super(AttackCmdMsg.class);
}
@Override
protected boolean _handleNetMsg(ClientNetMsg baseMsg, ClientConnection origin) throws MsgSendException {
PlayerCharacter playerCharacter = origin.getPlayerCharacter();
// Member variable declaration
AttackCmdMsg msg;
// Member variable assignment
msg = (AttackCmdMsg) baseMsg;
if (TargetedActionMsg.un2cnt == 60 || TargetedActionMsg.un2cnt == 70)
return true;
if (playerCharacter == null)
return true;
AbstractWorldObject target = null;
Enum.GameObjectType targetType;
targetType = Enum.GameObjectType.values()[msg.getTargetType()];
switch(targetType){
case Mob:
target = Mob.getMob(msg.getTargetID());
break;
case PlayerCharacter:
target = PlayerCharacter.getPlayerCharacter(msg.getTargetID());
break;
case Building:
target = BuildingManager.getBuilding(msg.getTargetID());
break;
case NPC:
target = NPC.getNPC(msg.getTargetID());
break;
}
if(target == null) {
playerCharacter.setCombatTarget(null);
return true; // cannot attack a null target
}
//set sources target
playerCharacter.setCombatTarget(target);
//put in combat if not already
if (!playerCharacter.isCombat())
CombatManager.toggleCombat(true, origin);
//make character stand if sitting
if (playerCharacter.isSit())
CombatManager.toggleSit(false, origin);
CombatManager.AttackTarget(playerCharacter, target);
return true;
}
}

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

@ -8,7 +8,6 @@ import engine.gameManager.BuildingManager; @@ -8,7 +8,6 @@ import engine.gameManager.BuildingManager;
import engine.gameManager.DbManager;
import engine.gameManager.NPCManager;
import engine.gameManager.SessionManager;
import engine.math.Vector3fImmutable;
import engine.net.Dispatch;
import engine.net.DispatchMessage;
import engine.net.client.ClientConnection;
@ -16,9 +15,6 @@ import engine.net.client.msg.*; @@ -16,9 +15,6 @@ import engine.net.client.msg.*;
import engine.objects.*;
import org.pmw.tinylog.Logger;
import java.util.ArrayList;
import java.util.HashMap;
/*
* @Author:
* @Summary: Processes application protocol message which
@ -27,8 +23,6 @@ import java.util.HashMap; @@ -27,8 +23,6 @@ import java.util.HashMap;
public class MinionTrainingMsgHandler extends AbstractClientMsgHandler {
public static HashMap<Integer, ArrayList<Integer>> _minionsByCaptain = null;
public MinionTrainingMsgHandler() {
super(MinionTrainingMessage.class);
}
@ -38,9 +32,9 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler { @@ -38,9 +32,9 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler {
MinionTrainingMessage minionMsg = (MinionTrainingMessage) baseMsg;
PlayerCharacter player = SessionManager.getPlayerCharacter(origin);
PlayerCharacter playerCharacter = SessionManager.getPlayerCharacter(origin);
if (player == null)
if (playerCharacter == null)
return true;
if (minionMsg.getNpcType() == Enum.GameObjectType.NPC.ordinal()) {
@ -50,23 +44,24 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler { @@ -50,23 +44,24 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler {
if (npc == null)
return true;
Building b = BuildingManager.getBuildingFromCache(minionMsg.getBuildingID());
Building building = BuildingManager.getBuildingFromCache(minionMsg.getBuildingID());
if (b == null)
if (building == null)
return true;
//clear minion
if (npc.minionLock.writeLock().tryLock()) {
try {
if (minionMsg.getType() == 2) {
Mob toRemove = Mob.getFromCache(minionMsg.getUUID());
if (!npc.getSiegeMinionMap().containsKey(toRemove))
if (!npc.minions.contains(toRemove.getObjectUUID()))
return true;
npc.getSiegeMinionMap().remove(toRemove);
npc.minions.remove(Integer.valueOf(toRemove.getObjectUUID()));
WorldGrid.RemoveWorldObject(toRemove);
@ -74,33 +69,35 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler { @@ -74,33 +69,35 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler {
toRemove.getParentZone().zoneMobSet.remove(toRemove);
DbManager.removeFromCache(toRemove);
PlayerCharacter petOwner = toRemove.getOwner();
if (petOwner != null) {
petOwner.setPet(null);
toRemove.setOwner(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.
if(toRemove.guardCaptain.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) {
PlayerCharacter petOwner = (PlayerCharacter) toRemove.guardCaptain;
if (petOwner != null) {
petOwner.setPet(null);
toRemove.guardCaptain = null;
PetMsg petMsg = new PetMsg(5, null);
Dispatch dispatch = Dispatch.borrow(petOwner, petMsg);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
}
}
ManageCityAssetsMsg mca1 = new ManageCityAssetsMsg(player, b);
ManageCityAssetsMsg mca1 = new ManageCityAssetsMsg(playerCharacter, building);
mca1.actionType = 3;
mca1.setTargetType(b.getObjectType().ordinal());
mca1.setTargetID(b.getObjectUUID());
mca1.setTargetType(building.getObjectType().ordinal());
mca1.setTargetID(building.getObjectUUID());
mca1.setTargetType3(npc.getObjectType().ordinal());
mca1.setTargetID3(npc.getObjectUUID());
mca1.setAssetName1(b.getName());
mca1.setAssetName1(building.getName());
mca1.setUnknown54(1);
Dispatch dispatch = Dispatch.borrow(player, mca1);
Dispatch dispatch = Dispatch.borrow(playerCharacter, mca1);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
ManageNPCMsg mnm = new ManageNPCMsg(npc);
dispatch = Dispatch.borrow(player, mnm);
dispatch = Dispatch.borrow(playerCharacter, mnm);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
//Add Minion
@ -115,7 +112,7 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler { @@ -115,7 +112,7 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler {
if (npc.getContractID() == 842)
maxSlots = 1;
if (npc.getSiegeMinionMap().size() == maxSlots)
if (npc.minions.size() == maxSlots)
return true;
int mobBase;
@ -146,47 +143,15 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler { @@ -146,47 +143,15 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler {
if (mobBase == 0)
return true;
Mob siegeMob = Mob.createSiegeMob(npc, mobBase, npc.getGuild(), zone, b.getLoc(), (short) 1);
Mob siegeMob = Mob.createSiegeMinion(npc, mobBase);
if (siegeMob == null)
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);
mnm.setMessageType(1);
Dispatch dispatch = Dispatch.borrow(player, mnm);
Dispatch dispatch = Dispatch.borrow(playerCharacter, mnm);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
} finally {
@ -214,13 +179,13 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler { @@ -214,13 +179,13 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler {
Mob toRemove = Mob.getFromCache(minionMsg.getUUID());
if (!npc.getSiegeMinionMap().containsKey(toRemove))
if (!npc.minions.contains(toRemove.getObjectUUID()))
return true;
if (!DbManager.MobQueries.REMOVE_FROM_GUARDS(npc.getObjectUUID(), toRemove.getMobBaseID(), npc.getSiegeMinionMap().get(toRemove)))
if (!DbManager.MobQueries.REMOVE_GUARD_MINION(npc.getObjectUUID(), toRemove.firstName))
return true;
npc.getSiegeMinionMap().remove(toRemove);
npc.minions.remove(Integer.valueOf(toRemove.getObjectUUID()));
WorldGrid.RemoveWorldObject(toRemove);
@ -228,17 +193,22 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler { @@ -228,17 +193,22 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler {
toRemove.getParentZone().zoneMobSet.remove(toRemove);
DbManager.removeFromCache(toRemove);
PlayerCharacter petOwner = toRemove.getOwner();
if (petOwner != null) {
petOwner.setPet(null);
toRemove.setOwner(null);
PetMsg petMsg = new PetMsg(5, null);
Dispatch dispatch = Dispatch.borrow(petOwner, petMsg);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
if (toRemove.agentType.equals(Enum.AIAgentType.SIEGEENGINE)) {
PlayerCharacter trebOwner = (PlayerCharacter) toRemove.guardCaptain;
if (trebOwner != null) {
trebOwner.setPet(null);
toRemove.guardCaptain = null;
PetMsg petMsg = new PetMsg(5, null);
Dispatch dispatch = Dispatch.borrow(trebOwner, petMsg);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
}
}
ManageCityAssetsMsg mca1 = new ManageCityAssetsMsg(player, building);
ManageCityAssetsMsg mca1 = new ManageCityAssetsMsg(playerCharacter, building);
mca1.actionType = 3;
mca1.setTargetType(building.getObjectType().ordinal());
mca1.setTargetID(building.getObjectUUID());
@ -248,11 +218,11 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler { @@ -248,11 +218,11 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler {
mca1.setAssetName1(building.getName());
mca1.setUnknown54(1);
Dispatch dispatch = Dispatch.borrow(player, mca1);
Dispatch dispatch = Dispatch.borrow(playerCharacter, mca1);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
ManageNPCMsg mnm = new ManageNPCMsg(npc);
dispatch = Dispatch.borrow(player, mnm);
dispatch = Dispatch.borrow(playerCharacter, mnm);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
//Add Minion
@ -288,7 +258,7 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler { @@ -288,7 +258,7 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler {
break;
}
if (npc.getSiegeMinionMap().size() == maxSlots)
if (npc.minions.size() == maxSlots)
return true;
int mobBase = npc.getMobBaseID();
@ -298,14 +268,14 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler { @@ -298,14 +268,14 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler {
String pirateName = NPCManager.getPirateName(mobBase);
if (!DbManager.MobQueries.ADD_TO_GUARDS(npc.getObjectUUID(), mobBase, pirateName, npc.getSiegeMinionMap().size() + 1))
return true;
Mob toCreate = Mob.createGuardMob(npc, npc.getGuild(), zone, building.getLoc(), npc.getLevel(), pirateName);
Mob toCreate = Mob.createGuardMinion(npc, npc.getLevel(), pirateName);
if (toCreate == null)
return true;
if (!DbManager.MobQueries.ADD_GUARD_MINION(npc.getObjectUUID(), pirateName))
return true;
if (toCreate != null) {
toCreate.setDeathTime(System.currentTimeMillis());
toCreate.parentZone.zoneMobSet.add(toCreate);
@ -314,7 +284,7 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler { @@ -314,7 +284,7 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler {
ManageNPCMsg mnm = new ManageNPCMsg(npc);
mnm.setMessageType(1);
Dispatch dispatch = Dispatch.borrow(player, mnm);
Dispatch dispatch = Dispatch.borrow(playerCharacter, mnm);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
} catch (Exception e) {

12
src/engine/net/client/handlers/MoveToPointHandler.java

@ -9,12 +9,14 @@ @@ -9,12 +9,14 @@
package engine.net.client.handlers;
import engine.Enum;
import engine.exception.MsgSendException;
import engine.gameManager.BuildingManager;
import engine.gameManager.MovementManager;
import engine.net.client.ClientConnection;
import engine.net.client.msg.ClientNetMsg;
import engine.net.client.msg.MoveToPointMsg;
import engine.objects.PlayerCharacter;
import engine.objects.*;
public class MoveToPointHandler extends AbstractClientMsgHandler {
@ -26,13 +28,11 @@ public class MoveToPointHandler extends AbstractClientMsgHandler { @@ -26,13 +28,11 @@ public class MoveToPointHandler extends AbstractClientMsgHandler {
protected boolean _handleNetMsg(ClientNetMsg baseMsg,
ClientConnection origin) throws MsgSendException {
MoveToPointMsg msg = (MoveToPointMsg) baseMsg;
PlayerCharacter pc = (origin != null) ? (origin.getPlayerCharacter()) : null;
if (pc == null)
return false;
PlayerCharacter pc = origin.getPlayerCharacter();
if(pc == null)
return true;
MovementManager.movement(msg, pc);
return true;
}
}

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

@ -7,7 +7,6 @@ import engine.Enum.ProfitType; @@ -7,7 +7,6 @@ import engine.Enum.ProfitType;
import engine.exception.MsgSendException;
import engine.gameManager.BuildingManager;
import engine.gameManager.DbManager;
import engine.gameManager.NPCManager;
import engine.gameManager.SessionManager;
import engine.math.FastMath;
import engine.math.Vector3fImmutable;
@ -37,7 +36,7 @@ public class OrderNPCMsgHandler extends AbstractClientMsgHandler { @@ -37,7 +36,7 @@ public class OrderNPCMsgHandler extends AbstractClientMsgHandler {
super(OrderNPCMsg.class);
}
public static void processRedeedMob(Mob mob, Building building, ClientConnection origin) {
public static void processRedeedHireling(AbstractCharacter hireling, Building building, ClientConnection origin) {
PlayerCharacter player;
Contract contract;
@ -48,33 +47,28 @@ public class OrderNPCMsgHandler extends AbstractClientMsgHandler { @@ -48,33 +47,28 @@ public class OrderNPCMsgHandler extends AbstractClientMsgHandler {
player = SessionManager.getPlayerCharacter(origin);
itemMan = player.getCharItemManager();
contract = mob.getContract();
contract = hireling.contract;
if (!player.getCharItemManager().hasRoomInventory((short) 1)) {
ErrorPopupMsg.sendErrorPopup(player, 21);
return;
}
if (!building.getHirelings().containsKey(mob))
if (!building.getHirelings().containsKey(hireling))
return;
if (!NPCManager.removeMobileFromBuilding(mob, building)) {
PlaceAssetMsg.sendPlaceAssetError(player.getClientConnection(), 1, "A Serious error has occurred. Please post details for to ensure transaction integrity");
return;
}
building.getHirelings().remove(mob);
BuildingManager.removeHireling(building, hireling);
itemBase = ItemBase.getItemBase(contract.getContractID());
if (itemBase == null) {
Logger.error("Could not find Contract for npc: " + mob.getObjectUUID());
Logger.error("Could not find Contract for npc: " + hireling.getObjectUUID());
return;
}
boolean itemWorked = false;
item = new Item(itemBase, player.getObjectUUID(), Enum.OwnerType.PlayerCharacter, (byte) ((byte) mob.getRank() - 1), (byte) ((byte) mob.getRank() - 1), (short) 1, (short) 1, true, false, Enum.ItemContainerType.INVENTORY, (byte) 0, new ArrayList<>(), "");
item = new Item(itemBase, player.getObjectUUID(), Enum.OwnerType.PlayerCharacter, (byte) ((byte) hireling.getRank() - 1), (byte) ((byte) hireling.getRank() - 1), (short) 1, (short) 1, true, false, Enum.ItemContainerType.INVENTORY, (byte) 0, new ArrayList<>(), "");
item.setNumOfItems(1);
item.containerType = Enum.ItemContainerType.INVENTORY;
@ -212,10 +206,6 @@ public class OrderNPCMsgHandler extends AbstractClientMsgHandler { @@ -212,10 +206,6 @@ public class OrderNPCMsgHandler extends AbstractClientMsgHandler {
return;
}
for (AbstractCharacter guard : building.getHirelings().keySet()) {
if (guard.getObjectType() == GameObjectType.Mob)
((Mob) guard).setPatrolPointIndex(0);
}
} else if (building.getPatrolPoints() != null)
ClearPatrolPoints(building.getObjectUUID());
@ -223,10 +213,6 @@ public class OrderNPCMsgHandler extends AbstractClientMsgHandler { @@ -223,10 +213,6 @@ public class OrderNPCMsgHandler extends AbstractClientMsgHandler {
AddSentryPoints(building.getObjectUUID(), orderNpcMsg.getSentryPoints());
} else if (building.getSentryPoints() != null)
ClearSentryPoints(building.getObjectUUID());
// Dispatch dispatch = Dispatch.borrow(pc, msg);
// DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
}
private static void processUpgradeNPC(PlayerCharacter player, AbstractCharacter abstractCharacter) {
@ -290,28 +276,6 @@ public class OrderNPCMsgHandler extends AbstractClientMsgHandler { @@ -290,28 +276,6 @@ public class OrderNPCMsgHandler extends AbstractClientMsgHandler {
}
}
private static synchronized void processRedeedNPC(AbstractCharacter abstractCharacter, Building building, ClientConnection origin) {
// Member variable declaration
switch (abstractCharacter.getObjectType()) {
case NPC:
NPC npc = (NPC) abstractCharacter;
Building cityBuilding = npc.getBuilding();
if (cityBuilding == null)
return;
BuildingManager.processRedeedNPC(npc, npc.building, origin);
break;
case Mob:
Mob mob = (Mob) abstractCharacter;
processRedeedMob(mob, mob.building, origin);
break;
}
}
private static boolean AddPatrolPoints(int buildingID, ArrayList<Vector3fImmutable> patrolPoints) {
Building building = BuildingManager.getBuildingFromCache(buildingID);
@ -502,7 +466,7 @@ public class OrderNPCMsgHandler extends AbstractClientMsgHandler { @@ -502,7 +466,7 @@ public class OrderNPCMsgHandler extends AbstractClientMsgHandler {
if (BuildingManager.PlayerCanControlNotOwner(building, player) == false)
return true;
processRedeedNPC(npc, building, origin);
processRedeedHireling(npc, building, origin);
return true;
//MB TODO HANDLE all profits.
case 7:
@ -541,7 +505,7 @@ public class OrderNPCMsgHandler extends AbstractClientMsgHandler { @@ -541,7 +505,7 @@ public class OrderNPCMsgHandler extends AbstractClientMsgHandler {
} else if (orderNPCMsg.getObjectType() == GameObjectType.Mob.ordinal()) {
mob = Mob.getFromCacheDBID(orderNPCMsg.getNpcUUID());
mob = Mob.getMob(orderNPCMsg.getNpcUUID());
if (mob == null)
return true;
@ -570,10 +534,7 @@ public class OrderNPCMsgHandler extends AbstractClientMsgHandler { @@ -570,10 +534,7 @@ public class OrderNPCMsgHandler extends AbstractClientMsgHandler {
if (building.getHirelings().containsKey(mob) == false)
return true;
if (NPCManager.removeMobileFromBuilding(mob, building) == false) {
PlaceAssetMsg.sendPlaceAssetError(player.getClientConnection(), 1, "A Serious error has occurred. Please post details for to ensure transaction integrity");
return true;
}
BuildingManager.removeHireling(building, mob);
ManageCityAssetsMsg manageCityAssetsMsg = new ManageCityAssetsMsg();
manageCityAssetsMsg.actionType = SVR_CLOSE_WINDOW;
@ -608,7 +569,7 @@ public class OrderNPCMsgHandler extends AbstractClientMsgHandler { @@ -608,7 +569,7 @@ public class OrderNPCMsgHandler extends AbstractClientMsgHandler {
if (BuildingManager.PlayerCanControlNotOwner(building, player) == false)
return true;
processRedeedNPC(mob, building, origin);
processRedeedHireling(mob, building, origin);
return true;
//MB TODO HANDLE all profits.
case 7:

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

@ -745,7 +745,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler { @@ -745,7 +745,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
}
Vector3fImmutable plantLoc = new Vector3fImmutable(treeInfo.getLoc().x,
HeightMap.getWorldHeight(treeInfo.getLoc()),
0,
treeInfo.getLoc().z);
cityObjects = DbManager.CityQueries.CREATE_CITY(playerCharacter.getObjectUUID(), serverZone.getObjectUUID(),
@ -754,6 +754,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler { @@ -754,6 +754,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
plantLoc.z - serverZone.getAbsZ(), treeInfo.getRot().y, treeInfo.getW(), playerCharacter.getGuild().getName(), LocalDateTime.now());
// Uh oh!
if (cityObjects == null || cityObjects.isEmpty()) {
PlaceAssetMsg.sendPlaceAssetError(origin, 1, "A Serious error has occurred. Please post details for to ensure transaction integrity");
return false;
@ -767,7 +768,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler { @@ -767,7 +768,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
treeObject = (Building) cityObjectMap.get(GameObjectType.Building);
treeObject.runAfterLoad();
;
cityObject = (City) cityObjectMap.get(GameObjectType.City);
zoneObject = (Zone) cityObjectMap.get(GameObjectType.Zone);
@ -792,10 +793,11 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler { @@ -792,10 +793,11 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
ZoneManager.addPlayerCityZone(zoneObject);
serverZone.addNode(zoneObject);
zoneObject.generateWorldAltitude();
zoneObject.worldAltitude = ZoneManager.caclulateWorldAltitude(zoneObject);
cityObject.setParent(zoneObject);
cityObject.setObjectTypeMask(MBServerStatics.MASK_CITY); // *** Refactor : should have it already
//Link the tree of life with the new zone
treeObject.setObjectTypeMask(MBServerStatics.MASK_BUILDING);
@ -817,7 +819,6 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler { @@ -817,7 +819,6 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
City.lastCityUpdate = System.currentTimeMillis();
treeObject.setLoc(treeObject.getLoc());
InterestManager.setObjectDirty(treeObject);
// WorldGrid.addObject(treeObject, playerCharacter);
serverRealm.addCity(cityObject.getObjectUUID());
playerNation.setCityUUID(cityObject.getObjectUUID());
@ -915,6 +916,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler { @@ -915,6 +916,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
// Early exit if something went horribly wrong
// with locating the current realm and/or zone
if (serverZone == null)
return false;
@ -977,7 +979,8 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler { @@ -977,7 +979,8 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
City cityObject;
PlacementInfo buildingList;
// Setup working variables we'll need
// Setup working variables
buildingList = msg.getFirstPlacementInfo();
serverZone = ZoneManager.findSmallestZone(buildingList.getLoc());
@ -1090,7 +1093,6 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler { @@ -1090,7 +1093,6 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
placementCost = 0; // reset placement cost for fix bug with wall pieces somethings not taking gold out if forced an error.
// Overlap check and wall deed verifications
for (PlacementInfo wall : walls) {
@ -1109,7 +1111,6 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler { @@ -1109,7 +1111,6 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
for (Building building : serverZone.zoneBuildingSet) {
//TODO Clean up collision with placementInfo. don't need to create the same placementinfo bounds for collision checks on each building.
if ((building.getBlueprintUUID() != 0) && (Bounds.collide(wall, building) == true)) {
@ -1129,12 +1130,14 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler { @@ -1129,12 +1130,14 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
return false;
}
}
placementCost = PlaceAssetMsg.getWallCost(wall.getBlueprintUUID());
if (!itemMan.modifyInventoryGold(-placementCost)) {
ChatManager.chatSystemInfo(player, player.getFirstName() + " can't has free moneys! no for real.. Thor.. seriously... I didnt fix it because you getting laid isnt important enough for me.");
return false;
}
// Attempt to place wall piece
wallPiece = createStructure(player, wall, serverZone);
@ -1145,14 +1148,12 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler { @@ -1145,14 +1148,12 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
}
// walls are auto protected
wallPiece.setProtectionState(ProtectionState.PROTECTED);
PlaceAssetMsg.sendPlaceAssetConfirmWall(origin, serverZone);
}
// Deduct gold from character's inventory
return true;
}
@ -1172,6 +1173,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler { @@ -1172,6 +1173,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
}
// All siege buildings build in 15 minutes
if ((blueprint.getBuildingGroup().equals(BuildingGroup.SIEGETENT))
|| (blueprint.getBuildingGroup().equals(BuildingGroup.BULWARK)))
completionDate = DateTime.now().plusMinutes(15);
@ -1191,6 +1193,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler { @@ -1191,6 +1193,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
completionDate, blueprint.getMeshForRank(0), vendorRotation, buildingRotation);
// Make sure we have a valid mesh
if (newMesh == null) {
Logger.error("CreateStructure: DB returned null object.");
return null;
@ -1362,15 +1365,16 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler { @@ -1362,15 +1365,16 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
newMesh = (Building) ago;
newMesh.setObjectTypeMask(MBServerStatics.MASK_BUILDING);
MaintenanceManager.setMaintDateTime(newMesh, LocalDateTime.now().plusDays(7));
// WorldGrid.addObject(newMesh, player);
newMesh.setLoc(newMesh.getLoc());
InterestManager.setObjectDirty(newMesh);
newMesh.runAfterLoad();
} else if (ago.getObjectType() == GameObjectType.Warehouse) {
Warehouse warehouse = (Warehouse) ago;
City city = City.getCity(currentZone.getPlayerCityUUID());
if (city == null)
return true;
city.setWarehouseBuildingID(newMesh.getObjectUUID());
Warehouse.warehouseByBuildingUUID.put(newMesh.getObjectUUID(), warehouse);
}

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

@ -110,7 +110,6 @@ public class RequestEnterWorldHandler extends AbstractClientMsgHandler { @@ -110,7 +110,6 @@ public class RequestEnterWorldHandler extends AbstractClientMsgHandler {
player.stopMovement(player.getBindLoc());
player.setSafeMode();
player.updateLocation();
player.setRegion(AbstractWorldObject.GetRegionByWorldObject(player));
}
player.setTimeStamp("logout", 0);

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

@ -27,7 +27,6 @@ import org.pmw.tinylog.Logger; @@ -27,7 +27,6 @@ import org.pmw.tinylog.Logger;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
/**
@ -96,7 +95,7 @@ public class ManageNPCMsg extends ClientNetMsg { @@ -96,7 +95,7 @@ public class ManageNPCMsg extends ClientNetMsg {
writer.putString("A weapon suited to laying siege");
}
private static void serializeGuardList(ByteBufferWriter writer, int minion) {
private static void serializeGuardList(ByteBufferWriter writer, int minion, Mob captain) {
writer.putInt(1);
@ -106,7 +105,7 @@ public class ManageNPCMsg extends ClientNetMsg { @@ -106,7 +105,7 @@ public class ManageNPCMsg extends ClientNetMsg {
writer.putInt(minion);
writer.putInt(1);
writer.putInt(minion);
writer.putInt(1);
writer.putInt(captain.getRank());//minion rank
writer.put((byte) 0);
writer.putInt(600); //roll time
@ -343,14 +342,17 @@ public class ManageNPCMsg extends ClientNetMsg { @@ -343,14 +342,17 @@ public class ManageNPCMsg extends ClientNetMsg {
writer.putInt(0); //runemaster list
//artillery captain list
ConcurrentHashMap<Mob, Integer> siegeMinions = npc.getSiegeMinionMap();
writer.putInt(1 + siegeMinions.size());
writer.putInt(1 + npc.minions.size());
serializeBulwarkList(writer, 1); //Trebuchet
//serializeBulwarkList(writer, 2); //Ballista
if (siegeMinions != null && siegeMinions.size() > 0)
if (npc.minions != null && npc.minions.size() > 0)
for (Integer minionUUID : npc.minions) {
Mob mob = Mob.getMob(minionUUID);
for (Mob mob : siegeMinions.keySet()) {
this.unknown83 = mob.getObjectUUID();
writer.putInt(2);
writer.putInt(mob.getObjectType().ordinal());
@ -366,7 +368,7 @@ public class ManageNPCMsg extends ClientNetMsg { @@ -366,7 +368,7 @@ public class ManageNPCMsg extends ClientNetMsg {
long timeLife = upgradeTime - curTime;
if (upgradeTime * 1000 > System.currentTimeMillis()) {
if (mob.npcOwner.isAlive()) {
if (mob.guardCaptain.isAlive()) {
writer.put((byte) 0);//shows respawning timer
writer.putInt(mob.spawnTime);
writer.putInt(mob.spawnTime);
@ -557,7 +559,7 @@ public class ManageNPCMsg extends ClientNetMsg { @@ -557,7 +559,7 @@ public class ManageNPCMsg extends ClientNetMsg {
} else if (this.targetType == GameObjectType.Mob.ordinal()) {
mobA = Mob.getFromCacheDBID(this.targetID);
mobA = Mob.getMob(this.targetID);
if (mobA == null) {
Logger.error("Missing Mob of ID " + this.targetID);
@ -666,14 +668,15 @@ public class ManageNPCMsg extends ClientNetMsg { @@ -666,14 +668,15 @@ public class ManageNPCMsg extends ClientNetMsg {
writer.putInt(0); //runemaster list
//artillery captain list
ConcurrentHashMap<Mob, Integer> siegeMinions = mobA.getSiegeMinionMap();
writer.putInt(siegeMinions.size() + 1);
serializeGuardList(writer, mobA.getContract().getContractID()); //Guard
writer.putInt(mobA.minions.size() + 1);
serializeGuardList(writer, mobA.getContract().getContractID(), mobA); //Guard
if (siegeMinions != null && siegeMinions.size() > 0)
if (mobA.minions != null && mobA.minions.size() > 0)
for (Mob mob : siegeMinions.keySet()) {
for (Integer minionUUID : mobA.minions) {
Mob mob = Mob.getMob(minionUUID);
this.unknown83 = mob.getObjectUUID();
writer.putInt(2);
writer.putInt(mob.getObjectType().ordinal());
@ -689,7 +692,7 @@ public class ManageNPCMsg extends ClientNetMsg { @@ -689,7 +692,7 @@ public class ManageNPCMsg extends ClientNetMsg {
long timeLife = upgradeTime - curTime;
if (upgradeTime * 1000 > System.currentTimeMillis()) {
if (mob.npcOwner.isAlive()) {
if (mob.guardCaptain.isAlive()) {
writer.put((byte) 0);//shows respawning timer
writer.putInt(mob.spawnTime);
writer.putInt(mob.spawnTime);

111
src/engine/net/client/msg/MoveToPointMsg.java

@ -10,6 +10,7 @@ @@ -10,6 +10,7 @@
package engine.net.client.msg;
import engine.Enum.GameObjectType;
import engine.gameManager.BuildingManager;
import engine.gameManager.ZoneManager;
import engine.math.Vector3fImmutable;
import engine.net.AbstractConnection;
@ -21,19 +22,19 @@ import engine.objects.Building; @@ -21,19 +22,19 @@ import engine.objects.Building;
public class MoveToPointMsg extends ClientNetMsg {
private int sourceType;
private int sourceID;
private float startLat;
private float startLon;
private float startAlt;
private float endLat;
private float endLon;
private float endAlt;
private int targetType;
private int targetID;
private int inBuilding; // 0=true, -1=false 0/1/2 = floor you are on
private int unknown01;
private byte unknown02;
private int sourceType; //ordinal of the character type that sent this message 54=PlayerCharacter
private int sourceID; // uuid of the source character of this message
private float startLat; //start loc of move message (offset if inside a building not world loc)
private float startLon; //start loc of move message (offset if inside a building not world loc)
private float startAlt; //start loc of move message (offset if inside a building not world loc)
private float endLat; //end loc of move message (offset if inside a building not world loc)
private float endLon; //end loc of move message (offset if inside a building not world loc)
private float endAlt; //end loc of move message (offset if inside a building not world loc)
private int startLocType; // enum ordinal of the object player is inside 0=nothing 8=building
private int inBuildingUUID; // uuid of the building character is currently inside
private int inBuilding; // is inside a building 0=true -1=false
private int inBuildingFloor; // floor of building character is currently in -1=not inside building 0/1/2/3 = floor number
private byte initiatedByAttack; // move message sent as a result of move to target to attack 0=false 1=true
private byte unknown03;
/**
@ -54,11 +55,11 @@ public class MoveToPointMsg extends ClientNetMsg { @@ -54,11 +55,11 @@ public class MoveToPointMsg extends ClientNetMsg {
this.endLat = msg.endLat;
this.endLon = msg.endLon;
this.endAlt = msg.endAlt;
this.targetType = msg.targetType;
this.targetID = msg.targetID;
this.startLocType = msg.startLocType;
this.inBuildingUUID = msg.inBuildingUUID;
this.inBuilding = msg.inBuilding;
this.unknown01 = msg.unknown01;
this.unknown02 = msg.unknown02;
this.inBuildingFloor = msg.inBuildingFloor;
this.initiatedByAttack = msg.initiatedByAttack;
this.unknown03 = msg.unknown03;
}
@ -73,11 +74,11 @@ public class MoveToPointMsg extends ClientNetMsg { @@ -73,11 +74,11 @@ public class MoveToPointMsg extends ClientNetMsg {
this.endLat = building.getLoc().x;
this.endLon = building.getLoc().z;
this.endAlt = building.getLoc().y;
this.targetType = 0;
this.targetID = 0;
this.startLocType = 0;
this.inBuildingUUID = 0;
this.inBuilding = -1;
this.unknown01 = -1;
this.unknown02 = 0;
this.inBuildingFloor = -1;
this.initiatedByAttack = 0;
this.unknown03 = 0;
}
@ -108,11 +109,11 @@ public class MoveToPointMsg extends ClientNetMsg { @@ -108,11 +109,11 @@ public class MoveToPointMsg extends ClientNetMsg {
writer.putFloat(this.endAlt);
writer.putFloat(this.endLon);
writer.putInt(this.targetType);
writer.putInt(this.targetID);
writer.putInt(this.startLocType);
writer.putInt(this.inBuildingUUID);
writer.putInt(this.inBuilding);
writer.putInt(this.unknown01);
writer.putInt(this.inBuildingFloor);
writer.put((byte) 0);
writer.put((byte) 0);
@ -135,13 +136,13 @@ public class MoveToPointMsg extends ClientNetMsg { @@ -135,13 +136,13 @@ public class MoveToPointMsg extends ClientNetMsg {
this.endAlt = reader.getFloat();
this.endLon = reader.getFloat();
this.targetType = reader.getInt();
this.targetID = reader.getInt();
this.startLocType = reader.getInt();
this.inBuildingUUID = reader.getInt();
this.inBuilding = reader.getInt();
this.unknown01 = reader.getInt();
this.inBuildingFloor = reader.getInt();
this.unknown02 = reader.get();
this.initiatedByAttack = reader.get();
this.unknown03 = reader.get();
}
@ -209,20 +210,20 @@ public class MoveToPointMsg extends ClientNetMsg { @@ -209,20 +210,20 @@ public class MoveToPointMsg extends ClientNetMsg {
this.endAlt = value;
}
public int getTargetType() {
return this.targetType;
public int getStartLocType() {
return this.startLocType;
}
public void setTargetType(int value) {
this.targetType = value;
public void setStartLocType(int value) {
this.startLocType = value;
}
public int getTargetID() {
return this.targetID;
public int getInBuildingUUID() {
return this.inBuildingUUID;
}
public void setTargetID(int value) {
this.targetID = value;
public void setInBuildingUUID(int value) {
this.inBuildingUUID = value;
}
public int getInBuilding() {
@ -233,12 +234,8 @@ public class MoveToPointMsg extends ClientNetMsg { @@ -233,12 +234,8 @@ public class MoveToPointMsg extends ClientNetMsg {
this.inBuilding = value;
}
public int getUnknown01() {
return this.unknown01;
}
public void setUnknown01(int value) {
this.unknown01 = value;
public void setInBuildingFloor(int value) {
this.inBuildingFloor = value;
}
public void setStartCoord(Vector3fImmutable value) {
@ -254,8 +251,8 @@ public class MoveToPointMsg extends ClientNetMsg { @@ -254,8 +251,8 @@ public class MoveToPointMsg extends ClientNetMsg {
}
public void clearTarget() {
this.targetType = 0;
this.targetID = 0;
this.startLocType = 0;
this.inBuildingUUID = 0;
}
public void setPlayer(AbstractCharacter ac) {
@ -263,10 +260,10 @@ public class MoveToPointMsg extends ClientNetMsg { @@ -263,10 +260,10 @@ public class MoveToPointMsg extends ClientNetMsg {
this.sourceID = ac.getObjectUUID();
this.setStartCoord(ac.getLoc());
this.setEndCoord(ac.getEndLoc());
this.targetType = 0;
this.targetID = 0;
this.startLocType = 0;
this.inBuildingUUID = 0;
this.inBuilding = ac.getInBuilding();
this.unknown01 = ac.getInFloorID();
this.inBuildingFloor = ac.getInFloorID();
}
@ -274,10 +271,10 @@ public class MoveToPointMsg extends ClientNetMsg { @@ -274,10 +271,10 @@ public class MoveToPointMsg extends ClientNetMsg {
if (target == null) {
this.setStartCoord(ac.getLoc());
this.setEndCoord(ac.getEndLoc());
this.targetType = 0;
this.targetID = 0;
this.startLocType = 0;
this.inBuildingUUID = 0;
this.inBuilding = -1;
this.unknown01 = -1;
this.inBuildingFloor = -1;
} else {
Vector3fImmutable convertLocStart = ZoneManager.convertWorldToLocal(target, ac.getLoc());
Vector3fImmutable convertLocEnd = convertLocStart;
@ -286,10 +283,10 @@ public class MoveToPointMsg extends ClientNetMsg { @@ -286,10 +283,10 @@ public class MoveToPointMsg extends ClientNetMsg {
this.setStartCoord(convertLocStart);
this.setEndCoord(convertLocEnd);
this.targetType = GameObjectType.Building.ordinal();
this.targetID = target.getObjectUUID();
this.startLocType = GameObjectType.Building.ordinal();
this.inBuildingUUID = target.getObjectUUID();
this.inBuilding = ac.getInBuilding();
this.unknown01 = ac.getInFloorID();
this.inBuildingFloor = ac.getInFloorID();
}
}
@ -298,7 +295,11 @@ public class MoveToPointMsg extends ClientNetMsg { @@ -298,7 +295,11 @@ public class MoveToPointMsg extends ClientNetMsg {
return unknown03;
}
public int getUnknown02() {
return unknown02;
public int getInitiatedFromAttack() {
return initiatedByAttack;
}
public int getInBuildingFloor() {
return this.inBuildingFloor;
}
}

133
src/engine/objects/AbstractCharacter.java

@ -11,13 +11,11 @@ package engine.objects; @@ -11,13 +11,11 @@ package engine.objects;
import engine.Enum;
import engine.Enum.*;
import engine.InterestManagement.HeightMap;
import engine.InterestManagement.InterestManager;
import engine.InterestManagement.WorldGrid;
import engine.exception.SerializationException;
import engine.gameManager.CombatManager;
import engine.gameManager.ConfigManager;
import engine.gameManager.MovementManager;
import engine.gameManager.PowersManager;
import engine.gameManager.*;
import engine.job.AbstractJob;
import engine.job.JobContainer;
import engine.job.JobScheduler;
@ -39,6 +37,7 @@ import java.sql.SQLException; @@ -39,6 +37,7 @@ import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.ReentrantReadWriteLock;
@ -52,8 +51,8 @@ public abstract class AbstractCharacter extends AbstractWorldObject { @@ -52,8 +51,8 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
public int contractUUID;
public Contract contract;
protected String firstName;
protected String lastName;
public String firstName;
public String lastName;
protected short statStrCurrent;
protected short statDexCurrent;
protected short statConCurrent;
@ -71,7 +70,7 @@ public abstract class AbstractCharacter extends AbstractWorldObject { @@ -71,7 +70,7 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
public Guild guild;
protected byte runningTrains;
protected ConcurrentHashMap<Integer, CharacterPower> powers;
protected ConcurrentHashMap<String, CharacterSkill> skills;
public ConcurrentHashMap<String, CharacterSkill> skills;
// Variables NOT to be stored in db
protected boolean sit = false;
protected boolean walkMode;
@ -88,20 +87,20 @@ public abstract class AbstractCharacter extends AbstractWorldObject { @@ -88,20 +87,20 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
protected AtomicFloat mana = new AtomicFloat();
protected float manaMax; // Health/Mana/Stamina
protected AtomicBoolean isAlive = new AtomicBoolean(true);
protected Resists resists = new Resists("Genric");
public Resists resists = new Resists("Genric");
protected ConcurrentHashMap<String, JobContainer> timers;
protected ConcurrentHashMap<String, Long> timestamps;
protected int atrHandOne;
protected int atrHandTwo;
protected int minDamageHandOne;
protected int maxDamageHandOne;
protected int minDamageHandTwo;
protected int maxDamageHandTwo;
protected float rangeHandOne;
protected float rangeHandTwo;
protected float speedHandOne;
protected float speedHandTwo;
protected int defenseRating;
public int atrHandOne;
public int atrHandTwo;
public int minDamageHandOne;
public int maxDamageHandOne;
public int minDamageHandTwo;
public int maxDamageHandTwo;
public float rangeHandOne;
public float rangeHandTwo;
public float speedHandOne;
public float speedHandTwo;
public int defenseRating;
protected boolean isActive; // <-Do not use this for deleting character!
protected float altitude = 0; // 0=on terrain, 1=tier 1, 2=tier 2, etc.
protected ConcurrentHashMap<Integer, JobContainer> recycleTimers;
@ -117,16 +116,37 @@ public abstract class AbstractCharacter extends AbstractWorldObject { @@ -117,16 +116,37 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
protected boolean movingUp = false;
private float desiredAltitude = 0;
private long takeOffTime = 0;
private float hateValue = 0;
private long lastHateUpdate = 0;
private boolean collided = false;
private byte aoecntr = 0;
public int hidden = 0; // current rank of hide/sneak/invis
public CopyOnWriteArrayList<Integer> minions = new CopyOnWriteArrayList();
public ArrayList<CharacterRune> runes;
public AbstractCharacter() {
super();
this.firstName = "";
this.lastName = "";
this.powers = 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.statStrCurrent = (short) 0;
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();
}
@ -214,8 +234,6 @@ public abstract class AbstractCharacter extends AbstractWorldObject { @@ -214,8 +234,6 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
this.skills = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
this.initializeCharacter();
// Dangerous to use THIS in a constructor!!!
this.charItemManager = new CharacterItemManager(this);
}
/**
@ -258,8 +276,6 @@ public abstract class AbstractCharacter extends AbstractWorldObject { @@ -258,8 +276,6 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
this.powers = new ConcurrentHashMap<>();
this.initializeCharacter();
// Dangerous to use THIS in a constructor!!!
this.charItemManager = new CharacterItemManager(this);
}
/**
@ -291,8 +307,6 @@ public abstract class AbstractCharacter extends AbstractWorldObject { @@ -291,8 +307,6 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
this.powers = new ConcurrentHashMap<>();
initializeCharacter();
// Dangerous to use THIS in a constructor!!!
this.charItemManager = new CharacterItemManager(this);
}
/**
@ -342,9 +356,6 @@ public abstract class AbstractCharacter extends AbstractWorldObject { @@ -342,9 +356,6 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
this.powers = new ConcurrentHashMap<>();
this.initializeCharacter();
// Dangerous to use THIS in a constructor!!!
this.charItemManager = new CharacterItemManager(this);
}
public static int getBankCapacity() {
@ -504,10 +515,9 @@ public abstract class AbstractCharacter extends AbstractWorldObject { @@ -504,10 +515,9 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
}
public static void teleport(AbstractCharacter worldObject, final Vector3fImmutable targetLoc) {
Regions targetRegion = Regions.GetRegionForTeleport(targetLoc);
worldObject.locationLock.writeLock().lock();
try {
MovementManager.translocate(worldObject, targetLoc, targetRegion);
MovementManager.translocate(worldObject, targetLoc);
if (worldObject.getObjectType().equals(GameObjectType.PlayerCharacter))
InterestManager.INTERESTMANAGER.HandleLoadForTeleport((PlayerCharacter) worldObject);
} catch (Exception e) {
@ -975,8 +985,14 @@ public abstract class AbstractCharacter extends AbstractWorldObject { @@ -975,8 +985,14 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
@Override
public final void setLoc(final Vector3fImmutable value) {
Regions region = Regions.GetRegionForTeleport(value);
if(region != null){
this.region = region;
}
super.setLoc(value); // set the location in the world
this.resetLastSetLocUpdate();
}
public Vector3fImmutable getMovementLoc() {
@ -1096,6 +1112,7 @@ public abstract class AbstractCharacter extends AbstractWorldObject { @@ -1096,6 +1112,7 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
}
public final void setCombatTarget(final AbstractWorldObject value) {
if(this.getObjectTypeMask() == 2050) {//MOB?
if (value == null) {
if (this.isCombat()) {
@ -1113,7 +1130,9 @@ public abstract class AbstractCharacter extends AbstractWorldObject { @@ -1113,7 +1130,9 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
}
}
}
this.combatTarget = value;
}
public final ConcurrentHashMap<String, JobContainer> getTimers() {
@ -1230,11 +1249,29 @@ public abstract class AbstractCharacter extends AbstractWorldObject { @@ -1230,11 +1249,29 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
CombatManager.handleRetaliate(this, attacker);
}
if(this.getObjectType().equals(GameObjectType.Mob)){
//handle hate value addition
Mob target = (Mob)this;
if (attacker.getObjectType().equals(GameObjectType.PlayerCharacter)) {
target.playerAgroMap.put(attacker.getObjectUUID(), target.playerAgroMap.get(attacker.getObjectUUID()) + value);
if (target.isPlayerGuard()){
if(target.guardedCity != null && target.guardedCity.cityOutlaws.contains(attacker.getObjectUUID()) == false)
target.guardedCity.cityOutlaws.add(attacker.getObjectUUID());
}
}
} else if(this.getObjectType().equals(GameObjectType.PlayerCharacter)){
City playerCity = ZoneManager.getCityAtLocation(this.loc);
if(playerCity != null){
if(!attacker.getGuild().getNation().equals(playerCity.getGuild().getNation()))
if(!playerCity.getGuild().getNation().getAllyList().contains(attacker.getGuild().getNation()))
if(!playerCity.cityOutlaws.contains(attacker.getObjectUUID()))
playerCity.cityOutlaws.add(attacker.getObjectUUID());
}
}
return newHealth - oldHealth;
} finally {
this.healthLock.writeLock().unlock();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
@ -1420,10 +1457,9 @@ public abstract class AbstractCharacter extends AbstractWorldObject { @@ -1420,10 +1457,9 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
}
public void teleport(final Vector3fImmutable targetLoc) {
Regions targetRegion = Regions.GetRegionForTeleport(targetLoc);
locationLock.writeLock().lock();
try {
MovementManager.translocate(this, targetLoc, targetRegion);
MovementManager.translocate(this, targetLoc);
MovementManager.sendRWSSMsg(this);
} catch (Exception e) {
Logger.error(e);
@ -1758,29 +1794,6 @@ public abstract class AbstractCharacter extends AbstractWorldObject { @@ -1758,29 +1794,6 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
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() {
return inFloorID;
}

33
src/engine/objects/AbstractIntelligenceAgent.java

@ -9,6 +9,7 @@ @@ -9,6 +9,7 @@
package engine.objects;
import ch.claude_martin.enumbitset.EnumBitSet;
import engine.Enum;
import engine.Enum.GameObjectType;
import engine.Enum.ModType;
@ -32,6 +33,19 @@ public abstract class AbstractIntelligenceAgent extends AbstractCharacter { @@ -32,6 +33,19 @@ public abstract class AbstractIntelligenceAgent extends AbstractCharacter {
public boolean assist = false;
public Enum.AIAgentType agentType = Enum.AIAgentType.MOBILE;
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 {
super(rs);
@ -87,7 +101,8 @@ public abstract class AbstractIntelligenceAgent extends AbstractCharacter { @@ -87,7 +101,8 @@ public abstract class AbstractIntelligenceAgent extends AbstractCharacter {
this.agentType = Enum.AIAgentType.CHARMED;
if (this.getObjectType().equals(GameObjectType.Mob)) {
((Mob) this).setOwner(owner);
((Mob) this).guardCaptain = owner;
}
}
@ -110,14 +125,6 @@ public abstract class AbstractIntelligenceAgent extends AbstractCharacter { @@ -110,14 +125,6 @@ public abstract class AbstractIntelligenceAgent extends AbstractCharacter {
return 0;
}
public PlayerCharacter getOwner() {
if (this.getObjectType().equals(GameObjectType.Mob))
return this.getOwner();
return null;
}
public boolean getSafeZone() {
ArrayList<Zone> allIn = ZoneManager.getAllZonesIn(this.getLoc());
@ -156,9 +163,11 @@ public abstract class AbstractIntelligenceAgent extends AbstractCharacter { @@ -156,9 +163,11 @@ public abstract class AbstractIntelligenceAgent extends AbstractCharacter {
this.setCombatTarget(null);
}
//clear owner
// clear owner and set not alive
this.isAlive.set(false);
PlayerCharacter owner = this.getOwner();
PlayerCharacter owner = (PlayerCharacter) this.guardCaptain;
//close pet window
@ -174,7 +183,7 @@ public abstract class AbstractIntelligenceAgent extends AbstractCharacter { @@ -174,7 +183,7 @@ public abstract class AbstractIntelligenceAgent extends AbstractCharacter {
owner.setPet(null);
if (this.getObjectType().equals(GameObjectType.Mob))
((Mob) this).setOwner(null);
this.guardCaptain = null;
}

15
src/engine/objects/AbstractWorldObject.java

@ -357,7 +357,9 @@ public abstract class AbstractWorldObject extends AbstractGameObject { @@ -357,7 +357,9 @@ public abstract class AbstractWorldObject extends AbstractGameObject {
Mob mob = (Mob) this;
if (mob.isSiege()) {
if (mob.isPet()) {
PlayerCharacter petOwner = mob.getOwner();
PlayerCharacter petOwner = (PlayerCharacter) mob.guardCaptain;
if (petOwner != null && source.equals(EffectSourceType.Effect)) {
petOwner.dismissPet();
return;
@ -500,7 +502,13 @@ public abstract class AbstractWorldObject extends AbstractGameObject { @@ -500,7 +502,13 @@ public abstract class AbstractWorldObject extends AbstractGameObject {
return;
this.lastLoc = new Vector3fImmutable(this.loc);
this.loc = loc;
this.loc = this.loc.setY(HeightMap.getWorldHeight(this) + this.getAltitude());
if(this instanceof AbstractCharacter && this.region != null){
this.loc = this.loc.setY(this.region.lerpY(this) + this.getAltitude());
} else{
this.loc = this.loc.setY(HeightMap.getWorldHeight(this.getLoc()) + this.getAltitude());
}
//lets not add mob to world grid if he is currently despawned.
if (this.getObjectType().equals(GameObjectType.Mob) && ((Mob) this).despawned)
@ -608,9 +616,6 @@ public abstract class AbstractWorldObject extends AbstractGameObject { @@ -608,9 +616,6 @@ public abstract class AbstractWorldObject extends AbstractGameObject {
this.movingUp = movingUp;
}
public void setRegion(Regions region) {
this.region = region;
}
//used for interestmanager loading and unloading objects to client.
// if not in grid, unload from player.

12
src/engine/objects/Building.java

@ -537,6 +537,18 @@ public class Building extends AbstractWorldObject { @@ -537,6 +537,18 @@ public class Building extends AbstractWorldObject {
if (value < 0)
Mine.SendMineAttackMessage(this);
City playerCity = ZoneManager.getCityAtLocation(this.loc);
if(playerCity != null){
if(this.getGuild().getNation().equals(playerCity.getTOL().getGuild().getNation())){
//friendly building has been attacked, add attacker to city outlaw list
if(!playerCity.cityOutlaws.contains(attacker.getObjectUUID()) && attacker.getObjectType().equals(GameObjectType.PlayerCharacter))
playerCity.cityOutlaws.add(attacker.getObjectUUID());
for(Mob guard : playerCity.getParent().zoneMobSet)
if(guard.combatTarget == null)
guard.setCombatTarget(attacker);
}
}
return newHealth - oldHealth;

120
src/engine/objects/CharacterSkill.java

@ -223,7 +223,7 @@ public class CharacterSkill extends AbstractGameObject { @@ -223,7 +223,7 @@ public class CharacterSkill extends AbstractGameObject {
this.numTrains.set(0);
this.ownerUID = pc.getObjectUUID();
calculateBaseAmount();
calculateModifiedAmount();
calculateModifiedAmount(false);
this.skillType = CharacterSkills.GetCharacterSkillByToken(this.skillsBase.getToken());
}
@ -238,7 +238,7 @@ public class CharacterSkill extends AbstractGameObject { @@ -238,7 +238,7 @@ public class CharacterSkill extends AbstractGameObject {
this.ownerUID = pc.getObjectUUID();
this.trained = true;
calculateBaseAmount();
calculateModifiedAmount();
calculateModifiedAmount(false);
this.skillType = CharacterSkills.GetCharacterSkillByToken(this.skillsBase.getToken());
}
@ -254,7 +254,7 @@ public class CharacterSkill extends AbstractGameObject { @@ -254,7 +254,7 @@ public class CharacterSkill extends AbstractGameObject {
this.numTrains.set(rs.getShort("trains"));
this.ownerUID = pc.getObjectUUID();
calculateBaseAmount();
calculateModifiedAmount();
calculateModifiedAmount(false);
this.skillType = CharacterSkills.GetCharacterSkillByToken(this.skillsBase.getToken());
}
@ -264,8 +264,9 @@ public class CharacterSkill extends AbstractGameObject { @@ -264,8 +264,9 @@ public class CharacterSkill extends AbstractGameObject {
this.numTrains.set(trains);
this.ownerUID = mob.getObjectUUID();
this.isMobOwner = true;
calculateMobBaseAmount();
calculateModifiedAmount();
boolean isGuard = mob.agentType.equals(Enum.AIAgentType.GUARDCAPTAIN) || mob.agentType.equals(Enum.AIAgentType.GUARDMINION);
calculateMobBaseAmount(isGuard);
calculateModifiedAmount(isGuard);
this.skillType = CharacterSkills.GetCharacterSkillByToken(this.skillsBase.getToken());
}
@ -277,7 +278,7 @@ public class CharacterSkill extends AbstractGameObject { @@ -277,7 +278,7 @@ public class CharacterSkill extends AbstractGameObject {
this.ownerUID = rs.getInt("CharacterID");
// this.owner = DbManager.PlayerCharacterQueries.GET_PLAYER_CHARACTER(rs.getInt("CharacterID"));
calculateBaseAmount();
calculateModifiedAmount();
calculateModifiedAmount(false);
this.skillType = CharacterSkills.GetCharacterSkillByToken(this.skillsBase.getToken());
}
@ -370,7 +371,7 @@ public class CharacterSkill extends AbstractGameObject { @@ -370,7 +371,7 @@ public class CharacterSkill extends AbstractGameObject {
String name = it.next();
CharacterSkill cs = skills.get(name);
if (cs != null)
cs.calculateModifiedAmount();
cs.calculateModifiedAmount(false);
}
@ -756,7 +757,7 @@ public class CharacterSkill extends AbstractGameObject { @@ -756,7 +757,7 @@ public class CharacterSkill extends AbstractGameObject {
//recalculate this skill
calculateBaseAmount();
calculateModifiedAmount();
calculateModifiedAmount(false);
//see if any new skills or powers granted
pc.calculateSkills();
@ -848,7 +849,7 @@ public class CharacterSkill extends AbstractGameObject { @@ -848,7 +849,7 @@ public class CharacterSkill extends AbstractGameObject {
if (recalculate) {
//recalculate this skill
calculateBaseAmount();
calculateModifiedAmount();
calculateModifiedAmount(false);
//see if any skills or powers removed
pc.calculateSkills();
@ -887,7 +888,7 @@ public class CharacterSkill extends AbstractGameObject { @@ -887,7 +888,7 @@ public class CharacterSkill extends AbstractGameObject {
if (recalculate) {
//recalculate this skill
calculateBaseAmount();
calculateModifiedAmount();
calculateModifiedAmount(false);
//see if any skills or powers removed
pc.calculateSkills();
@ -1016,33 +1017,34 @@ public class CharacterSkill extends AbstractGameObject { @@ -1016,33 +1017,34 @@ public class CharacterSkill extends AbstractGameObject {
this.modifiedAmountBeforeMods = Math.round(this.baseAmountBeforeMods + calculateAmountAfterTrains());
}
public void calculateMobBaseAmount() {
if (CharacterSkill.GetOwner(this) == null) {
Logger.error("owner not found for owner uuid : " + this.ownerUID);
this.baseAmount = 1;
this.modifiedAmount = 1;
return;
}
public void calculateMobBaseAmount(boolean isGuard) {
if(!isGuard) {
if (CharacterSkill.GetOwner(this) == null) {
Logger.error("owner not found for owner uuid : " + this.ownerUID);
this.baseAmount = 1;
this.modifiedAmount = 1;
return;
}
if (this.skillsBase == null) {
Logger.error("SkillsBase not found for skill " + this.getObjectUUID());
this.baseAmount = 1;
this.modifiedAmount = 1;
return;
if (this.skillsBase == null) {
Logger.error("SkillsBase not found for skill " + this.getObjectUUID());
this.baseAmount = 1;
this.modifiedAmount = 1;
return;
}
}
//Get any rune bonus
float bonus = 0f;
//TODO SKILLS RUNES
if (CharacterSkill.GetOwner(this).getBonuses() != null) {
float base = 7f;
float statMod = 0.5f;
if (CharacterSkill.GetOwner(this) != null && CharacterSkill.GetOwner(this).getBonuses() != null) {
//Get bonuses from runes
bonus = CharacterSkill.GetOwner(this).getBonuses().getSkillBonus(this.skillsBase.sourceType);
}
//Get Base skill for unmodified stats
float base = 7f;
float statMod = 0.5f;
if (this.skillsBase.getStrMod() > 0)
statMod += (float) this.skillsBase.getStrMod() * (float) ((Mob) CharacterSkill.GetOwner(this)).getMobBase().getMobBaseStats().getBaseStr() / 100f;
if (this.skillsBase.getDexMod() > 0)
@ -1057,6 +1059,7 @@ public class CharacterSkill extends AbstractGameObject { @@ -1057,6 +1059,7 @@ public class CharacterSkill extends AbstractGameObject {
statMod = 1f;
else if (statMod > 600)
statMod = 600f;
}
base += CharacterSkill.baseSkillValues[(int) statMod];
if (base + bonus < 1f)
@ -1066,45 +1069,48 @@ public class CharacterSkill extends AbstractGameObject { @@ -1066,45 +1069,48 @@ public class CharacterSkill extends AbstractGameObject {
this.modifiedAmountBeforeMods = (int) (this.baseAmountBeforeMods + calculateAmountAfterTrains());
}
public void calculateModifiedAmount() {
if (CharacterSkill.GetOwner(this) == null || this.skillsBase == null) {
Logger.error("owner or SkillsBase not found for skill " + this.getObjectUUID());
this.baseAmount = 1;
this.modifiedAmount = 1;
return;
public void calculateModifiedAmount(boolean isGuard) {
if(!isGuard) {
if (CharacterSkill.GetOwner(this) == null || this.skillsBase == null) {
Logger.error("owner or SkillsBase not found for skill " + this.getObjectUUID());
this.baseAmount = 1;
this.modifiedAmount = 1;
return;
}
}
//Get any rune bonus
float bonus = 0f;
if (CharacterSkill.GetOwner(this).getBonuses() != null) {
float base = 7f;
float statMod = 0.5f;
if (CharacterSkill.GetOwner(this) != null && CharacterSkill.GetOwner(this).getBonuses() != null) {
//Get bonuses from runes
bonus = CharacterSkill.GetOwner(this).getBonuses().getSkillBonus(this.skillsBase.sourceType);
}
//Get Base skill for modified stats
//TODO this fomula needs verified
float base = 7f;
float statMod = 0.5f;
if (this.skillsBase.getStrMod() > 0)
statMod += (float) this.skillsBase.getStrMod() * (float) CharacterSkill.GetOwner(this).getStatStrCurrent() / 100f;
if (this.skillsBase.getDexMod() > 0)
statMod += (float) this.skillsBase.getDexMod() * (float) CharacterSkill.GetOwner(this).getStatDexCurrent() / 100f;
if (this.skillsBase.getConMod() > 0)
statMod += (float) this.skillsBase.getConMod() * (float) CharacterSkill.GetOwner(this).getStatConCurrent() / 100f;
if (this.skillsBase.getIntMod() > 0)
statMod += (float) this.skillsBase.getIntMod() * (float) CharacterSkill.GetOwner(this).getStatIntCurrent() / 100f;
if (this.skillsBase.getSpiMod() > 0)
statMod += (float) this.skillsBase.getSpiMod() * (float) CharacterSkill.GetOwner(this).getStatSpiCurrent() / 100f;
if (statMod < 1)
statMod = 1f;
else if (statMod > 600)
statMod = 600f;
//Get Base skill for modified stats
//TODO this fomula needs verified
if (this.skillsBase.getStrMod() > 0)
statMod += (float) this.skillsBase.getStrMod() * (float) CharacterSkill.GetOwner(this).getStatStrCurrent() / 100f;
if (this.skillsBase.getDexMod() > 0)
statMod += (float) this.skillsBase.getDexMod() * (float) CharacterSkill.GetOwner(this).getStatDexCurrent() / 100f;
if (this.skillsBase.getConMod() > 0)
statMod += (float) this.skillsBase.getConMod() * (float) CharacterSkill.GetOwner(this).getStatConCurrent() / 100f;
if (this.skillsBase.getIntMod() > 0)
statMod += (float) this.skillsBase.getIntMod() * (float) CharacterSkill.GetOwner(this).getStatIntCurrent() / 100f;
if (this.skillsBase.getSpiMod() > 0)
statMod += (float) this.skillsBase.getSpiMod() * (float) CharacterSkill.GetOwner(this).getStatSpiCurrent() / 100f;
if (statMod < 1)
statMod = 1f;
else if (statMod > 600)
statMod = 600f;
}
base += CharacterSkill.baseSkillValues[(int) statMod];
SourceType sourceType = SourceType.GetSourceType(this.skillsBase.getNameNoSpace());
//Get any rune, effect and item bonus
if (CharacterSkill.GetOwner(this).getBonuses() != null) {
if (CharacterSkill.GetOwner(this) != null && CharacterSkill.GetOwner(this).getBonuses() != null) {
//add bonuses from effects/items and runes
base += bonus + CharacterSkill.GetOwner(this).getBonuses().getFloat(ModType.Skill, sourceType);
}
@ -1116,7 +1122,7 @@ public class CharacterSkill extends AbstractGameObject { @@ -1116,7 +1122,7 @@ public class CharacterSkill extends AbstractGameObject {
float modAmount = this.baseAmount + calculateAmountAfterTrains();
if (CharacterSkill.GetOwner(this).getBonuses() != null) {
if (CharacterSkill.GetOwner(this) != null && CharacterSkill.GetOwner(this).getBonuses() != null) {
//Multiply any percent bonuses
modAmount *= (1 + CharacterSkill.GetOwner(this).getBonuses().getFloatPercentAll(ModType.Skill, sourceType));
}

195
src/engine/objects/City.java

@ -66,9 +66,6 @@ public class City extends AbstractWorldObject { @@ -66,9 +66,6 @@ public class City extends AbstractWorldObject {
private int realmID;
private int radiusType;
private float bindRadius;
private float statLat;
private float statAlt;
private float statLon;
private float bindX;
private float bindZ;
private byte isNpc; //aka Safehold
@ -77,7 +74,7 @@ public class City extends AbstractWorldObject { @@ -77,7 +74,7 @@ public class City extends AbstractWorldObject {
private boolean forceRename = false;
private boolean noTeleport = false; //used by npc cities
private boolean noRepledge = false; //used by npc cities
private boolean isOpen = false;
private final boolean isOpen = false;
private int treeOfLifeID;
private Vector3fImmutable location = Vector3fImmutable.ZERO;
@ -113,10 +110,7 @@ public class City extends AbstractWorldObject { @@ -113,10 +110,7 @@ public class City extends AbstractWorldObject {
if (establishedTimeStamp != null)
this.established = java.time.LocalDateTime.ofInstant(establishedTimeStamp.toInstant(), ZoneId.systemDefault());
this.location = new Vector3fImmutable(rs.getFloat("xCoord"), rs.getFloat("yCoord"), rs.getFloat("zCoord"));
this.statLat = rs.getFloat("xCoord");
this.statAlt = rs.getFloat("yCoord");
this.statLon = rs.getFloat("zCoord");
this.location = Vector3fImmutable.ZERO;
java.sql.Timestamp realmTaxTimeStamp = rs.getTimestamp("realmTaxDate");
@ -159,11 +153,6 @@ public class City extends AbstractWorldObject { @@ -159,11 +153,6 @@ public class City extends AbstractWorldObject {
this.motto = guild.getMotto();
}
//Disabled till i finish.
// this.reverseKOS = rs.getInt("kos") == 1;
Zone zone = ZoneManager.getZoneByUUID(rs.getInt("parent"));
if (zone != null)
@ -171,18 +160,12 @@ public class City extends AbstractWorldObject { @@ -171,18 +160,12 @@ public class City extends AbstractWorldObject {
//npc cities without heightmaps except swampstone are specials.
this.realmID = rs.getInt("realmID");
} catch (Exception e) {
Logger.error(e);
}
// *** Refactor: Is this working? Intended to supress
// login server errors from attempting to
// load cities/realms along with players
}
/*
@ -208,7 +191,6 @@ public class City extends AbstractWorldObject { @@ -208,7 +191,6 @@ public class City extends AbstractWorldObject {
Logger.error("NULL TOL FOR " + city.cityName);
}
// Assign city owner
if (city.getTOL() != null)
@ -226,7 +208,8 @@ public class City extends AbstractWorldObject { @@ -226,7 +208,8 @@ public class City extends AbstractWorldObject {
rulingNation = rulingGuild.getNation();
// Begin Serialzing soverign guild data
// Begin Serializing sovereign guild data
writer.putInt(city.getObjectType().ordinal());
writer.putInt(city.getObjectUUID());
writer.putString(city.cityName);
@ -281,7 +264,6 @@ public class City extends AbstractWorldObject { @@ -281,7 +264,6 @@ public class City extends AbstractWorldObject {
writer.putInt(rulingNation.getObjectUUID());
}
// Serialize nation name
if (rulingNation.isEmptyGuild())
@ -303,16 +285,8 @@ public class City extends AbstractWorldObject { @@ -303,16 +285,8 @@ public class City extends AbstractWorldObject {
else
writer.putString(Guild.GetGL(rulingNation).getFirstName() + ' ' + Guild.GetGL(rulingNation).getLastName());
writer.putLocalDateTime(city.established);
// writer.put((byte) city.established.getDayOfMonth());
// writer.put((byte) city.established.minusMonths(1).getMonth().getValue());
// writer.putInt((int) years);
// writer.put((byte) hours);
// writer.put((byte) minutes);
// writer.put((byte) seconds);
writer.putFloat(city.location.x);
writer.putFloat(city.location.y);
writer.putFloat(city.location.z);
@ -351,6 +325,7 @@ public class City extends AbstractWorldObject { @@ -351,6 +325,7 @@ public class City extends AbstractWorldObject {
ConcurrentHashMap<Integer, AbstractGameObject> worldCities = DbManager.getMap(Enum.GameObjectType.City);
//add npc cities
for (AbstractGameObject ago : worldCities.values()) {
if (ago.getObjectType().equals(GameObjectType.City)) {
@ -367,6 +342,7 @@ public class City extends AbstractWorldObject { @@ -367,6 +342,7 @@ public class City extends AbstractWorldObject {
//list Player cities
//open city, just list
if (city.open && city.getTOL() != null && city.getTOL().getRank() > 4) {
if (!BuildingManager.IsPlayerHostile(city.getTOL(), pc))
@ -376,7 +352,9 @@ public class City extends AbstractWorldObject { @@ -376,7 +352,9 @@ public class City extends AbstractWorldObject {
} else if (city.isNpc == 1) {
//list NPC cities
Guild g = city.getGuild();
if (g == null) {
if (city.isNpc == 1)
@ -386,32 +364,34 @@ public class City extends AbstractWorldObject { @@ -386,32 +364,34 @@ public class City extends AbstractWorldObject {
} else if (pc.getLevel() > 9)
cities.add(city);
} else if (pc.getLevel() >= g.getTeleportMin() && pc.getLevel() <= g.getTeleportMax()) {
} else if (pc.getLevel() >= g.getTeleportMin() && pc.getLevel() <= g.getTeleportMax())
cities.add(city);
}
}
}
}
return cities;
}
public static ArrayList<City> getCitiesToRepledgeTo(PlayerCharacter pc) {
public static ArrayList<City> getCitiesToRepledgeTo(PlayerCharacter playerCharacter) {
ArrayList<City> cities = new ArrayList<>();
if (pc == null)
if (playerCharacter == null)
return cities;
Guild pcG = pc.getGuild();
Guild pcG = playerCharacter.getGuild();
ConcurrentHashMap<Integer, AbstractGameObject> worldCities = DbManager.getMap(Enum.GameObjectType.City);
//add npc cities
for (AbstractGameObject ago : worldCities.values()) {
if (ago.getObjectType().equals(GameObjectType.City)) {
City city = (City) ago;
if (city.noRepledge)
continue;
@ -419,11 +399,12 @@ public class City extends AbstractWorldObject { @@ -419,11 +399,12 @@ public class City extends AbstractWorldObject {
//list Player cities
//open city, just list
if (pc.getAccount().status.equals(AccountStatus.ADMIN)) {
if (playerCharacter.getAccount().status.equals(AccountStatus.ADMIN)) {
cities.add(city);
} else if (city.open && city.getTOL() != null && city.getTOL().getRank() > 4) {
if (!BuildingManager.IsPlayerHostile(city.getTOL(), pc))
if (!BuildingManager.IsPlayerHostile(city.getTOL(), playerCharacter))
cities.add(city); //verify nation or guild is same
} else if (Guild.sameNationExcludeErrant(city.getGuild(), pcG))
cities.add(city);
@ -431,15 +412,16 @@ public class City extends AbstractWorldObject { @@ -431,15 +412,16 @@ public class City extends AbstractWorldObject {
} else if (city.isNpc == 1) {
//list NPC cities
Guild g = city.getGuild();
if (g == null) {
Guild guild = city.getGuild();
if (guild == null) {
if (city.isNpc == 1)
if (city.isNoobIsle == 1) {
if (pc.getLevel() < 21)
if (playerCharacter.getLevel() < 21)
cities.add(city);
} else if (pc.getLevel() > 9)
} else if (playerCharacter.getLevel() > 9)
cities.add(city);
} else if (pc.getLevel() >= g.getRepledgeMin() && pc.getLevel() <= g.getRepledgeMax()) {
} else if (playerCharacter.getLevel() >= guild.getRepledgeMin() && playerCharacter.getLevel() <= guild.getRepledgeMax()) {
cities.add(city);
}
@ -455,6 +437,7 @@ public class City extends AbstractWorldObject { @@ -455,6 +437,7 @@ public class City extends AbstractWorldObject {
return null;
City city = (City) DbManager.getFromCache(Enum.GameObjectType.City, cityId);
if (city != null)
return city;
@ -471,8 +454,10 @@ public class City extends AbstractWorldObject { @@ -471,8 +454,10 @@ public class City extends AbstractWorldObject {
}
public boolean renameCity(String cityName) {
if (!DbManager.CityQueries.renameCity(this, cityName))
return false;
if (!DbManager.CityQueries.updateforceRename(this, false))
return false;
@ -482,17 +467,22 @@ public class City extends AbstractWorldObject { @@ -482,17 +467,22 @@ public class City extends AbstractWorldObject {
}
public boolean updateTOL(Building tol) {
if (tol == null)
return false;
if (!DbManager.CityQueries.updateTOL(this, tol.getObjectUUID()))
return false;
this.treeOfLifeID = tol.getObjectUUID();
return true;
}
public boolean renameCityForNewPlant(String cityName) {
if (!DbManager.CityQueries.renameCity(this, cityName))
return false;
if (!DbManager.CityQueries.updateforceRename(this, true))
return false;
@ -515,19 +505,11 @@ public class City extends AbstractWorldObject { @@ -515,19 +505,11 @@ public class City extends AbstractWorldObject {
}
public Building getTOL() {
if (this.treeOfLifeID == 0)
return null;
return BuildingManager.getBuildingFromCache(this.treeOfLifeID);
}
public int getIsNoobIsle() {
return isNoobIsle;
}
public int getPopulation() {
return population;
}
/**
@ -557,14 +539,6 @@ public class City extends AbstractWorldObject { @@ -557,14 +539,6 @@ public class City extends AbstractWorldObject {
Logger.error("Error when writing to database for cityUUID: " + this.getObjectUUID());
}
public float getLatitude() {
return this.location.x;
}
public float getLongitude() {
return this.location.z;
}
public float getAltitude() {
return this.location.y;
}
@ -574,34 +548,10 @@ public class City extends AbstractWorldObject { @@ -574,34 +548,10 @@ public class City extends AbstractWorldObject {
return this.location;
}
public byte getIsNpcOwned() {
return isNpc;
}
public byte getIsSafeHold() {
return this.isSafeHold;
}
public boolean isSafeHold() {
return (this.isSafeHold == (byte) 1);
}
public byte getIsCapital() {
return isCapital;
}
public void setIsCapital(boolean state) {
this.isCapital = (state) ? (byte) 1 : (byte) 0;
}
public int getRadiusType() {
return this.radiusType;
}
public float getBindRadius() {
return this.bindRadius;
}
public int getRank() {
return (this.getTOL() == null) ? 0 : this.getTOL().getRank();
}
@ -624,7 +574,7 @@ public class City extends AbstractWorldObject { @@ -624,7 +574,7 @@ public class City extends AbstractWorldObject {
this.parentZone = zone;
this.location = new Vector3fImmutable(zone.absX + statLat, zone.absY + statAlt, zone.absZ + statLon);
this.location = new Vector3fImmutable(zone.absX, zone.absY, zone.absZ);
this.bindLoc = new Vector3fImmutable(this.location.x + this.bindX,
this.location.y,
this.location.z + this.bindZ);
@ -646,15 +596,6 @@ public class City extends AbstractWorldObject { @@ -646,15 +596,6 @@ public class City extends AbstractWorldObject {
}
}
public boolean isCityZone(Zone zone) {
if (zone == null || this.parentZone == null)
return false;
return zone.getObjectUUID() == this.parentZone.getObjectUUID();
}
public AbstractCharacter getOwner() {
if (this.getTOL() == null)
@ -676,13 +617,13 @@ public class City extends AbstractWorldObject { @@ -676,13 +617,13 @@ public class City extends AbstractWorldObject {
if (this.getTOL() == null)
return null;
if (this.isNpc == 1) {
if (this.getTOL().getOwner() == null)
return null;
return this.getTOL().getOwner().getGuild();
} else {
if (this.getTOL().getOwner() == null)
return null;
return this.getTOL().getOwner().getGuild();
@ -690,13 +631,16 @@ public class City extends AbstractWorldObject { @@ -690,13 +631,16 @@ public class City extends AbstractWorldObject {
}
public boolean openCity(boolean open) {
if (!DbManager.CityQueries.updateOpenCity(this, open))
return false;
this.open = open;
return true;
}
public Vector3fImmutable getBindLoc() {
Vector3fImmutable treeLoc = null;
if (this.getTOL() != null && this.getTOL().getRank() == 8)
@ -706,7 +650,9 @@ public class City extends AbstractWorldObject { @@ -706,7 +650,9 @@ public class City extends AbstractWorldObject {
return treeLoc;
if (this.radiusType == 1 && this.bindRadius > 0f) {
//square radius
float x = this.bindLoc.getX();
float z = this.bindLoc.getZ();
float offset = ((ThreadLocalRandom.current().nextFloat() * 2) - 1) * this.bindRadius;
@ -827,7 +773,6 @@ public class City extends AbstractWorldObject { @@ -827,7 +773,6 @@ public class City extends AbstractWorldObject {
try {
this.getTOL().addEffectBit((1 << 16));
this.getBane().getStone().addEffectBit((1 << 19));
;
} catch (Exception e) {
Logger.info("Failed ao add bane effects on city." + e.getMessage());
}
@ -852,6 +797,7 @@ public class City extends AbstractWorldObject { @@ -852,6 +797,7 @@ public class City extends AbstractWorldObject {
if (playerObject == null)
continue;
if (!this.isLocationWithinSiegeBounds(playerObject.getLoc()))
continue;
@ -868,8 +814,7 @@ public class City extends AbstractWorldObject { @@ -868,8 +814,7 @@ public class City extends AbstractWorldObject {
// Remove the city effect from the ago's internal collection
if (this.getEffects().containsKey(Integer.toString(effectBase.getUUID())))
this.getEffects().remove(Integer.toString(effectBase.getUUID()));
this.getEffects().remove(Integer.toString(effectBase.getUUID()));
// Any players currently in the zone will not be processed by the heartbeat
// so we do it here manually
@ -878,6 +823,7 @@ public class City extends AbstractWorldObject { @@ -878,6 +823,7 @@ public class City extends AbstractWorldObject {
for (Integer playerID : this._playerMemory) {
player = PlayerCharacter.getFromCache(playerID);
if (player == null)
continue;
@ -893,8 +839,10 @@ public class City extends AbstractWorldObject { @@ -893,8 +839,10 @@ public class City extends AbstractWorldObject {
}
public Warehouse getWarehouse() {
if (this.warehouseBuildingID == 0)
return null;
return Warehouse.warehouseByBuildingUUID.get(this.warehouseBuildingID);
}
@ -1066,8 +1014,7 @@ public class City extends AbstractWorldObject { @@ -1066,8 +1014,7 @@ public class City extends AbstractWorldObject {
_playerMemory.removeAll(toRemove);
for (Integer removalUUID : toRemove) {
if (this.cityOutlaws.contains(removalUUID))
this.cityOutlaws.remove(removalUUID);
this.cityOutlaws.remove(removalUUID);
}
}
@ -1083,7 +1030,7 @@ public class City extends AbstractWorldObject { @@ -1083,7 +1030,7 @@ public class City extends AbstractWorldObject {
Thread destroyCityThread = new Thread(new DestroyCityThread(this));
destroyCityThread.setName("deestroyCity:" + this.getName());
destroyCityThread.setName("destroyCity:" + this.getName());
destroyCityThread.start();
}
@ -1168,6 +1115,7 @@ public class City extends AbstractWorldObject { @@ -1168,6 +1115,7 @@ public class City extends AbstractWorldObject {
// All protection contracts are void upon transfer of a city
//Dont forget to not Flip protection on Banestones and siege Equipment... Noob.
if (cityBuilding.getBlueprint() != null && !cityBuilding.getBlueprint().isSiegeEquip()
&& cityBuilding.getBlueprint().getBuildingGroup() != BuildingGroup.BANESTONE)
cityBuilding.setProtectionState(ProtectionState.NONE);
@ -1199,7 +1147,6 @@ public class City extends AbstractWorldObject { @@ -1199,7 +1147,6 @@ public class City extends AbstractWorldObject {
Zone cityZone;
sourceGuild = sourcePlayer.getGuild();
if (sourceGuild == null)
return false;
@ -1255,14 +1202,6 @@ public class City extends AbstractWorldObject { @@ -1255,14 +1202,6 @@ public class City extends AbstractWorldObject {
this.forceRename = forceRename;
}
public boolean isReverseKOS() {
return reverseKOS;
}
public void setReverseKOS(boolean reverseKOS) {
this.reverseKOS = reverseKOS;
}
public String getHash() {
return hash;
}
@ -1290,26 +1229,6 @@ public class City extends AbstractWorldObject { @@ -1290,26 +1229,6 @@ public class City extends AbstractWorldObject {
}
//TODO use this for taxing later.
// public boolean isAfterTaxPeriod(LocalDateTime dateTime,PlayerCharacter player){
// if (dateTime.isBefore(realmTaxDate)){
// String wait = "";
// float hours = 1000*60*60;
// float seconds = 1000;
// float hoursUntil = realmTaxDate.minus(dateTime.get).getMillis() /hours;
// int secondsUntil = (int) (realmTaxDate.minus(dateTime.getMillis()).getMillis() /seconds);
// if (hoursUntil < 1)
// wait = "You must wait " + secondsUntil + " seconds before taxing this city again!";
// else
// wait = "You must wait " + hoursUntil + " hours before taxing this city again!";
// ErrorPopupMsg.sendErrorMsg(player, wait);
// return false;
// }
//
// return true;
// }
public synchronized boolean TaxWarehouse(TaxResourcesMsg msg, PlayerCharacter player) {
// Member variable declaration
@ -1322,12 +1241,12 @@ public class City extends AbstractWorldObject { @@ -1322,12 +1241,12 @@ public class City extends AbstractWorldObject {
}
City city = building.getCity();
if (city == null) {
ErrorPopupMsg.sendErrorMsg(player, "This building does not belong to a city.");
return true;
}
if (playerGuild == null || playerGuild.isEmptyGuild()) {
ErrorPopupMsg.sendErrorMsg(player, "You must belong to a guild to do that!");
return true;
@ -1352,6 +1271,7 @@ public class City extends AbstractWorldObject { @@ -1352,6 +1271,7 @@ public class City extends AbstractWorldObject {
ErrorPopupMsg.sendErrorMsg(player, "Cannot find realm for your city!");
return true;
}
Realm targetRealm = RealmMap.getRealmForCity(city);
if (targetRealm == null) {
@ -1380,31 +1300,32 @@ public class City extends AbstractWorldObject { @@ -1380,31 +1300,32 @@ public class City extends AbstractWorldObject {
return true;
}
if (this.realmTaxDate.isAfter(LocalDateTime.now()))
return true;
if (msg.getResources().size() == 0)
return true;
if (city.getWarehouse() == null)
return true;
Warehouse ruledWarehouse = playerGuild.getOwnedCity().getWarehouse();
if (ruledWarehouse == null)
return true;
ItemBase.getItemHashIDMap();
ArrayList<Integer> resources = new ArrayList<>();
float taxPercent = msg.getTaxPercent();
if (taxPercent > 20)
taxPercent = .20f;
for (int resourceHash : msg.getResources().keySet()) {
if (ItemBase.getItemHashIDMap().get(resourceHash) != null)
resources.add(ItemBase.getItemHashIDMap().get(resourceHash));
}
for (Integer itemBaseID : resources) {
@ -1422,6 +1343,7 @@ public class City extends AbstractWorldObject { @@ -1422,6 +1343,7 @@ public class City extends AbstractWorldObject {
ErrorPopupMsg.sendErrorMsg(player, "Failed to Update next Tax Date due to internal Error. City was not charged taxes this time.");
return false;
}
try {
city.getWarehouse().transferResources(player, msg, resources, taxPercent, ruledWarehouse);
} catch (Exception e) {
@ -1439,6 +1361,5 @@ public class City extends AbstractWorldObject { @@ -1439,6 +1361,5 @@ public class City extends AbstractWorldObject {
dispatch = Dispatch.borrow(player, msg);
DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.SECONDARY);
return true;
}
}

17
src/engine/objects/ItemBase.java

@ -914,4 +914,21 @@ public class ItemBase { @@ -914,4 +914,21 @@ public class ItemBase {
public void setAutoID(boolean autoID) {
this.autoID = autoID;
}
public boolean isArmor(){
if(this.isHeavyArmor())
return true;
if(this.isMediumArmor())
return true;
if(this.isLightArmor())
return true;
if(this.isClothArmor())
return true;
return false;
}
}

1305
src/engine/objects/Mob.java

File diff suppressed because it is too large Load Diff

31
src/engine/objects/MobBase.java

@ -27,6 +27,7 @@ public class MobBase extends AbstractGameObject { @@ -27,6 +27,7 @@ public class MobBase extends AbstractGameObject {
private final String firstName;
private final byte level;
private final float scale;
public final ArrayList<MobBaseEffects> effectsList;
public int bootySet;
public Enum.MobBehaviourType fsm;
public EnumBitSet<Enum.MonsterType> notEnemy;
@ -42,10 +43,6 @@ public class MobBase extends AbstractGameObject { @@ -42,10 +43,6 @@ public class MobBase extends AbstractGameObject {
private int goldMod;
private int seeInvis;
private int spawnTime = 0;
private int defense = 0;
private int atr = 0;
private float minDmg = 0;
private float maxDmg = 0;
private float attackRange;
private boolean isNecroPet = false;
private MobBaseStats mobBaseStats;
@ -108,6 +105,8 @@ public class MobBase extends AbstractGameObject { @@ -108,6 +105,8 @@ public class MobBase extends AbstractGameObject {
this.mobBaseStats = DbManager.MobBaseQueries.LOAD_STATS(this.loadID);
DbManager.MobBaseQueries.LOAD_ALL_MOBBASE_SPEEDS(this);
//load effects for mobbase
this.effectsList = DbManager.MobBaseQueries.GET_RUNEBASE_EFFECTS(this.loadID);
}
@ -245,30 +244,6 @@ public class MobBase extends AbstractGameObject { @@ -245,30 +244,6 @@ public class MobBase extends AbstractGameObject {
return mobBaseStats;
}
public float getMaxDmg() {
return maxDmg;
}
public float getMinDmg() {
return minDmg;
}
public int getAtr() {
return atr;
}
public void setAtr(int atr) {
this.atr = atr;
}
public int getDefense() {
return defense;
}
public void setDefense(int defense) {
this.defense = defense;
}
public float getAttackRange() {
return attackRange;
}

10
src/engine/objects/MobBaseStats.java

@ -21,6 +21,9 @@ public class MobBaseStats { @@ -21,6 +21,9 @@ public class MobBaseStats {
private final int baseSpi;
private final int baseDex;
private final int mobbaseSkill;
private final int mobbaseSkillAmount;
/**
* ResultSet Constructor
@ -31,6 +34,8 @@ public class MobBaseStats { @@ -31,6 +34,8 @@ public class MobBaseStats {
this.baseCon = rs.getInt("Constitution");
this.baseSpi = rs.getInt("Spirit");
this.baseDex = rs.getInt("Dexterity");
this.mobbaseSkill = rs.getInt("baseSkills");
this.mobbaseSkillAmount = rs.getInt("skillAmount");
}
/**
@ -43,6 +48,8 @@ public class MobBaseStats { @@ -43,6 +48,8 @@ public class MobBaseStats {
this.baseCon = 0;
this.baseSpi = 0;
this.baseDex = 0;
this.mobbaseSkill = 0;
this.mobbaseSkillAmount = 0;
}
public static MobBaseStats GetGenericStats() {
@ -72,5 +79,8 @@ public class MobBaseStats { @@ -72,5 +79,8 @@ public class MobBaseStats {
return baseDex;
}
public int getBaseSkill(){return mobbaseSkill;}
public int getBaseSkillAmount(){return mobbaseSkillAmount;}
}

40
src/engine/objects/NPC.java

@ -50,7 +50,6 @@ public class NPC extends AbstractCharacter { @@ -50,7 +50,6 @@ public class NPC extends AbstractCharacter {
// Used for thread safety
public final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
private final ArrayList<MobLoot> rolling = new ArrayList<>();
private final ConcurrentHashMap<Mob, Integer> siegeMinionMap = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
public ReentrantReadWriteLock minionLock = new ReentrantReadWriteLock();
public ArrayList<ProducedItem> forgedItems = new ArrayList<>();
public HashMap<Integer, MobEquipment> equip = null;
@ -86,6 +85,7 @@ public class NPC extends AbstractCharacter { @@ -86,6 +85,7 @@ public class NPC extends AbstractCharacter {
public NPC() {
super();
this.dbID = MBServerStatics.NO_DB_ROW_ASSIGNED_YET;
this.currentID = MBServerStatics.NO_DB_ROW_ASSIGNED_YET;
}
@ -640,26 +640,31 @@ public class NPC extends AbstractCharacter { @@ -640,26 +640,31 @@ public class NPC extends AbstractCharacter {
public void removeMinions() {
for (Mob toRemove : this.siegeMinionMap.keySet()) {
for (Integer minionUUID : this.minions) {
Mob minionMob = Mob.getMob(minionUUID);
try {
toRemove.clearEffects();
minionMob.clearEffects();
} catch (Exception e) {
Logger.error(e.getMessage());
}
if (toRemove.getParentZone() != null)
toRemove.getParentZone().zoneMobSet.remove(toRemove);
if (minionMob.getParentZone() != null)
minionMob.getParentZone().zoneMobSet.remove(minionMob);
WorldGrid.RemoveWorldObject(toRemove);
DbManager.removeFromCache(toRemove);
WorldGrid.RemoveWorldObject(minionMob);
DbManager.removeFromCache(minionMob);
PlayerCharacter petOwner = toRemove.getOwner();
PlayerCharacter petOwner = (PlayerCharacter) minionMob.guardCaptain;
if (petOwner != null) {
petOwner.setPet(null);
toRemove.setOwner(null);
minionMob.guardCaptain = null;
PetMsg petMsg = new PetMsg(5, null);
Dispatch dispatch = Dispatch.borrow(petOwner, petMsg);
@ -667,6 +672,7 @@ public class NPC extends AbstractCharacter { @@ -667,6 +672,7 @@ public class NPC extends AbstractCharacter {
}
}
}
@Override
@ -805,6 +811,8 @@ public class NPC extends AbstractCharacter { @@ -805,6 +811,8 @@ public class NPC extends AbstractCharacter {
@Override
public void runAfterLoad() {
this.charItemManager = new CharacterItemManager(this);
if (ConfigManager.serverType.equals(ServerType.LOGINSERVER))
return;
@ -846,10 +854,6 @@ public class NPC extends AbstractCharacter { @@ -846,10 +854,6 @@ public class NPC extends AbstractCharacter {
if (wordCount(this.name) < 2 && this.contract != null)
this.name += " the " + this.contract.getName();
// Initialize inventory
this.charItemManager = new CharacterItemManager(this);
// Configure parent zone adding this NPC to the
// zone collection
@ -861,7 +865,7 @@ public class NPC extends AbstractCharacter { @@ -861,7 +865,7 @@ public class NPC extends AbstractCharacter {
this.bindLoc = new Vector3fImmutable(this.statLat, this.statAlt, this.statLon);
this.bindLoc = this.parentZone.getLoc().add(this.bindLoc);
this.loc = new Vector3fImmutable(bindLoc);
this.setLoc(bindLoc);
// Handle NPCs within buildings
@ -968,6 +972,10 @@ public class NPC extends AbstractCharacter { @@ -968,6 +972,10 @@ public class NPC extends AbstractCharacter {
Bounds npcBounds = Bounds.borrow();
npcBounds.setBounds(this.getLoc());
//apply NPC rune effects
NPCManager.applyRunesForNPC(this);
this.resists.setImmuneToAll(true);
} catch (Exception e) {
Logger.error(e.getMessage());
}
@ -1103,10 +1111,6 @@ public class NPC extends AbstractCharacter { @@ -1103,10 +1111,6 @@ public class NPC extends AbstractCharacter {
return (int) time;
}
public ConcurrentHashMap<Mob, Integer> getSiegeMinionMap() {
return siegeMinionMap;
}
public boolean remove() {
Building building;

73
src/engine/objects/PlayerCharacter.java

@ -117,10 +117,8 @@ public class PlayerCharacter extends AbstractCharacter { @@ -117,10 +117,8 @@ public class PlayerCharacter extends AbstractCharacter {
public float landingAltitude = 0;
public int bindBuilding = 0;
public FriendStatus friendStatus = FriendStatus.Available;
protected ArrayList<CharacterRune> runes;
private BaseClass baseClass;
private PromotionClass promotionClass;
private long channelMute = 0; // none muted.
private ConcurrentHashMap<Integer, String> ignoredPlayerIDs = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
private boolean lfGroup = false;
private boolean lfGuild = false;
@ -135,7 +133,6 @@ public class PlayerCharacter extends AbstractCharacter { @@ -135,7 +133,6 @@ public class PlayerCharacter extends AbstractCharacter {
private Vector3fImmutable lastStaticLoc = new Vector3fImmutable(0.0f, 0.0f, 0.0f);
private GameObjectType lastTargetType;
private int lastTargetID;
private int hidden = 0; // current rank of hide/sneak/invis
private int seeInvis = 0; // current rank of see invis
private float speedMod;
private boolean teleportMode = false; // Teleport on MoveToPoint
@ -144,7 +141,6 @@ public class PlayerCharacter extends AbstractCharacter { @@ -144,7 +141,6 @@ public class PlayerCharacter extends AbstractCharacter {
private long lastUpdateTime = System.currentTimeMillis();
private long lastStamUpdateTime = System.currentTimeMillis();
private boolean safeZone = false;
private int bindBuildingID;
/*
DataWarehouse based kill/death tracking.
@ -205,15 +201,18 @@ public class PlayerCharacter extends AbstractCharacter { @@ -205,15 +201,18 @@ public class PlayerCharacter extends AbstractCharacter {
this.spiMod.set(spiMod);
this.guildStatus = new AtomicInteger(0);
this.bindBuildingID = -1;
this.buildingUUID = -1;
}
/**
* ResultSet Constructor
*/
public PlayerCharacter(ResultSet rs) throws SQLException {
super(rs, true);
this.charItemManager = new CharacterItemManager(this);
this.runes = DbManager.CharacterRuneQueries.GET_RUNES_FOR_CHARACTER(this.getObjectUUID());
int accountID = rs.getInt("parent");
this.account = DbManager.AccountQueries.GET_ACCOUNT(accountID);
@ -265,7 +264,7 @@ public class PlayerCharacter extends AbstractCharacter { @@ -265,7 +264,7 @@ public class PlayerCharacter extends AbstractCharacter {
this.intMod.set(rs.getShort("char_intMod"));
this.spiMod.set(rs.getShort("char_spiMod"));
this.bindBuildingID = rs.getInt("char_bindBuilding");
this.buildingUUID = rs.getInt("char_bindBuilding");
this.hash = rs.getString("hash");
@ -2721,12 +2720,12 @@ public class PlayerCharacter extends AbstractCharacter { @@ -2721,12 +2720,12 @@ public class PlayerCharacter extends AbstractCharacter {
*/
public synchronized int getBindBuildingID() {
return this.bindBuildingID;
return this.buildingUUID;
}
public synchronized void setBindBuildingID(int value) {
DbManager.PlayerCharacterQueries.SET_BIND_BUILDING(this, value);
this.bindBuildingID = value;
this.buildingUUID = value;
}
public AbstractGameObject getLastTarget() {
@ -2772,10 +2771,6 @@ public class PlayerCharacter extends AbstractCharacter { @@ -2772,10 +2771,6 @@ public class PlayerCharacter extends AbstractCharacter {
this.lastStaticLoc = value;
}
public int getHidden() {
return this.hidden;
}
public void setHidden(int value) {
this.hidden = value;
}
@ -4561,10 +4556,6 @@ public class PlayerCharacter extends AbstractCharacter { @@ -4561,10 +4556,6 @@ public class PlayerCharacter extends AbstractCharacter {
@Override
public void runAfterLoad() {
// Init inventory
this.charItemManager = new CharacterItemManager(this);
Bounds playerBounds = Bounds.borrow();
playerBounds.setBounds(this.getLoc());
this.setBounds(playerBounds);
@ -4692,7 +4683,8 @@ public class PlayerCharacter extends AbstractCharacter { @@ -4692,7 +4683,8 @@ public class PlayerCharacter extends AbstractCharacter {
} else if (currentPet.isSiege()) {
currentPet.agentType = AIAgentType.MOBILE;
currentPet.setOwner(null);
currentPet.guardCaptain = null;
currentPet.setCombatTarget(null);
if (currentPet.isAlive())
WorldGrid.updateObject(currentPet);
@ -4840,7 +4832,7 @@ public class PlayerCharacter extends AbstractCharacter { @@ -4840,7 +4832,7 @@ public class PlayerCharacter extends AbstractCharacter {
} else
this.altitude = this.getDesiredAltitude();
this.loc = this.loc.setY(HeightMap.getWorldHeight(this) + this.getAltitude());
this.loc = this.loc.setY(HeightMap.getWorldHeight(this.getLoc()) + this.getAltitude());
this.setTakeOffTime(0);
MovementManager.finishChangeAltitude(this, this.getDesiredAltitude());
@ -4848,7 +4840,7 @@ public class PlayerCharacter extends AbstractCharacter { @@ -4848,7 +4840,7 @@ public class PlayerCharacter extends AbstractCharacter {
return;
}
this.loc = this.loc.setY(HeightMap.getWorldHeight(this) + this.getAltitude());
this.loc = this.loc.setY(HeightMap.getWorldHeight(this.getLoc()) + this.getAltitude());
}
public boolean hasBoon() {
@ -4894,12 +4886,10 @@ public class PlayerCharacter extends AbstractCharacter { @@ -4894,12 +4886,10 @@ public class PlayerCharacter extends AbstractCharacter {
if (this.isAlive() == false || this.getBonuses().getBool(ModType.Stunned, SourceType.None) || this.getBonuses().getBool(ModType.CannotMove, SourceType.None)) {
//Target is stunned or rooted. Don't move
this.stopMovement(newLoc);
this.region = AbstractWorldObject.GetRegionByWorldObject(this);
return;
}
if (newLoc.equals(this.getEndLoc())) {
this.stopMovement(newLoc);
this.region = AbstractWorldObject.GetRegionByWorldObject(this);
if (this.getDebug(1))
ChatManager.chatSystemInfo(this,
"Arrived at End location. " + this.getEndLoc());
@ -4908,7 +4898,6 @@ public class PlayerCharacter extends AbstractCharacter { @@ -4908,7 +4898,6 @@ public class PlayerCharacter extends AbstractCharacter {
}
setLoc(newLoc);
this.region = AbstractWorldObject.GetRegionByWorldObject(this);
if (this.getDebug(1))
ChatManager.chatSystemInfo(this,
@ -5359,7 +5348,7 @@ public class PlayerCharacter extends AbstractCharacter { @@ -5359,7 +5348,7 @@ public class PlayerCharacter extends AbstractCharacter {
moveToMsg.setStartCoord(this.getLoc());
moveToMsg.setEndCoord(endLoc);
moveToMsg.setInBuilding(-1);
moveToMsg.setUnknown01(-1);
moveToMsg.setInBuildingFloor(-1);
moveToMsg.setSourceType(GameObjectType.PlayerCharacter.ordinal());
moveToMsg.setSourceID(this.getObjectUUID());
@ -5442,14 +5431,6 @@ public class PlayerCharacter extends AbstractCharacter { @@ -5442,14 +5431,6 @@ public class PlayerCharacter extends AbstractCharacter {
return characterHeight;
}
public void setCharacterHeight(float characterHeight) {
this.characterHeight = characterHeight;
}
public void setCenterHeight(float centerHeight) {
this.centerHeight = centerHeight;
}
public boolean isEnteredWorld() {
return enteredWorld;
}
@ -5458,40 +5439,10 @@ public class PlayerCharacter extends AbstractCharacter { @@ -5458,40 +5439,10 @@ public class PlayerCharacter extends AbstractCharacter {
this.enteredWorld = enteredWorld;
}
public long getChannelMute() {
return channelMute;
}
public void setChannelMute(long channelMute) {
this.channelMute = channelMute;
}
public boolean isLastSwimming() {
return lastSwimming;
}
public boolean isTeleporting() {
return isTeleporting;
}
public void setTeleporting(boolean isTeleporting) {
this.isTeleporting = isTeleporting;
}
@Override
public final void teleport(final Vector3fImmutable targetLoc) {
Regions targetRegion = Regions.GetRegionForTeleport(targetLoc);
locationLock.writeLock().lock();
try {
MovementManager.translocate(this, targetLoc, targetRegion);
} catch (Exception e) {
Logger.error(e);
} finally {
locationLock.writeLock().unlock();
}
}
public ReadWriteLock getTeleportLock() {
return teleportLock;

96
src/engine/objects/Zone.java

@ -56,9 +56,8 @@ public class Zone extends AbstractGameObject { @@ -56,9 +56,8 @@ public class Zone extends AbstractGameObject {
private boolean isNPCCity = false;
private boolean isPlayerCity = false;
private String hash;
private float worldAltitude = 0;
private float seaLevel = 0;
//public static ArrayList<Mob> respawnQue = new ArrayList<>();
public float worldAltitude = 0;
private float seaLevel = 0f;
public static final Set<Mob> respawnQue = Collections.newSetFromMap(new ConcurrentHashMap<>());
public static long lastRespawn = 0;
/**
@ -220,49 +219,6 @@ public class Zone extends AbstractGameObject { @@ -220,49 +219,6 @@ public class Zone extends AbstractGameObject {
return Icon1;
}
public void generateWorldAltitude() {
if (ZoneManager.getSeaFloor().getObjectUUID() == this.getObjectUUID()) {
this.worldAltitude = MBServerStatics.SEA_FLOOR_ALTITUDE;
return;
}
Zone parentZone = this.parent;
Zone currentZone = this;
float altitude = this.absY;
//seafloor only zone with null parent;
while (parentZone != ZoneManager.getSeaFloor()) {
if (parentZone.getHeightMap() != null) {
Vector2f zoneLoc = ZoneManager.worldToZoneSpace(currentZone.getLoc(), parentZone);
altitude += parentZone.getHeightMap().getInterpolatedTerrainHeight(zoneLoc);
}
currentZone = parentZone;
parentZone = parentZone.parent;
}
this.worldAltitude = altitude;
if (ZoneManager.getSeaFloor().equals(this))
this.seaLevel = 0;
else if
(this.getHeightMap() != null && this.getHeightMap().getSeaLevel() == 0) {
this.seaLevel = this.parent.seaLevel;
} else if (this.getHeightMap() != null) {
this.seaLevel = this.worldAltitude + this.getHeightMap().getSeaLevel();
} else {
this.seaLevel = this.parent.seaLevel;
}
}
public Zone getParent() {
return this.parent;
}
@ -272,26 +228,46 @@ public class Zone extends AbstractGameObject { @@ -272,26 +228,46 @@ public class Zone extends AbstractGameObject {
this.parent = value;
this.parentZoneID = (this.parent != null) ? this.parent.getObjectUUID() : 0;
if (this.parent != null) {
this.absX = this.xCoord + parent.absX;
this.absY = this.yCoord + parent.absY;
this.absZ = this.zCoord + parent.absZ;
// Zone AABB is set here as it's coordinate space is world requiring a parent.
// Seafloor
if (this.minLvl == 0 || this.maxLvl == 0) {
this.minLvl = this.parent.minLvl;
this.maxLvl = this.parent.maxLvl;
}
} else { //only the Sea Floor zone does not have a parent
if (this.parent == null) {
this.absX = this.xCoord;
this.absY = MBServerStatics.SEA_FLOOR_ALTITUDE;
this.absZ = this.zCoord;
this.seaLevel = 0;
this.setBounds();
return;
}
// Zone AABB is set here as it's coordinate space is world requiring a parent.
this.absX = this.xCoord + parent.absX;
this.absY = this.yCoord + parent.absY;
this.absZ = this.zCoord + parent.absZ;
if (this.minLvl == 0 || this.maxLvl == 0) {
this.minLvl = this.parent.minLvl;
this.maxLvl = this.parent.maxLvl;
}
this.worldAltitude = ZoneManager.caclulateWorldAltitude(this);
this.setBounds();
if (this.getHeightMap() != null && this.getHeightMap().getSeaLevel() != 0)
this.seaLevel = this.getHeightMap().getSeaLevel();
if (this.getParent() == null) {
this.seaLevel = MBServerStatics.SEA_FLOOR_ALTITUDE;
return;
}
if (this.getHeightMap() == null) {
this.seaLevel = this.parent.seaLevel;
return;
}
if (this.getHeightMap().getSeaLevel() != 0)
this.seaLevel = this.worldAltitude + this.getHeightMap().getSeaLevel();
else
this.seaLevel = this.parent.seaLevel;
}
@ -420,8 +396,4 @@ public class Zone extends AbstractGameObject { @@ -420,8 +396,4 @@ public class Zone extends AbstractGameObject {
return seaLevel;
}
public float getWorldAltitude() {
return worldAltitude;
}
}

17
src/engine/powers/MobPowerEntry.java

@ -1,17 +0,0 @@ @@ -1,17 +0,0 @@
package engine.powers;
import java.sql.ResultSet;
import java.sql.SQLException;
public class MobPowerEntry {
public int token;
public int rank;
public MobPowerEntry(ResultSet rs) throws SQLException {
this.token = rs.getInt("token");
this.rank = rs.getInt("rank");
}
}

29
src/engine/powers/RunePowerEntry.java

@ -0,0 +1,29 @@ @@ -0,0 +1,29 @@
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
package engine.powers;
import java.sql.ResultSet;
import java.sql.SQLException;
public class RunePowerEntry {
public String name;
public int token;
public String power_type;
public int rank;
public RunePowerEntry(ResultSet rs) throws SQLException {
this.name = rs.getString("name");
this.token = rs.getInt("token");
this.power_type = rs.getString("power_type");
this.rank = rs.getInt("rank");
}
}

31
src/engine/powers/RuneSkillAdjustEntry.java

@ -0,0 +1,31 @@ @@ -0,0 +1,31 @@
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
package engine.powers;
import java.sql.ResultSet;
import java.sql.SQLException;
public class RuneSkillAdjustEntry {
public String name;
public int token;
public String skill_type;
public int rank;
public int level;
public RuneSkillAdjustEntry(ResultSet rs) throws SQLException {
this.name = rs.getString("name");
this.token = rs.getInt("token");
this.skill_type = rs.getString("skill_type");
this.rank = rs.getInt("rank");
this.level = rs.getInt("level");
}
}

24
src/engine/powers/poweractions/ApplyEffectPowerAction.java

@ -11,6 +11,7 @@ package engine.powers.poweractions; @@ -11,6 +11,7 @@ package engine.powers.poweractions;
import engine.Enum.GameObjectType;
import engine.Enum.ModType;
import engine.Enum.SourceType;
import engine.InterestManagement.WorldGrid;
import engine.gameManager.ChatManager;
import engine.jobs.ChantJob;
import engine.jobs.DeferredPowerJob;
@ -22,6 +23,7 @@ import engine.objects.*; @@ -22,6 +23,7 @@ import engine.objects.*;
import engine.powers.ActionsBase;
import engine.powers.EffectsBase;
import engine.powers.PowersBase;
import engine.server.MBServerStatics;
import org.pmw.tinylog.Logger;
import java.sql.ResultSet;
@ -117,20 +119,12 @@ public class ApplyEffectPowerAction extends AbstractPowerAction { @@ -117,20 +119,12 @@ public class ApplyEffectPowerAction extends AbstractPowerAction {
awo.addEffect(stackType, duration, eff, effect, trains);
} else
awo.applyAllBonuses();
// //TODO if chant, start cycle
// if (pb.isChant() && source.equals(awo)) {
// ChantJob cj = new ChantJob(source, awo, stackType, trains, ab, pb, effect, eff);
// source.setLastChant((int)(pb.getChantDuration()-2) * 1000, cj);
// eff.setChant(true);
// }
if (this.effectID.equals("TAUNT")) {
if (awo != null && awo.getObjectType() == GameObjectType.Mob) {
((Mob) awo).setCombatTarget(source);
ChatSystemMsg msg = ChatManager.CombatInfo(source, awo);
DispatchMessage.sendToAllInRange(source, msg);
((Mob)awo).refresh();
}
}
if (awo != null && awo.getObjectType() == GameObjectType.Mob) {
@ -140,7 +134,21 @@ public class ApplyEffectPowerAction extends AbstractPowerAction { @@ -140,7 +134,21 @@ public class ApplyEffectPowerAction extends AbstractPowerAction {
}
this.effect.startEffect(source, awo, trains, eff);
}
//apply effects to mobs within range for chants
if(pb.isChant){
for(AbstractGameObject ago : WorldGrid.getObjectsInRangePartial(awo.loc,pb.range, MBServerStatics.MASK_MOB)){
Mob mob = (Mob)ago;
if(mob.playerAgroMap.containsKey(source.getObjectUUID()))
mob.playerAgroMap.put(source.getObjectUUID(), mob.playerAgroMap.get(source.getObjectUUID()).floatValue() + pb.hateValue);
}
}else {
if (awo != null && awo.getObjectType() == GameObjectType.Mob) {
Mob mob = (Mob) awo;
if (mob.playerAgroMap.containsKey(source.getObjectUUID()))
mob.playerAgroMap.put(source.getObjectUUID(), mob.playerAgroMap.get(source.getObjectUUID()).floatValue() + pb.hateValue);
}
}
}
protected void _applyEffectForItem(Item item, int trains) {

36
src/engine/powers/poweractions/CreateMobPowerAction.java

@ -12,7 +12,6 @@ package engine.powers.poweractions; @@ -12,7 +12,6 @@ package engine.powers.poweractions;
import engine.Enum;
import engine.InterestManagement.WorldGrid;
import engine.gameManager.DbManager;
import engine.gameManager.MovementManager;
import engine.gameManager.NPCManager;
import engine.gameManager.ZoneManager;
import engine.math.Vector3fImmutable;
@ -75,7 +74,7 @@ public class CreateMobPowerAction extends AbstractPowerAction { @@ -75,7 +74,7 @@ public class CreateMobPowerAction extends AbstractPowerAction {
return;
//create Pet
Mob pet = Mob.createPet(mobID, guild, seaFloor, owner, (short) mobLevel);
Mob pet = Mob.createPetMinion(mobID, seaFloor, owner, (short) mobLevel);
if (pet.getMobBaseID() == 12021 || pet.getMobBaseID() == 12022) { //is a necro pet
@ -84,8 +83,6 @@ public class CreateMobPowerAction extends AbstractPowerAction { @@ -84,8 +83,6 @@ public class CreateMobPowerAction extends AbstractPowerAction {
WorldGrid.RemoveWorldObject(currentPet);
currentPet.setCombatTarget(null);
//if (currentPet.getParentZone() != null)
//currentPet.getParentZone().zoneMobSet.remove(currentPet);
seaFloor.zoneMobSet.remove(currentPet);
currentPet.playerAgroMap.clear();
@ -95,10 +92,10 @@ public class CreateMobPowerAction extends AbstractPowerAction { @@ -95,10 +92,10 @@ public class CreateMobPowerAction extends AbstractPowerAction {
Logger.error(e.getMessage());
}
//currentPet.disableIntelligence();
} else if (currentPet != null && currentPet.isSiege()) {
currentPet.agentType = Enum.AIAgentType.MOBILE;
currentPet.setOwner(null);
currentPet.guardCaptain = null;
currentPet.setCombatTarget(null);
if (currentPet.isAlive())
@ -106,7 +103,6 @@ public class CreateMobPowerAction extends AbstractPowerAction { @@ -106,7 +103,6 @@ public class CreateMobPowerAction extends AbstractPowerAction {
}
//remove 10th pet
NPCManager.spawnNecroPet(owner, pet);
} else { //is not a necro pet
@ -115,7 +111,7 @@ public class CreateMobPowerAction extends AbstractPowerAction { @@ -115,7 +111,7 @@ public class CreateMobPowerAction extends AbstractPowerAction {
DbManager.removeFromCache(currentPet);
currentPet.setCombatTarget(null);
currentPet.setOwner(null);
currentPet.guardCaptain = null;
WorldGrid.RemoveWorldObject(currentPet);
//currentPet.getParentZone().zoneMobSet.remove(currentPet);
seaFloor.zoneMobSet.remove(currentPet);
@ -125,7 +121,8 @@ public class CreateMobPowerAction extends AbstractPowerAction { @@ -125,7 +121,8 @@ public class CreateMobPowerAction extends AbstractPowerAction {
} else {
if (currentPet.isSiege()) {
currentPet.agentType = Enum.AIAgentType.MOBILE;
currentPet.setOwner(null);
currentPet.guardCaptain = null;
currentPet.setCombatTarget(null);
if (currentPet.isAlive())
@ -137,26 +134,9 @@ public class CreateMobPowerAction extends AbstractPowerAction { @@ -137,26 +134,9 @@ public class CreateMobPowerAction extends AbstractPowerAction {
NPCManager.resetNecroPets(owner);
}
}
/* if(owner.getPet() != null) {
if(owner.getPet().getMobBaseID() != 12021 && owner.getPet().getMobBaseID() != 12022) {
//if not a necro pet, remove pet
WorldGrid.removeWorldObject(owner.getPet());
owner.getPet().disableIntelligence();
Mob.removePet(owner.getPet().getUUID());
owner.setPet(null);
}
else {
//if it is a necro pet, add it to the line and set as mob
owner.getPet().setMob();
}
}*/
// if (mobID == 12021 || mobID == 12022) //Necro Pets
// pet.setPet(owner, true);
owner.setPet(pet);
if(pet.isSiege() == false) {
MovementManager.translocate(pet, owner.getLoc(), owner.region);
}
pet.recalculateStats();
pet.healthMax = pet.level * 0.5f * 120;
pet.setHealth(pet.healthMax);

2
src/engine/powers/poweractions/FearPowerAction.java

@ -59,7 +59,7 @@ public class FearPowerAction extends AbstractPowerAction { @@ -59,7 +59,7 @@ public class FearPowerAction extends AbstractPowerAction {
int duration = 10 + ((int) (trains * 0.5));
String stackType = ab.getStackType();
EndFearJob efj = new EndFearJob(source, awo, stackType, trains, ab, pb, null);
((Mob) awo).setFearedObject(source);
((Mob) awo).fearedObject = source;
JobScheduler.getInstance().scheduleJob(efj, duration * 1000);
}

2
src/engine/powers/poweractions/MobRecallPowerAction.java

@ -38,7 +38,7 @@ public class MobRecallPowerAction extends AbstractPowerAction { @@ -38,7 +38,7 @@ public class MobRecallPowerAction extends AbstractPowerAction {
return;
MovementManager.translocate(awoac, awoac.getBindLoc(), null);
MovementManager.translocate(awoac, awoac.getBindLoc());
if (awoac.getObjectType() == GameObjectType.Mob) {
//MobAI.setAwake((Mob)awoac,true);
((Mob) awoac).setCombatTarget(null);

2
src/engine/powers/poweractions/RecallPowerAction.java

@ -58,7 +58,7 @@ public class RecallPowerAction extends AbstractPowerAction { @@ -58,7 +58,7 @@ public class RecallPowerAction extends AbstractPowerAction {
DispatchMessage.dispatchMsgDispatch(dispatch, engine.Enum.DispatchChannel.SECONDARY);
} else {
MovementManager.translocate(awoac, awoac.getBindLoc(), null);
MovementManager.translocate(awoac, awoac.getBindLoc());
}
} else {
Vector3fImmutable bindloc = awoac.getBindLoc();

2
src/engine/powers/poweractions/TeleportPowerAction.java

@ -101,7 +101,7 @@ public class TeleportPowerAction extends AbstractPowerAction { @@ -101,7 +101,7 @@ public class TeleportPowerAction extends AbstractPowerAction {
if (region != null && !region.isOutside())
return;
MovementManager.translocate(awoac, targetLoc, region);
MovementManager.translocate(awoac, targetLoc);
}
@Override

24
src/engine/server/login/LoginServerMsgHandler.java

@ -136,25 +136,25 @@ public class LoginServerMsgHandler implements NetMsgHandler { @@ -136,25 +136,25 @@ public class LoginServerMsgHandler implements NetMsgHandler {
cMajorVer = vim.getMajorVersion();
cMinorVer = vim.getMinorVersion();
if (!cMajorVer.equals(this.server.getDefaultVersionInfo().getMajorVersion())) {
this.KickToLogin(MBServerStatics.LOGINERROR_INCORRECT_CLIENT_VERSION, "Major Version Failure: " + cMajorVer, cc);
return;
}
// if (!cMajorVer.equals(this.server.getDefaultVersionInfo().getMajorVersion())) {
// this.KickToLogin(MBServerStatics.LOGINERROR_INCORRECT_CLIENT_VERSION, "Major Version Failure: " + cMajorVer, cc);
// return;
// }
/* if (!cMinorVer.equals(this.server.getDefaultVersionInfo().getMinorVersion())) {
this.KickToLogin(MBServerStatics.LOGINERROR_INCORRECT_CLIENT_VERSION, "Minor Version Failure: " + cMinorVer, cc);
return;
} */
if (cMinorVer == null) {
this.KickToLogin(MBServerStatics.LOGINERROR_INCORRECT_CLIENT_VERSION, "Minor Version Failure: ", cc);
return;
}
// if (cMinorVer == null) {
// this.KickToLogin(MBServerStatics.LOGINERROR_INCORRECT_CLIENT_VERSION, "Minor Version Failure: ", cc);
// return;
// }
if (cMinorVer.length() < 8 || cMinorVer.length() > 16) {
this.KickToLogin(MBServerStatics.LOGINERROR_INCORRECT_CLIENT_VERSION, "Minor Version Failure: ", cc);
return;
}
// if (cMinorVer.length() < 8 || cMinorVer.length() > 16) {
// this.KickToLogin(MBServerStatics.LOGINERROR_INCORRECT_CLIENT_VERSION, "Minor Version Failure: ", cc);
// return;
// }
// set MachineID for this connection

88
src/engine/server/world/WorldServer.java

@ -10,7 +10,6 @@ @@ -10,7 +10,6 @@
package engine.server.world;
import engine.Enum;
import engine.Enum.BuildingGroup;
import engine.Enum.DispatchChannel;
import engine.Enum.MinionType;
import engine.Enum.SupportMsgType;
@ -18,6 +17,7 @@ import engine.InterestManagement.HeightMap; @@ -18,6 +17,7 @@ import engine.InterestManagement.HeightMap;
import engine.InterestManagement.RealmMap;
import engine.InterestManagement.WorldGrid;
import engine.db.archive.DataWarehouse;
import engine.db.handlers.dbRuneBaseHandler;
import engine.exception.MsgSendException;
import engine.gameManager.*;
import engine.job.JobContainer;
@ -334,7 +334,7 @@ public class WorldServer { @@ -334,7 +334,7 @@ public class WorldServer {
DbManager.PromotionQueries.GET_ALL_PROMOTIONS();
Logger.info("Loading NPC and Mob Rune Sets");
NPCManager.LoadAllRuneSets();
NPCManager._runeSetMap = DbManager.ItemBaseQueries.LOAD_RUNES_FOR_NPC_AND_MOBS();
Logger.info("Loading Booty Sets");
LootManager._bootySetMap = DbManager.LootQueries.LOAD_BOOTY_TABLES();
@ -351,8 +351,11 @@ public class WorldServer { @@ -351,8 +351,11 @@ public class WorldServer {
Logger.info("Loading MobBases.");
DbManager.MobBaseQueries.GET_ALL_MOBBASES();
Logger.info("Loading Mob Powers");
PowersManager.AllMobPowers = DbManager.PowerQueries.LOAD_MOB_POWERS();
Logger.info("Loading Rune Powers");
PowersManager._allRunePowers = dbRuneBaseHandler.LOAD_RUNE_POWERS();
Logger.info("Loading Rune Skill Adjusts");
PowersManager._allRuneSkillAdjusts = dbRuneBaseHandler.LOAD_RUNE_SKILL_ADJUSTS();
Logger.info("Loading item enchants");
DbManager.LootQueries.LOAD_ENCHANT_VALUES();
@ -482,7 +485,7 @@ public class WorldServer { @@ -482,7 +485,7 @@ public class WorldServer {
Logger.info("Initializing Client Connection Manager");
initClientConnectionManager();
//intiate mob respawn thread
Logger.info("Starting Mob Respawn Thread");
MobRespawnThread.startRespawnThread();
@ -551,44 +554,38 @@ public class WorldServer { @@ -551,44 +554,38 @@ public class WorldServer {
}
//Set sea floor object for server
Zone seaFloor = rootParent.get(0);
seaFloor.setParent(null);
ZoneManager.setSeaFloor(seaFloor);
// zoneManager.addZone(seaFloor.getLoadNum(), seaFloor); <- DIE IN A FUCKING CAR FIRE BONUS CODE LIKE THIS SUCKS FUCKING DICK
rootParent.addAll(DbManager.ZoneQueries.GET_ALL_NODES(seaFloor));
long start = System.currentTimeMillis();
for (Zone zone : rootParent) {
try {
ZoneManager.addZone(zone.getLoadNum(), zone);
try {
zone.generateWorldAltitude();
} catch (Exception e) {
Logger.error(e.getMessage());
e.printStackTrace();
}
ZoneManager.addZone(zone.getLoadNum(), zone);
//Handle Buildings
//Handle Buildings
try {
ArrayList<Building> bList;
bList = DbManager.BuildingQueries.GET_ALL_BUILDINGS_FOR_ZONE(zone);
for (Building b : bList) {
try {
b.setObjectTypeMask(MBServerStatics.MASK_BUILDING);
b.setLoc(b.getLoc());
} catch (Exception e) {
Logger.error(b.getObjectUUID() + " returned an Error Message :" + e.getMessage());
}
b.setObjectTypeMask(MBServerStatics.MASK_BUILDING);
b.setLoc(b.getLoc());
}
} catch (Exception e) {
Logger.error(e);
e.printStackTrace();
}
//Handle Mobs
//Handle Mobs
try {
ArrayList<Mob> mobs;
mobs = DbManager.MobQueries.GET_ALL_MOBS_FOR_ZONE(zone);
@ -596,15 +593,22 @@ public class WorldServer { @@ -596,15 +593,22 @@ public class WorldServer {
m.setObjectTypeMask(MBServerStatics.MASK_MOB | m.getTypeMasks());
m.setLoc(m.getLoc());
//ADD GUARDS HERE.
if (m.building != null && m.building.getBlueprint() != null && m.building.getBlueprint().getBuildingGroup() == BuildingGroup.BARRACK)
DbManager.MobQueries.LOAD_PATROL_POINTS(m);
// Load Minions for Guard Captains here.
if (m.building != null && m.building.getBlueprint() != null && m.building.getBlueprint().getBuildingGroup() == Enum.BuildingGroup.BARRACK)
DbManager.MobQueries.LOAD_GUARD_MINIONS(m);
}
} catch (Exception e) {
Logger.error(e);
e.printStackTrace();
}
//Handle NPCs
//Handle npc's
try {
ArrayList<NPC> npcs;
// Ignore npc's on the seafloor (npc guild leaders, etc)
// Ignore NPCs on the seafloor (npc guild leaders, etc)
if (zone.equals(seaFloor))
continue;
@ -612,26 +616,22 @@ public class WorldServer { @@ -612,26 +616,22 @@ public class WorldServer {
npcs = DbManager.NPCQueries.GET_ALL_NPCS_FOR_ZONE(zone);
for (NPC n : npcs) {
try {
n.setObjectTypeMask(MBServerStatics.MASK_NPC);
n.setLoc(n.getLoc());
} catch (Exception e) {
Logger.error(n.getObjectUUID() + " returned an Error Message :" + e.getMessage());
}
n.setObjectTypeMask(MBServerStatics.MASK_NPC);
n.setLoc(n.getLoc());
}
//Handle cities
ZoneManager.loadCities(zone);
ZoneManager.populateWorldZones(zone);
} catch (Exception e) {
Logger.info(e.getMessage() + zone.getName() + ' ' + zone.getObjectUUID());
Logger.error(e);
e.printStackTrace();
}
//Handle cities
ZoneManager.loadCities(zone);
ZoneManager.populateWorldZones(zone);
}
Logger.info("time to load: " + (System.currentTimeMillis() - start) + " ms");
Logger.info("time to load World Objects: " + (System.currentTimeMillis() - start) + " ms");
}
/**
@ -704,7 +704,7 @@ public class WorldServer { @@ -704,7 +704,7 @@ public class WorldServer {
return;
}
//remove player from loaded mobs agro maps
for(AbstractWorldObject awo : WorldGrid.getObjectsInRangePartial(player.getLoc(),MBServerStatics.CHARACTER_LOAD_RANGE,MBServerStatics.MASK_MOB)) {
for (AbstractWorldObject awo : WorldGrid.getObjectsInRangePartial(player.getLoc(), MBServerStatics.CHARACTER_LOAD_RANGE, MBServerStatics.MASK_MOB)) {
Mob loadedMob = (Mob) awo;
loadedMob.playerAgroMap.remove(player.getObjectUUID());
}

Loading…
Cancel
Save