Compare commits

...

247 Commits

Author SHA1 Message Date
MagicBot 44b9ba911d Indices added to command output. 2023-09-15 17:29:51 -04:00
MagicBot c24f8fc85b Login check modified for testing. 2023-09-15 14:23:34 -04:00
MagicBot 75c56cbeee Devcmd output updated. 2023-09-14 14:11:26 -04:00
MagicBot 15f42c9658 Devcmd output updated. 2023-09-14 13:54:22 -04:00
MagicBot 525d0c21bb Devcmd output updated. 2023-09-14 13:41:07 -04:00
MagicBot cbf05cfe5b Devcmd output updated. 2023-09-14 13:30:46 -04:00
MagicBot aaa506a581 Divisor testing. 2023-09-14 13:21:02 -04:00
MagicBot a2fbfad00e Revert initialize. 2023-09-14 13:07:32 -04:00
MagicBot 031c52e25a Divisor test. 2023-09-14 13:03:06 -04:00
MagicBot 693dfd827c Updated dev cmd output 2023-09-14 13:01:22 -04:00
MagicBot d26a2d35bf Multiple not divide 2023-09-14 12:39:31 -04:00
MagicBot 9839de128c Variable initialized. 2023-09-14 12:38:47 -04:00
MagicBot 12872ee51e Variable initialized. 2023-09-14 12:30:54 -04:00
MagicBot 2af08d6823 Reformat file. 2023-09-14 12:29:26 -04:00
MagicBot f646075311 Static method to save memory. 2023-09-14 12:28:36 -04:00
MagicBot dfca767476 Multiple not divide. 2023-09-14 12:25:18 -04:00
MagicBot fd7b5952c2 Dev command updated 2023-09-14 12:21:12 -04:00
MagicBot 4b46eddc47 Dev command updated 2023-09-14 12:09:50 -04:00
MagicBot e26121177f World altitude set in setparent. 2023-09-14 12:07:08 -04:00
MagicBot 91eb0c314f SeAudit command created 2023-09-14 10:14:31 -04:00
MagicBot 1d7a2d4eae Added sea level info to command. 2023-09-14 10:09:10 -04:00
MagicBot e4235d4d75 Bugfix in setparent. 2023-09-14 09:13:02 -04:00
FatBoy 41a83115be safehold guard exclusion from equipment dropping 2023-09-13 22:34:57 -05:00
FatBoy 3ce887cb34 NPC are immune to all 2023-09-13 22:30:24 -05:00
FatBoy 874eb6189e NPC apply runes 2023-09-13 22:24:10 -05:00
FatBoy 5c5c491597 debug code 2023-09-13 22:10:22 -05:00
FatBoy ff78c1443c null check 2023-09-13 22:04:23 -05:00
FatBoy cdc1c2d776 region assignment 2023-09-13 21:58:20 -05:00
FatBoy a004c247ab abstract character cleanup 2023-09-13 21:57:17 -05:00
FatBoy 048e90fb8f NPC all apply "shopkeeper" rune 2023-09-13 21:56:18 -05:00
FatBoy c1498145e6 NPC rune work 2023-09-13 21:45:15 -05:00
FatBoy 7654d5183a region lookup and height offset for AbstractCharacters when setLoc is called 2023-09-13 21:28:20 -05:00
FatBoy 9b7fc0a93b region height work 2023-09-13 21:07:57 -05:00
FatBoy 200318ddcf add region height to world height in setLoc 2023-09-13 20:48:02 -05:00
FatBoy 1fdd0a1b32 initialize runes array list for NPC 2023-09-13 20:45:21 -05:00
FatBoy 8869772fa4 print effects command 2023-09-13 20:34:48 -05:00
FatBoy 96bc894962 print runes command 2023-09-13 20:27:38 -05:00
FatBoy 5a9f5f2eca NPCs apply runes from set 2023-09-13 20:22:56 -05:00
FatBoy bd9dbcbb42 NPCs load rune sets 2023-09-13 20:12:07 -05:00
FatBoy f8269bb764 character runes moved form PlayerCharacter to AbstractCharacter 2023-09-13 20:06:12 -05:00
FatBoy c215047c00 teleport method removed form PLayerCharacter to use AbstractCharacter.teleport instead 2023-09-13 20:00:23 -05:00
FatBoy a313e3f364 setRegion removal 2023-09-13 19:56:54 -05:00
FatBoy b34be1184e null region assignment 2023-09-13 19:53:13 -05:00
FatBoy e23c5527da null region assignment 2023-09-13 19:52:17 -05:00
FatBoy 847e62dd27 setLoc now handles region assignment 2023-09-13 19:51:39 -05:00
MagicBot f5d83aa259 Class cleanup of bonus code and unused methods. 2023-09-13 09:38:10 -04:00
MagicBot 4a5c0ae5a0 Cities don't actually have a location. They are a property of a zone. Let's start here. 2023-09-13 09:29:42 -04:00
MagicBot b4a4323906 Minor formatting cleanup. 2023-09-13 09:24:40 -04:00
MagicBot 48fc5af5f7 Removed unused variables from class. 2023-09-13 07:33:02 -04:00
MagicBot a1753a28ec Player cities write correct offset. 2023-09-13 07:29:29 -04:00
MagicBot fa4039cf63 Add y offset to zone altitude. 2023-09-12 16:25:46 -04:00
MagicBot 4b0814c0a1 Add y offset to zone altitude. 2023-09-12 16:24:47 -04:00
MagicBot 78d0b06b36 Revert for testing. 2023-09-12 16:22:41 -04:00
MagicBot 426bdf5df3 Removed yoffset from world altitude. 2023-09-12 16:13:27 -04:00
MagicBot 5dbad7ebd0 Player cities set to white. 2023-09-12 15:33:52 -04:00
MagicBot 6ef33c5b7f Update to world altitude calculation 2023-09-12 15:27:00 -04:00
MagicBot 3737a6eace Sea level logic updated. 2023-09-12 15:18:09 -04:00
MagicBot 967e129724 Sea level logic updated. 2023-09-12 15:09:52 -04:00
MagicBot e9d549377e Sea level logic updated. 2023-09-12 15:06:26 -04:00
MagicBot 924b8af827 Sea level logic updated. 2023-09-12 14:57:47 -04:00
MagicBot 045ee73b61 rework of world altitude calculation. 2023-09-12 14:51:04 -04:00
MagicBot 5d9d13ce07 Any argument rebuilds world altitude. 2023-09-12 13:06:46 -04:00
MagicBot 5a1347ec50 Devcmd updated 2023-09-12 13:01:32 -04:00
MagicBot c705f45856 Devcmd updated 2023-09-12 12:38:20 -04:00
MagicBot 83fc129d05 Dev command output update. 2023-09-11 15:59:08 -04:00
MagicBot d7cde3a77f Grid flip testing 2023-09-11 15:41:44 -04:00
MagicBot afb1ad8e94 Grid flip testing 2023-09-11 15:36:59 -04:00
MagicBot 15a79ee9bd devcmd output updated with grid. 2023-09-11 14:37:16 -04:00
MagicBot 68794c170b Removed usless method: added grid to cmd output. 2023-09-11 14:30:14 -04:00
MagicBot a9d84749ba Removed worthless command. 2023-09-11 14:26:06 -04:00
MagicBot dd5fc323ef bugfix in array loading 2023-09-11 14:06:22 -04:00
MagicBot cf1547d077 DevCmd Updated 2023-09-11 13:57:05 -04:00
MagicBot 9664c99e06 DevCmd Updated 2023-09-11 13:50:56 -04:00
MagicBot 17b7fb6999 Unused method 2023-09-11 13:48:16 -04:00
MagicBot 21a4db8a81 Pixels set to 0 2023-09-11 13:40:47 -04:00
MagicBot eabdabcfcd No insane bucket widths. 2023-09-11 12:38:46 -04:00
MagicBot c548383a4c Should not be putting empty maps into the collection with id 0. 2023-09-11 12:35:58 -04:00
MagicBot 7337f4be1e DevCmd update. 2023-09-11 12:14:42 -04:00
MagicBot d84f223b9d DevCmd update. 2023-09-11 12:08:39 -04:00
MagicBot 5431112186 DevCmd update. 2023-09-11 11:35:53 -04:00
MagicBot ff743151c6 DevCmd update. 2023-09-11 11:25:28 -04:00
MagicBot b923392b53 DevCmd update. 2023-09-11 11:18:22 -04:00
MagicBot 15d272c621 DevCmd update. 2023-09-11 11:17:34 -04:00
MagicBot eefa50b2c3 DevCmd update. 2023-09-11 11:14:55 -04:00
MagicBot ecc7a152f7 DevCmd update. 2023-09-11 11:08:03 -04:00
MagicBot 7bf31f9a47 Rework of class interface. 2023-09-11 11:01:09 -04:00
MagicBot 7dc970ff53 Rework of dev command; junk deleted. 2023-09-11 10:50:01 -04:00
FatBoy 97d71ec361 move to point handler revert 2023-09-11 01:36:45 -05:00
FatBoy 003b939d33 Move to point message variable naming and handler cleanup 2023-09-10 19:37:46 -05:00
FatBoy 9989cbff24 pc.teleport uneeded 2023-09-10 17:20:30 -05:00
FatBoy 426ef989f8 can no longer run to invalid targets 2023-09-10 16:45:17 -05:00
FatBoy ca6e079053 fresh start 2023-09-10 15:51:25 -05:00
FatBoy 13644fd308 use target from message in move to point 2023-09-10 15:02:26 -05:00
FatBoy 1ec76ae3fc use target from message in move to point 2023-09-10 14:58:56 -05:00
FatBoy 51d75146cc NPC added to attack message handler switch 2023-09-10 14:28:32 -05:00
FatBoy bc4222646d combat target usage 2023-09-10 14:12:01 -05:00
FatBoy c3e206e3b1 null check 2023-09-10 14:09:48 -05:00
FatBoy 04147e11cc logic for moveToPoint message handler 2023-09-10 14:08:54 -05:00
FatBoy 545cb4cddf null check for building pulled 2023-09-10 13:40:19 -05:00
FatBoy 0f948d4e2a removed redundant setCombatTarget 2023-09-10 13:39:27 -05:00
FatBoy 5fb3e0fe14 switch for target type in attack message handler 2023-09-10 13:38:07 -05:00
MagicBot fb87dfd91e TargetType declared. 2023-09-10 14:33:04 -04:00
FatBoy be8967b05f null set for target 2023-09-10 13:28:46 -05:00
FatBoy 8acfff7faa null check for target 2023-09-10 13:26:28 -05:00
FatBoy 18e1f4bd28 early exits for attack message handler 2023-09-10 13:25:08 -05:00
MagicBot 74f88a6643 Unused variable removed 2023-09-10 14:04:48 -04:00
FatBoy 47fe764cb0 early exits for attack message handler 2023-09-10 12:58:24 -05:00
MagicBot 9e53770e6c Handler added to protocol class. 2023-09-10 13:55:16 -04:00
MagicBot a9cc001791 Handler added to protocol class. 2023-09-10 13:53:12 -04:00
MagicBot c24913d124 Handler filled in with logic. 2023-09-10 13:52:04 -04:00
MagicBot 63bf0b6070 Handler created for AttackMsg 2023-09-10 13:43:28 -04:00
FatBoy 50792327a4 moveToPoint attack handling 2023-09-10 12:31:39 -05:00
FatBoy 46e67be8ca player character attacks added to city outlaws 2023-09-10 11:57:52 -05:00
FatBoy e7c3ba5eba guards and siege engines ignore idle state with no players loaded 2023-09-09 22:30:45 -05:00
FatBoy ea86ab2300 guards will revert cmbat target to null if its a player and is no longer loaded 2023-09-09 22:23:25 -05:00
FatBoy 501e8c937f guards use city player memory to determine whether they go idle or not 2023-09-09 22:10:10 -05:00
FatBoy cae5c36d84 guards will aggro siege equipment not belonging to the guild 2023-09-09 22:01:59 -05:00
FatBoy 1b92fa76e1 characters that attack city friendly buildings are added to cityOutlaws 2023-09-09 21:48:22 -05:00
FatBoy bbdb683061 players who attack buildinsg added to cityOutlaw list 2023-09-09 21:43:29 -05:00
FatBoy 2d04547c74 display seeInvis level in aiInfo command 2023-09-09 21:19:29 -05:00
FatBoy 5192c801f7 CombatUtilities cleanup 2023-09-09 20:56:19 -05:00
FatBoy d966d50bd5 removed duplicate variables in MobBase 2023-09-09 20:40:52 -05:00
FatBoy 7e20db33f2 final guard stat revisions 2023-09-09 20:37:47 -05:00
FatBoy 669ee7215b added range modification for guards 2023-09-09 20:11:00 -05:00
FatBoy 6fa00a43a4 removed unused method 2023-09-09 20:06:33 -05:00
FatBoy 4edf740179 finished modifications for guards 2023-09-09 19:57:17 -05:00
FatBoy c7abb4c920 stance modifiers for guards 2023-09-09 19:41:32 -05:00
FatBoy df3964110a stances for guards 2023-09-09 19:23:46 -05:00
FatBoy 96231260bc consolidated all guards to GuardLogic 2023-09-09 10:37:40 -05:00
FatBoy 967303d2de outlaw and hate value moved to modifyHealth 2023-09-09 10:20:25 -05:00
FatBoy 955481773d wall archer early exit for canCast 2023-09-09 09:52:47 -05:00
FatBoy d66a7049e8 guard walking bug fix 2023-09-09 09:35:03 -05:00
MagicBot e73b8d2826 Harden against null 2023-09-09 10:20:20 -04:00
MagicBot ea23003807 Hirelings removed from zone mob set 2023-09-09 10:16:36 -04:00
MagicBot 23f41f8ae7 Minions always have offset not determined by captain being alive. 2023-09-09 09:26:55 -04:00
MagicBot 3f416f83d3 Patrol points only set once. 2023-09-09 09:11:43 -04:00
MagicBot 931d1992b6 Patrol points are reset each patrol. 2023-09-09 09:10:08 -04:00
MagicBot fd927a7052 New method implemented. 2023-09-09 08:58:41 -04:00
MagicBot dd46224afe New method implemented. 2023-09-09 08:44:00 -04:00
MagicBot be2b29ccc7 New method implemented. 2023-09-09 08:38:00 -04:00
MagicBot c93e3bc947 Update to ordering of logic 2023-09-09 08:34:09 -04:00
MagicBot 7d49395c41 New method implemented. 2023-09-09 08:31:20 -04:00
MagicBot f4c9e6d7b8 Remove hireling method defined in manager. 2023-09-09 08:28:03 -04:00
MagicBot b7a907c8c8 db method to support removing all minions 2023-09-09 08:04:56 -04:00
MagicBot 36485a0f01 Formation enforced when captain is dead. 2023-09-08 12:44:36 -04:00
MagicBot efec1b4444 Load data only. 2023-09-08 12:39:04 -04:00
MagicBot bdf6500260 Outlaw moved before guild check. 2023-09-07 14:14:21 -04:00
MagicBot db4eb0579e Aggro code removed from check to send mob home. 2023-09-07 13:37:32 -04:00
MagicBot 76f33534d4 Captains force march minions 2023-09-07 13:09:25 -04:00
MagicBot 39fea5bc2f Captains order minions to patrol 2023-09-07 12:42:43 -04:00
MagicBot 660d5c1270 Captains order minions to patrol 2023-09-07 12:41:20 -04:00
MagicBot 781e2fc9b2 Comment adjusted 2023-09-07 12:27:23 -04:00
MagicBot c2a2464fe8 Errant delimiter removed. 2023-09-07 12:25:52 -04:00
MagicBot beb3c15eb3 Miniond patrol on own if captain is dead. 2023-09-07 12:24:45 -04:00
MagicBot 553010bb7b Minions get marching orders from captain 2023-09-07 12:07:39 -04:00
MagicBot 8d12bbf453 Formation offset for minions. 2023-09-07 11:48:42 -04:00
MagicBot fa7588826a Pets set to not alive when dismissing. 2023-09-07 11:15:30 -04:00
MagicBot 332f191e19 Merged switch cases. 2023-09-07 10:56:46 -04:00
MagicBot 8151382a6b Patrol points inherited from barracks not captain. 2023-09-07 10:49:07 -04:00
MagicBot ae44a21be1 Duplicate range check removed. 2023-09-07 10:40:27 -04:00
MagicBot b0ff0995de Start consolidation of guard logic 2023-09-07 10:37:09 -04:00
MagicBot e711095ecd Start consolidation of guard logic 2023-09-07 10:36:18 -04:00
MagicBot 08de97a2a8 Guild check removed from outlaw condition. 2023-09-07 09:55:55 -04:00
MagicBot 5eb6302d2a Null check is made before this method call. 2023-09-05 15:56:49 -04:00
MagicBot 2e346ae7fd Rework of combat deference to captain. 2023-09-05 15:51:14 -04:00
MagicBot 1285d12915 Consolidated cast methods. 2023-09-05 14:25:24 -04:00
MagicBot 8b5cb9258e dd roll removed 2023-09-05 14:09:48 -04:00
MagicBot ef3e3a0392 .contains check needed. 2023-09-05 13:43:09 -04:00
MagicBot 8fca6572f9 Typo in comment fixed. 2023-09-05 13:10:17 -04:00
MagicBot 33eaf0e583 Outlaws added to aiinfo. 2023-09-05 13:04:56 -04:00
MagicBot 16acd1c08c Simplify logic; variable is provided. 2023-09-05 12:55:12 -04:00
MagicBot a8e8804ce3 Attacking guard flags you as an outlaw. 2023-09-05 12:34:46 -04:00
MagicBot b8c0f997f6 Fix typo in thread name. 2023-09-05 12:30:47 -04:00
MagicBot 11e63f38b1 Update to mob retaliate logic. 2023-09-05 12:19:50 -04:00
MagicBot ff36d8f3db Modification to minion retaliate. 2023-09-05 08:27:34 -04:00
MagicBot 975542d8af sql column update. 2023-09-04 15:21:04 -04:00
MagicBot d71a9415b4 Integer object not int signature. 2023-09-04 15:09:51 -04:00
MagicBot e948da95b5 Column name updated. 2023-09-04 14:58:13 -04:00
MagicBot 9a6510c320 Minions now use copyonwrite collection. Slot agnostic. 2023-09-04 14:50:59 -04:00
MagicBot 57ff1ede97 Name is all that's needed. 2023-09-04 14:16:36 -04:00
MagicBot 7c0f2563f7 Already added to collection at this point. 2023-09-04 13:09:32 -04:00
FatBoy d11a954b40 remove test block 2023-09-03 20:41:21 -05:00
FatBoy f354339af1 null checks 2023-09-03 20:38:48 -05:00
FatBoy 89658bb77a null checks 2023-09-03 20:28:17 -05:00
FatBoy 1ff0238b6e skill loading bypass for guards 2023-09-03 20:22:01 -05:00
FatBoy e777434d57 Mob specific rune skill loading 2023-09-03 20:10:57 -05:00
FatBoy ee6efc30a3 rune skill loading broken into static method in NPCManager 2023-09-03 19:52:16 -05:00
FatBoy 0758bb5f38 SkillsBase are now cached when missing for mobs 2023-09-03 19:44:33 -05:00
FatBoy 299d5725a6 lookup using name 2023-09-03 19:31:04 -05:00
FatBoy d7c9b31ec7 indentation and comment 2023-09-03 19:24:34 -05:00
FatBoy 6c78bee5c1 null check 2023-09-03 19:24:06 -05:00
FatBoy dba0cbd5f9 skill type not name used 2023-09-03 19:22:28 -05:00
FatBoy 0752e780f2 mobs load skills 2023-09-03 19:19:18 -05:00
MagicBot c43919ce01 Level loaded into object. 2023-09-03 09:48:37 -04:00
MagicBot 0d95510b72 captain uuid added to aiInfoCmd 2023-09-03 09:15:20 -04:00
MagicBot 60fb2571a2 Support for loading of skill adjustment map. 2023-09-03 08:18:48 -04:00
MagicBot 90cbe90492 Merge remote-tracking branch 'origin/mobile-effects' into magicbox-1.5.2 2023-09-03 07:33:50 -04:00
FatBoy 95c203b0ed load and apply mobbaseSkill 2023-09-02 20:39:36 -05:00
FatBoy 449c5c5c77 infrastructure for mob skills loading 2023-09-02 20:29:03 -05:00
FatBoy 9aff208403 guard captains to move tot heir first patrol point right away 2023-09-02 19:43:40 -05:00
FatBoy 4318849127 minion relatiate handled inside retaliate function 2023-09-02 19:34:08 -05:00
FatBoy 29e8cdf699 attacking guard minion will no longer be ignored 2023-09-02 19:23:33 -05:00
MagicBot 4427dbdcad Fix in exception for werwolf/werebear (magic numbers) 2023-09-02 16:28:16 -04:00
MagicBot af4c3819b9 contract added to aiInfoCmd 2023-09-02 16:18:05 -04:00
MagicBot 39379e1ac0 Sight check moved out of cancast. 2023-09-02 16:04:40 -04:00
MagicBot 71eeb3f6b8 Variable hidden elevated to abschar. 2023-09-02 15:57:23 -04:00
MagicBot d409ef49af Can cast added to aiinfo. 2023-09-02 15:44:42 -04:00
MagicBot e7a80e9280 Comment cleanup 2023-09-02 15:33:12 -04:00
MagicBot 65c2d2ea0b Logic cleanup when dealing with contracts. 2023-09-02 15:30:10 -04:00
MagicBot 92666dca21 Invis check precedes power check. 2023-09-02 15:25:19 -04:00
MagicBot 3e1a79c248 AI info dev command updated. 2023-09-02 15:11:17 -04:00
MagicBot 73a1ce083a Unused method removed. 2023-09-02 15:00:38 -04:00
MagicBot 22dacebc5e Override unnecessary. 2023-09-02 15:00:06 -04:00
MagicBot 80d0948e24 Contract power handling now additive. 2023-09-02 14:04:47 -04:00
MagicBot 58b427b977 Contract support added to mobile ai when gathering powers. 2023-09-02 13:34:26 -04:00
MagicBot a4cab3565a Value cannot be null. Set early in runafterload. 2023-09-02 13:16:34 -04:00
MagicBot 205c9580e3 sql column name fix. 2023-09-02 12:52:55 -04:00
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. 2023-09-02 12:47:04 -04:00
FatBoy f556181d77 guardlist serialization displays correct minion rank 2023-09-01 22:15:29 -05:00
FatBoy d48e26904e revert last commit 2023-09-01 22:06:21 -05:00
FatBoy 19232ac405 archers added to human guards as minions 2023-09-01 22:01:09 -05:00
FatBoy 9ee2ccc8af werebear and werewolf guard can use powers 2023-09-01 21:48:57 -05:00
FatBoy 7079bb6a63 resist loading refactored as static method to NPCManager 2023-09-01 21:39:34 -05:00
FatBoy 0ab5827ee5 mobs to load equipment resists 2023-09-01 21:34:48 -05:00
FatBoy c5443f622c utilization and assignment of aiAgentType 2023-09-01 20:57:09 -05:00
FatBoy e4aa276cca cleanup old code 2023-09-01 20:42:33 -05:00
FatBoy 90ff2d679e create and use applyMobbaseEffects method, remove old unused methods 2023-09-01 20:39:31 -05:00
FatBoy da26c35d5a mobbase loads effectsList 2023-09-01 20:36:07 -05:00
MagicBot 779e3da74e Cleanup of clear minion logic. 2023-09-01 14:33:33 -04:00
MagicBot e358c08773 Removed msg from handler. 2023-09-01 14:23:55 -04:00
MagicBot 2945fa3a47 Class reformat and removal of try block. 2023-09-01 14:17:07 -04:00
MagicBot ab1541e741 Class not needed on login server. 2023-09-01 14:09:48 -04:00
MagicBot 3aeaa709a5 Comment cleanup 2023-09-01 14:07:00 -04:00
MagicBot 91e627df6b AI moved to top of runafterload. 2023-09-01 14:05:50 -04:00
MagicBot d0795e9e1c Rework of agent type init in runafterload. Only used for 2 instances from disk. 2023-09-01 13:57:58 -04:00
MagicBot 0e12dd4874 Contract powers loaded first to preserve ordering. 2023-09-01 12:57:20 -04:00
MagicBot 25c0e48181 Loot bypass now uses agent type. 2023-09-01 12:55:33 -04:00
MagicBot 0d43c3620d Value is set earlier. 2023-09-01 12:50:57 -04:00
MagicBot 2f6137f8df Minion agent type set properly. 2023-09-01 12:38:23 -04:00
FatBoy 2843b86a93 Moved agent type to top of constructor. 2023-09-01 12:29:06 -04:00
MagicBot 8235de07ff Updated output of devcmd. 2023-08-31 14:00:34 -04:00
MagicBot e2f9a4c7f0 Guard minions inherit powers from captain. 2023-08-31 13:57:46 -04:00
MagicBot 55c6e3cf93 Refactored out duplicate power collection. 2023-08-31 13:42:15 -04:00
MagicBot 11c154e564 Assignment fix and comment cleanup. 2023-08-31 08:58:55 -04:00
MagicBot 7fc0d27c3c Siege engine agent type set properly. 2023-08-31 08:31:48 -04:00
MagicBot 1ac76cfcd8 isPlayerguard refactored to derive from agenttype. 2023-08-31 08:13:37 -04:00
MagicBot c8ed04aaaf Refactor to separate persistence and write fsm to table. 2023-08-31 08:03:30 -04:00
65 changed files with 1970 additions and 2415 deletions
+4 -3
View File
@@ -2877,10 +2877,11 @@ public class Enum {
public enum AIAgentType { public enum AIAgentType {
MOBILE, MOBILE,
GUARDCAPTAIN,
GUARDMINION,
GUARDWALLARCHER,
PET, PET,
CHARMED, CHARMED,
SIEGEENGINE;
SIEGEENGINE,
GUARD;
} }
} }
+59 -304
View File
@@ -14,9 +14,7 @@ import engine.gameManager.DbManager;
import engine.gameManager.ZoneManager; import engine.gameManager.ZoneManager;
import engine.math.Vector2f; import engine.math.Vector2f;
import engine.math.Vector3fImmutable; import engine.math.Vector3fImmutable;
import engine.objects.AbstractWorldObject;
import engine.objects.Zone; import engine.objects.Zone;
import engine.util.MapLoader;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
@@ -32,6 +30,7 @@ public class HeightMap {
// Class variables // Class variables
public static float SCALEVALUE = 1.0f / 256;
// Heightmap data for all zones. // Heightmap data for all zones.
public static final HashMap<Integer, HeightMap> heightmapByLoadNum = new HashMap<>(); public static final HashMap<Integer, HeightMap> heightmapByLoadNum = new HashMap<>();
@@ -45,17 +44,17 @@ public class HeightMap {
public BufferedImage heightmapImage; public BufferedImage heightmapImage;
private int heightMapID; private final int heightMapID;
private int maxHeight; private final int maxHeight;
private int fullExtentsX; private final int fullExtentsX;
private int fullExtentsY; private final int fullExtentsY;
private float bucketWidthX; private float bucketWidthX;
private float bucketWidthY; private float bucketWidthY;
private int zoneLoadID; private final int zoneLoadID;
private float seaLevel = 0; private float seaLevel = 0;
private float outsetX; private final float outsetX;
private float outsetZ; private final float outsetZ;
private int[][] pixelColorValues; private int[][] pixelColorValues;
public HeightMap(ResultSet rs) throws SQLException { public HeightMap(ResultSet rs) throws SQLException {
@@ -88,12 +87,12 @@ public class HeightMap {
try { try {
this.heightmapImage = ImageIO.read(imageFile); this.heightmapImage = ImageIO.read(imageFile);
} catch (IOException e) { } 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. // 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 // Calculate the data we do not load from table
@@ -104,7 +103,7 @@ public class HeightMap {
// Generate pixel array from image data // Generate pixel array from image data
generatePixelData(); generatePixelData(this);
HeightMap.heightmapByLoadNum.put(this.zoneLoadID, this); HeightMap.heightmapByLoadNum.put(this.zoneLoadID, this);
@@ -123,35 +122,26 @@ public class HeightMap {
this.outsetX = 128; this.outsetX = 128;
this.outsetZ = 128; this.outsetZ = 128;
// Cache the full extents to avoid the calculation // Cache the full extents to avoid the calculation
this.fullExtentsX = halfExtentsX * 2; this.fullExtentsX = halfExtentsX * 2;
this.fullExtentsY = halfExtentsY * 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; this.heightmapImage = null;
// Calculate the data we do not load from table // Calculate the data we do not load from table
this.bucketWidthX = 1; this.bucketWidthX = halfExtentsX;
this.bucketWidthY = 1; 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 y = 0; y < this.fullExtentsY; y++) {
for (int x = 0; x <= this.fullExtentsX; x++) { for (int x = 0; x < this.fullExtentsX; x++) {
pixelColorValues[x][y] = 255; pixelColorValues[x][y] = 255;
} }
} }
HeightMap.heightmapByLoadNum.put(this.zoneLoadID, this);
} }
public HeightMap(Zone zone) { public HeightMap(Zone zone) {
@@ -170,26 +160,21 @@ public class HeightMap {
this.fullExtentsX = halfExtentsX * 2; this.fullExtentsX = halfExtentsX * 2;
this.fullExtentsY = halfExtentsY * 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; this.heightmapImage = null;
// Calculate the data we do not load from table // Calculate the data we do not load from table
this.bucketWidthX = 1; this.bucketWidthX = halfExtentsX;
this.bucketWidthY = 1; 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 y = 0; y < this.fullExtentsY; y++) {
for (int x = 0; x <= this.fullExtentsX; x++) { for (int x = 0; x < this.fullExtentsX; x++) {
pixelColorValues[x][y] = 255; pixelColorValues[x][y] = 0;
} }
} }
HeightMap.heightmapByLoadNum.put(this.zoneLoadID, this);
} }
public static void GeneratePlayerCityHeightMap() { public static void GeneratePlayerCityHeightMap() {
@@ -222,113 +207,9 @@ public class HeightMap {
return nextZone; return nextZone;
} }
public static float getWorldHeight(AbstractWorldObject worldObject) { public static float getWorldHeight(Zone currentZone, Vector3fImmutable worldLoc) {
Vector2f parentLoc = new Vector2f(-1, -1); 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) if (currentZone == null)
return 0; return 0;
@@ -352,7 +233,7 @@ public class HeightMap {
float interaltitude = currentZone.getHeightMap().getInterpolatedTerrainHeight(zoneLoc); float interaltitude = currentZone.getHeightMap().getInterpolatedTerrainHeight(zoneLoc);
float worldAltitude = currentZone.getWorldAltitude(); float worldAltitude = currentZone.worldAltitude;
float realWorldAltitude = interaltitude + worldAltitude; float realWorldAltitude = interaltitude + worldAltitude;
@@ -360,9 +241,6 @@ public class HeightMap {
if (parentZone != null) { 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 parentXRadius = currentZone.getBounds().getHalfExtents().x;
float parentZRadius = currentZone.getBounds().getHalfExtents().y; float parentZRadius = currentZone.getBounds().getHalfExtents().y;
@@ -378,7 +256,6 @@ public class HeightMap {
double scale; double scale;
if (offsetX > outsideGridSizeX && offsetX > offsetZ) { if (offsetX > outsideGridSizeX && offsetX > offsetZ) {
weight = (offsetX - outsideGridSizeX) / bucketScaleX; weight = (offsetX - outsideGridSizeX) / bucketScaleX;
scale = Math.atan2((.5 - weight) * 3.1415927, 1); scale = Math.atan2((.5 - weight) * 3.1415927, 1);
@@ -396,7 +273,7 @@ public class HeightMap {
float secondScale = parentCenterAltitude * scaleChild; float secondScale = parentCenterAltitude * scaleChild;
float outsetALt = firstScale + secondScale; float outsetALt = firstScale + secondScale;
outsetALt += currentZone.getParent().getWorldAltitude(); outsetALt += currentZone.getParent().worldAltitude;
realWorldAltitude = outsetALt; realWorldAltitude = outsetALt;
} else if (offsetZ > outsideGridSizeZ) { } else if (offsetZ > outsideGridSizeZ) {
@@ -415,7 +292,7 @@ public class HeightMap {
float secondScale = parentCenterAltitude * scaleChild; float secondScale = parentCenterAltitude * scaleChild;
float outsetALt = firstScale + secondScale; float outsetALt = firstScale + secondScale;
outsetALt += currentZone.getParent().getWorldAltitude(); outsetALt += currentZone.getParent().worldAltitude;
realWorldAltitude = outsetALt; realWorldAltitude = outsetALt;
} }
} }
@@ -423,85 +300,13 @@ public class HeightMap {
return realWorldAltitude; return realWorldAltitude;
} }
public static float getOutsetHeight(float interpolatedAltitude, Zone zone, Vector3fImmutable worldLocation) { public static float getWorldHeight(Vector3fImmutable worldLoc) {
Vector2f parentLoc; Zone currentZone = ZoneManager.findSmallestZone(worldLoc);
float outsetALt = 0;
if (zone.getParent() == null || zone.getParent().getHeightMap() == null) if (currentZone == null)
return interpolatedAltitude + zone.getWorldAltitude(); return 0;
return getWorldHeight(currentZone, worldLoc);
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) {
int floorX = (int) gridSquare.x;
int floorY = (int) gridSquare.y;
return new Vector2f(gridSquare.x - floorX, gridSquare.y - floorY);
} }
@@ -515,7 +320,6 @@ public class HeightMap {
HeightMap.GeneratePlayerCityHeightMap(); HeightMap.GeneratePlayerCityHeightMap();
// Clear all heightmap image data as it's no longer needed. // Clear all heightmap image data as it's no longer needed.
for (HeightMap heightMap : HeightMap.heightmapByLoadNum.values()) { for (HeightMap heightMap : HeightMap.heightmapByLoadNum.values()) {
@@ -530,10 +334,25 @@ public class HeightMap {
float localAltitude = HeightMap.getWorldHeight(currentLoc); float localAltitude = HeightMap.getWorldHeight(currentLoc);
Zone zone = ZoneManager.findSmallestZone(currentLoc); Zone zone = ZoneManager.findSmallestZone(currentLoc);
if (localAltitude < zone.getSeaLevel()) return localAltitude < zone.getSeaLevel();
return true; }
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) { public Vector2f getGridSquare(Vector2f zoneLoc) {
@@ -541,14 +360,18 @@ public class HeightMap {
if (zoneLoc.x < 0) if (zoneLoc.x < 0)
zoneLoc.setX(0); zoneLoc.setX(0);
if (zoneLoc.x > this.fullExtentsX - 1) if (zoneLoc.x >= this.fullExtentsX)
zoneLoc.setX((this.fullExtentsX - 1) + .9999999f); zoneLoc.setX(this.fullExtentsX);
if (zoneLoc.y < 0) if (zoneLoc.y < 0)
zoneLoc.setY(0); zoneLoc.setY(0);
if (zoneLoc.y > this.fullExtentsY - 1) if (zoneLoc.y > this.fullExtentsY)
zoneLoc.setY((this.fullExtentsY - 1) + .9999999f); zoneLoc.setY(this.fullExtentsY);
// Flip Y coordinates
zoneLoc.setY(this.fullExtentsY - zoneLoc.y);
float xBucket = (zoneLoc.x / this.bucketWidthX); float xBucket = (zoneLoc.x / this.bucketWidthX);
float yBucket = (zoneLoc.y / this.bucketWidthY); float yBucket = (zoneLoc.y / this.bucketWidthY);
@@ -569,13 +392,10 @@ public class HeightMap {
int maxX = (int) (this.fullExtentsX / this.bucketWidthX); int maxX = (int) (this.fullExtentsX / this.bucketWidthX);
int maxY = (int) (this.fullExtentsY / this.bucketWidthY); 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); gridSquare = getGridSquare(zoneLoc);
int gridX = (int) gridSquare.x; int gridX = (int) gridSquare.x;
int gridY = (int) (gridSquare.y); int gridY = (int) gridSquare.y;
if (gridX > maxX) if (gridX > maxX)
gridX = maxX; gridX = maxX;
@@ -613,76 +433,11 @@ public class HeightMap {
interpolatedHeight += (bottomLeftHeight * (1 - offsetX) * offsetY); interpolatedHeight += (bottomLeftHeight * (1 - offsetX) * offsetY);
interpolatedHeight += (topLeftHeight * (1 - offsetX) * (1 - offsetY)); interpolatedHeight += (topLeftHeight * (1 - offsetX) * (1 - offsetY));
interpolatedHeight *= (float) this.maxHeight / 256; // Scale height interpolatedHeight *= (float) this.maxHeight * SCALEVALUE; // Scale height
return interpolatedHeight; 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
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() { public float getBucketWidthX() {
return bucketWidthX; return bucketWidthX;
} }
@@ -140,7 +140,7 @@ public enum InterestManager implements Runnable {
else { else {
if (pc != null) if (pc != null)
if (pcc.getSeeInvis() < pc.getHidden()) if (pcc.getSeeInvis() < pc.hidden)
continue; continue;
if (!cc.sendMsg(uom)) { if (!cc.sendMsg(uom)) {
@@ -340,7 +340,7 @@ public enum InterestManager implements Runnable {
if (loadedPlayer.getObjectUUID() == player.getObjectUUID()) if (loadedPlayer.getObjectUUID() == player.getObjectUUID())
continue; continue;
if (player.getSeeInvis() < loadedPlayer.getHidden()) if (player.getSeeInvis() < loadedPlayer.hidden)
continue; continue;
if (loadedPlayer.safemodeInvis()) if (loadedPlayer.safemodeInvis())
@@ -372,7 +372,7 @@ public enum InterestManager implements Runnable {
if (playerLoadedObject.getObjectType().equals(GameObjectType.PlayerCharacter)) { if (playerLoadedObject.getObjectType().equals(GameObjectType.PlayerCharacter)) {
PlayerCharacter loadedPlayer = (PlayerCharacter) playerLoadedObject; PlayerCharacter loadedPlayer = (PlayerCharacter) playerLoadedObject;
if (player.getSeeInvis() < loadedPlayer.getHidden()) if (player.getSeeInvis() < loadedPlayer.hidden)
toRemove.add(playerLoadedObject); toRemove.add(playerLoadedObject);
else if (loadedPlayer.safemodeInvis()) else if (loadedPlayer.safemodeInvis())
toRemove.add(playerLoadedObject); toRemove.add(playerLoadedObject);
@@ -437,7 +437,7 @@ public enum InterestManager implements Runnable {
// dont load if invis // dont load if invis
if (player.getSeeInvis() < awopc.getHidden()) if (player.getSeeInvis() < awopc.hidden)
continue; continue;
lcm = new LoadCharacterMsg(awopc, PlayerCharacter.hideNonAscii()); lcm = new LoadCharacterMsg(awopc, PlayerCharacter.hideNonAscii());
+23 -11
View File
@@ -33,7 +33,7 @@ public class dbMobHandler extends dbHandlerBase {
Mob mobile = null; Mob mobile = null;
try (Connection connection = DbManager.getConnection(); try (Connection connection = DbManager.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement("CALL `mob_CREATE`(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);")) { PreparedStatement preparedStatement = connection.prepareStatement("CALL `mob_CREATE`(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);")) {
preparedStatement.setLong(1, toAdd.parentZoneUUID); preparedStatement.setLong(1, toAdd.parentZoneUUID);
preparedStatement.setInt(2, toAdd.loadID); preparedStatement.setInt(2, toAdd.loadID);
@@ -48,6 +48,7 @@ public class dbMobHandler extends dbHandlerBase {
preparedStatement.setInt(11, toAdd.buildingUUID); preparedStatement.setInt(11, toAdd.buildingUUID);
preparedStatement.setInt(12, toAdd.level); preparedStatement.setInt(12, toAdd.level);
preparedStatement.setString(13, toAdd.firstName); preparedStatement.setString(13, toAdd.firstName);
preparedStatement.setString(14, toAdd.behaviourType.toString());
ResultSet rs = preparedStatement.executeQuery(); ResultSet rs = preparedStatement.executeQuery();
@@ -110,7 +111,7 @@ public class dbMobHandler extends dbHandlerBase {
ResultSet rs = preparedStatement.executeQuery(); ResultSet rs = preparedStatement.executeQuery();
while (rs.next()) { while (rs.next()) {
String minionName = rs.getString("name"); String minionName = rs.getString("minionName");
Mob toCreate = Mob.createGuardMinion(guardCaptain, guardCaptain.getLevel(), minionName); Mob toCreate = Mob.createGuardMinion(guardCaptain, guardCaptain.getLevel(), minionName);
if (toCreate == null) if (toCreate == null)
@@ -126,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(); 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.setLong(1, captainUID);
preparedStatement.setInt(2, mobBaseID); preparedStatement.setString(2, minionName);
preparedStatement.setString(3, name);
preparedStatement.setInt(4, slot);
return (preparedStatement.executeUpdate() > 0); return (preparedStatement.executeUpdate() > 0);
@@ -144,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(); 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.setLong(1, captainUID);
preparedStatement.setInt(2, mobBaseID); preparedStatement.setString(2, minionName);
preparedStatement.setInt(3, slot);
return (preparedStatement.executeUpdate() > 0); return (preparedStatement.executeUpdate() > 0);
@@ -161,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) { public ArrayList<Mob> GET_ALL_MOBS_FOR_ZONE(Zone zone) {
@@ -15,15 +15,9 @@ import engine.gameManager.PowersManager;
import engine.objects.Mob; import engine.objects.Mob;
import engine.objects.PreparedStatementShared; import engine.objects.PreparedStatementShared;
import engine.powers.EffectsBase; import engine.powers.EffectsBase;
import engine.powers.MobPowerEntry;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
public class dbPowerHandler extends dbHandlerBase { 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;
}
} }
@@ -11,6 +11,8 @@ package engine.db.handlers;
import engine.gameManager.DbManager; import engine.gameManager.DbManager;
import engine.objects.RuneBase; import engine.objects.RuneBase;
import engine.powers.RunePowerEntry;
import engine.powers.RuneSkillAdjustEntry;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
import java.sql.Connection; import java.sql.Connection;
@@ -27,6 +29,84 @@ public class dbRuneBaseHandler extends dbHandlerBase {
this.localObjectType = engine.Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); 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) { public void GET_RUNE_REQS(final RuneBase rb) {
try (Connection connection = DbManager.getConnection(); try (Connection connection = DbManager.getConnection();
+3 -2
View File
@@ -9,6 +9,7 @@
package engine.devcmd.cmds; package engine.devcmd.cmds;
import engine.Enum;
import engine.Enum.GameObjectType; import engine.Enum.GameObjectType;
import engine.devcmd.AbstractDevCmd; import engine.devcmd.AbstractDevCmd;
import engine.gameManager.ChatManager; import engine.gameManager.ChatManager;
@@ -43,7 +44,7 @@ public class AddMobCmd extends AbstractDevCmd {
MobBase mb = (MobBase) mobbaseAGO; MobBase mb = (MobBase) mobbaseAGO;
int loadID = mb.getObjectUUID(); int loadID = mb.getObjectUUID();
Mob mob = Mob.createMob(loadID, Vector3fImmutable.getRandomPointInCircle(pc.getLoc(), 100), Mob mob = Mob.createMob(loadID, Vector3fImmutable.getRandomPointInCircle(pc.getLoc(), 100),
null, zone, null, null, "", 1); null, zone, null, null, "", 1, Enum.AIAgentType.MOBILE);
if (mob != null) { if (mob != null) {
mob.updateDatabase(); mob.updateDatabase();
this.setResult(String.valueOf(mob.getDBID())); this.setResult(String.valueOf(mob.getDBID()));
@@ -84,7 +85,7 @@ public class AddMobCmd extends AbstractDevCmd {
Mob mob = Mob.createMob(loadID, pc.getLoc(), Mob mob = Mob.createMob(loadID, pc.getLoc(),
null, zone, null, null, "", 1); null, zone, null, null, "", 1, Enum.AIAgentType.MOBILE);
if (mob != null) { if (mob != null) {
mob.updateDatabase(); mob.updateDatabase();
ChatManager.chatSayInfo(pc, ChatManager.chatSayInfo(pc,
@@ -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.";
}
}
+32 -180
View File
@@ -13,7 +13,6 @@ import engine.InterestManagement.HeightMap;
import engine.devcmd.AbstractDevCmd; import engine.devcmd.AbstractDevCmd;
import engine.gameManager.ZoneManager; import engine.gameManager.ZoneManager;
import engine.math.Vector2f; import engine.math.Vector2f;
import engine.math.Vector3fImmutable;
import engine.objects.AbstractGameObject; import engine.objects.AbstractGameObject;
import engine.objects.PlayerCharacter; import engine.objects.PlayerCharacter;
import engine.objects.Zone; import engine.objects.Zone;
@@ -22,205 +21,58 @@ public class GetHeightCmd extends AbstractDevCmd {
public GetHeightCmd() { public GetHeightCmd() {
super("getHeight"); super("getHeight");
this.addCmdString("height");
} }
@Override @Override
protected void _doCmd(PlayerCharacter pc, String[] words, protected void _doCmd(PlayerCharacter playerCharacter, String[] words,
AbstractGameObject target) { AbstractGameObject target) {
boolean end = true; Zone currentZone;
Zone parentZone;
Zone heightmapZone;
float height = HeightMap.getWorldHeight(pc); currentZone = ZoneManager.findSmallestZone(playerCharacter.getLoc());
heightmapZone = HeightMap.getNextZoneWithTerrain(currentZone);
parentZone = HeightMap.getNextZoneWithTerrain(currentZone.getParent());
this.throwbackInfo(pc, "Altitude : " + height); float currentHeight = HeightMap.getWorldHeight(currentZone, playerCharacter.getLoc());
float parentHeight = HeightMap.getWorldHeight(parentZone, playerCharacter.getLoc());
this.throwbackInfo(pc, "Character Height: " + pc.getCharacterHeight()); Vector2f zoneLoc = ZoneManager.worldToZoneSpace(playerCharacter.getLoc(), heightmapZone);
this.throwbackInfo(pc, "Character Height to start swimming: " + pc.centerHeight); Vector2f gridSquare = heightmapZone.getHeightMap().getGridSquare(zoneLoc);
Zone zone = ZoneManager.findSmallestZone(pc.getLoc()); this.throwbackInfo(playerCharacter, "Current Zone : " + currentZone.getName());
this.throwbackInfo(pc, "Water Level : " + zone.getSeaLevel()); this.throwbackInfo(playerCharacter, "Heightmap Zone : " + heightmapZone.getName());
this.throwbackInfo(pc, "Character Water Level Above : " + (pc.getCharacterHeight() + height - zone.getSeaLevel())); 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()));
if (end) HeightMap.SCALEVALUE = 1f / 255f;
return; currentHeight = HeightMap.getWorldHeight(currentZone, playerCharacter.getLoc());
HeightMap.SCALEVALUE = 1f / 256f;
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);
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 @Override
protected String _getHelpString() { protected String _getHelpString() {
return "Temporarily Changes SubRace"; return "Queries heightmap engine";
} }
@Override @Override
protected String _getUsageString() { protected String _getUsageString() {
return "' /subrace mobBaseID"; return "' /getheight";
} }
} }
@@ -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
View File
@@ -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'";
}
}
+13 -9
View File
@@ -103,15 +103,19 @@ public class PrintStatsCmd extends AbstractDevCmd {
main = getWeaponBase(1, equip); main = getWeaponBase(1, equip);
ItemBase off = null; ItemBase off = null;
if (equip != null) if(equip != null){
getWeaponBase(2, equip); if(equip.get(2) != null && !equip.get(2).getItemBase().isShield()){
if (main == null && off == null) { //off hand weapon
out += "Main Hand: atr: " + tar.getAtrHandOne() + ", damage: " + tar.getMinDamageHandOne() + " to " + tar.getMaxDamageHandOne() + ", speed: " + tar.getSpeedHandOne() + ", range: 6" + newline; out += "Attack Rating: " + tar.atrHandTwo + newline;
} else { out += "Damage: " + tar.minDamageHandTwo + " - " + tar.maxDamageHandTwo + newline;
if (main != null) out += "Range: " + tar.rangeHandTwo + newline;
out += "Main Hand: atr: " + tar.getAtrHandOne() + ", damage: " + tar.getMinDamageHandOne() + " to " + tar.getMaxDamageHandOne() + ", speed: " + tar.getSpeedHandOne() + ", range: " + main.getRange() + newline; out += "Attack Speed: " + tar.speedHandTwo + newline;
if (off != null) } else{
out += "Main Hand: atr: " + tar.getAtrHandTwo() + ", damage: " + tar.getMinDamageHandTwo() + " to " + tar.getMaxDamageHandTwo() + ", speed: " + tar.getSpeedHandTwo() + ", range: " + off.getRange() + newline; 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; out += "isAlive: " + tar.isAlive() + ", Combat: " + tar.isCombat() + newline;
+13 -8
View File
@@ -59,22 +59,25 @@ public class PurgeObjectsCmd extends AbstractDevCmd {
if (npc != null) { if (npc != null) {
for (Mob mob : npc.siegeMinionMap.keySet()) { for (Integer minionUUID : npc.minions) {
Mob mob = Mob.getMob(minionUUID);
WorldGrid.RemoveWorldObject(mob); WorldGrid.RemoveWorldObject(mob);
WorldGrid.removeObject(mob, pc); WorldGrid.removeObject(mob, pc);
//Mob.getRespawnMap().remove(mob);
if (mob.getParentZone() != null) if (mob.getParentZone() != null)
mob.getParentZone().zoneMobSet.remove(mob); mob.getParentZone().zoneMobSet.remove(mob);
} }
DbManager.NPCQueries.DELETE_NPC(npc); DbManager.NPCQueries.DELETE_NPC(npc);
DbManager.removeFromCache(GameObjectType.NPC, DbManager.removeFromCache(GameObjectType.NPC,
npc.getObjectUUID()); npc.getObjectUUID());
WorldGrid.RemoveWorldObject(npc); WorldGrid.RemoveWorldObject(npc);
} else if (mobA != null) { } else if (mobA != null) {
for (Mob mob : mobA.getSiegeMinionMap().keySet()) { for (Integer minionUUID : mobA.minions) {
Mob mob = Mob.getMob(minionUUID);
WorldGrid.RemoveWorldObject(mob); WorldGrid.RemoveWorldObject(mob);
WorldGrid.removeObject(mob, pc); WorldGrid.removeObject(mob, pc);
//Mob.getRespawnMap().remove(mob);
if (mob.getParentZone() != null) if (mob.getParentZone() != null)
mob.getParentZone().zoneMobSet.remove(mob); mob.getParentZone().zoneMobSet.remove(mob);
} }
@@ -151,10 +154,11 @@ public class PurgeObjectsCmd extends AbstractDevCmd {
if (npc != null) { if (npc != null) {
for (Mob mob : npc.siegeMinionMap.keySet()) { for (Integer minionUUID : npc.minions) {
Mob mob = Mob.getMob(minionUUID);
WorldGrid.RemoveWorldObject(mob); WorldGrid.RemoveWorldObject(mob);
WorldGrid.removeObject(mob, pc); WorldGrid.removeObject(mob, pc);
//Mob.getRespawnMap().remove(mob);
if (mob.getParentZone() != null) if (mob.getParentZone() != null)
mob.getParentZone().zoneMobSet.remove(mob); mob.getParentZone().zoneMobSet.remove(mob);
} }
@@ -163,10 +167,11 @@ public class PurgeObjectsCmd extends AbstractDevCmd {
npc.getObjectUUID()); npc.getObjectUUID());
WorldGrid.RemoveWorldObject(npc); WorldGrid.RemoveWorldObject(npc);
} else if (mobA != null) { } else if (mobA != null) {
for (Mob mob : mobA.getSiegeMinionMap().keySet()) { for (Integer minionUUID : mobA.minions) {
Mob mob = Mob.getMob(minionUUID);
WorldGrid.RemoveWorldObject(mob); WorldGrid.RemoveWorldObject(mob);
WorldGrid.removeObject(mob, pc); WorldGrid.removeObject(mob, pc);
//Mob.getRespawnMap().remove(mob);
if (mob.getParentZone() != null) if (mob.getParentZone() != null)
mob.getParentZone().zoneMobSet.remove(mob); mob.getParentZone().zoneMobSet.remove(mob);
} }
+8 -33
View File
@@ -9,9 +9,9 @@
package engine.devcmd.cmds; package engine.devcmd.cmds;
import engine.Enum;
import engine.devcmd.AbstractDevCmd; import engine.devcmd.AbstractDevCmd;
import engine.objects.AbstractGameObject; import engine.objects.*;
import engine.objects.PlayerCharacter;
import java.lang.reflect.Field; import java.lang.reflect.Field;
@@ -25,42 +25,17 @@ public class RegionCmd extends AbstractDevCmd {
protected void _doCmd(PlayerCharacter pc, String[] words, protected void _doCmd(PlayerCharacter pc, String[] words,
AbstractGameObject target) { AbstractGameObject target) {
Regions region = ((AbstractCharacter)target).region;
if (pc.region == null) { if (region == null) {
this.throwbackInfo(pc, "No Region Found."); this.throwbackInfo(pc, "No Region Found.");
return; return;
} }
if(region != null) {
String newLine = System.getProperty("line.separator"); this.throwbackInfo(pc, "Region Info: " + ((AbstractCharacter) target).getName());
String result = ""; this.throwbackInfo(pc, "Region Name: " + region);
result += (pc.region.getClass().getSimpleName()); this.throwbackInfo(pc, "Region Height: " + region.lerpY((AbstractCharacter)target));
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);
} }
result += ("}");
this.throwbackInfo(pc, result.toString());
} }
+10 -42
View File
@@ -11,7 +11,6 @@ package engine.devcmd.cmds;
import engine.Enum.BuildingGroup; import engine.Enum.BuildingGroup;
import engine.Enum.DbObjectType; import engine.Enum.DbObjectType;
import engine.Enum.GameObjectType;
import engine.InterestManagement.WorldGrid; import engine.InterestManagement.WorldGrid;
import engine.devcmd.AbstractDevCmd; import engine.devcmd.AbstractDevCmd;
import engine.gameManager.BuildingManager; import engine.gameManager.BuildingManager;
@@ -138,49 +137,16 @@ public class RemoveObjectCmd extends AbstractDevCmd {
Warehouse.warehouseByBuildingUUID.remove(building.getObjectUUID()); Warehouse.warehouseByBuildingUUID.remove(building.getObjectUUID());
} }
//remove cached shrines. //remove cached shrines.
if ((building.getBlueprintUUID() != 0) if ((building.getBlueprintUUID() != 0)
&& (building.getBlueprint().getBuildingGroup() == BuildingGroup.SHRINE)) && (building.getBlueprint().getBuildingGroup() == BuildingGroup.SHRINE))
Shrine.RemoveShrineFromCacheByBuilding(building); Shrine.RemoveShrineFromCacheByBuilding(building);
for (AbstractCharacter ac : building.getHirelings().keySet()) { // Remove hirelings for this building
NPC npc = null;
Mob mobA = null;
if (ac.getObjectType() == GameObjectType.NPC) for (AbstractCharacter abstractCharacter : building.getHirelings().keySet())
npc = (NPC) ac; BuildingManager.removeHireling(building, abstractCharacter);
else if (ac.getObjectType() == GameObjectType.Mob)
mobA = (Mob) ac;
if (npc != null) {
for (Mob mob : npc.siegeMinionMap.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);
}
}
Zone zone = building.getParentZone(); Zone zone = building.getParentZone();
DbManager.BuildingQueries.DELETE_FROM_DATABASE(building); DbManager.BuildingQueries.DELETE_FROM_DATABASE(building);
DbManager.removeFromCache(building); DbManager.removeFromCache(building);
@@ -209,11 +175,13 @@ public class RemoveObjectCmd extends AbstractDevCmd {
if (npc.building != null) if (npc.building != null)
npc.building.getHirelings().remove(npc); npc.building.getHirelings().remove(npc);
for (Mob mob : npc.siegeMinionMap.keySet()) { for (Integer minionUUID : npc.minions) {
WorldGrid.RemoveWorldObject(mob); Mob minionMob = Mob.getMob(minionUUID);
WorldGrid.removeObject(mob, pc); WorldGrid.RemoveWorldObject(minionMob);
if (mob.getParentZone() != null) WorldGrid.removeObject(minionMob, pc);
mob.getParentZone().zoneMobSet.remove(mob);
if (minionMob.getParentZone() != null)
minionMob.getParentZone().zoneMobSet.remove(minionMob);
} }
DbManager.NPCQueries.DELETE_NPC(npc); DbManager.NPCQueries.DELETE_NPC(npc);
+43
View File
@@ -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";
}
}
+1 -1
View File
@@ -159,7 +159,7 @@ public class SetSubRaceCmd extends AbstractDevCmd {
// pum.setEffectID(token); // pum.setEffectID(token);
// pum.setSourceType(pc.getObjectType().ordinal()); // pum.setSourceType(pc.getObjectType().ordinal());
// pum.setSourceID(pc.getObjectUUID()); // pum.setSourceID(pc.getObjectUUID());
// pum.setTargetType(pc.getObjectType().ordinal()); // pum.setStartLocType(pc.getObjectType().ordinal());
// pum.setTargetID(pc.getObjectUUID()); // pum.setTargetID(pc.getObjectUUID());
// pum.setNumTrains(40); // pum.setNumTrains(40);
// pum.setDuration(-1); // pum.setDuration(-1);
+2 -1
View File
@@ -1,5 +1,6 @@
package engine.devcmd.cmds; package engine.devcmd.cmds;
import engine.Enum;
import engine.devcmd.AbstractDevCmd; import engine.devcmd.AbstractDevCmd;
import engine.gameManager.ZoneManager; import engine.gameManager.ZoneManager;
import engine.math.Vector3fImmutable; import engine.math.Vector3fImmutable;
@@ -110,7 +111,7 @@ public class SplatMobCmd extends AbstractDevCmd {
mobile = Mob.createMob(_mobileUUID, mobile = Mob.createMob(_mobileUUID,
Vector3fImmutable.getRandomPointInCircle(_currentLocation, _targetRange), Vector3fImmutable.getRandomPointInCircle(_currentLocation, _targetRange),
null, serverZone, null, null, "", 1); null, serverZone, null, null, "", 1, Enum.AIAgentType.MOBILE);
if (mobile != null) { if (mobile != null) {
mobile.updateDatabase(); mobile.updateDatabase();
+1 -1
View File
@@ -104,7 +104,7 @@ public class ZoneInfoCmd extends AbstractDevCmd {
output += newline; output += newline;
output += "Sea Level = " + zone.getSeaLevel(); output += "Sea Level = " + zone.getSeaLevel();
output += newline; output += newline;
output += "World Altitude = " + zone.getWorldAltitude(); output += "World Altitude = " + zone.worldAltitude;
throwbackInfo(player, output); throwbackInfo(player, output);
City city = ZoneManager.getCityAtLocation(player.getLoc()); City city = ZoneManager.getCityAtLocation(player.getLoc());
+61 -3
View File
@@ -9,13 +9,17 @@
package engine.devcmd.cmds; package engine.devcmd.cmds;
import engine.Enum;
import engine.Enum.GameObjectType; import engine.Enum.GameObjectType;
import engine.devcmd.AbstractDevCmd; import engine.devcmd.AbstractDevCmd;
import engine.gameManager.PowersManager; import engine.gameManager.PowersManager;
import engine.mobileAI.MobAI;
import engine.objects.AbstractGameObject; import engine.objects.AbstractGameObject;
import engine.objects.Mob; import engine.objects.Mob;
import engine.objects.PlayerCharacter; import engine.objects.PlayerCharacter;
import engine.powers.RunePowerEntry;
import java.util.ArrayList;
import java.util.Map; import java.util.Map;
@@ -57,6 +61,27 @@ public class aiInfoCmd extends AbstractDevCmd {
Mob mob = (Mob) target; Mob mob = (Mob) target;
output = "Mob AI Information:" + newline; output = "Mob AI Information:" + newline;
output += mob.getName() + newline; output += mob.getName() + newline;
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) { if (mob.behaviourType != null) {
output += "BehaviourType: " + mob.behaviourType.toString() + newline; output += "BehaviourType: " + mob.behaviourType.toString() + newline;
if (mob.behaviourType.BehaviourHelperType != null) { if (mob.behaviourType.BehaviourHelperType != null) {
@@ -87,11 +112,44 @@ public class aiInfoCmd extends AbstractDevCmd {
if (mob.guardedCity != null) if (mob.guardedCity != null)
output += "Patrolling: " + mob.guardedCity.getCityName() + newline; output += "Patrolling: " + mob.guardedCity.getCityName() + newline;
output += "See Invis Level: " + mob.mobBase.getSeeInvis() + newline;
output += "Can Cast: " + MobAI.canCast(mob) + newline;
output += "Powers:" + newline; output += "Powers:" + newline;
for (int token : mob.mobPowers.keySet()) ArrayList<RunePowerEntry> powerEntries = new ArrayList<>(PowersManager.getPowersForRune(mob.getMobBaseID()));
output += PowersManager.getPowerByToken(token).getName() + newline;
// 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); throwbackInfo(playerCharacter, output);
} }
+102 -38
View File
@@ -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) { public static void cleanupHirelings(Building building) {
// Early exit: Cannot have hirelings in a building // Early exit: Cannot have hirelings in a building
@@ -320,42 +386,18 @@ public enum BuildingManager {
if (building.getRank() < 1) { 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; return;
} }
// Delete hireling if building has deranked. // Delete hireling if building has deranked.
for (AbstractCharacter hireling : building.getHirelings().keySet()) { 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;
if (building.getHirelings().get(hireling) > building.getBlueprint().getSlotsForRank(building.getRank())) if (building.getHirelings().get(hireling) > building.getBlueprint().getSlotsForRank(building.getRank()))
BuildingManager.removeHireling(building, hireling);
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);
}
} }
@@ -530,41 +572,63 @@ public enum BuildingManager {
else else
rank = 10; rank = 10;
Mob mob; Mob mobile;
NPC npc; NPC npc;
if (NPC.ISWallArcher(contract)) { if (NPC.ISWallArcher(contract)) {
mob = Mob.createMob(contract.getMobbaseID(), Vector3fImmutable.ZERO, contractOwner.getGuild(), zone, building, contract, 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; 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; return true;
} }
if (NPC.ISGuardCaptain(contract.getContractID())) { if (NPC.ISGuardCaptain(contract.getContractID())) {
mob = Mob.createMob(contract.getMobbaseID(), Vector3fImmutable.ZERO, contractOwner.getGuild(), zone, building, contract, 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; 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; return true;
} }
if (contract.getContractID() == 910) { if (contract.getContractID() == 910) {
//guard dog //guard dog
mob = Mob.createMob(contract.getMobbaseID(), Vector3fImmutable.ZERO, contractOwner.getGuild(), zone, building, contract, 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; 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; return true;
} }
+1 -1
View File
@@ -788,7 +788,7 @@ public enum ChatManager {
it.remove(); it.remove();
else { else {
PlayerCharacter pcc = (PlayerCharacter) awo; PlayerCharacter pcc = (PlayerCharacter) awo;
if (pcc.getSeeInvis() < pc.getHidden()) if (pcc.getSeeInvis() < pc.hidden)
it.remove(); it.remove();
} }
} }
+92 -180
View File
@@ -30,8 +30,6 @@ import java.util.HashSet;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
import static engine.math.FastMath.sqr;
public enum CombatManager { public enum CombatManager {
COMBATMANAGER; COMBATMANAGER;
@@ -41,63 +39,6 @@ public enum CombatManager {
/** /**
* Message sent by player to attack something. * 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) { public static void AttackTarget(PlayerCharacter playerCharacter, AbstractWorldObject target) {
@@ -141,11 +82,6 @@ public enum CombatManager {
if (off == null) if (off == null)
CombatManager.createTimer(playerCharacter, MBServerStatics.SLOT_OFFHAND, 1, true); // attack in 0.1 of a second 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 { public static void setAttackTarget(PetAttackMsg msg, ClientConnection origin) throws MsgSendException {
@@ -523,7 +459,7 @@ public enum CombatManager {
/** /**
* Attempt to attack target * 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; float atr;
int minDamage, maxDamage; int minDamage, maxDamage;
@@ -531,20 +467,20 @@ public enum CombatManager {
try { try {
if (ac == null) if (attacker == null)
return; return;
if (target == null) if (target == null)
return; return;
if (mainHand) { if (mainHand) {
atr = ac.getAtrHandOne(); atr = attacker.getAtrHandOne();
minDamage = ac.getMinDamageHandOne(); minDamage = attacker.getMinDamageHandOne();
maxDamage = ac.getMaxDamageHandOne(); maxDamage = attacker.getMaxDamageHandOne();
} else { } else {
atr = ac.getAtrHandTwo(); atr = attacker.getAtrHandTwo();
minDamage = ac.getMinDamageHandTwo(); minDamage = attacker.getMinDamageHandTwo();
maxDamage = ac.getMaxDamageHandTwo(); maxDamage = attacker.getMaxDamageHandTwo();
} }
boolean tarIsRat = false; boolean tarIsRat = false;
@@ -563,9 +499,9 @@ public enum CombatManager {
//Dont think we need to do this anymore. //Dont think we need to do this anymore.
if (tarIsRat) 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; minDamage *= percent;
maxDamage *= percent; maxDamage *= percent;
@@ -576,24 +512,24 @@ public enum CombatManager {
//subtract stamina //subtract stamina
if (wb == null) if (wb == null)
ac.modifyStamina(-0.5f, ac, true); attacker.modifyStamina(-0.5f, attacker, true);
else { else {
float stam = wb.getWeight() / 3; float stam = wb.getWeight() / 3;
stam = (stam < 1) ? 1 : stam; stam = (stam < 1) ? 1 : stam;
ac.modifyStamina(-(stam), ac, true); attacker.modifyStamina(-(stam), attacker, true);
} }
ac.cancelOnAttackSwing(); attacker.cancelOnAttackSwing();
errorTrack = 2; errorTrack = 2;
//set last time this player has attacked something. //set last time this player has attacked something.
if (target.getObjectType().equals(GameObjectType.PlayerCharacter) && target.getObjectUUID() != ac.getObjectUUID() && ac.getObjectType() == GameObjectType.PlayerCharacter) { if (target.getObjectType().equals(GameObjectType.PlayerCharacter) && target.getObjectUUID() != attacker.getObjectUUID() && attacker.getObjectType() == GameObjectType.PlayerCharacter) {
ac.setTimeStamp("LastCombatPlayer", System.currentTimeMillis()); attacker.setTimeStamp("LastCombatPlayer", System.currentTimeMillis());
((PlayerCharacter) target).setTimeStamp("LastCombatPlayer", System.currentTimeMillis()); ((PlayerCharacter) target).setTimeStamp("LastCombatPlayer", System.currentTimeMillis());
} else } else
ac.setTimeStamp("LastCombatMob", System.currentTimeMillis()); attacker.setTimeStamp("LastCombatMob", System.currentTimeMillis());
errorTrack = 3; errorTrack = 3;
@@ -604,42 +540,16 @@ public enum CombatManager {
if (target.getObjectType().equals(GameObjectType.Building)) { if (target.getObjectType().equals(GameObjectType.Building)) {
if (BuildingManager.getBuildingFromCache(target.getObjectUUID()) == null) { if (BuildingManager.getBuildingFromCache(target.getObjectUUID()) == null) {
ac.setCombatTarget(null); attacker.setCombatTarget(null);
return; return;
} }
defense = 0; 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 { } else {
AbstractCharacter tar = (AbstractCharacter) target; AbstractCharacter tar = (AbstractCharacter) target;
defense = tar.getDefenseRating(); 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; errorTrack = 4;
@@ -665,11 +575,11 @@ public enum CombatManager {
if (roll < chance) { if (roll < chance) {
if (ac.getObjectType().equals(GameObjectType.PlayerCharacter)) if (attacker.getObjectType().equals(GameObjectType.PlayerCharacter))
updateAttackTimers((PlayerCharacter) ac, target, true); updateAttackTimers((PlayerCharacter) attacker, target, true);
boolean skipPassives = false; boolean skipPassives = false;
PlayerBonuses bonuses = ac.getBonuses(); PlayerBonuses bonuses = attacker.getBonuses();
if (bonuses != null && bonuses.getBool(ModType.IgnorePassiveDefense, SourceType.None)) if (bonuses != null && bonuses.getBool(ModType.IgnorePassiveDefense, SourceType.None))
skipPassives = true; skipPassives = true;
@@ -684,26 +594,26 @@ public enum CombatManager {
// Apply Weapon power effect if any. don't try to apply twice if // Apply Weapon power effect if any. don't try to apply twice if
// dual wielding. Perform after passive test for sync purposes. // 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) { if (dpj != null) {
PlayerBonuses bonus = ac.getBonuses(); PlayerBonuses bonus = attacker.getBonuses();
float attackRange = getWeaponRange(wb, bonus); float attackRange = getWeaponRange(wb, bonus);
dpj.attack(target, attackRange); dpj.attack(target, attackRange);
if (dpj.getPower() != null && (dpj.getPowerToken() == -1851459567 || dpj.getPowerToken() == -1851489518)) if (dpj.getPower() != null && (dpj.getPowerToken() == -1851459567 || dpj.getPowerToken() == -1851489518))
((PlayerCharacter) ac).setWeaponPower(dpj); ((PlayerCharacter) attacker).setWeaponPower(dpj);
} }
} }
//check to apply second backstab. //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)) { if (dpj != null && dpj.getPower() != null && (dpj.getPowerToken() == -1851459567 || dpj.getPowerToken() == -1851489518)) {
float attackRange = getWeaponRange(wb, bonuses); float attackRange = getWeaponRange(wb, bonuses);
@@ -723,24 +633,24 @@ public enum CombatManager {
//Handle Block passive //Handle Block passive
if (testPassive(ac, tarAc, "Block") && canTestBlock(ac, target)) { if (testPassive(attacker, tarAc, "Block") && canTestBlock(attacker, target)) {
if (!target.isAlive()) if (!target.isAlive())
return; return;
sendPassiveDefenseMessage(ac, wb, target, MBServerStatics.COMBAT_SEND_BLOCK, dpj, mainHand); sendPassiveDefenseMessage(attacker, wb, target, MBServerStatics.COMBAT_SEND_BLOCK, dpj, mainHand);
passiveFired = true; passiveFired = true;
} }
//Handle Parry passive //Handle Parry passive
if (!passiveFired) if (!passiveFired)
if (canTestParry(ac, target) && testPassive(ac, tarAc, "Parry")) { if (canTestParry(attacker, target) && testPassive(attacker, tarAc, "Parry")) {
if (!target.isAlive()) if (!target.isAlive())
return; return;
sendPassiveDefenseMessage(ac, wb, target, MBServerStatics.COMBAT_SEND_PARRY, dpj, mainHand); sendPassiveDefenseMessage(attacker, wb, target, MBServerStatics.COMBAT_SEND_PARRY, dpj, mainHand);
passiveFired = true; passiveFired = true;
} }
@@ -751,12 +661,12 @@ public enum CombatManager {
//Handle Dodge passive //Handle Dodge passive
if (!passiveFired) if (!passiveFired)
if (testPassive(ac, tarAc, "Dodge")) { if (testPassive(attacker, tarAc, "Dodge")) {
if (!target.isAlive()) if (!target.isAlive())
return; return;
sendPassiveDefenseMessage(ac, wb, target, MBServerStatics.COMBAT_SEND_DODGE, dpj, mainHand); sendPassiveDefenseMessage(attacker, wb, target, MBServerStatics.COMBAT_SEND_DODGE, dpj, mainHand);
passiveFired = true; passiveFired = true;
} }
} }
@@ -772,7 +682,7 @@ public enum CombatManager {
//if target is player, set last attack timestamp //if target is player, set last attack timestamp
if (target.getObjectType().equals(GameObjectType.PlayerCharacter)) if (target.getObjectType().equals(GameObjectType.PlayerCharacter))
updateAttackTimers((PlayerCharacter) target, ac, false); updateAttackTimers((PlayerCharacter) target, attacker, false);
//Get damage Type //Get damage Type
@@ -780,7 +690,7 @@ public enum CombatManager {
if (wb != null) if (wb != null)
damageType = wb.getDamageType(); 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; damageType = DamageType.Siege;
else else
damageType = DamageType.Crush; damageType = DamageType.Crush;
@@ -799,7 +709,7 @@ public enum CombatManager {
//make sure target is not immune to damage type; //make sure target is not immune to damage type;
if (resists != null && resists.immuneTo(damageType)) { if (resists != null && resists.immuneTo(damageType)) {
sendCombatMessage(ac, target, 0f, wb, dpj, mainHand); sendCombatMessage(attacker, target, 0f, wb, dpj, mainHand);
return; return;
} }
@@ -810,9 +720,9 @@ public enum CombatManager {
float damage; float damage;
if (wb != null) if (wb != null)
damage = calculateDamage(ac, tarAc, minDamage, maxDamage, damageType, resists); damage = calculateDamage(attacker, tarAc, minDamage, maxDamage, damageType, resists);
else else
damage = calculateDamage(ac, tarAc, minDamage, maxDamage, damageType, resists); damage = calculateDamage(attacker, tarAc, minDamage, maxDamage, damageType, resists);
float d = 0f; float d = 0f;
@@ -825,41 +735,35 @@ public enum CombatManager {
if (tarAc.isSit()) if (tarAc.isSit())
damage *= 2.5f; //increase damage if sitting damage *= 2.5f; //increase damage if sitting
if (tarAc.getObjectType() == GameObjectType.Mob) {
if(ac.getObjectType().equals(GameObjectType.PlayerCharacter))
((Mob)tarAc).playerAgroMap.put(ac.getObjectUUID(), ((Mob) tarAc).playerAgroMap.get(ac.getObjectUUID()) + damage);
((Mob) tarAc).handleDirectAggro(ac);
}
if (tarAc.getHealth() > 0) if (tarAc.getHealth() > 0)
d = tarAc.modifyHealth(-damage, ac, false); d = tarAc.modifyHealth(-damage, attacker, false);
} else if (target.getObjectType().equals(GameObjectType.Building)) { } else if (target.getObjectType().equals(GameObjectType.Building)) {
if (BuildingManager.getBuildingFromCache(target.getObjectUUID()) == null) { if (BuildingManager.getBuildingFromCache(target.getObjectUUID()) == null) {
ac.setCombatTarget(null); attacker.setCombatTarget(null);
return; return;
} }
if (target.getHealth() > 0) if (target.getHealth() > 0)
d = ((Building) target).modifyHealth(-damage, ac); d = ((Building) target).modifyHealth(-damage, attacker);
} }
errorTrack = 13; errorTrack = 13;
//Test to see if any damage needs done to weapon or armor //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 target is dead, we got the killing blow, remove attack timers on our weapons
if (tarAc != null && !tarAc.isAlive()) if (tarAc != null && !tarAc.isAlive())
removeAttackTimers(ac); removeAttackTimers(attacker);
//test double death fix //test double death fix
if (d != 0) 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; errorTrack = 14;
@@ -886,7 +790,7 @@ public enum CombatManager {
int procChance = ThreadLocalRandom.current().nextInt(100); int procChance = ThreadLocalRandom.current().nextInt(100);
if (procChance < MBServerStatics.PROC_CHANCE) if (procChance < MBServerStatics.PROC_CHANCE)
((WeaponProcEffectModifier) aem).applyProc(ac, target); ((WeaponProcEffectModifier) aem).applyProc(attacker, target);
} }
} }
@@ -898,52 +802,52 @@ public enum CombatManager {
//handle damage shields //handle damage shields
if (ac.isAlive() && tarAc != null && tarAc.isAlive()) if (attacker.isAlive() && tarAc != null && tarAc.isAlive())
handleDamageShields(ac, tarAc, damage); handleDamageShields(attacker, tarAc, damage);
} else { } else {
// Apply Weapon power effect if any. // Apply Weapon power effect if any.
// don't try to apply twice if dual wielding. // don't try to apply twice if dual wielding.
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) { if (dpj != null) {
PowersBase wp = dpj.getPower(); PowersBase wp = dpj.getPower();
if (wp.requiresHitRoll() == false) { if (wp.requiresHitRoll() == false) {
PlayerBonuses bonus = ac.getBonuses(); PlayerBonuses bonus = attacker.getBonuses();
float attackRange = getWeaponRange(wb, bonus); float attackRange = getWeaponRange(wb, bonus);
dpj.attack(target, attackRange); dpj.attack(target, attackRange);
} else } else
((PlayerCharacter) ac).setWeaponPower(null); ((PlayerCharacter) attacker).setWeaponPower(null);
} }
} }
if (target.getObjectType() == GameObjectType.Mob) if (target.getObjectType() == GameObjectType.Mob)
((Mob) target).handleDirectAggro(ac); ((Mob) target).handleDirectAggro(attacker);
errorTrack = 17; errorTrack = 17;
//miss, Send miss message //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 attacker is player, set last attack timestamp
if (ac.getObjectType().equals(GameObjectType.PlayerCharacter)) if (attacker.getObjectType().equals(GameObjectType.PlayerCharacter))
updateAttackTimers((PlayerCharacter) ac, target, true); updateAttackTimers((PlayerCharacter) attacker, target, true);
} }
errorTrack = 18; errorTrack = 18;
//cancel effects that break on attack or attackSwing //cancel effects that break on attack or attackSwing
ac.cancelOnAttack(); attacker.cancelOnAttack();
} catch (Exception e) { } catch (Exception e) {
Logger.error(ac.getName() + ' ' + errorTrack + ' ' + e); Logger.error(attacker.getName() + ' ' + errorTrack + ' ' + e);
} }
} }
@@ -1221,7 +1125,7 @@ public enum CombatManager {
toggleCombat(msg.getToggle(), origin); 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); PlayerCharacter pc = SessionManager.getPlayerCharacter(origin);
@@ -1238,7 +1142,7 @@ public enum CombatManager {
DispatchMessage.dispatchMsgToInterestArea(pc, rwss, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, false, false); 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); PlayerCharacter pc = SessionManager.getPlayerCharacter(origin);
@@ -1268,61 +1172,69 @@ public enum CombatManager {
} }
//Called when character takes damage. //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; return;
if (ac.equals(tarAc)) if (attacker.equals(target))
return; return;
if (tarAc.isMoving() && tarAc.getObjectType().equals(GameObjectType.PlayerCharacter)) if (target.isMoving() && target.getObjectType().equals(GameObjectType.PlayerCharacter))
return; return;
if (!tarAc.isAlive() || !ac.isAlive()) if (!target.isAlive() || !attacker.isAlive())
return; return;
boolean isCombat = tarAc.isCombat(); boolean isCombat = target.isCombat();
//If target in combat and has no target, then attack back //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 ((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 (tarAc.getObjectType().equals(GameObjectType.PlayerCharacter)) { // we are in combat with no valid target if (target.getObjectType().equals(GameObjectType.PlayerCharacter)) { // we are in combat with no valid target
PlayerCharacter pc = (PlayerCharacter) tarAc; PlayerCharacter pc = (PlayerCharacter) target;
tarAc.setCombatTarget(ac); target.setCombatTarget(attacker);
pc.setLastTarget(ac.getObjectType(), ac.getObjectUUID()); pc.setLastTarget(attacker.getObjectType(), attacker.getObjectUUID());
if (tarAc.getTimers() != null) if (target.getTimers() != null)
if (!tarAc.getTimers().containsKey("Attack" + MBServerStatics.SLOT_MAINHAND)) if (!target.getTimers().containsKey("Attack" + MBServerStatics.SLOT_MAINHAND))
CombatManager.AttackTarget((PlayerCharacter) tarAc, tarAc.getCombatTarget()); CombatManager.AttackTarget((PlayerCharacter) target, target.getCombatTarget());
} }
//Handle pet retaliate if assist is on and pet doesn't have a target. //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) if (pet != null && pet.assist && pet.getCombatTarget() == null)
pet.setCombatTarget(ac); pet.setCombatTarget(attacker);
} }
//Handle Mob Retaliate. //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()) //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 (attackedMobile.getCombatTarget() != null && !attackedMobile.isSiege())
return; return;
if (ac.getObjectType() == GameObjectType.Mob && retaliater.isSiege()) attackedMobile.setCombatTarget(attacker);
return;
retaliater.setCombatTarget(ac);
} }
} }
+3 -2
View File
@@ -46,9 +46,11 @@ public enum DevCmdManager {
DevCmdManager.registerDevCmd(new GetZoneCmd()); DevCmdManager.registerDevCmd(new GetZoneCmd());
DevCmdManager.registerDevCmd(new ZoneSetCmd()); DevCmdManager.registerDevCmd(new ZoneSetCmd());
DevCmdManager.registerDevCmd(new PrintBankCmd()); DevCmdManager.registerDevCmd(new PrintBankCmd());
DevCmdManager.registerDevCmd(new PrintEffectsCmd());
DevCmdManager.registerDevCmd(new PrintEquipCmd()); DevCmdManager.registerDevCmd(new PrintEquipCmd());
DevCmdManager.registerDevCmd(new PrintInventoryCmd()); DevCmdManager.registerDevCmd(new PrintInventoryCmd());
DevCmdManager.registerDevCmd(new PrintVaultCmd()); DevCmdManager.registerDevCmd(new PrintVaultCmd());
DevCmdManager.registerDevCmd(new PrintRunesCmd());
DevCmdManager.registerDevCmd(new PrintStatsCmd()); DevCmdManager.registerDevCmd(new PrintStatsCmd());
DevCmdManager.registerDevCmd(new PrintSkillsCmd()); DevCmdManager.registerDevCmd(new PrintSkillsCmd());
DevCmdManager.registerDevCmd(new PrintPowersCmd()); DevCmdManager.registerDevCmd(new PrintPowersCmd());
@@ -128,7 +130,6 @@ public enum DevCmdManager {
DevCmdManager.registerDevCmd(new SetForceRenameCityCmd()); DevCmdManager.registerDevCmd(new SetForceRenameCityCmd());
DevCmdManager.registerDevCmd(new GotoObj()); DevCmdManager.registerDevCmd(new GotoObj());
DevCmdManager.registerDevCmd(new convertLoc()); DevCmdManager.registerDevCmd(new convertLoc());
DevCmdManager.registerDevCmd(new AuditHeightMapCmd());
DevCmdManager.registerDevCmd(new UnloadFurnitureCmd()); DevCmdManager.registerDevCmd(new UnloadFurnitureCmd());
DevCmdManager.registerDevCmd(new SetNpcEquipSetCmd()); DevCmdManager.registerDevCmd(new SetNpcEquipSetCmd());
DevCmdManager.registerDevCmd(new SetBuildingAltitudeCmd()); DevCmdManager.registerDevCmd(new SetBuildingAltitudeCmd());
@@ -143,7 +144,7 @@ public enum DevCmdManager {
DevCmdManager.registerDevCmd(new ApplyBonusCmd()); DevCmdManager.registerDevCmd(new ApplyBonusCmd());
DevCmdManager.registerDevCmd(new AuditFailedItemsCmd()); DevCmdManager.registerDevCmd(new AuditFailedItemsCmd());
DevCmdManager.registerDevCmd(new SlotTestCmd()); DevCmdManager.registerDevCmd(new SlotTestCmd());
DevCmdManager.registerDevCmd(new SeaAuditCmd());
} }
private static void registerDevCmd(AbstractDevCmd cmd) { private static void registerDevCmd(AbstractDevCmd cmd) {
+2
View File
@@ -330,6 +330,8 @@ public enum LootManager {
public static void GenerateEquipmentDrop(Mob mob) { public static void GenerateEquipmentDrop(Mob mob) {
if(mob.behaviourType.equals(Enum.MobBehaviourType.HamletGuard))
return; // safehold guards don't drop their equipment
//do equipment here //do equipment here
int dropCount = 0; int dropCount = 0;
if (mob.getEquip() != null) if (mob.getEquip() != null)
+11 -12
View File
@@ -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 inside a building, convert both locations from the building local reference frame to the world reference frame
if (msg.getTargetID() > 0) { if (msg.getInBuildingUUID() > 0) {
Building building = BuildingManager.getBuildingFromCache(msg.getTargetID()); Building building = BuildingManager.getBuildingFromCache(msg.getInBuildingUUID());
if (building != null) { if (building != null) {
Vector3fImmutable convertLocEnd = new Vector3fImmutable(ZoneManager.convertLocalToWorld(building, endLocation)); Vector3fImmutable convertLocEnd = new Vector3fImmutable(ZoneManager.convertLocalToWorld(building, endLocation));
@@ -128,8 +128,8 @@ public enum MovementManager {
// } // }
// else { // else {
toMove.setInBuilding(msg.getInBuilding()); toMove.setInBuilding(msg.getInBuilding());
toMove.setInFloorID(msg.getUnknown01()); toMove.setInFloorID(msg.getInBuildingFloor());
toMove.setInBuildingID(msg.getTargetID()); toMove.setInBuildingID(msg.getInBuildingUUID());
msg.setStartCoord(ZoneManager.convertWorldToLocal(building, toMove.getLoc())); msg.setStartCoord(ZoneManager.convertWorldToLocal(building, toMove.getLoc()));
if (toMove.getObjectType() == GameObjectType.PlayerCharacter) { if (toMove.getObjectType() == GameObjectType.PlayerCharacter) {
@@ -174,9 +174,9 @@ public enum MovementManager {
msg.setStartCoord(ZoneManager.convertWorldToLocal(Regions.GetBuildingForRegion(toMove.region), toMove.getLoc())); msg.setStartCoord(ZoneManager.convertWorldToLocal(Regions.GetBuildingForRegion(toMove.region), toMove.getLoc()));
msg.setEndCoord(ZoneManager.convertWorldToLocal(regionBuilding, endLocation)); msg.setEndCoord(ZoneManager.convertWorldToLocal(regionBuilding, endLocation));
msg.setInBuilding(toMove.region.level); msg.setInBuilding(toMove.region.level);
msg.setUnknown01(toMove.region.room); msg.setInBuildingFloor(toMove.region.room);
msg.setTargetType(GameObjectType.Building.ordinal()); msg.setStartLocType(GameObjectType.Building.ordinal());
msg.setTargetID(regionBuilding.getObjectUUID()); msg.setInBuildingUUID(regionBuilding.getObjectUUID());
} }
} else { } else {
@@ -185,8 +185,8 @@ public enum MovementManager {
toMove.setInBuilding(-1); toMove.setInBuilding(-1);
msg.setStartCoord(toMove.getLoc()); msg.setStartCoord(toMove.getLoc());
msg.setEndCoord(endLocation); msg.setEndCoord(endLocation);
msg.setTargetType(0); msg.setStartLocType(0);
msg.setTargetID(0); msg.setInBuildingUUID(0);
} }
//checks sync between character and server, if out of sync, teleport player to original position and return. //checks sync between character and server, if out of sync, teleport player to original position and return.
@@ -233,7 +233,7 @@ public enum MovementManager {
toMove.cancelOnMove(); toMove.cancelOnMove();
//cancel any attacks for manual move. //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); toMove.setCombatTarget(null);
@@ -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) if (targetLoc == null)
@@ -473,7 +473,6 @@ public enum MovementManager {
Vector3fImmutable oldLoc = new Vector3fImmutable(teleporter.getLoc()); Vector3fImmutable oldLoc = new Vector3fImmutable(teleporter.getLoc());
teleporter.stopMovement(targetLoc); teleporter.stopMovement(targetLoc);
teleporter.setRegion(region);
//mobs ignore region sets for now. //mobs ignore region sets for now.
if (teleporter.getObjectType().equals(GameObjectType.Mob)) { if (teleporter.getObjectType().equals(GameObjectType.Mob)) {
+231 -181
View File
@@ -5,13 +5,17 @@ import engine.InterestManagement.WorldGrid;
import engine.math.Quaternion; import engine.math.Quaternion;
import engine.math.Vector3f; import engine.math.Vector3f;
import engine.math.Vector3fImmutable; import engine.math.Vector3fImmutable;
import engine.mobileAI.MobAI;
import engine.net.Dispatch; import engine.net.Dispatch;
import engine.net.DispatchMessage; import engine.net.DispatchMessage;
import engine.net.client.msg.PetMsg; import engine.net.client.msg.PetMsg;
import engine.objects.*; import engine.objects.*;
import engine.powers.EffectsBase; import engine.powers.EffectsBase;
import engine.powers.PowersBase;
import engine.powers.RuneSkillAdjustEntry;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
import javax.smartcardio.ATR;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
@@ -23,84 +27,6 @@ public enum NPCManager {
NPC_MANAGER; NPC_MANAGER;
public static HashMap<Integer, ArrayList<Integer>> _runeSetMap = new HashMap<>(); public static HashMap<Integer, ArrayList<Integer>> _runeSetMap = new HashMap<>();
public static void 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) { public static void dismissNecroPet(Mob necroPet, boolean updateOwner) {
necroPet.setCombatTarget(null); necroPet.setCombatTarget(null);
@@ -196,80 +122,6 @@ public enum NPCManager {
playerCharacter.necroPets.clear(); 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 = (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, 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() { public static void loadAllPirateNames() {
DbManager.NPCQueries.LOAD_PIRATE_NAMES(); DbManager.NPCQueries.LOAD_PIRATE_NAMES();
@@ -340,7 +192,7 @@ public enum NPCManager {
if (abstractCharacter.getObjectType().equals(Enum.GameObjectType.Mob) && ((Mob) abstractCharacter).behaviourType.equals(Enum.MobBehaviourType.SiegeEngine)) { if (abstractCharacter.getObjectType().equals(Enum.GameObjectType.Mob) && ((Mob) abstractCharacter).behaviourType.equals(Enum.MobBehaviourType.SiegeEngine)) {
Mob siegeMobile = (Mob) abstractCharacter; Mob siegeMobile = (Mob) abstractCharacter;
buildingSlot = siegeMobile.guardCaptain.siegeMinionMap.size() + 2; buildingSlot = siegeMobile.guardCaptain.minions.size() + 2;
} }
if (buildingSlot == -1) if (buildingSlot == -1)
@@ -376,33 +228,6 @@ public enum NPCManager {
return buildingSlot; return buildingSlot;
} }
public static int getMaxMinions(Mob guardCaptain) {
int maxSlots;
switch (guardCaptain.getRank()) {
case 3:
maxSlots = 2;
break;
case 4:
case 5:
maxSlots = 3;
break;
case 6:
maxSlots = 4;
break;
case 7:
maxSlots = 5;
break;
case 1:
case 2:
default:
maxSlots = 1;
}
return maxSlots;
}
public static void AssignPatrolPoints(Mob mob) { public static void AssignPatrolPoints(Mob mob) {
mob.patrolPoints = new ArrayList<>(); mob.patrolPoints = new ArrayList<>();
@@ -419,9 +244,234 @@ public enum NPCManager {
mob.patrolPoints.add(newPatrolPoint); mob.patrolPoints.add(newPatrolPoint);
if (i == 1) { if (i == 1) {
mob.loc = newPatrolPoint; mob.setLoc(newPatrolPoint);
mob.endLoc = 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);
}
}
}
}
} }
+12 -5
View File
@@ -53,13 +53,10 @@ public enum PowersManager {
public static HashMap<Integer, AbstractPowerAction> powerActionsByID = new HashMap<>(); public static HashMap<Integer, AbstractPowerAction> powerActionsByID = new HashMap<>();
public static HashMap<String, Integer> ActionTokenByIDString = new HashMap<>(); public static HashMap<String, Integer> ActionTokenByIDString = new HashMap<>();
public static HashMap<String, Integer> AnimationOverrides = 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 static JobScheduler js;
private PowersManager() {
}
public static void initPowersManager(boolean fullPowersLoad) { public static void initPowersManager(boolean fullPowersLoad) {
if (fullPowersLoad) if (fullPowersLoad)
@@ -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 // This pre-loads all powers and effects
public static void InitializePowers() { public static void InitializePowers() {
+28
View File
@@ -9,6 +9,7 @@
package engine.gameManager; package engine.gameManager;
import engine.Enum; import engine.Enum;
import engine.InterestManagement.HeightMap;
import engine.db.archive.CityRecord; import engine.db.archive.CityRecord;
import engine.db.archive.DataWarehouse; import engine.db.archive.DataWarehouse;
import engine.math.Bounds; import engine.math.Bounds;
@@ -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;
}
} }
-2
View File
@@ -61,8 +61,6 @@ public class FinishSummonsJob extends AbstractScheduleJob {
return; return;
} }
if (this.source.region != null)
this.target.setRegion(this.source.region);
//teleport target to source //teleport target to source
target.teleport(source.getLoc()); target.teleport(source.getLoc());
} }
+223 -320
View File
@@ -23,6 +23,7 @@ import engine.net.client.msg.PowerProjectileMsg;
import engine.objects.*; import engine.objects.*;
import engine.powers.ActionsBase; import engine.powers.ActionsBase;
import engine.powers.PowersBase; import engine.powers.PowersBase;
import engine.powers.RunePowerEntry;
import engine.server.MBServerStatics; import engine.server.MBServerStatics;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
@@ -49,17 +50,19 @@ public class MobAI {
return; 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 (target.getObjectType() == Enum.GameObjectType.PlayerCharacter && canCast(mob)) {
if (mob.isPlayerGuard() == false && MobCast(mob)) { if (MobCast(mob)) {
mob.updateLocation(); mob.updateLocation();
return; return;
} }
if (mob.isPlayerGuard() == true && GuardCast(mob)) {
mob.updateLocation();
return;
}
} }
if (!CombatUtilities.inRangeToAttack(mob, target)) if (!CombatUtilities.inRangeToAttack(mob, target))
@@ -165,7 +168,7 @@ public class MobAI {
if (playercity != null) if (playercity != null)
for (Mob guard : playercity.getParent().zoneMobSet) for (Mob guard : playercity.getParent().zoneMobSet)
if (guard.behaviourType != null && guard.behaviourType.equals(Enum.MobBehaviourType.GuardCaptain)) if (guard.agentType.equals(Enum.AIAgentType.GUARDCAPTAIN))
if (guard.getCombatTarget() == null && !guard.getGuild().equals(mob.getGuild())) if (guard.getCombatTarget() == null && !guard.getGuild().equals(mob.getGuild()))
guard.setCombatTarget(mob); guard.setCombatTarget(mob);
@@ -249,50 +252,58 @@ public class MobAI {
try { 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; 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()) if (mob.stopPatrolTime + (patrolDelay * 1000) > System.currentTimeMillis())
return; if (!forced)
//guard captains inherit barracks patrol points dynamically
if (mob.behaviourType.equals(Enum.MobBehaviourType.GuardCaptain)) {
Building barracks = mob.building;
if (barracks != null && barracks.patrolPoints != null && !barracks.getPatrolPoints().isEmpty()) {
mob.patrolPoints = barracks.patrolPoints;
} else {
randomGuardPatrolPoint(mob);
return; return;
//guards inherit barracks patrol points dynamically
if (mob.patrolPoints == null || mob.patrolPoints.isEmpty())
if (mob.agentType.equals(Enum.AIAgentType.GUARDCAPTAIN) || mob.agentType.equals(Enum.AIAgentType.GUARDMINION)) {
Building barracks = mob.building;
if (barracks != null && barracks.patrolPoints != null && !barracks.getPatrolPoints().isEmpty()) {
mob.patrolPoints = barracks.patrolPoints;
} else {
randomGuardPatrolPoint(mob);
return;
}
} }
}
if (mob.lastPatrolPointIndex > mob.patrolPoints.size() - 1) if (mob.lastPatrolPointIndex > mob.patrolPoints.size() - 1)
mob.lastPatrolPointIndex = 0; mob.lastPatrolPointIndex = 0;
mob.destination = mob.patrolPoints.get(mob.lastPatrolPointIndex); // Minions are given marching orders by the captain if he is alive
mob.lastPatrolPointIndex += 1;
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;
}
// Captain orders minions to patrol
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); MovementUtilities.aiMove(mob, mob.destination, true);
if (mob.behaviourType.equals(Enum.MobBehaviourType.GuardCaptain))
for (Entry<Mob, Integer> minion : mob.siegeMinionMap.entrySet())
//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();
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) { } catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: AttackTarget" + " " + e.getMessage()); Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: AttackTarget" + " " + e.getMessage());
} }
@@ -300,6 +311,8 @@ public class MobAI {
public static boolean canCast(Mob mob) { public static boolean canCast(Mob mob) {
int contractID = 0;
try { try {
// Performs validation to determine if a // Performs validation to determine if a
@@ -308,26 +321,27 @@ public class MobAI {
if (mob == null) if (mob == null)
return false; return false;
if(mob.isPlayerGuard == true){ if (mob.isPlayerGuard() == true) {
int contractID; if(mob.agentType.equals(Enum.AIAgentType.GUARDWALLARCHER))
return false; //wall archers don't cast
if (mob.behaviourType.equals(Enum.MobBehaviourType.GuardMinion)) if (mob.agentType.equals(Enum.AIAgentType.GUARDMINION))
contractID = mob.guardCaptain.contract.getContractID(); contractID = mob.guardCaptain.contract.getContractID();
else else
contractID = mob.contract.getContractID(); 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; return false;
} }
if (mob.mobPowers.isEmpty()) // Mobile has no powers defined in mobbase or contract..
if (PowersManager.getPowersForRune(mob.getMobBaseID()).isEmpty() &&
PowersManager.getPowersForRune(contractID).isEmpty())
return false; return false;
if (!mob.canSee((PlayerCharacter) mob.getCombatTarget())) {
mob.setCombatTarget(null);
return false;
}
if (mob.nextCastTime == 0) if (mob.nextCastTime == 0)
mob.nextCastTime = System.currentTimeMillis(); mob.nextCastTime = System.currentTimeMillis();
@@ -346,8 +360,8 @@ public class MobAI {
// and casts it on the current target (or itself). Validation // and casts it on the current target (or itself). Validation
// (including empty lists) is done previously within canCast(); // (including empty lists) is done previously within canCast();
ArrayList<Integer> powerTokens; ArrayList<RunePowerEntry> powerEntries;
ArrayList<Integer> purgeTokens; ArrayList<RunePowerEntry> purgeEntries;
AbstractCharacter target = (AbstractCharacter) mob.getCombatTarget(); AbstractCharacter target = (AbstractCharacter) mob.getCombatTarget();
if (mob.behaviourType.callsForHelp) if (mob.behaviourType.callsForHelp)
@@ -355,38 +369,58 @@ public class MobAI {
// Generate a list of tokens from the mob powers for this mobile. // Generate a list of tokens from the mob powers for this mobile.
powerTokens = new ArrayList<>(mob.mobPowers.keySet()); powerEntries = new ArrayList<>(PowersManager.getPowersForRune(mob.getMobBaseID()));
purgeTokens = new ArrayList<>(); purgeEntries = new ArrayList<>();
// 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 = PowersManager.getPowersForRune(mob.contractUUID);
if (mob.agentType.equals(Enum.AIAgentType.GUARDMINION))
contractEntries = PowersManager.getPowersForRune(mob.guardCaptain.contractUUID);
powerEntries.addAll(contractEntries);
}
// If player has this effect on them currently then remove // If player has this effect on them currently then remove
// this token from our list. // 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()) { for (ActionsBase actionBase : powerBase.getActions()) {
String stackType = actionBase.stackType; String stackType = actionBase.stackType;
if (target.getEffects() != null && target.getEffects().containsKey(stackType)) if (target.getEffects() != null && target.getEffects().containsKey(stackType))
purgeTokens.add(powerToken); purgeEntries.add(runePowerEntry);
} }
} }
powerTokens.removeAll(purgeTokens); powerEntries.removeAll(purgeEntries);
// Sanity check // Sanity check
if (powerTokens.isEmpty()) if (powerEntries.isEmpty())
return false; return false;
// Pick random spell from our list of powers // Pick random spell from our list of powers
int powerToken = powerTokens.get(ThreadLocalRandom.current().nextInt(powerTokens.size())); RunePowerEntry runePowerEntry = powerEntries.get(ThreadLocalRandom.current().nextInt(powerEntries.size()));
int powerRank = mob.mobPowers.get(powerToken);
PowersBase mobPower = PowersManager.getPowerByToken(powerToken); PowersBase mobPower = PowersManager.getPowerByToken(runePowerEntry.token);
int powerRank = runePowerEntry.rank;
if (mob.isPlayerGuard())
powerRank = getGuardPowerRank(mob);
//check for hit-roll //check for hit-roll
@@ -411,7 +445,7 @@ public class MobAI {
msg.setUnknown04(2); msg.setUnknown04(2);
PowersManager.finishUseMobPower(msg, mob, 0, 0); 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; mob.nextCastTime = System.currentTimeMillis() + randomCooldown;
return true; return true;
@@ -422,127 +456,33 @@ public class MobAI {
return false; return false;
} }
public static boolean GuardCast(Mob mob) { public static int getGuardPowerRank(Mob mob) {
int powerRank = 1;
try { switch (mob.getRank()) {
// Method picks a random spell from a mobile's list of powers case 1:
// and casts it on the current target (or itself). Validation powerRank = 10;
// (including empty lists) is done previously within canCast(); break;
case 2:
ArrayList<Integer> powerTokens; powerRank = 15;
ArrayList<Integer> purgeTokens; break;
AbstractCharacter target = (AbstractCharacter) mob.getCombatTarget(); case 3:
powerRank = 20;
if (mob.behaviourType.callsForHelp) break;
MobCallForHelp(mob); case 4:
powerRank = 25;
// Generate a list of tokens from the mob powers for this mobile. break;
case 5:
powerTokens = new ArrayList<>(mob.mobPowers.keySet()); powerRank = 30;
purgeTokens = new ArrayList<>(); break;
case 6:
// If player has this effect on them currently then remove powerRank = 35;
// this token from our list. break;
case 7:
for (int powerToken : powerTokens) { powerRank = 40;
break;
PowersBase powerBase = PowersManager.getPowerByToken(powerToken);
for (ActionsBase actionBase : powerBase.getActions()) {
String stackType = actionBase.stackType;
if (target.getEffects() != null && target.getEffects().containsKey(stackType))
purgeTokens.add(powerToken);
}
}
powerTokens.removeAll(purgeTokens);
// Sanity check
if (powerTokens.isEmpty())
return false;
int powerToken = 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()));
}
int powerRank = 1;
switch(mob.getRank()){
case 1:
powerRank = 10;
break;
case 2:
powerRank = 15;
break;
case 3:
powerRank = 20;
break;
case 4:
powerRank = 25;
break;
case 5:
powerRank = 30;
break;
case 6:
powerRank = 35;
break;
case 7:
powerRank = 40;
break;
}
PowersBase mobPower = PowersManager.getPowerByToken(powerToken);
//check for hit-roll
if (mobPower.requiresHitRoll)
if (CombatUtilities.triggerDefense(mob, mob.getCombatTarget()))
return false;
// Cast the spell
if (CombatUtilities.inRange2D(mob, mob.getCombatTarget(), mobPower.getRange())) {
PerformActionMsg msg;
if (!mobPower.isHarmful() || mobPower.targetSelf) {
if (mobPower.category.equals("DISPEL")) {
PowersManager.useMobPower(mob, target, mobPower, powerRank);
msg = PowersManager.createPowerMsg(mobPower, powerRank, mob, target);
} else {
PowersManager.useMobPower(mob, mob, mobPower, powerRank);
msg = PowersManager.createPowerMsg(mobPower, powerRank, mob, mob);
}
} else {
PowersManager.useMobPower(mob, target, mobPower, powerRank);
msg = PowersManager.createPowerMsg(mobPower, powerRank, mob, target);
}
msg.setUnknown04(2);
PowersManager.finishUseMobPower(msg, mob, 0, 0);
long randomCooldown = (long)((ThreadLocalRandom.current().nextInt(10,15) * 1000) * MobAIThread.AI_CAST_FREQUENCY);
mob.nextCastTime = System.currentTimeMillis() + randomCooldown;
return true;
}
} catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: MobCast" + " " + e.getMessage());
} }
return false; return powerRank;
} }
public static void MobCallForHelp(Mob mob) { public static void MobCallForHelp(Mob mob) {
@@ -606,9 +546,9 @@ public class MobAI {
//override for guards //override for guards
if (mob.despawned && mob.isPlayerGuard) { if (mob.despawned && mob.isPlayerGuard()) {
if (mob.behaviourType.equals(Enum.MobBehaviourType.GuardMinion)) { if (mob.agentType.equals(Enum.AIAgentType.GUARDMINION)) {
if (mob.guardCaptain.isAlive() == false || ((Mob) mob.guardCaptain).despawned == true) { if (mob.guardCaptain.isAlive() == false || ((Mob) mob.guardCaptain).despawned == true) {
//minions don't respawn while guard captain is dead //minions don't respawn while guard captain is dead
@@ -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 //check to send mob home for player guards to prevent exploit of dragging guards away and then teleporting
if (mob.behaviourType.equals(Enum.MobBehaviourType.Pet1) == false) if (!mob.agentType.equals(Enum.AIAgentType.PET))
CheckToSendMobHome(mob); CheckToSendMobHome(mob);
return; return;
@@ -638,15 +578,23 @@ public class MobAI {
return; 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.playerAgroMap.isEmpty() && !bypassLoadedPlayerCheck) {
if(mob.getCombatTarget() != null) if (mob.getCombatTarget() != null)
mob.setCombatTarget(null); mob.setCombatTarget(null);
return; return;
} }
if (mob.behaviourType.equals(Enum.MobBehaviourType.Pet1) == false)
if (mob.agentType.equals(Enum.AIAgentType.PET) == false)
CheckToSendMobHome(mob); CheckToSendMobHome(mob);
if (mob.getCombatTarget() != null) { if (mob.getCombatTarget() != null) {
@@ -675,13 +623,9 @@ public class MobAI {
switch (mob.behaviourType) { switch (mob.behaviourType) {
case GuardCaptain: case GuardCaptain:
GuardCaptainLogic(mob);
break;
case GuardMinion: case GuardMinion:
GuardMinionLogic(mob);
break;
case GuardWallArcher: case GuardWallArcher:
GuardWallArcherLogic(mob); GuardLogic(mob);
break; break;
case Pet1: case Pet1:
case SiegeEngine: case SiegeEngine:
@@ -748,7 +692,6 @@ public class MobAI {
aiAgent.setCombatTarget(loadedPlayer); aiAgent.setCombatTarget(loadedPlayer);
return; return;
} }
} }
if (aiAgent.getCombatTarget() == null) { if (aiAgent.getCombatTarget() == null) {
@@ -787,49 +730,41 @@ public class MobAI {
case Pet1: case Pet1:
if (mob.guardCaptain == null)
if ((PlayerCharacter) mob.guardCaptain == null)
return; return;
//mob no longer has its owner loaded, translate pet to owner
if (!mob.playerAgroMap.containsKey(((PlayerCharacter) mob.guardCaptain).getObjectUUID())) { if (!mob.playerAgroMap.containsKey(mob.guardCaptain.getObjectUUID())) {
MovementManager.translocate(mob, mob.guardCaptain.getLoc());
//mob no longer has its owner loaded, translocate pet to owner
MovementManager.translocate(mob, ((PlayerCharacter) mob.guardCaptain).getLoc(), null);
return; return;
} }
if (mob.getCombatTarget() == null) { if (mob.getCombatTarget() == null) {
//move back to owner //move back to owner
if (CombatUtilities.inRange2D(mob, mob.guardCaptain, 6))
if (CombatUtilities.inRange2D(mob, (PlayerCharacter) mob.guardCaptain, 6))
return; return;
mob.destination = mob.guardCaptain.getLoc();
mob.destination = ((PlayerCharacter) mob.guardCaptain).getLoc(); MovementUtilities.moveToLocation(mob, mob.destination, 5, false);
MovementUtilities.moveToLocation(mob, mob.destination, 5);
} else } else
chaseTarget(mob); chaseTarget(mob);
break; break;
case GuardMinion:
if (!mob.guardCaptain.isAlive() || ((Mob) mob.guardCaptain).despawned)
randomGuardPatrolPoint(mob);
else {
if (mob.getCombatTarget() != null) {
chaseTarget(mob);
}
}
break;
default: default:
if (mob.getCombatTarget() == null) { if (mob.getCombatTarget() == null) {
if (!mob.isMoving())
Patrol(mob); if (!mob.isMoving()) {
else {
// 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(); mob.stopPatrolTime = System.currentTimeMillis();
}
} else { } else {
chaseTarget(mob); chaseTarget(mob);
} }
@@ -901,7 +836,7 @@ public class MobAI {
return; return;
if (mob.getCombatTarget().getObjectType().equals(Enum.GameObjectType.PlayerCharacter) && MovementUtilities.inRangeDropAggro(mob, (PlayerCharacter) mob.getCombatTarget()) == false && if (mob.getCombatTarget().getObjectType().equals(Enum.GameObjectType.PlayerCharacter) && MovementUtilities.inRangeDropAggro(mob, (PlayerCharacter) mob.getCombatTarget()) == false &&
mob.behaviourType.equals(Enum.MobBehaviourType.Pet1) == false) { mob.agentType.equals(Enum.AIAgentType.PET) == false) {
mob.setCombatTarget(null); mob.setCombatTarget(null);
return; return;
@@ -917,15 +852,6 @@ public class MobAI {
private static void CheckToSendMobHome(Mob mob) { private static void CheckToSendMobHome(Mob mob) {
try { try {
if (mob.behaviourType.isAgressive) {
if (mob.isPlayerGuard()) {
if (mob.behaviourType.equals(Enum.MobBehaviourType.GuardCaptain))
CheckForPlayerGuardAggro(mob);
} else {
CheckForAggro(mob);
}
}
if (mob.getCombatTarget() != null && CombatUtilities.inRange2D(mob, mob.getCombatTarget(), MobAIThread.AI_BASE_AGGRO_RANGE * 0.5f)) if (mob.getCombatTarget() != null && CombatUtilities.inRange2D(mob, mob.getCombatTarget(), MobAIThread.AI_BASE_AGGRO_RANGE * 0.5f))
return; return;
@@ -940,13 +866,15 @@ public class MobAI {
PowersManager.useMobPower(mob, mob, recall, 40); PowersManager.useMobPower(mob, mob, recall, 40);
mob.setCombatTarget(null); mob.setCombatTarget(null);
if (mob.behaviourType.equals(Enum.MobBehaviourType.GuardCaptain) && mob.isAlive()) { if (mob.agentType.equals(Enum.AIAgentType.GUARDCAPTAIN) && mob.isAlive()) {
//guard captain pulls his minions home with him //guard captain pulls his minions home with him
for (Entry<Mob, Integer> minion : mob.siegeMinionMap.entrySet()) { for (Integer minionUUID : mob.minions) {
PowersManager.useMobPower(minion.getKey(), minion.getKey(), recall, 40); Mob minion = Mob.getMob(minionUUID);
minion.getKey().setCombatTarget(null);
PowersManager.useMobPower(minion, minion, recall, 40);
minion.setCombatTarget(null);
} }
} }
} }
@@ -957,7 +885,7 @@ public class MobAI {
mob.setCombatTarget(null); mob.setCombatTarget(null);
for (Integer playerEntry : mob.playerAgroMap.keySet()) for (Integer playerEntry : mob.playerAgroMap.keySet())
mob.playerAgroMap.put(playerEntry,0f); mob.playerAgroMap.put(playerEntry, 0f);
} }
} catch (Exception e) { } catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: CheckToSendMobHome" + " " + e.getMessage()); Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: CheckToSendMobHome" + " " + e.getMessage());
@@ -968,16 +896,10 @@ public class MobAI {
try { try {
float rangeSquared = mob.getRange() * mob.getRange(); if (CombatUtilities.inRange2D(mob, mob.getCombatTarget(), mob.getRange()) == false) {
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 (mob.getRange() > 15) { if (mob.getRange() > 15) {
mob.destination = mob.getCombatTarget().getLoc(); mob.destination = mob.getCombatTarget().getLoc();
MovementUtilities.moveToLocation(mob, mob.destination, 0); MovementUtilities.moveToLocation(mob, mob.destination, 0, false);
} else { } else {
//check if building //check if building
@@ -986,11 +908,11 @@ public class MobAI {
case PlayerCharacter: case PlayerCharacter:
case Mob: case Mob:
mob.destination = MovementUtilities.GetDestinationToCharacter(mob, (AbstractCharacter) mob.getCombatTarget()); 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; break;
case Building: case Building:
mob.destination = mob.getCombatTarget().getLoc(); mob.destination = mob.getCombatTarget().getLoc();
MovementUtilities.moveToLocation(mob, mob.getCombatTarget().getLoc(), 0); MovementUtilities.moveToLocation(mob, mob.getCombatTarget().getLoc(), 0, false);
break; break;
} }
} }
@@ -1011,17 +933,17 @@ public class MobAI {
//dont scan self. //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; continue;
Mob aggroMob = (Mob) awoMob; Mob aggroMob = (Mob) awoMob;
//don't attack other guards //don't attack other guards
if ((aggroMob.agentType.equals(Enum.AIAgentType.GUARD))) if ((aggroMob.agentType.equals(Enum.AIAgentType.GUARDCAPTAIN)))
continue; continue;
if (aggroMob.behaviourType.equals(Enum.MobBehaviourType.Pet1)) if (aggroMob.agentType.equals(Enum.AIAgentType.PET))
continue; continue;
if (mob.getLoc().distanceSquared2D(aggroMob.getLoc()) > sqr(50)) if (mob.getLoc().distanceSquared2D(aggroMob.getLoc()) > sqr(50))
@@ -1034,74 +956,33 @@ public class MobAI {
} }
} }
public static void GuardCaptainLogic(Mob mob) { public static void GuardLogic(Mob mob) {
try { try {
if (mob.getCombatTarget() == null) if (mob.getCombatTarget() == null) {
CheckForPlayerGuardAggro(mob); 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 != null) { if (newTarget.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) {
if (GuardCanAggro(mob, (PlayerCharacter) newTarget))
if (newTarget.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) {
if (GuardCanAggro(mob, (PlayerCharacter) newTarget))
mob.setCombatTarget(newTarget);
} else
mob.setCombatTarget(newTarget);
}
CheckMobMovement(mob);
CheckForAttack(mob);
} catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: GuardCaptainLogic" + " " + e.getMessage());
}
}
public static void GuardMinionLogic(Mob mob) {
try {
if (!mob.guardCaptain.isAlive()) {
if (mob.getCombatTarget() == null) {
CheckForPlayerGuardAggro(mob);
} else {
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); mob.setCombatTarget(newTarget);
} else
} mob.setCombatTarget(newTarget);
} }
}else {
if (mob.guardCaptain.getCombatTarget() != null)
mob.setCombatTarget(mob.guardCaptain.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) { } 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());
} }
} }
@@ -1109,7 +990,6 @@ public class MobAI {
try { try {
if (mob.guardCaptain == null && mob.isNecroPet() == false && mob.isSiege() == false) if (mob.guardCaptain == null && mob.isNecroPet() == false && mob.isSiege() == false)
if (ZoneManager.getSeaFloor().zoneMobSet.contains(mob)) if (ZoneManager.getSeaFloor().zoneMobSet.contains(mob))
mob.killCharacter("no owner"); mob.killCharacter("no owner");
@@ -1204,6 +1084,15 @@ public class MobAI {
if (!mob.isAlive()) if (!mob.isAlive())
return; return;
// 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; ConcurrentHashMap<Integer, Float> loadedPlayers = mob.playerAgroMap;
for (Entry playerEntry : loadedPlayers.entrySet()) { for (Entry playerEntry : loadedPlayers.entrySet()) {
@@ -1239,27 +1128,39 @@ public class MobAI {
mob.setCombatTarget(loadedPlayer); mob.setCombatTarget(loadedPlayer);
return; 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) { } catch (Exception e) {
Logger.info(mob.getObjectUUID() + " " + mob.getName() + " Failed At: CheckForPlayerGuardAggro" + e.getMessage()); 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 { try {
if (mob.guardedCity.cityOutlaws.contains(target.getObjectUUID()) == true)
return true;
if (mob.getGuild().getNation().equals(target.getGuild().getNation())) if (mob.getGuild().getNation().equals(target.getGuild().getNation()))
return false; return false;
if (mob.behaviourType.equals(Enum.MobBehaviourType.GuardMinion)) {
if (((Mob) mob.guardCaptain).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) //first check condemn list for aggro allowed (allies button is checked)
if (ZoneManager.getCityAtLocation(mob.getLoc()).getTOL().reverseKOS) { if (ZoneManager.getCityAtLocation(mob.getLoc()).getTOL().reverseKOS) {
@@ -1337,17 +1238,19 @@ public class MobAI {
MovementUtilities.aiMove(mob, mob.destination, true); MovementUtilities.aiMove(mob, mob.destination, true);
if (mob.behaviourType.equals(Enum.MobBehaviourType.GuardCaptain)) { if (mob.agentType.equals(Enum.AIAgentType.GUARDCAPTAIN)) {
for (Entry<Mob, Integer> minion : mob.siegeMinionMap.entrySet()) { for (Integer minionUUID : mob.minions) {
Mob minion = Mob.getMob(minionUUID);
//make sure mob is out of combat stance //make sure mob is out of combat stance
if (minion.getKey().despawned == false) { if (minion.despawned == false) {
if (MovementUtilities.canMove(minion.getKey())) { if (MovementUtilities.canMove(minion)) {
Vector3f minionOffset = Formation.getOffset(2, minion.getValue() + 3); Vector3f minionOffset = Formation.getOffset(2, mob.minions.indexOf(minionUUID) + 3);
minion.getKey().updateLocation(); minion.updateLocation();
Vector3fImmutable formationPatrolPoint = new Vector3fImmutable(mob.destination.x + minionOffset.x, mob.destination.y, mob.destination.z + minionOffset.z); 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);
} }
} }
} }
@@ -264,19 +264,9 @@ public class CombatUtilities {
swingIsBlock(agent, target, passiveAnim); swingIsBlock(agent, target, passiveAnim);
return; 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 swingIsDamage(agent, target, determineDamage(agent), anim);
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);
}
if (agent.getWeaponPower() != null) if (agent.getWeaponPower() != null)
agent.getWeaponPower().attack(target, MBServerStatics.ONE_MINUTE); agent.getWeaponPower().attack(target, MBServerStatics.ONE_MINUTE);
@@ -319,19 +309,10 @@ public class CombatUtilities {
if (target == null) if (target == null)
return 0; return 0;
float damage = 0; int damage = 0;
DamageType dt = getDamageType(agent); DamageType dt = getDamageType(agent);
if ((agent.agentType.equals(AIAgentType.PET)) == true || agent.isPet() == true || agent.isNecroPet() == true) { damage = ThreadLocalRandom.current().nextInt((int)getMinDmg(agent), (int)getMaxDmg(agent) + 1);
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);
}
if (AbstractWorldObject.IsAbstractCharacter(target)) { if (AbstractWorldObject.IsAbstractCharacter(target)) {
if (((AbstractCharacter) target).isSit()) { if (((AbstractCharacter) target).isSit()) {
damage *= 2.5f; //increase damage if sitting damage *= 2.5f; //increase damage if sitting
@@ -357,158 +338,16 @@ public class CombatUtilities {
return dt; return dt;
} }
public static int calculatePetDamage(Mob agent) { public static double getMinDmg(Mob agent) {
//damage calc for pet if(agent.equip.get(2) != null && !agent.equip.get(2).getItemBase().isShield())
float range; return agent.minDamageHandTwo;
float damage; else return agent.minDamageHandOne;
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) { public static double getMaxDmg(Mob agent) {
//damage calc for guard if(agent.equip.get(2) != null && !agent.equip.get(2).getItemBase().isShield())
ItemBase weapon = agent.getEquip().get(1).getItemBase(); return agent.maxDamageHandTwo;
AbstractWorldObject target = agent.getCombatTarget(); else return agent.maxDamageHandOne;
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(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));
} }
} }
@@ -147,7 +147,7 @@ public class MovementUtilities {
return aiAgent.getLoc().ClosestPointOnLine(aggroTarget.getLoc(), aggroTarget.getEndLoc()); 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 { try {
//don't move farther than 30 units from player. //don't move farther than 30 units from player.
@@ -158,7 +158,7 @@ public class MovementUtilities {
agent.setFaceDir(newLoc.subtract2D(agent.getLoc()).normalize()); agent.setFaceDir(newLoc.subtract2D(agent.getLoc()).normalize());
aiMove(agent, newLoc, false); aiMove(agent, newLoc, isWalking);
} catch (Exception e) { } catch (Exception e) {
Logger.error(e.toString()); Logger.error(e.toString());
} }
@@ -244,10 +244,10 @@ public class MovementUtilities {
msg.setSourceID(agent.getObjectUUID()); msg.setSourceID(agent.getObjectUUID());
msg.setStartCoord(startLoc); msg.setStartCoord(startLoc);
msg.setEndCoord(endLoc); msg.setEndCoord(endLoc);
msg.setUnknown01(-1); msg.setInBuildingFloor(-1);
msg.setInBuilding(-1); msg.setInBuilding(-1);
msg.setTargetType(0); msg.setStartLocType(0);
msg.setTargetID(0); msg.setInBuildingUUID(0);
try { try {
+1 -1
View File
@@ -28,7 +28,7 @@ import static engine.net.MessageDispatcher.maxRecipients;
/* /*
* Dispatch Message is the main interface to Magicbane's threaded * Dispatch Message is the main interface to Magicbane's threaded
* asynch message delivery system. * async message delivery system.
*/ */
public class DispatchMessage { public class DispatchMessage {
+1 -4
View File
@@ -643,7 +643,7 @@ public class ClientMessagePump implements NetMsgHandler {
moveMsg.setStartCoord(sourcePlayer.getLoc()); moveMsg.setStartCoord(sourcePlayer.getLoc());
moveMsg.setEndCoord(sourcePlayer.getLoc()); moveMsg.setEndCoord(sourcePlayer.getLoc());
moveMsg.setInBuilding(-1); moveMsg.setInBuilding(-1);
moveMsg.setUnknown01(-1); moveMsg.setInBuildingFloor(-1);
dispatch = Dispatch.borrow(sourcePlayer, moveMsg); dispatch = Dispatch.borrow(sourcePlayer, moveMsg);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY); DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY);
@@ -1892,9 +1892,6 @@ public class ClientMessagePump implements NetMsgHandler {
case POWER: case POWER:
PowersManager.usePower((PerformActionMsg) msg, origin, false); PowersManager.usePower((PerformActionMsg) msg, origin, false);
break; break;
case REQUESTMELEEATTACK:
CombatManager.setAttackTarget((AttackCmdMsg) msg, origin);
break;
case READYTOENTER: case READYTOENTER:
break; break;
case OPENVAULT: case OPENVAULT:
+1 -1
View File
@@ -173,7 +173,7 @@ public enum Protocol {
REPAIROBJECT(0x782219CE, RepairMsg.class, null), //Repair Window Req/Ack, RepairObject item Req/Ack REPAIROBJECT(0x782219CE, RepairMsg.class, null), //Repair Window Req/Ack, RepairObject item Req/Ack
REQUESTCONTENTS(0xA786B0A2, LootWindowRequestMsg.class, null), // MoveObjectToContainer Window Request REQUESTCONTENTS(0xA786B0A2, LootWindowRequestMsg.class, null), // MoveObjectToContainer Window Request
REQUESTGUILDLIST(0x85DCC6D7, ReqGuildListMsg.class, RequestGuildListHandler.class), 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 REQUESTMEMBERLIST(0x3235E5EA, GuildControlMsg.class, GuildControlHandler.class), // Part of Promote/Demote, Also Player History
REQUESTTOOPENBANK(0xF26E453F, null, null), // RequestToOpenBankMsg REQUESTTOOPENBANK(0xF26E453F, null, null), // RequestToOpenBankMsg
REQUESTTOTRADE(0x4D84259B, TradeRequestMsg.class, null), // Trade Request REQUESTTOTRADE(0x4D84259B, TradeRequestMsg.class, null), // Trade Request
@@ -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;
}
}
@@ -15,9 +15,6 @@ import engine.net.client.msg.*;
import engine.objects.*; import engine.objects.*;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
import java.util.ArrayList;
import java.util.HashMap;
/* /*
* @Author: * @Author:
* @Summary: Processes application protocol message which * @Summary: Processes application protocol message which
@@ -26,8 +23,6 @@ import java.util.HashMap;
public class MinionTrainingMsgHandler extends AbstractClientMsgHandler { public class MinionTrainingMsgHandler extends AbstractClientMsgHandler {
public static HashMap<Integer, ArrayList<Integer>> _minionsByCaptain = null;
public MinionTrainingMsgHandler() { public MinionTrainingMsgHandler() {
super(MinionTrainingMessage.class); super(MinionTrainingMessage.class);
} }
@@ -37,10 +32,11 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler {
MinionTrainingMessage minionMsg = (MinionTrainingMessage) baseMsg; MinionTrainingMessage minionMsg = (MinionTrainingMessage) baseMsg;
PlayerCharacter player = SessionManager.getPlayerCharacter(origin); PlayerCharacter playerCharacter = SessionManager.getPlayerCharacter(origin);
if (player == null) if (playerCharacter == null)
return true; return true;
if (minionMsg.getNpcType() == Enum.GameObjectType.NPC.ordinal()) { if (minionMsg.getNpcType() == Enum.GameObjectType.NPC.ordinal()) {
NPC npc = NPC.getFromCache(minionMsg.getNpcID()); NPC npc = NPC.getFromCache(minionMsg.getNpcID());
@@ -48,23 +44,24 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler {
if (npc == null) if (npc == null)
return true; return true;
Building b = BuildingManager.getBuildingFromCache(minionMsg.getBuildingID()); Building building = BuildingManager.getBuildingFromCache(minionMsg.getBuildingID());
if (b == null) if (building == null)
return true; return true;
//clear minion //clear minion
if (npc.minionLock.writeLock().tryLock()) { if (npc.minionLock.writeLock().tryLock()) {
try { try {
if (minionMsg.getType() == 2) { if (minionMsg.getType() == 2) {
Mob toRemove = Mob.getFromCache(minionMsg.getUUID()); Mob toRemove = Mob.getFromCache(minionMsg.getUUID());
if (!npc.siegeMinionMap.containsKey(toRemove)) if (!npc.minions.contains(toRemove.getObjectUUID()))
return true; return true;
npc.siegeMinionMap.remove(toRemove); npc.minions.remove(Integer.valueOf(toRemove.getObjectUUID()));
WorldGrid.RemoveWorldObject(toRemove); WorldGrid.RemoveWorldObject(toRemove);
@@ -86,23 +83,21 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler {
} }
} }
// we Found the move to remove, lets break the for loop so it doesnt look for more. ManageCityAssetsMsg mca1 = new ManageCityAssetsMsg(playerCharacter, building);
ManageCityAssetsMsg mca1 = new ManageCityAssetsMsg(player, b);
mca1.actionType = 3; mca1.actionType = 3;
mca1.setTargetType(b.getObjectType().ordinal()); mca1.setTargetType(building.getObjectType().ordinal());
mca1.setTargetID(b.getObjectUUID()); mca1.setTargetID(building.getObjectUUID());
mca1.setTargetType3(npc.getObjectType().ordinal()); mca1.setTargetType3(npc.getObjectType().ordinal());
mca1.setTargetID3(npc.getObjectUUID()); mca1.setTargetID3(npc.getObjectUUID());
mca1.setAssetName1(b.getName()); mca1.setAssetName1(building.getName());
mca1.setUnknown54(1); mca1.setUnknown54(1);
Dispatch dispatch = Dispatch.borrow(player, mca1); Dispatch dispatch = Dispatch.borrow(playerCharacter, mca1);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
ManageNPCMsg mnm = new ManageNPCMsg(npc); ManageNPCMsg mnm = new ManageNPCMsg(npc);
dispatch = Dispatch.borrow(player, mnm); dispatch = Dispatch.borrow(playerCharacter, mnm);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
//Add Minion //Add Minion
@@ -117,7 +112,7 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler {
if (npc.getContractID() == 842) if (npc.getContractID() == 842)
maxSlots = 1; maxSlots = 1;
if (npc.siegeMinionMap.size() == maxSlots) if (npc.minions.size() == maxSlots)
return true; return true;
int mobBase; int mobBase;
@@ -156,7 +151,7 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler {
ManageNPCMsg mnm = new ManageNPCMsg(npc); ManageNPCMsg mnm = new ManageNPCMsg(npc);
mnm.setMessageType(1); mnm.setMessageType(1);
Dispatch dispatch = Dispatch.borrow(player, mnm); Dispatch dispatch = Dispatch.borrow(playerCharacter, mnm);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
} finally { } finally {
@@ -184,13 +179,13 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler {
Mob toRemove = Mob.getFromCache(minionMsg.getUUID()); Mob toRemove = Mob.getFromCache(minionMsg.getUUID());
if (!npc.getSiegeMinionMap().containsKey(toRemove)) if (!npc.minions.contains(toRemove.getObjectUUID()))
return true; 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; return true;
npc.getSiegeMinionMap().remove(toRemove); npc.minions.remove(Integer.valueOf(toRemove.getObjectUUID()));
WorldGrid.RemoveWorldObject(toRemove); WorldGrid.RemoveWorldObject(toRemove);
@@ -199,19 +194,21 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler {
DbManager.removeFromCache(toRemove); DbManager.removeFromCache(toRemove);
if (toRemove.agentType.equals(Enum.AIAgentType.SIEGEENGINE)) {
PlayerCharacter petOwner = (PlayerCharacter) toRemove.guardCaptain; PlayerCharacter trebOwner = (PlayerCharacter) toRemove.guardCaptain;
if (petOwner != null) { if (trebOwner != null) {
petOwner.setPet(null); trebOwner.setPet(null);
toRemove.guardCaptain = null; toRemove.guardCaptain = null;
PetMsg petMsg = new PetMsg(5, null); PetMsg petMsg = new PetMsg(5, null);
Dispatch dispatch = Dispatch.borrow(petOwner, petMsg); Dispatch dispatch = Dispatch.borrow(trebOwner, petMsg);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
}
} }
ManageCityAssetsMsg mca1 = new ManageCityAssetsMsg(player, building); ManageCityAssetsMsg mca1 = new ManageCityAssetsMsg(playerCharacter, building);
mca1.actionType = 3; mca1.actionType = 3;
mca1.setTargetType(building.getObjectType().ordinal()); mca1.setTargetType(building.getObjectType().ordinal());
mca1.setTargetID(building.getObjectUUID()); mca1.setTargetID(building.getObjectUUID());
@@ -221,11 +218,11 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler {
mca1.setAssetName1(building.getName()); mca1.setAssetName1(building.getName());
mca1.setUnknown54(1); mca1.setUnknown54(1);
Dispatch dispatch = Dispatch.borrow(player, mca1); Dispatch dispatch = Dispatch.borrow(playerCharacter, mca1);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
ManageNPCMsg mnm = new ManageNPCMsg(npc); ManageNPCMsg mnm = new ManageNPCMsg(npc);
dispatch = Dispatch.borrow(player, mnm); dispatch = Dispatch.borrow(playerCharacter, mnm);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
//Add Minion //Add Minion
@@ -261,7 +258,7 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler {
break; break;
} }
if (npc.getSiegeMinionMap().size() == maxSlots) if (npc.minions.size() == maxSlots)
return true; return true;
int mobBase = npc.getMobBaseID(); int mobBase = npc.getMobBaseID();
@@ -276,7 +273,7 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler {
if (toCreate == null) if (toCreate == null)
return true; return true;
if (!DbManager.MobQueries.ADD_TO_GUARDS(npc.getObjectUUID(), mobBase, pirateName, npc.getSiegeMinionMap().size() + 1)) if (!DbManager.MobQueries.ADD_GUARD_MINION(npc.getObjectUUID(), pirateName))
return true; return true;
if (toCreate != null) { if (toCreate != null) {
@@ -287,7 +284,7 @@ public class MinionTrainingMsgHandler extends AbstractClientMsgHandler {
ManageNPCMsg mnm = new ManageNPCMsg(npc); ManageNPCMsg mnm = new ManageNPCMsg(npc);
mnm.setMessageType(1); mnm.setMessageType(1);
Dispatch dispatch = Dispatch.borrow(player, mnm); Dispatch dispatch = Dispatch.borrow(playerCharacter, mnm);
DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY);
} catch (Exception e) { } catch (Exception e) {
@@ -9,12 +9,14 @@
package engine.net.client.handlers; package engine.net.client.handlers;
import engine.Enum;
import engine.exception.MsgSendException; import engine.exception.MsgSendException;
import engine.gameManager.BuildingManager;
import engine.gameManager.MovementManager; import engine.gameManager.MovementManager;
import engine.net.client.ClientConnection; import engine.net.client.ClientConnection;
import engine.net.client.msg.ClientNetMsg; import engine.net.client.msg.ClientNetMsg;
import engine.net.client.msg.MoveToPointMsg; import engine.net.client.msg.MoveToPointMsg;
import engine.objects.PlayerCharacter; import engine.objects.*;
public class MoveToPointHandler extends AbstractClientMsgHandler { public class MoveToPointHandler extends AbstractClientMsgHandler {
@@ -26,13 +28,11 @@ public class MoveToPointHandler extends AbstractClientMsgHandler {
protected boolean _handleNetMsg(ClientNetMsg baseMsg, protected boolean _handleNetMsg(ClientNetMsg baseMsg,
ClientConnection origin) throws MsgSendException { ClientConnection origin) throws MsgSendException {
MoveToPointMsg msg = (MoveToPointMsg) baseMsg; MoveToPointMsg msg = (MoveToPointMsg) baseMsg;
PlayerCharacter pc = origin.getPlayerCharacter();
PlayerCharacter pc = (origin != null) ? (origin.getPlayerCharacter()) : null; if(pc == null)
if (pc == null) return true;
return false;
MovementManager.movement(msg, pc); MovementManager.movement(msg, pc);
return true; return true;
} }
} }
@@ -7,7 +7,6 @@ import engine.Enum.ProfitType;
import engine.exception.MsgSendException; import engine.exception.MsgSendException;
import engine.gameManager.BuildingManager; import engine.gameManager.BuildingManager;
import engine.gameManager.DbManager; import engine.gameManager.DbManager;
import engine.gameManager.NPCManager;
import engine.gameManager.SessionManager; import engine.gameManager.SessionManager;
import engine.math.FastMath; import engine.math.FastMath;
import engine.math.Vector3fImmutable; import engine.math.Vector3fImmutable;
@@ -37,7 +36,7 @@ public class OrderNPCMsgHandler extends AbstractClientMsgHandler {
super(OrderNPCMsg.class); 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; PlayerCharacter player;
Contract contract; Contract contract;
@@ -48,33 +47,28 @@ public class OrderNPCMsgHandler extends AbstractClientMsgHandler {
player = SessionManager.getPlayerCharacter(origin); player = SessionManager.getPlayerCharacter(origin);
itemMan = player.getCharItemManager(); itemMan = player.getCharItemManager();
contract = mob.getContract(); contract = hireling.contract;
if (!player.getCharItemManager().hasRoomInventory((short) 1)) { if (!player.getCharItemManager().hasRoomInventory((short) 1)) {
ErrorPopupMsg.sendErrorPopup(player, 21); ErrorPopupMsg.sendErrorPopup(player, 21);
return; return;
} }
if (!building.getHirelings().containsKey(mob)) if (!building.getHirelings().containsKey(hireling))
return; return;
if (!NPCManager.removeMobileFromBuilding(mob, building)) { BuildingManager.removeHireling(building, hireling);
PlaceAssetMsg.sendPlaceAssetError(player.getClientConnection(), 1, "A Serious error has occurred. Please post details for to ensure transaction integrity");
return;
}
building.getHirelings().remove(mob);
itemBase = ItemBase.getItemBase(contract.getContractID()); itemBase = ItemBase.getItemBase(contract.getContractID());
if (itemBase == null) { if (itemBase == null) {
Logger.error("Could not find Contract for npc: " + mob.getObjectUUID()); Logger.error("Could not find Contract for npc: " + hireling.getObjectUUID());
return; return;
} }
boolean itemWorked = false; 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.setNumOfItems(1);
item.containerType = Enum.ItemContainerType.INVENTORY; item.containerType = Enum.ItemContainerType.INVENTORY;
@@ -282,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) { private static boolean AddPatrolPoints(int buildingID, ArrayList<Vector3fImmutable> patrolPoints) {
Building building = BuildingManager.getBuildingFromCache(buildingID); Building building = BuildingManager.getBuildingFromCache(buildingID);
@@ -494,7 +466,7 @@ public class OrderNPCMsgHandler extends AbstractClientMsgHandler {
if (BuildingManager.PlayerCanControlNotOwner(building, player) == false) if (BuildingManager.PlayerCanControlNotOwner(building, player) == false)
return true; return true;
processRedeedNPC(npc, building, origin); processRedeedHireling(npc, building, origin);
return true; return true;
//MB TODO HANDLE all profits. //MB TODO HANDLE all profits.
case 7: case 7:
@@ -562,10 +534,7 @@ public class OrderNPCMsgHandler extends AbstractClientMsgHandler {
if (building.getHirelings().containsKey(mob) == false) if (building.getHirelings().containsKey(mob) == false)
return true; return true;
if (NPCManager.removeMobileFromBuilding(mob, building) == false) { BuildingManager.removeHireling(building, mob);
PlaceAssetMsg.sendPlaceAssetError(player.getClientConnection(), 1, "A Serious error has occurred. Please post details for to ensure transaction integrity");
return true;
}
ManageCityAssetsMsg manageCityAssetsMsg = new ManageCityAssetsMsg(); ManageCityAssetsMsg manageCityAssetsMsg = new ManageCityAssetsMsg();
manageCityAssetsMsg.actionType = SVR_CLOSE_WINDOW; manageCityAssetsMsg.actionType = SVR_CLOSE_WINDOW;
@@ -600,7 +569,7 @@ public class OrderNPCMsgHandler extends AbstractClientMsgHandler {
if (BuildingManager.PlayerCanControlNotOwner(building, player) == false) if (BuildingManager.PlayerCanControlNotOwner(building, player) == false)
return true; return true;
processRedeedNPC(mob, building, origin); processRedeedHireling(mob, building, origin);
return true; return true;
//MB TODO HANDLE all profits. //MB TODO HANDLE all profits.
case 7: case 7:
@@ -745,7 +745,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
} }
Vector3fImmutable plantLoc = new Vector3fImmutable(treeInfo.getLoc().x, Vector3fImmutable plantLoc = new Vector3fImmutable(treeInfo.getLoc().x,
HeightMap.getWorldHeight(treeInfo.getLoc()), 0,
treeInfo.getLoc().z); treeInfo.getLoc().z);
cityObjects = DbManager.CityQueries.CREATE_CITY(playerCharacter.getObjectUUID(), serverZone.getObjectUUID(), cityObjects = DbManager.CityQueries.CREATE_CITY(playerCharacter.getObjectUUID(), serverZone.getObjectUUID(),
@@ -754,6 +754,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
plantLoc.z - serverZone.getAbsZ(), treeInfo.getRot().y, treeInfo.getW(), playerCharacter.getGuild().getName(), LocalDateTime.now()); plantLoc.z - serverZone.getAbsZ(), treeInfo.getRot().y, treeInfo.getW(), playerCharacter.getGuild().getName(), LocalDateTime.now());
// Uh oh! // Uh oh!
if (cityObjects == null || cityObjects.isEmpty()) { if (cityObjects == null || cityObjects.isEmpty()) {
PlaceAssetMsg.sendPlaceAssetError(origin, 1, "A Serious error has occurred. Please post details for to ensure transaction integrity"); PlaceAssetMsg.sendPlaceAssetError(origin, 1, "A Serious error has occurred. Please post details for to ensure transaction integrity");
return false; return false;
@@ -767,7 +768,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
treeObject = (Building) cityObjectMap.get(GameObjectType.Building); treeObject = (Building) cityObjectMap.get(GameObjectType.Building);
treeObject.runAfterLoad(); treeObject.runAfterLoad();
;
cityObject = (City) cityObjectMap.get(GameObjectType.City); cityObject = (City) cityObjectMap.get(GameObjectType.City);
zoneObject = (Zone) cityObjectMap.get(GameObjectType.Zone); zoneObject = (Zone) cityObjectMap.get(GameObjectType.Zone);
@@ -792,10 +793,11 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
ZoneManager.addPlayerCityZone(zoneObject); ZoneManager.addPlayerCityZone(zoneObject);
serverZone.addNode(zoneObject); serverZone.addNode(zoneObject);
zoneObject.generateWorldAltitude(); zoneObject.worldAltitude = ZoneManager.caclulateWorldAltitude(zoneObject);
cityObject.setParent(zoneObject); cityObject.setParent(zoneObject);
cityObject.setObjectTypeMask(MBServerStatics.MASK_CITY); // *** Refactor : should have it already cityObject.setObjectTypeMask(MBServerStatics.MASK_CITY); // *** Refactor : should have it already
//Link the tree of life with the new zone //Link the tree of life with the new zone
treeObject.setObjectTypeMask(MBServerStatics.MASK_BUILDING); treeObject.setObjectTypeMask(MBServerStatics.MASK_BUILDING);
@@ -817,7 +819,6 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
City.lastCityUpdate = System.currentTimeMillis(); City.lastCityUpdate = System.currentTimeMillis();
treeObject.setLoc(treeObject.getLoc()); treeObject.setLoc(treeObject.getLoc());
InterestManager.setObjectDirty(treeObject); InterestManager.setObjectDirty(treeObject);
// WorldGrid.addObject(treeObject, playerCharacter);
serverRealm.addCity(cityObject.getObjectUUID()); serverRealm.addCity(cityObject.getObjectUUID());
playerNation.setCityUUID(cityObject.getObjectUUID()); playerNation.setCityUUID(cityObject.getObjectUUID());
@@ -915,6 +916,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
// Early exit if something went horribly wrong // Early exit if something went horribly wrong
// with locating the current realm and/or zone // with locating the current realm and/or zone
if (serverZone == null) if (serverZone == null)
return false; return false;
@@ -977,7 +979,8 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
City cityObject; City cityObject;
PlacementInfo buildingList; PlacementInfo buildingList;
// Setup working variables we'll need // Setup working variables
buildingList = msg.getFirstPlacementInfo(); buildingList = msg.getFirstPlacementInfo();
serverZone = ZoneManager.findSmallestZone(buildingList.getLoc()); serverZone = ZoneManager.findSmallestZone(buildingList.getLoc());
@@ -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. 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 // Overlap check and wall deed verifications
for (PlacementInfo wall : walls) { for (PlacementInfo wall : walls) {
@@ -1109,7 +1111,6 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
for (Building building : serverZone.zoneBuildingSet) { 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. //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)) { if ((building.getBlueprintUUID() != 0) && (Bounds.collide(wall, building) == true)) {
@@ -1129,12 +1130,14 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
return false; return false;
} }
} }
placementCost = PlaceAssetMsg.getWallCost(wall.getBlueprintUUID()); placementCost = PlaceAssetMsg.getWallCost(wall.getBlueprintUUID());
if (!itemMan.modifyInventoryGold(-placementCost)) { 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."); 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; return false;
} }
// Attempt to place wall piece // Attempt to place wall piece
wallPiece = createStructure(player, wall, serverZone); wallPiece = createStructure(player, wall, serverZone);
@@ -1145,14 +1148,12 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
} }
// walls are auto protected // walls are auto protected
wallPiece.setProtectionState(ProtectionState.PROTECTED); wallPiece.setProtectionState(ProtectionState.PROTECTED);
PlaceAssetMsg.sendPlaceAssetConfirmWall(origin, serverZone); PlaceAssetMsg.sendPlaceAssetConfirmWall(origin, serverZone);
} }
// Deduct gold from character's inventory
return true; return true;
} }
@@ -1172,6 +1173,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
} }
// All siege buildings build in 15 minutes // All siege buildings build in 15 minutes
if ((blueprint.getBuildingGroup().equals(BuildingGroup.SIEGETENT)) if ((blueprint.getBuildingGroup().equals(BuildingGroup.SIEGETENT))
|| (blueprint.getBuildingGroup().equals(BuildingGroup.BULWARK))) || (blueprint.getBuildingGroup().equals(BuildingGroup.BULWARK)))
completionDate = DateTime.now().plusMinutes(15); completionDate = DateTime.now().plusMinutes(15);
@@ -1191,6 +1193,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
completionDate, blueprint.getMeshForRank(0), vendorRotation, buildingRotation); completionDate, blueprint.getMeshForRank(0), vendorRotation, buildingRotation);
// Make sure we have a valid mesh // Make sure we have a valid mesh
if (newMesh == null) { if (newMesh == null) {
Logger.error("CreateStructure: DB returned null object."); Logger.error("CreateStructure: DB returned null object.");
return null; return null;
@@ -1362,15 +1365,16 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler {
newMesh = (Building) ago; newMesh = (Building) ago;
newMesh.setObjectTypeMask(MBServerStatics.MASK_BUILDING); newMesh.setObjectTypeMask(MBServerStatics.MASK_BUILDING);
MaintenanceManager.setMaintDateTime(newMesh, LocalDateTime.now().plusDays(7)); MaintenanceManager.setMaintDateTime(newMesh, LocalDateTime.now().plusDays(7));
// WorldGrid.addObject(newMesh, player);
newMesh.setLoc(newMesh.getLoc()); newMesh.setLoc(newMesh.getLoc());
InterestManager.setObjectDirty(newMesh); InterestManager.setObjectDirty(newMesh);
newMesh.runAfterLoad(); newMesh.runAfterLoad();
} else if (ago.getObjectType() == GameObjectType.Warehouse) { } else if (ago.getObjectType() == GameObjectType.Warehouse) {
Warehouse warehouse = (Warehouse) ago; Warehouse warehouse = (Warehouse) ago;
City city = City.getCity(currentZone.getPlayerCityUUID()); City city = City.getCity(currentZone.getPlayerCityUUID());
if (city == null) if (city == null)
return true; return true;
city.setWarehouseBuildingID(newMesh.getObjectUUID()); city.setWarehouseBuildingID(newMesh.getObjectUUID());
Warehouse.warehouseByBuildingUUID.put(newMesh.getObjectUUID(), warehouse); Warehouse.warehouseByBuildingUUID.put(newMesh.getObjectUUID(), warehouse);
} }
@@ -110,7 +110,6 @@ public class RequestEnterWorldHandler extends AbstractClientMsgHandler {
player.stopMovement(player.getBindLoc()); player.stopMovement(player.getBindLoc());
player.setSafeMode(); player.setSafeMode();
player.updateLocation(); player.updateLocation();
player.setRegion(AbstractWorldObject.GetRegionByWorldObject(player));
} }
player.setTimeStamp("logout", 0); player.setTimeStamp("logout", 0);
+15 -12
View File
@@ -27,7 +27,6 @@ import org.pmw.tinylog.Logger;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
@@ -96,7 +95,7 @@ public class ManageNPCMsg extends ClientNetMsg {
writer.putString("A weapon suited to laying siege"); 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); writer.putInt(1);
@@ -106,7 +105,7 @@ public class ManageNPCMsg extends ClientNetMsg {
writer.putInt(minion); writer.putInt(minion);
writer.putInt(1); writer.putInt(1);
writer.putInt(minion); writer.putInt(minion);
writer.putInt(1); writer.putInt(captain.getRank());//minion rank
writer.put((byte) 0); writer.put((byte) 0);
writer.putInt(600); //roll time writer.putInt(600); //roll time
@@ -343,14 +342,17 @@ public class ManageNPCMsg extends ClientNetMsg {
writer.putInt(0); //runemaster list writer.putInt(0); //runemaster list
//artillery captain list //artillery captain list
ConcurrentHashMap<Mob, Integer> siegeMinions = npc.siegeMinionMap;
writer.putInt(1 + siegeMinions.size()); writer.putInt(1 + npc.minions.size());
serializeBulwarkList(writer, 1); //Trebuchet serializeBulwarkList(writer, 1); //Trebuchet
//serializeBulwarkList(writer, 2); //Ballista //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(); this.unknown83 = mob.getObjectUUID();
writer.putInt(2); writer.putInt(2);
writer.putInt(mob.getObjectType().ordinal()); writer.putInt(mob.getObjectType().ordinal());
@@ -666,14 +668,15 @@ public class ManageNPCMsg extends ClientNetMsg {
writer.putInt(0); //runemaster list writer.putInt(0); //runemaster list
//artillery captain list //artillery captain list
ConcurrentHashMap<Mob, Integer> siegeMinions = mobA.getSiegeMinionMap();
writer.putInt(siegeMinions.size() + 1); writer.putInt(mobA.minions.size() + 1);
serializeGuardList(writer, mobA.getContract().getContractID()); //Guard
if (siegeMinions != null && siegeMinions.size() > 0) serializeGuardList(writer, mobA.getContract().getContractID(), mobA); //Guard
for (Mob mob : siegeMinions.keySet()) { if (mobA.minions != null && mobA.minions.size() > 0)
for (Integer minionUUID : mobA.minions) {
Mob mob = Mob.getMob(minionUUID);
this.unknown83 = mob.getObjectUUID(); this.unknown83 = mob.getObjectUUID();
writer.putInt(2); writer.putInt(2);
writer.putInt(mob.getObjectType().ordinal()); writer.putInt(mob.getObjectType().ordinal());
+56 -55
View File
@@ -10,6 +10,7 @@
package engine.net.client.msg; package engine.net.client.msg;
import engine.Enum.GameObjectType; import engine.Enum.GameObjectType;
import engine.gameManager.BuildingManager;
import engine.gameManager.ZoneManager; import engine.gameManager.ZoneManager;
import engine.math.Vector3fImmutable; import engine.math.Vector3fImmutable;
import engine.net.AbstractConnection; import engine.net.AbstractConnection;
@@ -21,19 +22,19 @@ import engine.objects.Building;
public class MoveToPointMsg extends ClientNetMsg { public class MoveToPointMsg extends ClientNetMsg {
private int sourceType; private int sourceType; //ordinal of the character type that sent this message 54=PlayerCharacter
private int sourceID; private int sourceID; // uuid of the source character of this message
private float startLat; private float startLat; //start loc of move message (offset if inside a building not world loc)
private float startLon; private float startLon; //start loc of move message (offset if inside a building not world loc)
private float startAlt; private float startAlt; //start loc of move message (offset if inside a building not world loc)
private float endLat; private float endLat; //end loc of move message (offset if inside a building not world loc)
private float endLon; private float endLon; //end loc of move message (offset if inside a building not world loc)
private float endAlt; private float endAlt; //end loc of move message (offset if inside a building not world loc)
private int targetType; private int startLocType; // enum ordinal of the object player is inside 0=nothing 8=building
private int targetID; private int inBuildingUUID; // uuid of the building character is currently inside
private int inBuilding; // 0=true, -1=false 0/1/2 = floor you are on private int inBuilding; // is inside a building 0=true -1=false
private int unknown01; private int inBuildingFloor; // floor of building character is currently in -1=not inside building 0/1/2/3 = floor number
private byte unknown02; private byte initiatedByAttack; // move message sent as a result of move to target to attack 0=false 1=true
private byte unknown03; private byte unknown03;
/** /**
@@ -54,11 +55,11 @@ public class MoveToPointMsg extends ClientNetMsg {
this.endLat = msg.endLat; this.endLat = msg.endLat;
this.endLon = msg.endLon; this.endLon = msg.endLon;
this.endAlt = msg.endAlt; this.endAlt = msg.endAlt;
this.targetType = msg.targetType; this.startLocType = msg.startLocType;
this.targetID = msg.targetID; this.inBuildingUUID = msg.inBuildingUUID;
this.inBuilding = msg.inBuilding; this.inBuilding = msg.inBuilding;
this.unknown01 = msg.unknown01; this.inBuildingFloor = msg.inBuildingFloor;
this.unknown02 = msg.unknown02; this.initiatedByAttack = msg.initiatedByAttack;
this.unknown03 = msg.unknown03; this.unknown03 = msg.unknown03;
} }
@@ -73,11 +74,11 @@ public class MoveToPointMsg extends ClientNetMsg {
this.endLat = building.getLoc().x; this.endLat = building.getLoc().x;
this.endLon = building.getLoc().z; this.endLon = building.getLoc().z;
this.endAlt = building.getLoc().y; this.endAlt = building.getLoc().y;
this.targetType = 0; this.startLocType = 0;
this.targetID = 0; this.inBuildingUUID = 0;
this.inBuilding = -1; this.inBuilding = -1;
this.unknown01 = -1; this.inBuildingFloor = -1;
this.unknown02 = 0; this.initiatedByAttack = 0;
this.unknown03 = 0; this.unknown03 = 0;
} }
@@ -108,11 +109,11 @@ public class MoveToPointMsg extends ClientNetMsg {
writer.putFloat(this.endAlt); writer.putFloat(this.endAlt);
writer.putFloat(this.endLon); writer.putFloat(this.endLon);
writer.putInt(this.targetType); writer.putInt(this.startLocType);
writer.putInt(this.targetID); writer.putInt(this.inBuildingUUID);
writer.putInt(this.inBuilding); writer.putInt(this.inBuilding);
writer.putInt(this.unknown01); writer.putInt(this.inBuildingFloor);
writer.put((byte) 0); writer.put((byte) 0);
writer.put((byte) 0); writer.put((byte) 0);
@@ -135,13 +136,13 @@ public class MoveToPointMsg extends ClientNetMsg {
this.endAlt = reader.getFloat(); this.endAlt = reader.getFloat();
this.endLon = reader.getFloat(); this.endLon = reader.getFloat();
this.targetType = reader.getInt(); this.startLocType = reader.getInt();
this.targetID = reader.getInt(); this.inBuildingUUID = reader.getInt();
this.inBuilding = 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(); this.unknown03 = reader.get();
} }
@@ -209,20 +210,20 @@ public class MoveToPointMsg extends ClientNetMsg {
this.endAlt = value; this.endAlt = value;
} }
public int getTargetType() { public int getStartLocType() {
return this.targetType; return this.startLocType;
} }
public void setTargetType(int value) { public void setStartLocType(int value) {
this.targetType = value; this.startLocType = value;
} }
public int getTargetID() { public int getInBuildingUUID() {
return this.targetID; return this.inBuildingUUID;
} }
public void setTargetID(int value) { public void setInBuildingUUID(int value) {
this.targetID = value; this.inBuildingUUID = value;
} }
public int getInBuilding() { public int getInBuilding() {
@@ -233,12 +234,8 @@ public class MoveToPointMsg extends ClientNetMsg {
this.inBuilding = value; this.inBuilding = value;
} }
public int getUnknown01() { public void setInBuildingFloor(int value) {
return this.unknown01; this.inBuildingFloor = value;
}
public void setUnknown01(int value) {
this.unknown01 = value;
} }
public void setStartCoord(Vector3fImmutable value) { public void setStartCoord(Vector3fImmutable value) {
@@ -254,8 +251,8 @@ public class MoveToPointMsg extends ClientNetMsg {
} }
public void clearTarget() { public void clearTarget() {
this.targetType = 0; this.startLocType = 0;
this.targetID = 0; this.inBuildingUUID = 0;
} }
public void setPlayer(AbstractCharacter ac) { public void setPlayer(AbstractCharacter ac) {
@@ -263,10 +260,10 @@ public class MoveToPointMsg extends ClientNetMsg {
this.sourceID = ac.getObjectUUID(); this.sourceID = ac.getObjectUUID();
this.setStartCoord(ac.getLoc()); this.setStartCoord(ac.getLoc());
this.setEndCoord(ac.getEndLoc()); this.setEndCoord(ac.getEndLoc());
this.targetType = 0; this.startLocType = 0;
this.targetID = 0; this.inBuildingUUID = 0;
this.inBuilding = ac.getInBuilding(); this.inBuilding = ac.getInBuilding();
this.unknown01 = ac.getInFloorID(); this.inBuildingFloor = ac.getInFloorID();
} }
@@ -274,10 +271,10 @@ public class MoveToPointMsg extends ClientNetMsg {
if (target == null) { if (target == null) {
this.setStartCoord(ac.getLoc()); this.setStartCoord(ac.getLoc());
this.setEndCoord(ac.getEndLoc()); this.setEndCoord(ac.getEndLoc());
this.targetType = 0; this.startLocType = 0;
this.targetID = 0; this.inBuildingUUID = 0;
this.inBuilding = -1; this.inBuilding = -1;
this.unknown01 = -1; this.inBuildingFloor = -1;
} else { } else {
Vector3fImmutable convertLocStart = ZoneManager.convertWorldToLocal(target, ac.getLoc()); Vector3fImmutable convertLocStart = ZoneManager.convertWorldToLocal(target, ac.getLoc());
Vector3fImmutable convertLocEnd = convertLocStart; Vector3fImmutable convertLocEnd = convertLocStart;
@@ -286,10 +283,10 @@ public class MoveToPointMsg extends ClientNetMsg {
this.setStartCoord(convertLocStart); this.setStartCoord(convertLocStart);
this.setEndCoord(convertLocEnd); this.setEndCoord(convertLocEnd);
this.targetType = GameObjectType.Building.ordinal(); this.startLocType = GameObjectType.Building.ordinal();
this.targetID = target.getObjectUUID(); this.inBuildingUUID = target.getObjectUUID();
this.inBuilding = ac.getInBuilding(); this.inBuilding = ac.getInBuilding();
this.unknown01 = ac.getInFloorID(); this.inBuildingFloor = ac.getInFloorID();
} }
} }
@@ -298,7 +295,11 @@ public class MoveToPointMsg extends ClientNetMsg {
return unknown03; return unknown03;
} }
public int getUnknown02() { public int getInitiatedFromAttack() {
return unknown02; return initiatedByAttack;
}
public int getInBuildingFloor() {
return this.inBuildingFloor;
} }
} }
+51 -23
View File
@@ -11,13 +11,11 @@ package engine.objects;
import engine.Enum; import engine.Enum;
import engine.Enum.*; import engine.Enum.*;
import engine.InterestManagement.HeightMap;
import engine.InterestManagement.InterestManager; import engine.InterestManagement.InterestManager;
import engine.InterestManagement.WorldGrid; import engine.InterestManagement.WorldGrid;
import engine.exception.SerializationException; import engine.exception.SerializationException;
import engine.gameManager.CombatManager; import engine.gameManager.*;
import engine.gameManager.ConfigManager;
import engine.gameManager.MovementManager;
import engine.gameManager.PowersManager;
import engine.job.AbstractJob; import engine.job.AbstractJob;
import engine.job.JobContainer; import engine.job.JobContainer;
import engine.job.JobScheduler; import engine.job.JobScheduler;
@@ -39,6 +37,7 @@ import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock;
@@ -71,7 +70,7 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
public Guild guild; public Guild guild;
protected byte runningTrains; protected byte runningTrains;
protected ConcurrentHashMap<Integer, CharacterPower> powers; protected ConcurrentHashMap<Integer, CharacterPower> powers;
protected ConcurrentHashMap<String, CharacterSkill> skills; public ConcurrentHashMap<String, CharacterSkill> skills;
// Variables NOT to be stored in db // Variables NOT to be stored in db
protected boolean sit = false; protected boolean sit = false;
protected boolean walkMode; protected boolean walkMode;
@@ -88,20 +87,20 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
protected AtomicFloat mana = new AtomicFloat(); protected AtomicFloat mana = new AtomicFloat();
protected float manaMax; // Health/Mana/Stamina protected float manaMax; // Health/Mana/Stamina
protected AtomicBoolean isAlive = new AtomicBoolean(true); protected AtomicBoolean isAlive = new AtomicBoolean(true);
protected Resists resists = new Resists("Genric"); public Resists resists = new Resists("Genric");
protected ConcurrentHashMap<String, JobContainer> timers; protected ConcurrentHashMap<String, JobContainer> timers;
protected ConcurrentHashMap<String, Long> timestamps; protected ConcurrentHashMap<String, Long> timestamps;
protected int atrHandOne; public int atrHandOne;
protected int atrHandTwo; public int atrHandTwo;
protected int minDamageHandOne; public int minDamageHandOne;
protected int maxDamageHandOne; public int maxDamageHandOne;
protected int minDamageHandTwo; public int minDamageHandTwo;
protected int maxDamageHandTwo; public int maxDamageHandTwo;
protected float rangeHandOne; public float rangeHandOne;
protected float rangeHandTwo; public float rangeHandTwo;
protected float speedHandOne; public float speedHandOne;
protected float speedHandTwo; public float speedHandTwo;
protected int defenseRating; public int defenseRating;
protected boolean isActive; // <-Do not use this for deleting character! 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 float altitude = 0; // 0=on terrain, 1=tier 1, 2=tier 2, etc.
protected ConcurrentHashMap<Integer, JobContainer> recycleTimers; protected ConcurrentHashMap<Integer, JobContainer> recycleTimers;
@@ -119,7 +118,11 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
private long takeOffTime = 0; private long takeOffTime = 0;
private long lastHateUpdate = 0; private long lastHateUpdate = 0;
private byte aoecntr = 0; private byte aoecntr = 0;
public final ConcurrentHashMap<Mob, Integer> siegeMinionMap = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
public int hidden = 0; // current rank of hide/sneak/invis
public CopyOnWriteArrayList<Integer> minions = new CopyOnWriteArrayList();
public ArrayList<CharacterRune> runes;
public AbstractCharacter() { public AbstractCharacter() {
super(); super();
@@ -512,10 +515,9 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
} }
public static void teleport(AbstractCharacter worldObject, final Vector3fImmutable targetLoc) { public static void teleport(AbstractCharacter worldObject, final Vector3fImmutable targetLoc) {
Regions targetRegion = Regions.GetRegionForTeleport(targetLoc);
worldObject.locationLock.writeLock().lock(); worldObject.locationLock.writeLock().lock();
try { try {
MovementManager.translocate(worldObject, targetLoc, targetRegion); MovementManager.translocate(worldObject, targetLoc);
if (worldObject.getObjectType().equals(GameObjectType.PlayerCharacter)) if (worldObject.getObjectType().equals(GameObjectType.PlayerCharacter))
InterestManager.INTERESTMANAGER.HandleLoadForTeleport((PlayerCharacter) worldObject); InterestManager.INTERESTMANAGER.HandleLoadForTeleport((PlayerCharacter) worldObject);
} catch (Exception e) { } catch (Exception e) {
@@ -983,8 +985,14 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
@Override @Override
public final void setLoc(final Vector3fImmutable value) { 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 super.setLoc(value); // set the location in the world
this.resetLastSetLocUpdate(); this.resetLastSetLocUpdate();
} }
public Vector3fImmutable getMovementLoc() { public Vector3fImmutable getMovementLoc() {
@@ -1104,6 +1112,7 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
} }
public final void setCombatTarget(final AbstractWorldObject value) { public final void setCombatTarget(final AbstractWorldObject value) {
if(this.getObjectTypeMask() == 2050) {//MOB? if(this.getObjectTypeMask() == 2050) {//MOB?
if (value == null) { if (value == null) {
if (this.isCombat()) { if (this.isCombat()) {
@@ -1121,7 +1130,9 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
} }
} }
} }
this.combatTarget = value; this.combatTarget = value;
} }
public final ConcurrentHashMap<String, JobContainer> getTimers() { public final ConcurrentHashMap<String, JobContainer> getTimers() {
@@ -1238,11 +1249,29 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
CombatManager.handleRetaliate(this, attacker); 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; return newHealth - oldHealth;
} finally { } finally {
this.healthLock.writeLock().unlock(); this.healthLock.writeLock().unlock();
} }
} catch (InterruptedException e) { } catch (InterruptedException e) {
// TODO Auto-generated catch block // TODO Auto-generated catch block
e.printStackTrace(); e.printStackTrace();
@@ -1428,10 +1457,9 @@ public abstract class AbstractCharacter extends AbstractWorldObject {
} }
public void teleport(final Vector3fImmutable targetLoc) { public void teleport(final Vector3fImmutable targetLoc) {
Regions targetRegion = Regions.GetRegionForTeleport(targetLoc);
locationLock.writeLock().lock(); locationLock.writeLock().lock();
try { try {
MovementManager.translocate(this, targetLoc, targetRegion); MovementManager.translocate(this, targetLoc);
MovementManager.sendRWSSMsg(this); MovementManager.sendRWSSMsg(this);
} catch (Exception e) { } catch (Exception e) {
Logger.error(e); Logger.error(e);
@@ -32,7 +32,7 @@ public abstract class AbstractIntelligenceAgent extends AbstractCharacter {
protected Vector3fImmutable lastBindLoc; protected Vector3fImmutable lastBindLoc;
public boolean assist = false; public boolean assist = false;
public Enum.AIAgentType agentType = Enum.AIAgentType.MOBILE; public Enum.AIAgentType agentType = Enum.AIAgentType.MOBILE;
public boolean isPlayerGuard = false;
public AbstractCharacter guardCaptain; public AbstractCharacter guardCaptain;
public EnumBitSet<Enum.MonsterType> notEnemy = EnumBitSet.noneOf(Enum.MonsterType.class); public EnumBitSet<Enum.MonsterType> notEnemy = EnumBitSet.noneOf(Enum.MonsterType.class);
public EnumBitSet<Enum.MonsterType> enemy = EnumBitSet.noneOf(Enum.MonsterType.class); public EnumBitSet<Enum.MonsterType> enemy = EnumBitSet.noneOf(Enum.MonsterType.class);
@@ -163,7 +163,9 @@ public abstract class AbstractIntelligenceAgent extends AbstractCharacter {
this.setCombatTarget(null); this.setCombatTarget(null);
} }
//clear owner // clear owner and set not alive
this.isAlive.set(false);
PlayerCharacter owner = (PlayerCharacter) this.guardCaptain; PlayerCharacter owner = (PlayerCharacter) this.guardCaptain;
@@ -181,7 +183,7 @@ public abstract class AbstractIntelligenceAgent extends AbstractCharacter {
owner.setPet(null); owner.setPet(null);
if (this.getObjectType().equals(GameObjectType.Mob)) if (this.getObjectType().equals(GameObjectType.Mob))
((Mob) this).guardCaptain = null; this.guardCaptain = null;
} }
+7 -4
View File
@@ -502,7 +502,13 @@ public abstract class AbstractWorldObject extends AbstractGameObject {
return; return;
this.lastLoc = new Vector3fImmutable(this.loc); this.lastLoc = new Vector3fImmutable(this.loc);
this.loc = 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. //lets not add mob to world grid if he is currently despawned.
if (this.getObjectType().equals(GameObjectType.Mob) && ((Mob) this).despawned) if (this.getObjectType().equals(GameObjectType.Mob) && ((Mob) this).despawned)
@@ -610,9 +616,6 @@ public abstract class AbstractWorldObject extends AbstractGameObject {
this.movingUp = movingUp; this.movingUp = movingUp;
} }
public void setRegion(Regions region) {
this.region = region;
}
//used for interestmanager loading and unloading objects to client. //used for interestmanager loading and unloading objects to client.
// if not in grid, unload from player. // if not in grid, unload from player.
+12
View File
@@ -537,6 +537,18 @@ public class Building extends AbstractWorldObject {
if (value < 0) if (value < 0)
Mine.SendMineAttackMessage(this); 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; return newHealth - oldHealth;
+66 -60
View File
@@ -223,7 +223,7 @@ public class CharacterSkill extends AbstractGameObject {
this.numTrains.set(0); this.numTrains.set(0);
this.ownerUID = pc.getObjectUUID(); this.ownerUID = pc.getObjectUUID();
calculateBaseAmount(); calculateBaseAmount();
calculateModifiedAmount(); calculateModifiedAmount(false);
this.skillType = CharacterSkills.GetCharacterSkillByToken(this.skillsBase.getToken()); this.skillType = CharacterSkills.GetCharacterSkillByToken(this.skillsBase.getToken());
} }
@@ -238,7 +238,7 @@ public class CharacterSkill extends AbstractGameObject {
this.ownerUID = pc.getObjectUUID(); this.ownerUID = pc.getObjectUUID();
this.trained = true; this.trained = true;
calculateBaseAmount(); calculateBaseAmount();
calculateModifiedAmount(); calculateModifiedAmount(false);
this.skillType = CharacterSkills.GetCharacterSkillByToken(this.skillsBase.getToken()); this.skillType = CharacterSkills.GetCharacterSkillByToken(this.skillsBase.getToken());
} }
@@ -254,7 +254,7 @@ public class CharacterSkill extends AbstractGameObject {
this.numTrains.set(rs.getShort("trains")); this.numTrains.set(rs.getShort("trains"));
this.ownerUID = pc.getObjectUUID(); this.ownerUID = pc.getObjectUUID();
calculateBaseAmount(); calculateBaseAmount();
calculateModifiedAmount(); calculateModifiedAmount(false);
this.skillType = CharacterSkills.GetCharacterSkillByToken(this.skillsBase.getToken()); this.skillType = CharacterSkills.GetCharacterSkillByToken(this.skillsBase.getToken());
} }
@@ -264,8 +264,9 @@ public class CharacterSkill extends AbstractGameObject {
this.numTrains.set(trains); this.numTrains.set(trains);
this.ownerUID = mob.getObjectUUID(); this.ownerUID = mob.getObjectUUID();
this.isMobOwner = true; this.isMobOwner = true;
calculateMobBaseAmount(); boolean isGuard = mob.agentType.equals(Enum.AIAgentType.GUARDCAPTAIN) || mob.agentType.equals(Enum.AIAgentType.GUARDMINION);
calculateModifiedAmount(); calculateMobBaseAmount(isGuard);
calculateModifiedAmount(isGuard);
this.skillType = CharacterSkills.GetCharacterSkillByToken(this.skillsBase.getToken()); this.skillType = CharacterSkills.GetCharacterSkillByToken(this.skillsBase.getToken());
} }
@@ -277,7 +278,7 @@ public class CharacterSkill extends AbstractGameObject {
this.ownerUID = rs.getInt("CharacterID"); this.ownerUID = rs.getInt("CharacterID");
// this.owner = DbManager.PlayerCharacterQueries.GET_PLAYER_CHARACTER(rs.getInt("CharacterID")); // this.owner = DbManager.PlayerCharacterQueries.GET_PLAYER_CHARACTER(rs.getInt("CharacterID"));
calculateBaseAmount(); calculateBaseAmount();
calculateModifiedAmount(); calculateModifiedAmount(false);
this.skillType = CharacterSkills.GetCharacterSkillByToken(this.skillsBase.getToken()); this.skillType = CharacterSkills.GetCharacterSkillByToken(this.skillsBase.getToken());
} }
@@ -370,7 +371,7 @@ public class CharacterSkill extends AbstractGameObject {
String name = it.next(); String name = it.next();
CharacterSkill cs = skills.get(name); CharacterSkill cs = skills.get(name);
if (cs != null) if (cs != null)
cs.calculateModifiedAmount(); cs.calculateModifiedAmount(false);
} }
@@ -756,7 +757,7 @@ public class CharacterSkill extends AbstractGameObject {
//recalculate this skill //recalculate this skill
calculateBaseAmount(); calculateBaseAmount();
calculateModifiedAmount(); calculateModifiedAmount(false);
//see if any new skills or powers granted //see if any new skills or powers granted
pc.calculateSkills(); pc.calculateSkills();
@@ -848,7 +849,7 @@ public class CharacterSkill extends AbstractGameObject {
if (recalculate) { if (recalculate) {
//recalculate this skill //recalculate this skill
calculateBaseAmount(); calculateBaseAmount();
calculateModifiedAmount(); calculateModifiedAmount(false);
//see if any skills or powers removed //see if any skills or powers removed
pc.calculateSkills(); pc.calculateSkills();
@@ -887,7 +888,7 @@ public class CharacterSkill extends AbstractGameObject {
if (recalculate) { if (recalculate) {
//recalculate this skill //recalculate this skill
calculateBaseAmount(); calculateBaseAmount();
calculateModifiedAmount(); calculateModifiedAmount(false);
//see if any skills or powers removed //see if any skills or powers removed
pc.calculateSkills(); pc.calculateSkills();
@@ -1016,33 +1017,34 @@ public class CharacterSkill extends AbstractGameObject {
this.modifiedAmountBeforeMods = Math.round(this.baseAmountBeforeMods + calculateAmountAfterTrains()); this.modifiedAmountBeforeMods = Math.round(this.baseAmountBeforeMods + calculateAmountAfterTrains());
} }
public void calculateMobBaseAmount() { public void calculateMobBaseAmount(boolean isGuard) {
if (CharacterSkill.GetOwner(this) == null) { if(!isGuard) {
Logger.error("owner not found for owner uuid : " + this.ownerUID); if (CharacterSkill.GetOwner(this) == null) {
this.baseAmount = 1; Logger.error("owner not found for owner uuid : " + this.ownerUID);
this.modifiedAmount = 1; this.baseAmount = 1;
return; this.modifiedAmount = 1;
} return;
}
if (this.skillsBase == null) { if (this.skillsBase == null) {
Logger.error("SkillsBase not found for skill " + this.getObjectUUID()); Logger.error("SkillsBase not found for skill " + this.getObjectUUID());
this.baseAmount = 1; this.baseAmount = 1;
this.modifiedAmount = 1; this.modifiedAmount = 1;
return; return;
}
} }
//Get any rune bonus //Get any rune bonus
float bonus = 0f; float bonus = 0f;
//TODO SKILLS RUNES //TODO SKILLS RUNES
if (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 base = 7f;
float statMod = 0.5f; 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
if (this.skillsBase.getStrMod() > 0) if (this.skillsBase.getStrMod() > 0)
statMod += (float) this.skillsBase.getStrMod() * (float) ((Mob) CharacterSkill.GetOwner(this)).getMobBase().getMobBaseStats().getBaseStr() / 100f; statMod += (float) this.skillsBase.getStrMod() * (float) ((Mob) CharacterSkill.GetOwner(this)).getMobBase().getMobBaseStats().getBaseStr() / 100f;
if (this.skillsBase.getDexMod() > 0) if (this.skillsBase.getDexMod() > 0)
@@ -1057,6 +1059,7 @@ public class CharacterSkill extends AbstractGameObject {
statMod = 1f; statMod = 1f;
else if (statMod > 600) else if (statMod > 600)
statMod = 600f; statMod = 600f;
}
base += CharacterSkill.baseSkillValues[(int) statMod]; base += CharacterSkill.baseSkillValues[(int) statMod];
if (base + bonus < 1f) if (base + bonus < 1f)
@@ -1066,45 +1069,48 @@ public class CharacterSkill extends AbstractGameObject {
this.modifiedAmountBeforeMods = (int) (this.baseAmountBeforeMods + calculateAmountAfterTrains()); this.modifiedAmountBeforeMods = (int) (this.baseAmountBeforeMods + calculateAmountAfterTrains());
} }
public void calculateModifiedAmount() { public void calculateModifiedAmount(boolean isGuard) {
if (CharacterSkill.GetOwner(this) == null || this.skillsBase == null) { if(!isGuard) {
Logger.error("owner or SkillsBase not found for skill " + this.getObjectUUID()); if (CharacterSkill.GetOwner(this) == null || this.skillsBase == null) {
this.baseAmount = 1; Logger.error("owner or SkillsBase not found for skill " + this.getObjectUUID());
this.modifiedAmount = 1; this.baseAmount = 1;
return; this.modifiedAmount = 1;
return;
}
} }
//Get any rune bonus //Get any rune bonus
float bonus = 0f; float bonus = 0f;
if (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 base = 7f;
float statMod = 0.5f; float statMod = 0.5f;
if (this.skillsBase.getStrMod() > 0) if (CharacterSkill.GetOwner(this) != null && CharacterSkill.GetOwner(this).getBonuses() != null) {
statMod += (float) this.skillsBase.getStrMod() * (float) CharacterSkill.GetOwner(this).getStatStrCurrent() / 100f; //Get bonuses from runes
if (this.skillsBase.getDexMod() > 0) bonus = CharacterSkill.GetOwner(this).getBonuses().getSkillBonus(this.skillsBase.sourceType);
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; //Get Base skill for modified stats
if (this.skillsBase.getIntMod() > 0) //TODO this fomula needs verified
statMod += (float) this.skillsBase.getIntMod() * (float) CharacterSkill.GetOwner(this).getStatIntCurrent() / 100f;
if (this.skillsBase.getSpiMod() > 0) if (this.skillsBase.getStrMod() > 0)
statMod += (float) this.skillsBase.getSpiMod() * (float) CharacterSkill.GetOwner(this).getStatSpiCurrent() / 100f; statMod += (float) this.skillsBase.getStrMod() * (float) CharacterSkill.GetOwner(this).getStatStrCurrent() / 100f;
if (statMod < 1) if (this.skillsBase.getDexMod() > 0)
statMod = 1f; statMod += (float) this.skillsBase.getDexMod() * (float) CharacterSkill.GetOwner(this).getStatDexCurrent() / 100f;
else if (statMod > 600) if (this.skillsBase.getConMod() > 0)
statMod = 600f; 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]; base += CharacterSkill.baseSkillValues[(int) statMod];
SourceType sourceType = SourceType.GetSourceType(this.skillsBase.getNameNoSpace()); SourceType sourceType = SourceType.GetSourceType(this.skillsBase.getNameNoSpace());
//Get any rune, effect and item bonus //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 //add bonuses from effects/items and runes
base += bonus + CharacterSkill.GetOwner(this).getBonuses().getFloat(ModType.Skill, sourceType); base += bonus + CharacterSkill.GetOwner(this).getBonuses().getFloat(ModType.Skill, sourceType);
} }
@@ -1116,7 +1122,7 @@ public class CharacterSkill extends AbstractGameObject {
float modAmount = this.baseAmount + calculateAmountAfterTrains(); 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 //Multiply any percent bonuses
modAmount *= (1 + CharacterSkill.GetOwner(this).getBonuses().getFloatPercentAll(ModType.Skill, sourceType)); modAmount *= (1 + CharacterSkill.GetOwner(this).getBonuses().getFloatPercentAll(ModType.Skill, sourceType));
} }
+58 -137
View File
@@ -66,9 +66,6 @@ public class City extends AbstractWorldObject {
private int realmID; private int realmID;
private int radiusType; private int radiusType;
private float bindRadius; private float bindRadius;
private float statLat;
private float statAlt;
private float statLon;
private float bindX; private float bindX;
private float bindZ; private float bindZ;
private byte isNpc; //aka Safehold private byte isNpc; //aka Safehold
@@ -77,7 +74,7 @@ public class City extends AbstractWorldObject {
private boolean forceRename = false; private boolean forceRename = false;
private boolean noTeleport = false; //used by npc cities private boolean noTeleport = false; //used by npc cities
private boolean noRepledge = 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 int treeOfLifeID;
private Vector3fImmutable location = Vector3fImmutable.ZERO; private Vector3fImmutable location = Vector3fImmutable.ZERO;
@@ -113,10 +110,7 @@ public class City extends AbstractWorldObject {
if (establishedTimeStamp != null) if (establishedTimeStamp != null)
this.established = java.time.LocalDateTime.ofInstant(establishedTimeStamp.toInstant(), ZoneId.systemDefault()); this.established = java.time.LocalDateTime.ofInstant(establishedTimeStamp.toInstant(), ZoneId.systemDefault());
this.location = new Vector3fImmutable(rs.getFloat("xCoord"), rs.getFloat("yCoord"), rs.getFloat("zCoord")); this.location = Vector3fImmutable.ZERO;
this.statLat = rs.getFloat("xCoord");
this.statAlt = rs.getFloat("yCoord");
this.statLon = rs.getFloat("zCoord");
java.sql.Timestamp realmTaxTimeStamp = rs.getTimestamp("realmTaxDate"); java.sql.Timestamp realmTaxTimeStamp = rs.getTimestamp("realmTaxDate");
@@ -159,11 +153,6 @@ public class City extends AbstractWorldObject {
this.motto = guild.getMotto(); this.motto = guild.getMotto();
} }
//Disabled till i finish.
// this.reverseKOS = rs.getInt("kos") == 1;
Zone zone = ZoneManager.getZoneByUUID(rs.getInt("parent")); Zone zone = ZoneManager.getZoneByUUID(rs.getInt("parent"));
if (zone != null) if (zone != null)
@@ -171,18 +160,12 @@ public class City extends AbstractWorldObject {
//npc cities without heightmaps except swampstone are specials. //npc cities without heightmaps except swampstone are specials.
this.realmID = rs.getInt("realmID"); this.realmID = rs.getInt("realmID");
} catch (Exception e) { } catch (Exception e) {
Logger.error(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 {
Logger.error("NULL TOL FOR " + city.cityName); Logger.error("NULL TOL FOR " + city.cityName);
} }
// Assign city owner // Assign city owner
if (city.getTOL() != null) if (city.getTOL() != null)
@@ -226,7 +208,8 @@ public class City extends AbstractWorldObject {
rulingNation = rulingGuild.getNation(); rulingNation = rulingGuild.getNation();
// Begin Serialzing soverign guild data // Begin Serializing sovereign guild data
writer.putInt(city.getObjectType().ordinal()); writer.putInt(city.getObjectType().ordinal());
writer.putInt(city.getObjectUUID()); writer.putInt(city.getObjectUUID());
writer.putString(city.cityName); writer.putString(city.cityName);
@@ -281,7 +264,6 @@ public class City extends AbstractWorldObject {
writer.putInt(rulingNation.getObjectUUID()); writer.putInt(rulingNation.getObjectUUID());
} }
// Serialize nation name // Serialize nation name
if (rulingNation.isEmptyGuild()) if (rulingNation.isEmptyGuild())
@@ -303,16 +285,8 @@ public class City extends AbstractWorldObject {
else else
writer.putString(Guild.GetGL(rulingNation).getFirstName() + ' ' + Guild.GetGL(rulingNation).getLastName()); writer.putString(Guild.GetGL(rulingNation).getFirstName() + ' ' + Guild.GetGL(rulingNation).getLastName());
writer.putLocalDateTime(city.established); 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.x);
writer.putFloat(city.location.y); writer.putFloat(city.location.y);
writer.putFloat(city.location.z); writer.putFloat(city.location.z);
@@ -351,6 +325,7 @@ public class City extends AbstractWorldObject {
ConcurrentHashMap<Integer, AbstractGameObject> worldCities = DbManager.getMap(Enum.GameObjectType.City); ConcurrentHashMap<Integer, AbstractGameObject> worldCities = DbManager.getMap(Enum.GameObjectType.City);
//add npc cities //add npc cities
for (AbstractGameObject ago : worldCities.values()) { for (AbstractGameObject ago : worldCities.values()) {
if (ago.getObjectType().equals(GameObjectType.City)) { if (ago.getObjectType().equals(GameObjectType.City)) {
@@ -367,6 +342,7 @@ public class City extends AbstractWorldObject {
//list Player cities //list Player cities
//open city, just list //open city, just list
if (city.open && city.getTOL() != null && city.getTOL().getRank() > 4) { if (city.open && city.getTOL() != null && city.getTOL().getRank() > 4) {
if (!BuildingManager.IsPlayerHostile(city.getTOL(), pc)) if (!BuildingManager.IsPlayerHostile(city.getTOL(), pc))
@@ -376,7 +352,9 @@ public class City extends AbstractWorldObject {
} else if (city.isNpc == 1) { } else if (city.isNpc == 1) {
//list NPC cities //list NPC cities
Guild g = city.getGuild(); Guild g = city.getGuild();
if (g == null) { if (g == null) {
if (city.isNpc == 1) if (city.isNpc == 1)
@@ -386,32 +364,34 @@ public class City extends AbstractWorldObject {
} else if (pc.getLevel() > 9) } else if (pc.getLevel() > 9)
cities.add(city); 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); cities.add(city);
}
} }
} }
} }
return cities; return cities;
} }
public static ArrayList<City> getCitiesToRepledgeTo(PlayerCharacter pc) { public static ArrayList<City> getCitiesToRepledgeTo(PlayerCharacter playerCharacter) {
ArrayList<City> cities = new ArrayList<>(); ArrayList<City> cities = new ArrayList<>();
if (pc == null)
if (playerCharacter == null)
return cities; return cities;
Guild pcG = pc.getGuild();
Guild pcG = playerCharacter.getGuild();
ConcurrentHashMap<Integer, AbstractGameObject> worldCities = DbManager.getMap(Enum.GameObjectType.City); ConcurrentHashMap<Integer, AbstractGameObject> worldCities = DbManager.getMap(Enum.GameObjectType.City);
//add npc cities //add npc cities
for (AbstractGameObject ago : worldCities.values()) { for (AbstractGameObject ago : worldCities.values()) {
if (ago.getObjectType().equals(GameObjectType.City)) { if (ago.getObjectType().equals(GameObjectType.City)) {
City city = (City) ago; City city = (City) ago;
if (city.noRepledge) if (city.noRepledge)
continue; continue;
@@ -419,11 +399,12 @@ public class City extends AbstractWorldObject {
//list Player cities //list Player cities
//open city, just list //open city, just list
if (pc.getAccount().status.equals(AccountStatus.ADMIN)) {
if (playerCharacter.getAccount().status.equals(AccountStatus.ADMIN)) {
cities.add(city); cities.add(city);
} else if (city.open && city.getTOL() != null && city.getTOL().getRank() > 4) { } 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 cities.add(city); //verify nation or guild is same
} else if (Guild.sameNationExcludeErrant(city.getGuild(), pcG)) } else if (Guild.sameNationExcludeErrant(city.getGuild(), pcG))
cities.add(city); cities.add(city);
@@ -431,15 +412,16 @@ public class City extends AbstractWorldObject {
} else if (city.isNpc == 1) { } else if (city.isNpc == 1) {
//list NPC cities //list NPC cities
Guild g = city.getGuild(); Guild guild = city.getGuild();
if (g == null) {
if (guild == null) {
if (city.isNpc == 1) if (city.isNpc == 1)
if (city.isNoobIsle == 1) { if (city.isNoobIsle == 1) {
if (pc.getLevel() < 21) if (playerCharacter.getLevel() < 21)
cities.add(city); cities.add(city);
} else if (pc.getLevel() > 9) } else if (playerCharacter.getLevel() > 9)
cities.add(city); 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); cities.add(city);
} }
@@ -455,6 +437,7 @@ public class City extends AbstractWorldObject {
return null; return null;
City city = (City) DbManager.getFromCache(Enum.GameObjectType.City, cityId); City city = (City) DbManager.getFromCache(Enum.GameObjectType.City, cityId);
if (city != null) if (city != null)
return city; return city;
@@ -471,8 +454,10 @@ public class City extends AbstractWorldObject {
} }
public boolean renameCity(String cityName) { public boolean renameCity(String cityName) {
if (!DbManager.CityQueries.renameCity(this, cityName)) if (!DbManager.CityQueries.renameCity(this, cityName))
return false; return false;
if (!DbManager.CityQueries.updateforceRename(this, false)) if (!DbManager.CityQueries.updateforceRename(this, false))
return false; return false;
@@ -482,17 +467,22 @@ public class City extends AbstractWorldObject {
} }
public boolean updateTOL(Building tol) { public boolean updateTOL(Building tol) {
if (tol == null) if (tol == null)
return false; return false;
if (!DbManager.CityQueries.updateTOL(this, tol.getObjectUUID())) if (!DbManager.CityQueries.updateTOL(this, tol.getObjectUUID()))
return false; return false;
this.treeOfLifeID = tol.getObjectUUID(); this.treeOfLifeID = tol.getObjectUUID();
return true; return true;
} }
public boolean renameCityForNewPlant(String cityName) { public boolean renameCityForNewPlant(String cityName) {
if (!DbManager.CityQueries.renameCity(this, cityName)) if (!DbManager.CityQueries.renameCity(this, cityName))
return false; return false;
if (!DbManager.CityQueries.updateforceRename(this, true)) if (!DbManager.CityQueries.updateforceRename(this, true))
return false; return false;
@@ -515,19 +505,11 @@ public class City extends AbstractWorldObject {
} }
public Building getTOL() { public Building getTOL() {
if (this.treeOfLifeID == 0) if (this.treeOfLifeID == 0)
return null; return null;
return BuildingManager.getBuildingFromCache(this.treeOfLifeID); return BuildingManager.getBuildingFromCache(this.treeOfLifeID);
}
public int getIsNoobIsle() {
return isNoobIsle;
}
public int getPopulation() {
return population;
} }
/** /**
@@ -557,14 +539,6 @@ public class City extends AbstractWorldObject {
Logger.error("Error when writing to database for cityUUID: " + this.getObjectUUID()); 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() { public float getAltitude() {
return this.location.y; return this.location.y;
} }
@@ -574,34 +548,10 @@ public class City extends AbstractWorldObject {
return this.location; return this.location;
} }
public byte getIsNpcOwned() {
return isNpc;
}
public byte getIsSafeHold() {
return this.isSafeHold;
}
public boolean isSafeHold() { public boolean isSafeHold() {
return (this.isSafeHold == (byte) 1); 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() { public int getRank() {
return (this.getTOL() == null) ? 0 : this.getTOL().getRank(); return (this.getTOL() == null) ? 0 : this.getTOL().getRank();
} }
@@ -624,7 +574,7 @@ public class City extends AbstractWorldObject {
this.parentZone = zone; 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.bindLoc = new Vector3fImmutable(this.location.x + this.bindX,
this.location.y, this.location.y,
this.location.z + this.bindZ); this.location.z + this.bindZ);
@@ -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() { public AbstractCharacter getOwner() {
if (this.getTOL() == null) if (this.getTOL() == null)
@@ -676,13 +617,13 @@ public class City extends AbstractWorldObject {
if (this.getTOL() == null) if (this.getTOL() == null)
return null; return null;
if (this.isNpc == 1) { if (this.isNpc == 1) {
if (this.getTOL().getOwner() == null) if (this.getTOL().getOwner() == null)
return null; return null;
return this.getTOL().getOwner().getGuild(); return this.getTOL().getOwner().getGuild();
} else { } else {
if (this.getTOL().getOwner() == null) if (this.getTOL().getOwner() == null)
return null; return null;
return this.getTOL().getOwner().getGuild(); return this.getTOL().getOwner().getGuild();
@@ -690,13 +631,16 @@ public class City extends AbstractWorldObject {
} }
public boolean openCity(boolean open) { public boolean openCity(boolean open) {
if (!DbManager.CityQueries.updateOpenCity(this, open)) if (!DbManager.CityQueries.updateOpenCity(this, open))
return false; return false;
this.open = open; this.open = open;
return true; return true;
} }
public Vector3fImmutable getBindLoc() { public Vector3fImmutable getBindLoc() {
Vector3fImmutable treeLoc = null; Vector3fImmutable treeLoc = null;
if (this.getTOL() != null && this.getTOL().getRank() == 8) if (this.getTOL() != null && this.getTOL().getRank() == 8)
@@ -706,7 +650,9 @@ public class City extends AbstractWorldObject {
return treeLoc; return treeLoc;
if (this.radiusType == 1 && this.bindRadius > 0f) { if (this.radiusType == 1 && this.bindRadius > 0f) {
//square radius //square radius
float x = this.bindLoc.getX(); float x = this.bindLoc.getX();
float z = this.bindLoc.getZ(); float z = this.bindLoc.getZ();
float offset = ((ThreadLocalRandom.current().nextFloat() * 2) - 1) * this.bindRadius; float offset = ((ThreadLocalRandom.current().nextFloat() * 2) - 1) * this.bindRadius;
@@ -827,7 +773,6 @@ public class City extends AbstractWorldObject {
try { try {
this.getTOL().addEffectBit((1 << 16)); this.getTOL().addEffectBit((1 << 16));
this.getBane().getStone().addEffectBit((1 << 19)); this.getBane().getStone().addEffectBit((1 << 19));
;
} catch (Exception e) { } catch (Exception e) {
Logger.info("Failed ao add bane effects on city." + e.getMessage()); Logger.info("Failed ao add bane effects on city." + e.getMessage());
} }
@@ -852,6 +797,7 @@ public class City extends AbstractWorldObject {
if (playerObject == null) if (playerObject == null)
continue; continue;
if (!this.isLocationWithinSiegeBounds(playerObject.getLoc())) if (!this.isLocationWithinSiegeBounds(playerObject.getLoc()))
continue; continue;
@@ -868,8 +814,7 @@ public class City extends AbstractWorldObject {
// Remove the city effect from the ago's internal collection // 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 // Any players currently in the zone will not be processed by the heartbeat
// so we do it here manually // so we do it here manually
@@ -878,6 +823,7 @@ public class City extends AbstractWorldObject {
for (Integer playerID : this._playerMemory) { for (Integer playerID : this._playerMemory) {
player = PlayerCharacter.getFromCache(playerID); player = PlayerCharacter.getFromCache(playerID);
if (player == null) if (player == null)
continue; continue;
@@ -893,8 +839,10 @@ public class City extends AbstractWorldObject {
} }
public Warehouse getWarehouse() { public Warehouse getWarehouse() {
if (this.warehouseBuildingID == 0) if (this.warehouseBuildingID == 0)
return null; return null;
return Warehouse.warehouseByBuildingUUID.get(this.warehouseBuildingID); return Warehouse.warehouseByBuildingUUID.get(this.warehouseBuildingID);
} }
@@ -1066,8 +1014,7 @@ public class City extends AbstractWorldObject {
_playerMemory.removeAll(toRemove); _playerMemory.removeAll(toRemove);
for (Integer removalUUID : 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 {
Thread destroyCityThread = new Thread(new DestroyCityThread(this)); Thread destroyCityThread = new Thread(new DestroyCityThread(this));
destroyCityThread.setName("deestroyCity:" + this.getName()); destroyCityThread.setName("destroyCity:" + this.getName());
destroyCityThread.start(); destroyCityThread.start();
} }
@@ -1168,6 +1115,7 @@ public class City extends AbstractWorldObject {
// All protection contracts are void upon transfer of a city // All protection contracts are void upon transfer of a city
//Dont forget to not Flip protection on Banestones and siege Equipment... Noob. //Dont forget to not Flip protection on Banestones and siege Equipment... Noob.
if (cityBuilding.getBlueprint() != null && !cityBuilding.getBlueprint().isSiegeEquip() if (cityBuilding.getBlueprint() != null && !cityBuilding.getBlueprint().isSiegeEquip()
&& cityBuilding.getBlueprint().getBuildingGroup() != BuildingGroup.BANESTONE) && cityBuilding.getBlueprint().getBuildingGroup() != BuildingGroup.BANESTONE)
cityBuilding.setProtectionState(ProtectionState.NONE); cityBuilding.setProtectionState(ProtectionState.NONE);
@@ -1199,7 +1147,6 @@ public class City extends AbstractWorldObject {
Zone cityZone; Zone cityZone;
sourceGuild = sourcePlayer.getGuild(); sourceGuild = sourcePlayer.getGuild();
if (sourceGuild == null) if (sourceGuild == null)
return false; return false;
@@ -1255,14 +1202,6 @@ public class City extends AbstractWorldObject {
this.forceRename = forceRename; this.forceRename = forceRename;
} }
public boolean isReverseKOS() {
return reverseKOS;
}
public void setReverseKOS(boolean reverseKOS) {
this.reverseKOS = reverseKOS;
}
public String getHash() { public String getHash() {
return hash; return hash;
} }
@@ -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) { public synchronized boolean TaxWarehouse(TaxResourcesMsg msg, PlayerCharacter player) {
// Member variable declaration // Member variable declaration
@@ -1322,12 +1241,12 @@ public class City extends AbstractWorldObject {
} }
City city = building.getCity(); City city = building.getCity();
if (city == null) { if (city == null) {
ErrorPopupMsg.sendErrorMsg(player, "This building does not belong to a city."); ErrorPopupMsg.sendErrorMsg(player, "This building does not belong to a city.");
return true; return true;
} }
if (playerGuild == null || playerGuild.isEmptyGuild()) { if (playerGuild == null || playerGuild.isEmptyGuild()) {
ErrorPopupMsg.sendErrorMsg(player, "You must belong to a guild to do that!"); ErrorPopupMsg.sendErrorMsg(player, "You must belong to a guild to do that!");
return true; return true;
@@ -1352,6 +1271,7 @@ public class City extends AbstractWorldObject {
ErrorPopupMsg.sendErrorMsg(player, "Cannot find realm for your city!"); ErrorPopupMsg.sendErrorMsg(player, "Cannot find realm for your city!");
return true; return true;
} }
Realm targetRealm = RealmMap.getRealmForCity(city); Realm targetRealm = RealmMap.getRealmForCity(city);
if (targetRealm == null) { if (targetRealm == null) {
@@ -1380,31 +1300,32 @@ public class City extends AbstractWorldObject {
return true; return true;
} }
if (this.realmTaxDate.isAfter(LocalDateTime.now())) if (this.realmTaxDate.isAfter(LocalDateTime.now()))
return true; return true;
if (msg.getResources().size() == 0) if (msg.getResources().size() == 0)
return true; return true;
if (city.getWarehouse() == null) if (city.getWarehouse() == null)
return true; return true;
Warehouse ruledWarehouse = playerGuild.getOwnedCity().getWarehouse(); Warehouse ruledWarehouse = playerGuild.getOwnedCity().getWarehouse();
if (ruledWarehouse == null) if (ruledWarehouse == null)
return true; return true;
ItemBase.getItemHashIDMap(); ItemBase.getItemHashIDMap();
ArrayList<Integer> resources = new ArrayList<>(); ArrayList<Integer> resources = new ArrayList<>();
float taxPercent = msg.getTaxPercent(); float taxPercent = msg.getTaxPercent();
if (taxPercent > 20) if (taxPercent > 20)
taxPercent = .20f; taxPercent = .20f;
for (int resourceHash : msg.getResources().keySet()) { for (int resourceHash : msg.getResources().keySet()) {
if (ItemBase.getItemHashIDMap().get(resourceHash) != null) if (ItemBase.getItemHashIDMap().get(resourceHash) != null)
resources.add(ItemBase.getItemHashIDMap().get(resourceHash)); resources.add(ItemBase.getItemHashIDMap().get(resourceHash));
} }
for (Integer itemBaseID : resources) { for (Integer itemBaseID : resources) {
@@ -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."); ErrorPopupMsg.sendErrorMsg(player, "Failed to Update next Tax Date due to internal Error. City was not charged taxes this time.");
return false; return false;
} }
try { try {
city.getWarehouse().transferResources(player, msg, resources, taxPercent, ruledWarehouse); city.getWarehouse().transferResources(player, msg, resources, taxPercent, ruledWarehouse);
} catch (Exception e) { } catch (Exception e) {
@@ -1439,6 +1361,5 @@ public class City extends AbstractWorldObject {
dispatch = Dispatch.borrow(player, msg); dispatch = Dispatch.borrow(player, msg);
DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.SECONDARY); DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.SECONDARY);
return true; return true;
} }
} }
+17
View File
@@ -914,4 +914,21 @@ public class ItemBase {
public void setAutoID(boolean autoID) { public void setAutoID(boolean autoID) {
this.autoID = 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;
}
} }
+168 -196
View File
@@ -25,15 +25,14 @@ import engine.net.Dispatch;
import engine.net.DispatchMessage; import engine.net.DispatchMessage;
import engine.net.client.msg.PetMsg; import engine.net.client.msg.PetMsg;
import engine.net.client.msg.PlaceAssetMsg; import engine.net.client.msg.PlaceAssetMsg;
import engine.powers.MobPowerEntry;
import engine.server.MBServerStatics; import engine.server.MBServerStatics;
import org.joda.time.DateTime; import org.joda.time.DateTime;
import org.pmw.tinylog.Logger; import org.pmw.tinylog.Logger;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.EnumSet;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock;
@@ -51,7 +50,6 @@ public class Mob extends AbstractIntelligenceAgent {
public ReentrantReadWriteLock minionLock = new ReentrantReadWriteLock(); public ReentrantReadWriteLock minionLock = new ReentrantReadWriteLock();
public boolean despawned = false; public boolean despawned = false;
public Vector3fImmutable destination = Vector3fImmutable.ZERO; public Vector3fImmutable destination = Vector3fImmutable.ZERO;
public LinkedHashMap<Integer, Integer> mobPowers = new LinkedHashMap<>();
public MobBase mobBase; public MobBase mobBase;
public int spawnTime; public int spawnTime;
public Zone parentZone; public Zone parentZone;
@@ -65,15 +63,13 @@ public class Mob extends AbstractIntelligenceAgent {
public float spawnRadius; public float spawnRadius;
//used by static mobs //used by static mobs
public int parentZoneUUID; public int parentZoneUUID;
protected int dbID; //the database ID
private int currentID;
//TODO implement feared object system //TODO implement feared object system
public AbstractWorldObject fearedObject = null; public AbstractWorldObject fearedObject = null;
protected int dbID; //the database ID
private int currentID;
private long lastAttackTime = 0; private long lastAttackTime = 0;
private int lastMobPowerToken = 0; private int lastMobPowerToken = 0;
private HashMap<Integer, MobEquipment> equip = null; public HashMap<Integer, MobEquipment> equip = null;
private DeferredPowerJob weaponPower; private DeferredPowerJob weaponPower;
private DateTime upgradeDateTime = null; private DateTime upgradeDateTime = null;
private boolean lootSync = false; private boolean lootSync = false;
@@ -105,6 +101,7 @@ public class Mob extends AbstractIntelligenceAgent {
this.dbID = rs.getInt(1); this.dbID = rs.getInt(1);
this.loadID = rs.getInt("mob_mobbaseID"); this.loadID = rs.getInt("mob_mobbaseID");
this.gridObjectType = GridObjectType.DYNAMIC; this.gridObjectType = GridObjectType.DYNAMIC;
this.agentType = AIAgentType.MOBILE;
this.spawnRadius = rs.getFloat("mob_spawnRadius"); this.spawnRadius = rs.getFloat("mob_spawnRadius");
this.spawnTime = rs.getInt("mob_spawnTime"); this.spawnTime = rs.getInt("mob_spawnTime");
@@ -153,7 +150,6 @@ public class Mob extends AbstractIntelligenceAgent {
this.currentID = this.dbID; this.currentID = this.dbID;
this.agentType = AIAgentType.MOBILE;
} catch (Exception e) { } catch (Exception e) {
Logger.error(e + " " + this.dbID); Logger.error(e + " " + this.dbID);
} }
@@ -183,7 +179,7 @@ public class Mob extends AbstractIntelligenceAgent {
} else if (tid == 100962 || tid == 100965) { //Spydraxxx the Mighty, Denigo Tantric } else if (tid == 100962 || tid == 100965) { //Spydraxxx the Mighty, Denigo Tantric
writer.putInt(2); writer.putInt(2);
serializeRune(mob, writer, 5, GameObjectType.NPCClassRuneTwo.ordinal(), 252621); //guard rune serializeRune(mob, writer, 5, GameObjectType.NPCClassRuneTwo.ordinal(), 252621); //guard rune
} else if (mob.contract != null || mob.isPlayerGuard) { } else if (mob.contract != null || mob.isPlayerGuard()) {
writer.putInt(3); writer.putInt(3);
serializeRune(mob, writer, 3, GameObjectType.NPCClassRuneTwo.ordinal(), MobBase.GetClassType(mob.getMobBaseID())); //warrior class serializeRune(mob, writer, 3, GameObjectType.NPCClassRuneTwo.ordinal(), MobBase.GetClassType(mob.getMobBaseID())); //warrior class
serializeRune(mob, writer, 5, GameObjectType.NPCClassRuneThree.ordinal(), 252621); //guard rune serializeRune(mob, writer, 5, GameObjectType.NPCClassRuneThree.ordinal(), 252621); //guard rune
@@ -316,13 +312,13 @@ public class Mob extends AbstractIntelligenceAgent {
writer.put((byte) 1); writer.put((byte) 1);
if ((PlayerCharacter) mob.guardCaptain != null) { if (mob.guardCaptain != null) {
writer.putInt(((PlayerCharacter) mob.guardCaptain).getObjectType().ordinal()); writer.putInt(mob.guardCaptain.getObjectType().ordinal());
writer.putInt(((PlayerCharacter) mob.guardCaptain).getObjectUUID()); writer.putInt(mob.guardCaptain.getObjectUUID());
} else { } else {
writer.putInt(0); //ownerType writer.putInt(0); //ownerType
writer.putInt(0); //ownerID writer.putInt(0); //ownerID
@@ -340,7 +336,7 @@ public class Mob extends AbstractIntelligenceAgent {
writer.putInt(0); writer.putInt(0);
writer.putInt(0); writer.putInt(0);
if (!mob.isAlive() && !mob.isPet() && !mob.isNecroPet() && !mob.behaviourType.equals(MobBehaviourType.SiegeEngine) && !mob.isPlayerGuard) { if (!mob.isAlive() && !mob.isPet() && !mob.isNecroPet() && !mob.behaviourType.equals(MobBehaviourType.SiegeEngine) && !mob.isPlayerGuard()) {
writer.putInt(0); writer.putInt(0);
writer.putInt(0); writer.putInt(0);
} }
@@ -401,10 +397,13 @@ public class Mob extends AbstractIntelligenceAgent {
writer.putInt(mob.currentID); writer.putInt(mob.currentID);
} }
public static Mob createMob(int loadID, Vector3fImmutable spawn, Guild guild, Zone parent, Building building, Contract contract, String pirateName, int level) { public static Mob createMob(int loadID, Vector3fImmutable spawn, Guild guild, Zone parent, Building building, Contract contract, String pirateName, int level, AIAgentType mobType) {
Mob mobile = new Mob(); Mob mobile = new Mob();
mobile.dbID = MBServerStatics.NO_DB_ROW_ASSIGNED_YET; mobile.dbID = MBServerStatics.NO_DB_ROW_ASSIGNED_YET;
//mobile.agentType = AIAgentType.MOBILE; this method is only called to make guard captains and wall archers
mobile.agentType = mobType;
mobile.behaviourType = MobBehaviourType.None;
mobile.loadID = loadID; mobile.loadID = loadID;
mobile.level = (short) level; mobile.level = (short) level;
@@ -428,18 +427,8 @@ public class Mob extends AbstractIntelligenceAgent {
else else
mobile.contractUUID = contract.getContractID(); mobile.contractUUID = contract.getContractID();
Mob mob;
mobile.agentType = AIAgentType.GUARD; return mobile;
try {
mob = DbManager.MobQueries.PERSIST(mobile);
} catch (Exception e) {
Logger.error("SQLException:" + e.getMessage());
mob = null;
}
return mob;
} }
public static synchronized Mob createGuardMinion(Mob guardCaptain, short level, String minionName) { public static synchronized Mob createGuardMinion(Mob guardCaptain, short level, String minionName) {
@@ -463,8 +452,7 @@ public class Mob extends AbstractIntelligenceAgent {
minionMobile.guardCaptain = guardCaptain; minionMobile.guardCaptain = guardCaptain;
minionMobile.spawnTime = (int) (-2.500 * guardCaptain.building.getRank() + 22.5) * 60; minionMobile.spawnTime = (int) (-2.500 * guardCaptain.building.getRank() + 22.5) * 60;
minionMobile.behaviourType = Enum.MobBehaviourType.GuardMinion; minionMobile.behaviourType = Enum.MobBehaviourType.GuardMinion;
minionMobile.agentType = AIAgentType.GUARD; minionMobile.agentType = AIAgentType.GUARDMINION;
minionMobile.isPlayerGuard = true;
minionMobile.guardedCity = guardCaptain.guardedCity; minionMobile.guardedCity = guardCaptain.guardedCity;
minionMobile.patrolPoints = guardCaptain.building.patrolPoints; minionMobile.patrolPoints = guardCaptain.building.patrolPoints;
@@ -499,8 +487,7 @@ public class Mob extends AbstractIntelligenceAgent {
minionMobile.setLoc(minionMobile.bindLoc); minionMobile.setLoc(minionMobile.bindLoc);
minionMobile.despawn(); minionMobile.despawn();
int slot = guardCaptain.siegeMinionMap.size() + 1; guardCaptain.minions.add(minionMobile.getObjectUUID());
guardCaptain.siegeMinionMap.put(minionMobile, slot);
return minionMobile; return minionMobile;
} }
@@ -530,8 +517,7 @@ public class Mob extends AbstractIntelligenceAgent {
siegeMinion.setLoc(siegeMinion.bindLoc); siegeMinion.setLoc(siegeMinion.bindLoc);
siegeMinion.despawn(); siegeMinion.despawn();
int slot = artyCaptain.siegeMinionMap.size() + 1; artyCaptain.minions.add(siegeMinion.getObjectUUID());
artyCaptain.siegeMinionMap.put(siegeMinion, slot);
return siegeMinion; return siegeMinion;
} }
@@ -566,20 +552,22 @@ public class Mob extends AbstractIntelligenceAgent {
return petMinion; return petMinion;
} }
public static Mob getMob(int id) { public static Mob getMob(int id) {
if (id == 0) if (id == 0)
return null; return null;
Mob mob = (Mob) DbManager.getFromCache(GameObjectType.Mob, id); Mob mob = (Mob) DbManager.getFromCache(GameObjectType.Mob, id);
if (mob != null) if (mob != null)
return mob; return mob;
return DbManager.MobQueries.GET_MOB(id); return DbManager.MobQueries.GET_MOB(id);
} }
public static Mob getFromCache(int id) { public static Mob getFromCache(int id) {
return (Mob) DbManager.getFromCache(GameObjectType.Mob, id); return (Mob) DbManager.getFromCache(GameObjectType.Mob, id);
} }
@@ -636,7 +624,6 @@ public class Mob extends AbstractIntelligenceAgent {
mob.upgradeDateTime = upgradeDateTime; mob.upgradeDateTime = upgradeDateTime;
} }
/* /*
* Getters * Getters
*/ */
@@ -662,10 +649,6 @@ public class Mob extends AbstractIntelligenceAgent {
return this.spawnRadius; return this.spawnRadius;
} }
public void setSpawnTime(int value) {
this.spawnTime = value;
}
public String getSpawnTimeAsString() { public String getSpawnTimeAsString() {
if (this.spawnTime == 0) if (this.spawnTime == 0)
return MBServerStatics.DEFAULT_SPAWN_TIME_MS / 1000 + " seconds (Default)"; return MBServerStatics.DEFAULT_SPAWN_TIME_MS / 1000 + " seconds (Default)";
@@ -680,11 +663,7 @@ public class Mob extends AbstractIntelligenceAgent {
} }
public int getMobBaseID() { public int getMobBaseID() {
return this.mobBase.getObjectUUID();
if (this.mobBase != null)
return this.mobBase.getObjectUUID();
return 0;
} }
public Vector3fImmutable getTrueBindLoc() { public Vector3fImmutable getTrueBindLoc() {
@@ -708,7 +687,7 @@ public class Mob extends AbstractIntelligenceAgent {
public Vector3fImmutable getBindLoc() { public Vector3fImmutable getBindLoc() {
if (this.isPet() && !this.behaviourType.equals(MobBehaviourType.SiegeEngine)) if (this.isPet() && !this.behaviourType.equals(MobBehaviourType.SiegeEngine))
return (PlayerCharacter) this.guardCaptain != null ? ((PlayerCharacter) this.guardCaptain).getLoc() : this.getLoc(); return this.guardCaptain != null ? this.guardCaptain.getLoc() : this.getLoc();
else else
return this.bindLoc; return this.bindLoc;
} }
@@ -737,8 +716,6 @@ public class Mob extends AbstractIntelligenceAgent {
conVal *= (1 + this.bonuses.getFloatPercentAll(ModType.Attr, SourceType.Constitution)); conVal *= (1 + this.bonuses.getFloatPercentAll(ModType.Attr, SourceType.Constitution));
intVal *= (1 + this.bonuses.getFloatPercentAll(ModType.Attr, SourceType.Intelligence)); intVal *= (1 + this.bonuses.getFloatPercentAll(ModType.Attr, SourceType.Intelligence));
spiVal *= (1 + this.bonuses.getFloatPercentAll(ModType.Attr, SourceType.Spirit)); spiVal *= (1 + this.bonuses.getFloatPercentAll(ModType.Attr, SourceType.Spirit));
} else {
// apply dex penalty for armor
} }
// Set current stats // Set current stats
@@ -757,7 +734,7 @@ public class Mob extends AbstractIntelligenceAgent {
// get rune and effect bonuses // get rune and effect bonuses
bonus *= (1 + this.bonuses.getFloatPercentAll(ModType.Speed, SourceType.None)); bonus *= (1 + this.bonuses.getFloatPercentAll(ModType.Speed, SourceType.None));
if (this.isPlayerGuard) if (this.isPlayerGuard())
switch (this.mobBase.getLoadID()) { switch (this.mobBase.getLoadID()) {
case 2111: case 2111:
if (this.isWalk()) if (this.isWalk())
@@ -825,7 +802,7 @@ public class Mob extends AbstractIntelligenceAgent {
Group g = GroupManager.getGroup((PlayerCharacter) attacker); Group g = GroupManager.getGroup((PlayerCharacter) attacker);
// Give XP, now handled inside the Experience Object // Give XP, now handled inside the Experience Object
if (!this.isPet() && !this.isNecroPet() && !(this.agentType.equals(AIAgentType.PET)) && !this.isPlayerGuard) if (!this.isPet() && !this.isNecroPet() && !(this.agentType.equals(AIAgentType.PET)) && !this.isPlayerGuard())
Experience.doExperience((PlayerCharacter) attacker, this, g); Experience.doExperience((PlayerCharacter) attacker, this, g);
} else if (attacker.getObjectType().equals(GameObjectType.Mob)) { } else if (attacker.getObjectType().equals(GameObjectType.Mob)) {
Mob mobAttacker = (Mob) attacker; Mob mobAttacker = (Mob) attacker;
@@ -836,7 +813,7 @@ public class Mob extends AbstractIntelligenceAgent {
PlayerCharacter owner = (PlayerCharacter) mobAttacker.guardCaptain; PlayerCharacter owner = (PlayerCharacter) mobAttacker.guardCaptain;
if (owner != null) if (owner != null)
if (!this.isPet() && !this.isNecroPet() && !(this.agentType.equals(AIAgentType.PET)) && !this.isPlayerGuard) { if (!this.isPet() && !this.isNecroPet() && !(this.agentType.equals(AIAgentType.PET)) && !this.isPlayerGuard()) {
Group g = GroupManager.getGroup(owner); Group g = GroupManager.getGroup(owner);
// Give XP, now handled inside the Experience Object // Give XP, now handled inside the Experience Object
@@ -864,13 +841,11 @@ public class Mob extends AbstractIntelligenceAgent {
if (newLoc.equals(this.getEndLoc())) { if (newLoc.equals(this.getEndLoc())) {
this.stopMovement(newLoc); this.stopMovement(newLoc);
this.region = AbstractWorldObject.GetRegionByWorldObject(this);
return; return;
//Next upda //Next upda
} }
setLoc(newLoc); setLoc(newLoc);
this.region = AbstractWorldObject.GetRegionByWorldObject(this);
//Next update will be end Loc, lets stop him here. //Next update will be end Loc, lets stop him here.
} }
@@ -950,7 +925,7 @@ public class Mob extends AbstractIntelligenceAgent {
playerAgroMap.clear(); playerAgroMap.clear();
if (!this.isPlayerGuard && this.equip != null) if (!this.isPlayerGuard() && this.equip != null)
LootManager.GenerateEquipmentDrop(this); LootManager.GenerateEquipmentDrop(this);
} }
@@ -987,18 +962,15 @@ public class Mob extends AbstractIntelligenceAgent {
this.setLoc(this.lastBindLoc); this.setLoc(this.lastBindLoc);
this.stopMovement(this.lastBindLoc); this.stopMovement(this.lastBindLoc);
NPCManager.applyRuneSetEffects(this); NPCManager.applyMobbaseEffects(this);
this.recalculateStats(); this.recalculateStats();
this.setHealth(this.healthMax); this.setHealth(this.healthMax);
if (this.building == null && this.guardCaptain != null && ((Mob) this.guardCaptain).behaviourType.equals(MobBehaviourType.GuardCaptain)) if (this.building == null && this.guardCaptain != null && ((Mob) this.guardCaptain).behaviourType.equals(MobBehaviourType.GuardCaptain))
this.building = this.guardCaptain.building; this.building = this.guardCaptain.building;
else if (this.building != null)
this.region = BuildingManager.GetRegion(this.building, bindLoc.x, bindLoc.y, bindLoc.z);
if (!this.behaviourType.equals(MobBehaviourType.SiegeEngine) && !this.isPlayerGuard && contract == null) this.loadInventory();
loadInventory();
this.updateLocation(); this.updateLocation();
} }
@@ -1036,7 +1008,9 @@ public class Mob extends AbstractIntelligenceAgent {
this.charItemManager.clearInventory(); this.charItemManager.clearInventory();
this.charItemManager.clearEquip(); this.charItemManager.clearEquip();
if (isPlayerGuard) // Only generate loot for mobiles
if (!this.agentType.equals(AIAgentType.MOBILE))
return; return;
LootManager.GenerateMobLoot(this); LootManager.GenerateMobLoot(this);
@@ -1052,80 +1026,88 @@ public class Mob extends AbstractIntelligenceAgent {
} }
public void recalculateStats() { public void recalculateStats() {
if(this.isPlayerGuard()){
NPCManager.setMaxHealthForGuard(this);
NPCManager.setAttackRatingForGuard(this);
NPCManager.setDefenseForGuard(this);
NPCManager.setDamageAndSpeedForGuard(this);
NPCManager.applyGuardStanceModifiers(this);
}else {
try {
calculateAtrDefenseDamage();
} catch (Exception e) {
Logger.error(this.getMobBaseID() + " /" + e.getMessage());
}
try {
calculateMaxHealthManaStamina();
} catch (Exception e) {
Logger.error(e.getMessage());
}
}
try { try {
calculateModifiedStats(); calculateModifiedStats();
} catch (Exception e) { } catch (Exception e) {
Logger.error(e.getMessage()); Logger.error(e.getMessage());
} }
if(this.isSiege())
try { this.healthMax = 10000;
calculateAtrDefenseDamage();
} catch (Exception e) {
Logger.error(this.getMobBaseID() + " /" + e.getMessage());
}
try {
calculateMaxHealthManaStamina();
} catch (Exception e) {
Logger.error(e.getMessage());
}
Resists.calculateResists(this); Resists.calculateResists(this);
} }
public void calculateMaxHealthManaStamina() { public void calculateMaxHealthManaStamina() {
float h; float h;
float m; float m;
float s; float s;
h = this.mobBase.getHealthMax(); h = this.mobBase.getHealthMax();
if (this.isPet()) { if (this.isPet()) {
h = this.level * 0.5f * 120; h = this.level * 0.5f * 120;
} }
m = this.statSpiCurrent; m = this.statSpiCurrent;
s = this.statConCurrent; s = this.statConCurrent;
// Apply any bonuses from runes and effects // Apply any bonuses from runes and effects
if (this.bonuses != null) { if (this.bonuses != null) {
h += this.bonuses.getFloat(ModType.HealthFull, SourceType.None); h += this.bonuses.getFloat(ModType.HealthFull, SourceType.None);
m += this.bonuses.getFloat(ModType.ManaFull, SourceType.None); m += this.bonuses.getFloat(ModType.ManaFull, SourceType.None);
s += this.bonuses.getFloat(ModType.StaminaFull, SourceType.None); s += this.bonuses.getFloat(ModType.StaminaFull, SourceType.None);
//apply effects percent modifiers. DO THIS LAST! //apply effects percent modifiers. DO THIS LAST!
h *= (1 + this.bonuses.getFloatPercentAll(ModType.HealthFull, SourceType.None)); h *= (1 + this.bonuses.getFloatPercentAll(ModType.HealthFull, SourceType.None));
m *= (1 + this.bonuses.getFloatPercentAll(ModType.ManaFull, SourceType.None)); m *= (1 + this.bonuses.getFloatPercentAll(ModType.ManaFull, SourceType.None));
s *= (1 + this.bonuses.getFloatPercentAll(ModType.StaminaFull, SourceType.None)); s *= (1 + this.bonuses.getFloatPercentAll(ModType.StaminaFull, SourceType.None));
} }
// Set max health, mana and stamina // Set max health, mana and stamina
if (h > 0) if (h > 0)
this.healthMax = h; this.healthMax = h;
else else
this.healthMax = 1; this.healthMax = 1;
if (m > -1) if (m > -1)
this.manaMax = m; this.manaMax = m;
else else
this.manaMax = 0; this.manaMax = 0;
if (s > -1) if (s > -1)
this.staminaMax = s; this.staminaMax = s;
else else
this.staminaMax = 0; this.staminaMax = 0;
// Update health, mana and stamina if needed // Update health, mana and stamina if needed
if (this.getHealth() > this.healthMax) if (this.getHealth() > this.healthMax)
this.setHealth(this.healthMax); this.setHealth(this.healthMax);
if (this.mana.get() > this.manaMax) if (this.mana.get() > this.manaMax)
this.mana.set(this.manaMax); this.mana.set(this.manaMax);
if (this.stamina.get() > this.staminaMax) if (this.stamina.get() > this.staminaMax)
this.stamina.set(staminaMax); this.stamina.set(staminaMax);
} }
@@ -1138,14 +1120,34 @@ public class Mob extends AbstractIntelligenceAgent {
this.defenseRating = 0; this.defenseRating = 0;
return; return;
} }
this.atrHandOne = (short) this.mobBase.getAttackRating();
this.minDamageHandOne = (short) this.mobBase.getDamageMin();
this.maxDamageHandOne = (short) this.mobBase.getDamageMax();
this.rangeHandOne = 6.5f;
this.speedHandOne = 20;
this.atrHandTwo = (short) this.mobBase.getAttackRating();
this.minDamageHandTwo = (short) this.mobBase.getDamageMin();
this.maxDamageHandTwo = (short) this.mobBase.getDamageMax();
this.rangeHandTwo = 6.5f;
this.speedHandTwo = 20;
if(this.equip.get(MBServerStatics.SLOT_MAINHAND) != null){
//has mainhand weapon to calculate
calculateAtrDamageForWeapon(this.equip.get(MBServerStatics.SLOT_MAINHAND), true);
}
if(this.equip.get(MBServerStatics.SLOT_OFFHAND) != null && !this.equip.get(MBServerStatics.SLOT_OFFHAND).getItemBase().isShield()){
//has offhand weapon to calculate
calculateAtrDamageForWeapon(this.equip.get(MBServerStatics.SLOT_OFFHAND), false);
}
try { try {
calculateAtrDamageForWeapon(this.equip.get(MBServerStatics.SLOT_MAINHAND), true); calculateAtrDamageForWeapon(this.equip.get(MBServerStatics.SLOT_MAINHAND), true);
} catch (Exception e) { } catch (Exception e) {
this.atrHandOne = (short) this.mobBase.getAttackRating(); this.atrHandOne = (short) this.mobBase.getAttackRating();
this.minDamageHandOne = (short) this.mobBase.getMinDmg(); this.minDamageHandOne = (short) this.mobBase.getDamageMin();
this.maxDamageHandOne = (short) this.mobBase.getMaxDmg(); this.maxDamageHandOne = (short) this.mobBase.getDamageMax();
this.rangeHandOne = 6.5f; this.rangeHandOne = 6.5f;
this.speedHandOne = 20; this.speedHandOne = 20;
Logger.info("Mobbase ID " + this.getMobBaseID() + " returned an error. setting to default ATR and Damage." + e.getMessage()); Logger.info("Mobbase ID " + this.getMobBaseID() + " returned an error. setting to default ATR and Damage." + e.getMessage());
@@ -1157,8 +1159,8 @@ public class Mob extends AbstractIntelligenceAgent {
} catch (Exception e) { } catch (Exception e) {
this.atrHandTwo = (short) this.mobBase.getAttackRating(); this.atrHandTwo = (short) this.mobBase.getAttackRating();
this.minDamageHandTwo = (short) this.mobBase.getMinDmg(); this.minDamageHandTwo = (short) this.mobBase.getDamageMin();
this.maxDamageHandTwo = (short) this.mobBase.getMaxDmg(); this.maxDamageHandTwo = (short) this.mobBase.getDamageMax();
this.rangeHandTwo = 6.5f; this.rangeHandTwo = 6.5f;
this.speedHandTwo = 20; this.speedHandTwo = 20;
Logger.info("Mobbase ID " + this.getMobBaseID() + " returned an error. setting to default ATR and Damage." + e.getMessage()); Logger.info("Mobbase ID " + this.getMobBaseID() + " returned an error. setting to default ATR and Damage." + e.getMessage());
@@ -1202,7 +1204,7 @@ public class Mob extends AbstractIntelligenceAgent {
this.defenseRating = (short) (defense + 0.5f); this.defenseRating = (short) (defense + 0.5f);
} catch (Exception e) { } catch (Exception e) {
Logger.info("Mobbase ID " + this.getMobBaseID() + " returned an error. Setting to Default Defense." + e.getMessage()); Logger.info("Mobbase ID " + this.getMobBaseID() + " returned an error. Setting to Default Defense." + e.getMessage());
this.defenseRating = (short) this.mobBase.getDefense(); this.defenseRating = (short) this.mobBase.getDefenseRating();
} }
// calculate defense for equipment // calculate defense for equipment
} }
@@ -1353,8 +1355,8 @@ public class Mob extends AbstractIntelligenceAgent {
mastDam = masteryPercentage; mastDam = masteryPercentage;
// TODO Correct these // TODO Correct these
min = this.mobBase.getMinDmg(); min = this.mobBase.getDamageMin();
max = this.mobBase.getMaxDmg(); max = this.mobBase.getDamageMax();
} else { } else {
if (mainHand) if (mainHand)
@@ -1529,49 +1531,33 @@ public class Mob extends AbstractIntelligenceAgent {
@Override @Override
public void runAfterLoad() { public void runAfterLoad() {
this.charItemManager = new CharacterItemManager(this); this.setObjectTypeMask(MBServerStatics.MASK_MOB | this.getTypeMasks());
if (ConfigManager.serverType.equals(ServerType.LOGINSERVER)) if (ConfigManager.serverType.equals(ServerType.LOGINSERVER))
return; return;
this.mobBase = MobBase.getMobBase(loadID); this.charItemManager = new CharacterItemManager(this);
this.setObjectTypeMask(MBServerStatics.MASK_MOB | this.getTypeMasks()); this.mobBase = MobBase.getMobBase(loadID);
this.building = BuildingManager.getBuilding(this.buildingUUID); this.building = BuildingManager.getBuilding(this.buildingUUID);
if (this.contractUUID == 0) // Configure AI related values
this.contract = null;
else
this.contract = DbManager.ContractQueries.GET_CONTRACT(this.contractUUID);
// Setup mobile AI and equipset for contract switch (this.behaviourType) {
case GuardCaptain:
if (this.contract != null) { this.agentType = AIAgentType.GUARDCAPTAIN;
this.spawnTime = 600;
this.equipmentSetID = this.contract.getEquipmentSet();
// Load AI for guard captains
if (NPC.ISGuardCaptain(contract.getContractID()) || this.contract.getContractID() == 910) { // Guard Dog
this.behaviourType = MobBehaviourType.GuardCaptain;
this.spawnTime = 60 * 15;
this.isPlayerGuard = true;
this.guardedCity = ZoneManager.getCityAtLocation(this.building.getLoc()); this.guardedCity = ZoneManager.getCityAtLocation(this.building.getLoc());
} break;
case GuardWallArcher:
// Load AI for wall archers this.agentType = AIAgentType.GUARDWALLARCHER;
if (NPC.ISWallArcher(this.contract)) {
this.gridObjectType = GridObjectType.DYNAMIC;
this.behaviourType = MobBehaviourType.GuardWallArcher;
this.isPlayerGuard = true;
this.spawnTime = 450; this.spawnTime = 450;
this.guardedCity = ZoneManager.getCityAtLocation(this.building.getLoc()); this.guardedCity = ZoneManager.getCityAtLocation(this.building.getLoc());
} break;
} }
// Default to the mobbase for AI if nothing is hte mob field to override. // Default to the mobbase for AI if nothing is in mob field to override.
if (this.behaviourType == null || this.behaviourType.equals(MobBehaviourType.None)) if (this.behaviourType == null || this.behaviourType.equals(MobBehaviourType.None))
this.behaviourType = this.getMobBase().fsm; this.behaviourType = this.getMobBase().fsm;
@@ -1579,6 +1565,18 @@ public class Mob extends AbstractIntelligenceAgent {
if (this.behaviourType == null) if (this.behaviourType == null)
this.behaviourType = MobBehaviourType.None; this.behaviourType = MobBehaviourType.None;
if (this.contractUUID == 0)
this.contract = null;
else
this.contract = DbManager.ContractQueries.GET_CONTRACT(this.contractUUID);
// Setup equipset for contract
if (this.contract != null)
this.equipmentSetID = this.contract.getEquipmentSet();
// Mobiles default to the building guild.
if (this.building != null) if (this.building != null)
this.guild = this.building.getGuild(); this.guild = this.building.getGuild();
else else
@@ -1604,7 +1602,7 @@ public class Mob extends AbstractIntelligenceAgent {
// Don't override level for guard minions or pets // Don't override level for guard minions or pets
if (this.contract == null) if (this.contract == null)
if (!this.agentType.equals(AIAgentType.GUARD) && !this.agentType.equals(AIAgentType.PET)) if (!this.agentType.equals(AIAgentType.GUARDMINION) && !this.agentType.equals(AIAgentType.PET))
this.level = (short) this.mobBase.getLevel(); this.level = (short) this.mobBase.getLevel();
//set bonuses //set bonuses
@@ -1614,11 +1612,11 @@ public class Mob extends AbstractIntelligenceAgent {
//TODO set these correctly later //TODO set these correctly later
this.rangeHandOne = this.mobBase.getAttackRange(); this.rangeHandOne = this.mobBase.getAttackRange();
this.rangeHandTwo = -1; this.rangeHandTwo = -1;
this.minDamageHandOne = (int)this.mobBase.getMinDmg(); this.minDamageHandOne = (int) this.mobBase.getDamageMin();
this.maxDamageHandOne = (int)this.mobBase.getMaxDmg(); this.maxDamageHandOne = (int) this.mobBase.getDamageMax();
this.minDamageHandTwo = 0; this.minDamageHandTwo = 0;
this.maxDamageHandTwo = 0; this.maxDamageHandTwo = 0;
this.atrHandOne = this.mobBase.getAtr(); this.atrHandOne = this.mobBase.getAttackRating();
this.defenseRating = (short) this.mobBase.getDefenseRating(); this.defenseRating = (short) this.mobBase.getDefenseRating();
this.isActive = true; this.isActive = true;
@@ -1651,7 +1649,7 @@ public class Mob extends AbstractIntelligenceAgent {
// Setup location for this Mobile // Setup location for this Mobile
this.loc = new Vector3fImmutable(bindLoc); this.setLoc(bindLoc);
this.endLoc = new Vector3fImmutable(bindLoc); this.endLoc = new Vector3fImmutable(bindLoc);
// Initialize inventory // Initialize inventory
@@ -1664,18 +1662,6 @@ public class Mob extends AbstractIntelligenceAgent {
else else
this.equip = new HashMap<>(); this.equip = new HashMap<>();
// Powers from mobbase
if (PowersManager.AllMobPowers.containsKey(this.getMobBaseID()))
for (MobPowerEntry mobPowerEntry : PowersManager.AllMobPowers.get(this.getMobBaseID()))
mobPowers.put(mobPowerEntry.token, mobPowerEntry.rank);
// Powers from contract
if (this.contract != null && PowersManager.AllMobPowers.containsKey(this.contract.getContractID()))
for (MobPowerEntry mobPowerEntry : PowersManager.AllMobPowers.get(this.contract.getContractID()))
mobPowers.put(mobPowerEntry.token, mobPowerEntry.rank);
if (this.equip == null) { if (this.equip == null) {
Logger.error("Null equipset returned for uuid " + currentID); Logger.error("Null equipset returned for uuid " + currentID);
this.equip = new HashMap<>(0); this.equip = new HashMap<>(0);
@@ -1691,29 +1677,25 @@ public class Mob extends AbstractIntelligenceAgent {
if (this.getMobBase().enemy.size() > 0) if (this.getMobBase().enemy.size() > 0)
this.enemy.addAll(this.getMobBase().enemy); this.enemy.addAll(this.getMobBase().enemy);
} }
NPCManager.applyMobbaseEffects(this);
NPCManager.applyEquipmentResists(this);
NPCManager.applyMobbaseSkill(this);
NPCManager.applyRuneSkills(this,this.getMobBaseID());
this.recalculateStats();
this.setHealth(this.healthMax);
try { // Set bounds for this mobile
NPCManager.applyRuneSetEffects(this);
recalculateStats();
this.setHealth(this.healthMax);
// Set bounds for this mobile Bounds mobBounds = Bounds.borrow();
mobBounds.setBounds(this.getLoc());
this.setBounds(mobBounds);
Bounds mobBounds = Bounds.borrow(); //assign 5 random patrol points for regular mobs
mobBounds.setBounds(this.getLoc());
this.setBounds(mobBounds);
//assign 5 random patrol points for regular mobs if (this.agentType.equals(AIAgentType.MOBILE))
NPCManager.AssignPatrolPoints(this);
if (this.agentType.equals(AIAgentType.MOBILE)) { this.deathTime = 0;
NPCManager.AssignPatrolPoints(this);
}
this.deathTime = 0;
} catch (Exception e) {
Logger.error(e.getMessage());
}
} }
@Override @Override
@@ -1721,8 +1703,8 @@ public class Mob extends AbstractIntelligenceAgent {
return new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW); return new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
} }
public boolean canSee(PlayerCharacter target) { public boolean canSee(AbstractCharacter target) {
return this.mobBase.getSeeInvis() >= target.getHidden(); return this.mobBase.getSeeInvis() >= target.hidden;
} }
public int getBuildingID() { public int getBuildingID() {
@@ -1750,23 +1732,17 @@ public class Mob extends AbstractIntelligenceAgent {
if (!ac.getObjectType().equals(GameObjectType.PlayerCharacter)) if (!ac.getObjectType().equals(GameObjectType.PlayerCharacter))
return; return;
PlayerCharacter player = (PlayerCharacter) ac;
if (this.getCombatTarget() == null) { if (this.getCombatTarget() == null) {
this.setCombatTarget(ac); this.setCombatTarget(ac);
return;
} }
if (player.getObjectUUID() == this.getCombatTarget().getObjectUUID())
return;
} }
public void setRank(int newRank) { public void setRank(int newRank) {
DbManager.MobQueries.SET_PROPERTY(this, "mob_level", newRank); DbManager.MobQueries.SET_PROPERTY(this, "mob_level", newRank);
this.level = (short) newRank; this.level = (short) newRank;
this.recalculateStats();
this.setHealth(this.healthMax);
} }
public boolean isRanking() { public boolean isRanking() {
@@ -1798,10 +1774,6 @@ public class Mob extends AbstractIntelligenceAgent {
this.weaponPower = weaponPower; this.weaponPower = weaponPower;
} }
public ConcurrentHashMap<Mob, Integer> getSiegeMinionMap() {
return siegeMinionMap;
}
public DateTime getUpgradeDateTime() { public DateTime getUpgradeDateTime() {
lock.readLock().lock(); lock.readLock().lock();
@@ -1822,7 +1794,8 @@ public class Mob extends AbstractIntelligenceAgent {
} }
public boolean isPlayerGuard() { public boolean isPlayerGuard() {
return isPlayerGuard;
return EnumSet.of(AIAgentType.GUARDCAPTAIN, AIAgentType.GUARDMINION, AIAgentType.GUARDWALLARCHER).contains(this.agentType);
} }
public int getLastMobPowerToken() { public int getLastMobPowerToken() {
@@ -1902,5 +1875,4 @@ public class Mob extends AbstractIntelligenceAgent {
lock.writeLock().unlock(); lock.writeLock().unlock();
} }
} }
} }
+3 -28
View File
@@ -27,6 +27,7 @@ public class MobBase extends AbstractGameObject {
private final String firstName; private final String firstName;
private final byte level; private final byte level;
private final float scale; private final float scale;
public final ArrayList<MobBaseEffects> effectsList;
public int bootySet; public int bootySet;
public Enum.MobBehaviourType fsm; public Enum.MobBehaviourType fsm;
public EnumBitSet<Enum.MonsterType> notEnemy; public EnumBitSet<Enum.MonsterType> notEnemy;
@@ -42,10 +43,6 @@ public class MobBase extends AbstractGameObject {
private int goldMod; private int goldMod;
private int seeInvis; private int seeInvis;
private int spawnTime = 0; private int spawnTime = 0;
private int defense = 0;
private int atr = 0;
private float minDmg = 0;
private float maxDmg = 0;
private float attackRange; private float attackRange;
private boolean isNecroPet = false; private boolean isNecroPet = false;
private MobBaseStats mobBaseStats; private MobBaseStats mobBaseStats;
@@ -108,6 +105,8 @@ public class MobBase extends AbstractGameObject {
this.mobBaseStats = DbManager.MobBaseQueries.LOAD_STATS(this.loadID); this.mobBaseStats = DbManager.MobBaseQueries.LOAD_STATS(this.loadID);
DbManager.MobBaseQueries.LOAD_ALL_MOBBASE_SPEEDS(this); 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 {
return mobBaseStats; 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() { public float getAttackRange() {
return attackRange; return attackRange;
} }
+10
View File
@@ -21,6 +21,9 @@ public class MobBaseStats {
private final int baseSpi; private final int baseSpi;
private final int baseDex; private final int baseDex;
private final int mobbaseSkill;
private final int mobbaseSkillAmount;
/** /**
* ResultSet Constructor * ResultSet Constructor
@@ -31,6 +34,8 @@ public class MobBaseStats {
this.baseCon = rs.getInt("Constitution"); this.baseCon = rs.getInt("Constitution");
this.baseSpi = rs.getInt("Spirit"); this.baseSpi = rs.getInt("Spirit");
this.baseDex = rs.getInt("Dexterity"); this.baseDex = rs.getInt("Dexterity");
this.mobbaseSkill = rs.getInt("baseSkills");
this.mobbaseSkillAmount = rs.getInt("skillAmount");
} }
/** /**
@@ -43,6 +48,8 @@ public class MobBaseStats {
this.baseCon = 0; this.baseCon = 0;
this.baseSpi = 0; this.baseSpi = 0;
this.baseDex = 0; this.baseDex = 0;
this.mobbaseSkill = 0;
this.mobbaseSkillAmount = 0;
} }
public static MobBaseStats GetGenericStats() { public static MobBaseStats GetGenericStats() {
@@ -72,5 +79,8 @@ public class MobBaseStats {
return baseDex; return baseDex;
} }
public int getBaseSkill(){return mobbaseSkill;}
public int getBaseSkillAmount(){return mobbaseSkillAmount;}
} }
+17 -9
View File
@@ -640,28 +640,31 @@ public class NPC extends AbstractCharacter {
public void removeMinions() { public void removeMinions() {
for (Mob toRemove : this.siegeMinionMap.keySet()) {
for (Integer minionUUID : this.minions) {
Mob minionMob = Mob.getMob(minionUUID);
try { try {
toRemove.clearEffects(); minionMob.clearEffects();
} catch (Exception e) { } catch (Exception e) {
Logger.error(e.getMessage()); Logger.error(e.getMessage());
} }
if (toRemove.getParentZone() != null) if (minionMob.getParentZone() != null)
toRemove.getParentZone().zoneMobSet.remove(toRemove); minionMob.getParentZone().zoneMobSet.remove(minionMob);
WorldGrid.RemoveWorldObject(toRemove); WorldGrid.RemoveWorldObject(minionMob);
DbManager.removeFromCache(toRemove); DbManager.removeFromCache(minionMob);
PlayerCharacter petOwner = (PlayerCharacter) toRemove.guardCaptain; PlayerCharacter petOwner = (PlayerCharacter) minionMob.guardCaptain;
if (petOwner != null) { if (petOwner != null) {
petOwner.setPet(null); petOwner.setPet(null);
toRemove.guardCaptain = null; minionMob.guardCaptain = null;
PetMsg petMsg = new PetMsg(5, null); PetMsg petMsg = new PetMsg(5, null);
Dispatch dispatch = Dispatch.borrow(petOwner, petMsg); Dispatch dispatch = Dispatch.borrow(petOwner, petMsg);
@@ -669,6 +672,7 @@ public class NPC extends AbstractCharacter {
} }
} }
} }
@Override @Override
@@ -861,7 +865,7 @@ public class NPC extends AbstractCharacter {
this.bindLoc = new Vector3fImmutable(this.statLat, this.statAlt, this.statLon); this.bindLoc = new Vector3fImmutable(this.statLat, this.statAlt, this.statLon);
this.bindLoc = this.parentZone.getLoc().add(this.bindLoc); this.bindLoc = this.parentZone.getLoc().add(this.bindLoc);
this.loc = new Vector3fImmutable(bindLoc); this.setLoc(bindLoc);
// Handle NPCs within buildings // Handle NPCs within buildings
@@ -968,6 +972,10 @@ public class NPC extends AbstractCharacter {
Bounds npcBounds = Bounds.borrow(); Bounds npcBounds = Bounds.borrow();
npcBounds.setBounds(this.getLoc()); npcBounds.setBounds(this.getLoc());
//apply NPC rune effects
NPCManager.applyRunesForNPC(this);
this.resists.setImmuneToAll(true);
} catch (Exception e) { } catch (Exception e) {
Logger.error(e.getMessage()); Logger.error(e.getMessage());
} }
+3 -51
View File
@@ -117,10 +117,8 @@ public class PlayerCharacter extends AbstractCharacter {
public float landingAltitude = 0; public float landingAltitude = 0;
public int bindBuilding = 0; public int bindBuilding = 0;
public FriendStatus friendStatus = FriendStatus.Available; public FriendStatus friendStatus = FriendStatus.Available;
protected ArrayList<CharacterRune> runes;
private BaseClass baseClass; private BaseClass baseClass;
private PromotionClass promotionClass; 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 ConcurrentHashMap<Integer, String> ignoredPlayerIDs = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW);
private boolean lfGroup = false; private boolean lfGroup = false;
private boolean lfGuild = false; private boolean lfGuild = false;
@@ -135,7 +133,6 @@ public class PlayerCharacter extends AbstractCharacter {
private Vector3fImmutable lastStaticLoc = new Vector3fImmutable(0.0f, 0.0f, 0.0f); private Vector3fImmutable lastStaticLoc = new Vector3fImmutable(0.0f, 0.0f, 0.0f);
private GameObjectType lastTargetType; private GameObjectType lastTargetType;
private int lastTargetID; private int lastTargetID;
private int hidden = 0; // current rank of hide/sneak/invis
private int seeInvis = 0; // current rank of see invis private int seeInvis = 0; // current rank of see invis
private float speedMod; private float speedMod;
private boolean teleportMode = false; // Teleport on MoveToPoint private boolean teleportMode = false; // Teleport on MoveToPoint
@@ -2774,10 +2771,6 @@ public class PlayerCharacter extends AbstractCharacter {
this.lastStaticLoc = value; this.lastStaticLoc = value;
} }
public int getHidden() {
return this.hidden;
}
public void setHidden(int value) { public void setHidden(int value) {
this.hidden = value; this.hidden = value;
} }
@@ -4839,7 +4832,7 @@ public class PlayerCharacter extends AbstractCharacter {
} else } else
this.altitude = this.getDesiredAltitude(); 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); this.setTakeOffTime(0);
MovementManager.finishChangeAltitude(this, this.getDesiredAltitude()); MovementManager.finishChangeAltitude(this, this.getDesiredAltitude());
@@ -4847,7 +4840,7 @@ public class PlayerCharacter extends AbstractCharacter {
return; 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() { public boolean hasBoon() {
@@ -4893,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)) { 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 //Target is stunned or rooted. Don't move
this.stopMovement(newLoc); this.stopMovement(newLoc);
this.region = AbstractWorldObject.GetRegionByWorldObject(this);
return; return;
} }
if (newLoc.equals(this.getEndLoc())) { if (newLoc.equals(this.getEndLoc())) {
this.stopMovement(newLoc); this.stopMovement(newLoc);
this.region = AbstractWorldObject.GetRegionByWorldObject(this);
if (this.getDebug(1)) if (this.getDebug(1))
ChatManager.chatSystemInfo(this, ChatManager.chatSystemInfo(this,
"Arrived at End location. " + this.getEndLoc()); "Arrived at End location. " + this.getEndLoc());
@@ -4907,7 +4898,6 @@ public class PlayerCharacter extends AbstractCharacter {
} }
setLoc(newLoc); setLoc(newLoc);
this.region = AbstractWorldObject.GetRegionByWorldObject(this);
if (this.getDebug(1)) if (this.getDebug(1))
ChatManager.chatSystemInfo(this, ChatManager.chatSystemInfo(this,
@@ -5358,7 +5348,7 @@ public class PlayerCharacter extends AbstractCharacter {
moveToMsg.setStartCoord(this.getLoc()); moveToMsg.setStartCoord(this.getLoc());
moveToMsg.setEndCoord(endLoc); moveToMsg.setEndCoord(endLoc);
moveToMsg.setInBuilding(-1); moveToMsg.setInBuilding(-1);
moveToMsg.setUnknown01(-1); moveToMsg.setInBuildingFloor(-1);
moveToMsg.setSourceType(GameObjectType.PlayerCharacter.ordinal()); moveToMsg.setSourceType(GameObjectType.PlayerCharacter.ordinal());
moveToMsg.setSourceID(this.getObjectUUID()); moveToMsg.setSourceID(this.getObjectUUID());
@@ -5441,14 +5431,6 @@ public class PlayerCharacter extends AbstractCharacter {
return characterHeight; return characterHeight;
} }
public void setCharacterHeight(float characterHeight) {
this.characterHeight = characterHeight;
}
public void setCenterHeight(float centerHeight) {
this.centerHeight = centerHeight;
}
public boolean isEnteredWorld() { public boolean isEnteredWorld() {
return enteredWorld; return enteredWorld;
} }
@@ -5457,40 +5439,10 @@ public class PlayerCharacter extends AbstractCharacter {
this.enteredWorld = enteredWorld; this.enteredWorld = enteredWorld;
} }
public long getChannelMute() {
return channelMute;
}
public void setChannelMute(long channelMute) {
this.channelMute = channelMute;
}
public boolean isLastSwimming() { public boolean isLastSwimming() {
return lastSwimming; 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() { public ReadWriteLock getTeleportLock() {
return teleportLock; return teleportLock;
+34 -62
View File
@@ -56,9 +56,8 @@ public class Zone extends AbstractGameObject {
private boolean isNPCCity = false; private boolean isNPCCity = false;
private boolean isPlayerCity = false; private boolean isPlayerCity = false;
private String hash; private String hash;
private float worldAltitude = 0; public float worldAltitude = 0;
private float seaLevel = 0; private float seaLevel = 0f;
//public static ArrayList<Mob> respawnQue = new ArrayList<>();
public static final Set<Mob> respawnQue = Collections.newSetFromMap(new ConcurrentHashMap<>()); public static final Set<Mob> respawnQue = Collections.newSetFromMap(new ConcurrentHashMap<>());
public static long lastRespawn = 0; public static long lastRespawn = 0;
/** /**
@@ -220,49 +219,6 @@ public class Zone extends AbstractGameObject {
return Icon1; 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() { public Zone getParent() {
return this.parent; return this.parent;
} }
@@ -272,26 +228,46 @@ public class Zone extends AbstractGameObject {
this.parent = value; this.parent = value;
this.parentZoneID = (this.parent != null) ? this.parent.getObjectUUID() : 0; this.parentZoneID = (this.parent != null) ? this.parent.getObjectUUID() : 0;
if (this.parent != null) { // 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) { // Seafloor
this.minLvl = this.parent.minLvl;
this.maxLvl = this.parent.maxLvl; if (this.parent == null) {
}
} else { //only the Sea Floor zone does not have a parent
this.absX = this.xCoord; this.absX = this.xCoord;
this.absY = MBServerStatics.SEA_FLOOR_ALTITUDE; this.absY = MBServerStatics.SEA_FLOOR_ALTITUDE;
this.absZ = this.zCoord; 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(); this.setBounds();
if (this.getHeightMap() != null && this.getHeightMap().getSeaLevel() != 0) if (this.getParent() == null) {
this.seaLevel = this.getHeightMap().getSeaLevel(); 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 {
return seaLevel; return seaLevel;
} }
public float getWorldAltitude() {
return worldAltitude;
}
} }
-17
View File
@@ -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
View File
@@ -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");
}
}
@@ -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");
}
}
@@ -38,7 +38,7 @@ public class MobRecallPowerAction extends AbstractPowerAction {
return; return;
MovementManager.translocate(awoac, awoac.getBindLoc(), null); MovementManager.translocate(awoac, awoac.getBindLoc());
if (awoac.getObjectType() == GameObjectType.Mob) { if (awoac.getObjectType() == GameObjectType.Mob) {
//MobAI.setAwake((Mob)awoac,true); //MobAI.setAwake((Mob)awoac,true);
((Mob) awoac).setCombatTarget(null); ((Mob) awoac).setCombatTarget(null);
@@ -58,7 +58,7 @@ public class RecallPowerAction extends AbstractPowerAction {
DispatchMessage.dispatchMsgDispatch(dispatch, engine.Enum.DispatchChannel.SECONDARY); DispatchMessage.dispatchMsgDispatch(dispatch, engine.Enum.DispatchChannel.SECONDARY);
} else { } else {
MovementManager.translocate(awoac, awoac.getBindLoc(), null); MovementManager.translocate(awoac, awoac.getBindLoc());
} }
} else { } else {
Vector3fImmutable bindloc = awoac.getBindLoc(); Vector3fImmutable bindloc = awoac.getBindLoc();
@@ -101,7 +101,7 @@ public class TeleportPowerAction extends AbstractPowerAction {
if (region != null && !region.isOutside()) if (region != null && !region.isOutside())
return; return;
MovementManager.translocate(awoac, targetLoc, region); MovementManager.translocate(awoac, targetLoc);
} }
@Override @Override
@@ -136,25 +136,25 @@ public class LoginServerMsgHandler implements NetMsgHandler {
cMajorVer = vim.getMajorVersion(); cMajorVer = vim.getMajorVersion();
cMinorVer = vim.getMinorVersion(); cMinorVer = vim.getMinorVersion();
if (!cMajorVer.equals(this.server.getDefaultVersionInfo().getMajorVersion())) { // if (!cMajorVer.equals(this.server.getDefaultVersionInfo().getMajorVersion())) {
this.KickToLogin(MBServerStatics.LOGINERROR_INCORRECT_CLIENT_VERSION, "Major Version Failure: " + cMajorVer, cc); // this.KickToLogin(MBServerStatics.LOGINERROR_INCORRECT_CLIENT_VERSION, "Major Version Failure: " + cMajorVer, cc);
return; // return;
} // }
/* if (!cMinorVer.equals(this.server.getDefaultVersionInfo().getMinorVersion())) { /* if (!cMinorVer.equals(this.server.getDefaultVersionInfo().getMinorVersion())) {
this.KickToLogin(MBServerStatics.LOGINERROR_INCORRECT_CLIENT_VERSION, "Minor Version Failure: " + cMinorVer, cc); this.KickToLogin(MBServerStatics.LOGINERROR_INCORRECT_CLIENT_VERSION, "Minor Version Failure: " + cMinorVer, cc);
return; return;
} */ } */
if (cMinorVer == null) { // if (cMinorVer == null) {
this.KickToLogin(MBServerStatics.LOGINERROR_INCORRECT_CLIENT_VERSION, "Minor Version Failure: ", cc); // this.KickToLogin(MBServerStatics.LOGINERROR_INCORRECT_CLIENT_VERSION, "Minor Version Failure: ", cc);
return; // return;
} // }
if (cMinorVer.length() < 8 || cMinorVer.length() > 16) { // if (cMinorVer.length() < 8 || cMinorVer.length() > 16) {
this.KickToLogin(MBServerStatics.LOGINERROR_INCORRECT_CLIENT_VERSION, "Minor Version Failure: ", cc); // this.KickToLogin(MBServerStatics.LOGINERROR_INCORRECT_CLIENT_VERSION, "Minor Version Failure: ", cc);
return; // return;
} // }
// set MachineID for this connection // set MachineID for this connection
+6 -5
View File
@@ -17,7 +17,7 @@ import engine.InterestManagement.HeightMap;
import engine.InterestManagement.RealmMap; import engine.InterestManagement.RealmMap;
import engine.InterestManagement.WorldGrid; import engine.InterestManagement.WorldGrid;
import engine.db.archive.DataWarehouse; import engine.db.archive.DataWarehouse;
import engine.db.handlers.dbPowerHandler; import engine.db.handlers.dbRuneBaseHandler;
import engine.exception.MsgSendException; import engine.exception.MsgSendException;
import engine.gameManager.*; import engine.gameManager.*;
import engine.job.JobContainer; import engine.job.JobContainer;
@@ -351,8 +351,11 @@ public class WorldServer {
Logger.info("Loading MobBases."); Logger.info("Loading MobBases.");
DbManager.MobBaseQueries.GET_ALL_MOBBASES(); DbManager.MobBaseQueries.GET_ALL_MOBBASES();
Logger.info("Loading Mob Powers"); Logger.info("Loading Rune Powers");
PowersManager.AllMobPowers = dbPowerHandler.LOAD_MOB_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"); Logger.info("Loading item enchants");
DbManager.LootQueries.LOAD_ENCHANT_VALUES(); DbManager.LootQueries.LOAD_ENCHANT_VALUES();
@@ -563,8 +566,6 @@ public class WorldServer {
for (Zone zone : rootParent) { for (Zone zone : rootParent) {
ZoneManager.addZone(zone.getLoadNum(), zone); ZoneManager.addZone(zone.getLoadNum(), zone);
zone.generateWorldAltitude();
//Handle Buildings //Handle Buildings