mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-25 06:52:29 +00:00
Compare commits
196 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a3f21cc9ea | |||
| 3c9e6d913a | |||
| 153e587cea | |||
| fbb13ec416 | |||
| e7785d5693 | |||
| 23bc535e23 | |||
| d04d6750a2 | |||
| 9c08d6f25b | |||
| f8d000d660 | |||
| b2c6bb4df5 | |||
| 542d0795c4 | |||
| c3b7f6d0bf | |||
| 21e53a3cd0 | |||
| 2d24237aac | |||
| 750e65f847 | |||
| 3ce99d9f00 | |||
| 598196329d | |||
| 31cc6f63d6 | |||
| bbfacd902c | |||
| 5cfb3111a6 | |||
| 5b674f23bd | |||
| 81cadf3bb2 | |||
| 54c28117a8 | |||
| 79f9433dfa | |||
| 67a95b59a7 | |||
| 09b9d398e2 | |||
| 3dd0d43e96 | |||
| 8d1fe63e77 | |||
| 3fa72218a4 | |||
| f3f034d948 | |||
| bd364a4049 | |||
| 41b1634199 | |||
| 0159e1cc72 | |||
| ab372b0f6b | |||
| 14d09485eb | |||
| 8cd6416754 | |||
| 4fad93824b | |||
| fe70834a6b | |||
| 17b5cc1fa5 | |||
| 04ce4f66ed | |||
| 5b24cbde5d | |||
| 3555791e1f | |||
| 262bcf5c29 | |||
| 226a49cb42 | |||
| bf3d9b2d02 | |||
| 3d229e1da1 | |||
| df5d58f43d | |||
| 37d22e17a3 | |||
| 999650d368 | |||
| 09bbfbcc31 | |||
| f26b7a4adc | |||
| becd7b5c24 | |||
| d559e9da10 | |||
| 2690d8fed8 | |||
| 7d13475bac | |||
| 2ab280bef0 | |||
| 15af28720a | |||
| 5213e4c7d4 | |||
| 12d7f242b4 | |||
| 7ac597270b | |||
| 05ca4669a9 | |||
| a7cbe2f60e | |||
| 52d79f89a9 | |||
| a8a1c3f809 | |||
| 24bae49401 | |||
| bf239f9691 | |||
| 666513c4ab | |||
| 1b2df18cea | |||
| b1be667884 | |||
| 91ae6a6613 | |||
| 303f056075 | |||
| ec9af74dc9 | |||
| a49e3d6471 | |||
| 9ae585dd81 | |||
| 0ee3168241 | |||
| 3fd40e9449 | |||
| c61c275221 | |||
| 7a6d5d46f4 | |||
| 14a5ff399a | |||
| 31907382c8 | |||
| 5c6492bc0f | |||
| 0968ce0d60 | |||
| 171474f1d2 | |||
| 3383f65ff7 | |||
| 7621bf47c8 | |||
| 72ed770037 | |||
| 4e8a03f7b4 | |||
| 602381ebec | |||
| e098836934 | |||
| ce3fc0f2c3 | |||
| 9adfe5b9ff | |||
| b423ad0d80 | |||
| 9a157fa028 | |||
| 7db82a3b14 | |||
| 056725b9bd | |||
| 8bbf099636 | |||
| a884639534 | |||
| 8f67df1f4f | |||
| f851b1a3b4 | |||
| b41bb8e179 | |||
| d9633dfee4 | |||
| 46b19e8e6f | |||
| f0f5c41c30 | |||
| 08c2f73e37 | |||
| 9f4604ec3e | |||
| 8177f7d9bb | |||
| 4ec3fda59d | |||
| e3c8b75259 | |||
| d62a449f9c | |||
| d043c38f71 | |||
| 5b8ad902ce | |||
| ef16522473 | |||
| fe21564659 | |||
| e3173d04d4 | |||
| 92d4468326 | |||
| 0f32f780a9 | |||
| 955514c20f | |||
| ed717add29 | |||
| a7b159fe65 | |||
| 38651258fc | |||
| 4605540955 | |||
| c83bc038f3 | |||
| d3dff3760a | |||
| 9e49b2ae0f | |||
| a81212e1b4 | |||
| 57d75572b2 | |||
| d1abe4a332 | |||
| cd11d7d1af | |||
| 3d1bb6bd08 | |||
| e9c1681e2c | |||
| 5dbbc5f21c | |||
| ef8b4754ea | |||
| a13694c859 | |||
| 51eaf25ea0 | |||
| 592f9a9cb9 | |||
| 409dc3ad35 | |||
| f8f783fa46 | |||
| 1d1382cb12 | |||
| 68680ac9d8 | |||
| df1d499da6 | |||
| a6a056ad0d | |||
| b1f14e1e29 | |||
| 1999982e6a | |||
| b0ad9524bc | |||
| d8519bc270 | |||
| da9792160d | |||
| dc308e2ecb | |||
| 984a009fbb | |||
| 5d61cf5bcf | |||
| 2db6464d14 | |||
| c17ac67296 | |||
| 37e87e8cef | |||
| e300f82c28 | |||
| 05cb9d56c2 | |||
| ac0cba64f9 | |||
| 0b3b3fdc88 | |||
| 104a0998ce | |||
| cdf0d5deb0 | |||
| 36300d6df1 | |||
| 3d54a4edcb | |||
| 31de6a63cc | |||
| ae81ab8a12 | |||
| 7033d9d919 | |||
| 905e3acab3 | |||
| 2c6e11b464 | |||
| 9aba993888 | |||
| f614c35f6e | |||
| 8f21b01b7e | |||
| 591fa003c6 | |||
| f3e09abf22 | |||
| 18e6e5e5e2 | |||
| 698a814fc3 | |||
| fb820f4fec | |||
| 0d84a73e9f | |||
| b92d6c57a1 | |||
| 8c6fefa33e | |||
| e03a90b05d | |||
| c030e1ce8d | |||
| 7e49a21b3b | |||
| 9e824876ba | |||
| 891fa0411c | |||
| a4fda2a951 | |||
| ffdc933ce0 | |||
| e3f15de1f8 | |||
| 6cef5c6beb | |||
| da08a622f1 | |||
| 50a67c76e7 | |||
| 0a4ccb11aa | |||
| af4a432745 | |||
| df86e644f4 | |||
| 80ff535215 | |||
| 30157a37a2 | |||
| f5827174ee | |||
| 1d19bd11d0 | |||
| 6a2be94282 | |||
| 630ea0d3c6 |
+159
-20
@@ -1,5 +1,144 @@
|
||||
EQEMu Changelog (Started on Sept 24, 2003 15:50)
|
||||
-------------------------------------------------------
|
||||
== 03/12/2017 ==
|
||||
Akkadius:
|
||||
- Implemented range rules for packets and other functions
|
||||
RULE_INT ( Range, Say, 135 )
|
||||
RULE_INT ( Range, Emote, 135 )
|
||||
RULE_INT ( Range, BeginCast, 200)
|
||||
RULE_INT ( Range, Anims, 135)
|
||||
RULE_INT ( Range, SpellParticles, 135)
|
||||
RULE_INT ( Range, DamageMessages, 50)
|
||||
RULE_INT ( Range, SpellMessages, 75)
|
||||
RULE_INT ( Range, SongMessages, 75)
|
||||
RULE_INT ( Range, MobPositionUpdates, 600)
|
||||
RULE_INT ( Range, CriticalDamage, 80)
|
||||
|
||||
- (Readability) Also cleaned up some formatting in messaging and packets so it is easier to understand what is going on with the code
|
||||
|
||||
== 03/09/2017 ==
|
||||
Uleat: Fixed a few glitches related to bot trading and other affected code
|
||||
- Added a temporary fail clause for partial stack transfers to prevent client item overwrites
|
||||
- Return messages no longer repeat the top cursor item when multiple items are pushed there
|
||||
- Test slot for client returns is now handled appropriately for parent and bag searches
|
||||
- FindFreeSlotForTradeItem() now begins at the correct bag index on subsequent parent iterations
|
||||
Uleat: First step of implementing inventory v2.0
|
||||
|
||||
== 03/08/2017 ==
|
||||
Uleat: Complete rework of the bot trading system
|
||||
- Equipment slot priority can now be tailored..though, a recompile will be required
|
||||
- All item validations and slot assignments for trades and returns are now performed before any actual item movements occur
|
||||
- Failed trade/returned items will now go straight into the client's inventory, just like a normal trade transaction
|
||||
- A 'green' message appears at the end of each successful trade informing the trader of 'accepted' and 'returned' item counts
|
||||
- Bots respond to the trader directly now instead of using BotGroupSay()
|
||||
- Bots will still only allow trades from their owner (currently, too high a risk of exploit and/or malicious activity)
|
||||
- Partial stack movements (i.e., ammo refills) have been scoped..but, not implemented
|
||||
- I have not been able to reproduce any 'illegal' weapon combinations with this code
|
||||
- NOTE: The report of item duplication with bot return items appears to be an inventory desync condition
|
||||
- I experienced this condition both before and after the rework with RoF+ clients (UF- appears ok)
|
||||
- The bug lies within the actual client inventory system and not with bot trades
|
||||
- Please post any issues with this change as they arise
|
||||
|
||||
== 02/27/2017 ==
|
||||
Uleat: Notes on bot movement speed changes:
|
||||
- Clients (players) appear to be on a different speed scale than other entities (NPCs, etc...)
|
||||
- The server does not calculate deltas/velocities for moving players..those come the client itself
|
||||
- GetBotWalkspeed() and GetBotRunspeed() are specific to bot movement calculations
|
||||
- The class Mob equivilents are not scalared so that a 'client-oriented' value can still be attained
|
||||
- The value of ~1.786f is derived from the ratio of 1.25f/0.7f (npc speed/client speed)
|
||||
- Modifying the two speeds like this is a rough guess-timate..but, appears to at least bring the incongruous behavior to acceptable levels
|
||||
|
||||
== 02/26/2017 ==
|
||||
Uleat: Moved bot `npc_spells` entries from '701-712' to 3000 + <class_id> .. also, added melee types for future expansion
|
||||
Uleat: Moved bot spell casting chance values into database - this will allow admins to tailor their bots without having to rebuild server code
|
||||
- Each entry uses a 3-dimensional identifier: [spell type index][class id][stance index]
|
||||
- [spell type index] is not the SpellType_## bit value..use SpellType_##Index instead
|
||||
- [class id] values of 1-16 are valid and hold a direct correlation to server-coded player class values
|
||||
- [stance index] is a direct correlation (0-6)
|
||||
- the 'conditional fields' are currently predicated on 4 compounded boolean states:
|
||||
- `pH_value` represents bit '0'
|
||||
- `pS_value` represents bit '1'
|
||||
- `pN_value` represents bit '2'
|
||||
- `pD_value` represents bit '3'
|
||||
- all other conditional fields are masked based on these 4 predicates
|
||||
- the full conditional field enumeration is as follows:
|
||||
- `nHSND_value` - negative Healer/Slower/Nuker/Doter
|
||||
- `pH_value` - positive Healer
|
||||
- `pS_value` - positive Slower
|
||||
- `pHS_value` - positive Healer/Slower
|
||||
- `pN_value` - positive Nuker
|
||||
- `pHN_value` - positive Healer/Nuker
|
||||
- `pSN_value` - positive Slower/Nuker
|
||||
- `pHSN_value` - positive Healer/Slower/Nuker
|
||||
- `pD_value` - positive Doter
|
||||
- `pHD_value` - positive Healer/Doter
|
||||
- `pSD_value` - positive Slower/Doter
|
||||
- `pHSD_value` - positive Healer/Slower/Doter
|
||||
- `pND_value` - positive Nuker/Doter
|
||||
- `pHND_value` - positive Healer/Nuker/Doter
|
||||
- `pSND_value` - positive Slower/Nuker/Doter
|
||||
- `pHSND_value` - positive Healer/Slower/Nuker/Doter
|
||||
- Single- and mixed-bits fields should be filled-in based on the boolean 'AND' concept
|
||||
- (i.e., if 'healer' then `pH_value`=x; if 'slower' then `pS_value`=y; if 'healer' AND 'slower' then `pHS_value`=z; )
|
||||
- most cases can allow the same value across all fields..but, there are some that shouldn't and this format allows for their discrimination
|
||||
- Valid `##_value` entries are 0-100..though, the field accepts up to 255... Anything above 100 is clamped to 100 upon loading, however...
|
||||
- Not all conditions are currently coded and changing a field may not produce any results
|
||||
- The 'default' database values will be changed and tweaked as bot spell code modifications occur
|
||||
|
||||
== 02/25/2017 ==
|
||||
Uleat: Implemented rule-based node pathing for bots
|
||||
- This currently applies to out-of-combat following movement and blocked los in-combat movement
|
||||
- The default is set to 'true' (use node pathing)..so, consider disabling it if cpu use is too high
|
||||
- If you want to disable node pathing, apply the optional sql '2017_02_25_bots_use_pathing_rule.sql' file located in the utils/sql/git/bots/optional sub-directory. This will apply a 'false' rule..but, it can be changed as desired
|
||||
- This helps with bot movement..but, there are still issues...
|
||||
Uleat: Implemented rule-based position update packet with movement timer check for bots
|
||||
- This currently only applies to out-of-combat movement
|
||||
- The default is set to 'false' (original behavior) to help save bandwidth (each bot will send an update packet every 1/10th of a second when enabled)
|
||||
- If you want to enable the position update packet, apply the optional sql '2017_02_25_bots_update_position_with_timer_rule.sql' file located in the utils/sql/git/bots/optional sub-directory. This will apply a 'true' rule..but, it can be changed as desired
|
||||
- This appears to help with/eliminate rubber banding
|
||||
|
||||
== 02/23/2017 ==
|
||||
** THIS NOTE HAS BEEN SUPERCEDED ON 02/26/2017 **
|
||||
Uleat: Moved bot spell casting chance values into database - this will allow admins to tailor their bots without having to rebuild server code
|
||||
- Each entry uses a 4-dimensional identifier: [spell type index][class index][stance index][conditional index]
|
||||
- [spell type index] is not the SpellType_## bit value..use SpellType_##Index instead
|
||||
- [class index] values of 0-15 are valid and determined by subtracting 1 from the actual class value
|
||||
- [stance index] is a direct correlation (0-6)
|
||||
- the [conditional index] is currently predicated on 2 compounded boolean states:
|
||||
- not primary healer/not primary slower: 0
|
||||
- primary healer/not primary slower: 1
|
||||
- not primary healer/ primary slower: 2
|
||||
- primary healer/primary slower: 3
|
||||
- Valid `value` entries are 0-100..though, the field accepts up to 255... Anything above 100 is clamped to 100 upon loading, however
|
||||
- Not all conditions are currently coded and changing a field may not produce any results
|
||||
- The 'default' database values will be changed and tweaked as bot spell code modifications occur
|
||||
|
||||
== 02/20/2017 ==
|
||||
Uleat: Reworked bard bot spell twisting and updated their spell (song) list
|
||||
Uleat: Added ability to shift to pre-combat song buffing by selecting a non-pet npc target, eliminating the need to mix all bard buff songs together
|
||||
|
||||
== 2/19/2017 ==
|
||||
Akkadius: Added a fix for limiting the amount of items sold in a stack when the resulting return coin is higher than the supporting struct for returning coin
|
||||
|
||||
== 01/31/2017 ==
|
||||
Uleat: Modifed bot movement behavior in an attempt to 'normalize' it. This is a hack fix and will be revisited at some point. (Probably just need a follow function rather than use movement, when the leader of the follow chain is moving.)
|
||||
|
||||
== 01/26/2017 ==
|
||||
Uleat: Change rogue bot behavior to eliminate twirling combat. They will only get behind the mob if they are not the mob's target or if the mob is feared or fleeing. This may lower rogue bot dps a small fraction..but, is more in-line with realistic game mechanics.
|
||||
|
||||
== 01/17/2017 ==
|
||||
Mackal: Combat Revamp
|
||||
- This change brings melee combat into line with how combat is done on live.
|
||||
- This correctly applies the PC damage tables and corrects stacking order of many spells
|
||||
- Given the scope of what had to be rewritten, it was not feasible to preserve the old combat system.
|
||||
This means you will likely have to rebalance your server, which sucks, but this is very
|
||||
accurate so shouldn't require any more changes, at least none that would cause you to have
|
||||
to rebalance your server again.
|
||||
- For rebalancing, I would recommend running the optional SQL and tweaking from there.
|
||||
- To help with rebalancing there is a simulator included at utils/combat-sim.
|
||||
- You can enter the mitigation or offense values you would like to balance around (#showstats will show you them)
|
||||
a 1 on the sim is min damage 20 is max.
|
||||
- Quick recommendations for best ways to improve PC DPS, give them some worn (or AA) SE_DamageModifier and/or SE_MinDamageModifier
|
||||
== 12/03/2016 ==
|
||||
Uleat: Added hack detection to trade code
|
||||
- If illegal items are found in trade slots when the 'trade' button is clicked, the trade is cancelled and a message is sent to the offending player
|
||||
@@ -28,7 +167,7 @@ take into account that rogue was sneaking. Now sneaking rogues can see full
|
||||
inventory on merchants (well, unless an item requires a + faction value).
|
||||
|
||||
== 09/12/2016 ==
|
||||
Akkadius: Massive overhaul of the update system and EQEmu Server management utility framework
|
||||
Akkadius: Massive overhaul of the update system and EQEmu Server management utility framework
|
||||
(known as eqemu_update.pl) now known as eqemu_server.pl
|
||||
- eqemu_server.pl is now a general EQEmu Server management utiltiy framework that can be used
|
||||
to extend to many purposes. It's main purpose is to simplify server management
|
||||
@@ -49,7 +188,7 @@ Akkadius: Massive overhaul of the update system and EQEmu Server management util
|
||||
- Regular bots database schema changes now happen automatically similarily to the above
|
||||
- Database checks can also be ran manually via the script menu
|
||||
- CLI Arguments
|
||||
- Arguments passed to eqemu_server.pl can execute the same name-based operations that
|
||||
- Arguments passed to eqemu_server.pl can execute the same name-based operations that
|
||||
are present in the interactive menu
|
||||
- Example: "perl eqemu_server.pl opcodes" will download opcodes
|
||||
- Example: "perl eqemu_server.pl backup_player_tables" will backup and export player tables
|
||||
@@ -64,7 +203,7 @@ Akkadius: Massive overhaul of the update system and EQEmu Server management util
|
||||
- server_start_dev.sh
|
||||
- server_start.sh
|
||||
- server_status.sh
|
||||
- server_stop.sh
|
||||
- server_stop.sh
|
||||
- Usage analytics
|
||||
- eqemu_server.pl now collects usage analytics, this is very helpful for our developers
|
||||
- Example: We can see how many installs have been performed:
|
||||
@@ -76,10 +215,10 @@ Akkadius: Massive overhaul of the update system and EQEmu Server management util
|
||||
- 'New Server' Utility
|
||||
- Running 'new_server' from the main menu or 'perl eqemu_server.pl new_server' while in
|
||||
a completely new folder with just the script present, will allow a server operator
|
||||
to initiate a full clean PEQ install in that folder. Pulling down all assets and
|
||||
installing a PEQ database with the name the server operator gives the prompts in the
|
||||
to initiate a full clean PEQ install in that folder. Pulling down all assets and
|
||||
installing a PEQ database with the name the server operator gives the prompts in the
|
||||
script
|
||||
|
||||
|
||||
== 09/10/2016 ==
|
||||
noudess: Task system experience based on a % of a level did not take into
|
||||
account the hell levels rule. Now it does.
|
||||
@@ -133,7 +272,7 @@ Kinglykrab: Implemented optional avoidance cap rules.
|
||||
- Rule Names:
|
||||
- Character:EnableAvoidanceCap (default is false)
|
||||
- Character:AvoidanceCap (default is 750, beyond 1,000 seems to make characters dodge all attacks)
|
||||
|
||||
|
||||
== 08/02/2016 ==
|
||||
Uleat: Changed 'SendZoneSpawnsBulk' behavior to use near/far criteria (live-like) when sending packets.
|
||||
- Zone-to-Zone client loading will see a small decrease in time (less than 10~15%)
|
||||
@@ -171,7 +310,7 @@ mackal: Fix up the SpellBuff struct
|
||||
Uleat: Important fix for mob pathing
|
||||
- This should fix failed pathing issues (and high cpu usage for zone.exe) for mobs in affect zones
|
||||
- Changed variable 'gridno' type from int16 to int32 to reflect actual return value of fetch (values do exceed 32767 aka int16.max)
|
||||
- Precision loss from int32 to int16 conversion was causing grid id to be changed to quest controlled movement in cases where (gridno & 0x8000 == true)
|
||||
- Precision loss from int32 to int16 conversion was causing grid id to be changed to quest controlled movement in cases where (gridno & 0x8000 == true)
|
||||
|
||||
== 06/28/2016 ==
|
||||
Noudess: Resurrection effects now block certain buffs like on live.
|
||||
@@ -240,7 +379,7 @@ Uleat: Moved database query code out of bot.cpp and into the new BotDatabase cla
|
||||
|
||||
== 03/25/2016 ==
|
||||
Uleat: Fix for heal rotation 'Stack Overflow' error
|
||||
Kayen: Defensive procs will now only proc once per attack round (instead of every attack chance).
|
||||
Kayen: Defensive procs will now only proc once per attack round (instead of every attack chance).
|
||||
Live like modifier added that decreases defensive proc chance if you are higher level then your attacker.
|
||||
|
||||
== 03/24/2016 ==
|
||||
@@ -283,7 +422,7 @@ Kinglykrab: Modified #flag so you can refresh your target's account status (GM s
|
||||
- Just target the person whose flag you want to refresh and type #flag.
|
||||
Uleat: Added itemlink functionality to the #summonitem command. Current use is limited to extracting the item id from the link.
|
||||
- Invoking by item link '#summonitem Arrow' produces the same result as by item id '#summonitem 8005'
|
||||
|
||||
|
||||
== 01/12/2016 ==
|
||||
Athrogate: Adding ClearCompassMark() to Lua.
|
||||
- Lua didn't have ClearCompassMark(). Perl already had this.
|
||||
@@ -313,7 +452,7 @@ Kinglykrab: Added GetInstanceTimer() to Perl and Lua.
|
||||
- Note: If you do not provide an instance id in the method it defaults to instance id 0 and returns 0 for time remaining.
|
||||
- Added UpdateZoneHeader(type, value) to Perl and Lua.
|
||||
- Note: UpdateZoneHeader allows you to manipulate fog color, fog density, and many other zone header settings on the fly in Perl and Lua.
|
||||
|
||||
|
||||
== 12/21/2015 ==
|
||||
Natedog: Updated item table fields and added a few missing fields for evolving items
|
||||
-DO NOT implement Heirloom items till the inventory code is fixed to allow placing NO DROP
|
||||
@@ -322,7 +461,7 @@ Natedog: Updated item table fields and added a few missing fields for evolving i
|
||||
100% 2HSlashing (Max 50) - can only increase 2hslash by 50 MAX! (item field located though)
|
||||
Kinglykrab: Added GetMeleeMitigation() for NPCs and Clients in Perl and Lua.
|
||||
- This allows you to check total item, spell, and AA melee mitigation contribution.
|
||||
|
||||
|
||||
== 12/19/2015 ==
|
||||
Kinglykrab: Added many methods to Perl and Lua, list below:
|
||||
- SeeInvisible()
|
||||
@@ -344,7 +483,7 @@ Kinglykrab: Added many methods to Perl and Lua, list below:
|
||||
- HasPet()
|
||||
- IsSilenced()
|
||||
- IsAmnesiad()
|
||||
|
||||
|
||||
== 12/16/2015 ==
|
||||
Noudess: Repaired issue with Bind Wounds on someone else. Message was not coming out on client (hold still) and a bind wounds on someone already binding their wounds would interrupt their bind and make them stand. Also removed some duplicate messaging.
|
||||
|
||||
@@ -353,7 +492,7 @@ Kinglykrab: Added IsBlind() and IsFeared() functionality to Perl and Lua.
|
||||
- Note: Both methods are Mob methods and may be used on NPCs or PCs.
|
||||
Natedog: Added Discipline functions, UpdateInstanceTimer function, and UnmemSpellBySpellID to lua and perl
|
||||
-Examples: http://wiki.eqemulator.org/i?M=Pastebin&Paste=BJ0ygmNM
|
||||
|
||||
|
||||
== 12/07/2015 ==
|
||||
Uleat: Command aliases are no longer handled through the command_add() function.
|
||||
- To add a command alias, edit the database table `command_settings` - here, you will find three columns: `command`, `access` and `aliases`
|
||||
@@ -366,7 +505,7 @@ Uleat: Command aliases are no longer handled through the command_add() function.
|
||||
- If you need need more name space for aliases, simply edit the `command_settings` table and increase the size of the `aliases` column
|
||||
- The old `commands` table has been renamed to `commands_old` for reference
|
||||
- All of the current 'standard' commands have been added to the new `command_settings` table
|
||||
|
||||
|
||||
- YOU WILL NEED TO VERIFY/IMPORT OLD ACCESS VALUES AS THIS CHANGE REVERTS ALL COMMAND ACCESS VALUES TO THEIR PEQDB DEFAULTS
|
||||
|
||||
== 11/30/2015 ==
|
||||
@@ -388,7 +527,7 @@ Akkadius: Performance boost (exponential) - Adjusted default idle cast check tim
|
||||
- Database version 9089 will take care of this update automatically only if you used the default values
|
||||
- The CPU cost of NPC's checking the entire entity list to cast beneficial spells (Heals/Buffs) becomes extremely high when higher NPC count zones exist (Based off of process profiling)
|
||||
- Distance checks for every single NPC to every single other NPC who are casting beneficial spells occur every .5 - 2 seconds unless npc_spells dictates other values, which most of the time it does not
|
||||
- Zones that once fluctuated from 1-8% CPU with no activity (Idle but players present) now idle at .5% based on my testings due
|
||||
- Zones that once fluctuated from 1-8% CPU with no activity (Idle but players present) now idle at .5% based on my testings due
|
||||
to this change in conjunction with the past few performance commits, these are zones that have 600-800 NPC's in them
|
||||
- These values normally are overidden by the spells table (npc_spells), fields (idle_no_sp_recast_min, idle_no_sp_recast_max)
|
||||
|
||||
@@ -396,7 +535,7 @@ Akkadius: Performance boost (exponential) - Adjusted default idle cast check tim
|
||||
Akkadius: Made many performance optimizing oriented code changes in the source
|
||||
- Added Rate limit the rate in which signals are processed for NPC's (.5 seconds instead of .01 seconds)
|
||||
Akkadius: Added Perl Export Settings which should heavily reduce the Perl footprint
|
||||
- Normally when any sub EVENT_ gets triggered, all kinds of variables have to get exported every single time an event is triggered and
|
||||
- Normally when any sub EVENT_ gets triggered, all kinds of variables have to get exported every single time an event is triggered and
|
||||
this can make Perl very slow when events are triggered constantly
|
||||
- The two most taxing variable exports are the item variables ($itemcount{} $hasitem{} $oncursor{}) and qglobals ($qglobals{})
|
||||
- qglobals can pose to be an issue quickly when global qglobals build up, it is highly recommend to use the GetGlobal() and SetGlobal()
|
||||
@@ -424,7 +563,7 @@ Akkadius: Added Perl Export Settings which should heavily reduce the Perl footpr
|
||||
| 4 | EVENT_ATTACK | 0 | 1 | 1 | 0 | 1 |
|
||||
| 5 | EVENT_COMBAT | 1 | 1 | 1 | 0 | 1 |
|
||||
+----------+-----------------------------------------+-----------------+------------+-------------+-------------+--------------+
|
||||
|
||||
|
||||
- If a change is made to this table while the server is live and running, you can hot reload all zone process settings via:
|
||||
#reloadperlexportsettings
|
||||
- For those who wonder what "exports" are, they are reference to variables that are made available at runtime of the sub event, such as:
|
||||
@@ -433,7 +572,7 @@ Akkadius: Added Perl Export Settings which should heavily reduce the Perl footpr
|
||||
(export_zone) : $zoneid, $instanceid, $zoneln etc. https://github.com/EQEmu/Server/blob/master/zone/embparser.cpp#L1083
|
||||
(export_mob) : $x, $y, $z, $h, $hpratio etc. https://github.com/EQEmu/Server/blob/master/zone/embparser.cpp#L1032
|
||||
(export_event) : (event specific) IE: EVENT_SAY ($text) https://github.com/EQEmu/Server/blob/master/zone/embparser.cpp#L1141
|
||||
|
||||
|
||||
== 10/16/2015 ==
|
||||
Uleat: Added command '#bot clearfollowdistance [ <target> | spawned | all ]' to coincide with the activation of the load/save feature for follow_distance
|
||||
|
||||
@@ -465,7 +604,7 @@ rules:
|
||||
commands:
|
||||
'#invsnapshot' - Takes a snapshot of target client's inventory (feature active or inactive)
|
||||
'#clearinvsnapshots [use rule]' - Clears snapshot entries based on bool argument ([true] - honors the 'InvSnapshotHistoryD' rule, [false] - erases all)
|
||||
|
||||
|
||||
== 08/02/2015 ==
|
||||
Shendare: VS2013 query StringFormat glitches when "%f" is passed for the int GetRunSpeed().
|
||||
Shendare: In CreateNewNPCCommand(), the npc_type_id and spawngroupid are created in the database, but never set in the spawn class, so later it can't delete them with #npcspawn remove or #npcspawn delete.
|
||||
|
||||
@@ -307,6 +307,7 @@ bool Database::DeleteCharacter(char *name) {
|
||||
query = StringFormat("DELETE FROM `quest_globals` WHERE `charid` = '%d'", charid); QueryDatabase(query);
|
||||
query = StringFormat("DELETE FROM `character_activities` WHERE `charid` = '%d'", charid); QueryDatabase(query);
|
||||
query = StringFormat("DELETE FROM `character_enabledtasks` WHERE `charid` = '%d'", charid); QueryDatabase(query);
|
||||
query = StringFormat("DELETE FROM `character_tasks` WHERE `charid` = '%d'", charid); QueryDatabase(query);
|
||||
query = StringFormat("DELETE FROM `completed_tasks` WHERE `charid` = '%d'", charid); QueryDatabase(query);
|
||||
query = StringFormat("DELETE FROM `friends` WHERE `charid` = '%d'", charid); QueryDatabase(query);
|
||||
query = StringFormat("DELETE FROM `mail` WHERE `charid` = '%d'", charid); QueryDatabase(query);
|
||||
|
||||
@@ -25,6 +25,9 @@ N(OP_AdventureRequest),
|
||||
N(OP_AdventureStatsReply),
|
||||
N(OP_AdventureStatsRequest),
|
||||
N(OP_AdventureUpdate),
|
||||
N(OP_AggroMeterLockTarget),
|
||||
N(OP_AggroMeterTargetInfo),
|
||||
N(OP_AggroMeterUpdate),
|
||||
N(OP_AltCurrency),
|
||||
N(OP_AltCurrencyMerchantReply),
|
||||
N(OP_AltCurrencyMerchantRequest),
|
||||
|
||||
@@ -2243,6 +2243,7 @@ struct GroupFollow_Struct { // SoF Follow Struct
|
||||
/*0132*/
|
||||
};
|
||||
|
||||
// this is generic struct
|
||||
struct GroupLeaderChange_Struct
|
||||
{
|
||||
/*000*/ char Unknown000[64];
|
||||
@@ -2495,6 +2496,7 @@ struct BookRequest_Struct {
|
||||
uint8 window; // where to display the text (0xFF means new window)
|
||||
uint8 type; //type: 0=scroll, 1=book, 2=item info.. prolly others.
|
||||
uint32 invslot; // Only used in Sof and later clients;
|
||||
int16 subslot; // The subslot inside of a bag if it is inside one.
|
||||
char txtfile[20];
|
||||
};
|
||||
|
||||
|
||||
+25
-32
@@ -123,26 +123,21 @@ void EQEmuLogSys::LoadLogSettingsDefaults()
|
||||
|
||||
std::string EQEmuLogSys::FormatOutMessageString(uint16 log_category, const std::string &in_message)
|
||||
{
|
||||
std::string category_string;
|
||||
if (log_category > 0 && Logs::LogCategoryName[log_category])
|
||||
category_string = StringFormat("[%s] ", Logs::LogCategoryName[log_category]);
|
||||
return StringFormat("%s%s", category_string.c_str(), in_message.c_str());
|
||||
std::string ret;
|
||||
ret.push_back('[');
|
||||
ret.append(Logs::LogCategoryName[log_category]);
|
||||
ret.push_back(']');
|
||||
ret.push_back(' ');
|
||||
ret.append(in_message);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void EQEmuLogSys::ProcessGMSay(uint16 debug_level, uint16 log_category, const std::string &message)
|
||||
{
|
||||
/* Check if category enabled for process */
|
||||
if (log_settings[log_category].log_to_gmsay == 0)
|
||||
return;
|
||||
|
||||
/* Enabling Netcode based GMSay output creates a feedback loop that ultimately ends in a crash */
|
||||
if (log_category == Logs::LogCategory::Netcode)
|
||||
return;
|
||||
|
||||
/* Make sure the message inbound is at a debug level we're set at */
|
||||
if (log_settings[log_category].log_to_gmsay < debug_level)
|
||||
return;
|
||||
|
||||
/* Check to see if the process that actually ran this is zone */
|
||||
if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformZone)
|
||||
on_log_gmsay_hook(log_category, message);
|
||||
@@ -160,14 +155,6 @@ void EQEmuLogSys::ProcessLogWrite(uint16 debug_level, uint16 log_category, const
|
||||
crash_log.close();
|
||||
}
|
||||
|
||||
/* Check if category enabled for process */
|
||||
if (log_settings[log_category].log_to_file == 0)
|
||||
return;
|
||||
|
||||
/* Make sure the message inbound is at a debug level we're set at */
|
||||
if (log_settings[log_category].log_to_file < debug_level)
|
||||
return;
|
||||
|
||||
char time_stamp[80];
|
||||
EQEmuLogSys::SetCurrentTimeStamp(time_stamp);
|
||||
|
||||
@@ -246,13 +233,6 @@ uint16 EQEmuLogSys::GetGMSayColorFromCategory(uint16 log_category) {
|
||||
|
||||
void EQEmuLogSys::ProcessConsoleMessage(uint16 debug_level, uint16 log_category, const std::string &message)
|
||||
{
|
||||
/* Check if category enabled for process */
|
||||
if (log_settings[log_category].log_to_console == 0)
|
||||
return;
|
||||
|
||||
/* Make sure the message inbound is at a debug level we're set at */
|
||||
if (log_settings[log_category].log_to_console < debug_level)
|
||||
return;
|
||||
|
||||
#ifdef _WINDOWS
|
||||
HANDLE console_handle;
|
||||
@@ -273,12 +253,25 @@ void EQEmuLogSys::ProcessConsoleMessage(uint16 debug_level, uint16 log_category,
|
||||
|
||||
void EQEmuLogSys::Out(Logs::DebugLevel debug_level, uint16 log_category, std::string message, ...)
|
||||
{
|
||||
const bool log_to_console = log_settings[log_category].log_to_console > 0;
|
||||
const bool log_to_file = log_settings[log_category].log_to_file > 0;
|
||||
const bool log_to_gmsay = log_settings[log_category].log_to_gmsay > 0;
|
||||
const bool nothing_to_log = !log_to_console && !log_to_file && !log_to_gmsay;
|
||||
|
||||
if (nothing_to_log) return;
|
||||
bool log_to_console = true;
|
||||
if (log_settings[log_category].log_to_console < debug_level) {
|
||||
log_to_console = false;
|
||||
}
|
||||
|
||||
bool log_to_file = true;
|
||||
if (log_settings[log_category].log_to_file < debug_level) {
|
||||
log_to_file = false;
|
||||
}
|
||||
|
||||
bool log_to_gmsay = true;
|
||||
if (log_settings[log_category].log_to_gmsay < debug_level) {
|
||||
log_to_gmsay = false;
|
||||
}
|
||||
|
||||
const bool nothing_to_log = !log_to_console && !log_to_file && !log_to_gmsay;
|
||||
if (nothing_to_log)
|
||||
return;
|
||||
|
||||
va_list args;
|
||||
va_start(args, message);
|
||||
|
||||
@@ -235,6 +235,9 @@ enum { //some random constants
|
||||
|
||||
#define ZONE_CONTROLLER_NPC_ID 10
|
||||
|
||||
// Timer to update aggrometer
|
||||
#define AGGRO_METER_UPDATE_MS 1000
|
||||
|
||||
//Some hard coded statuses from commands and other places:
|
||||
enum {
|
||||
minStatusToBeGM = 40,
|
||||
|
||||
@@ -635,18 +635,23 @@ int16 EQEmu::InventoryProfile::FindFreeSlot(bool for_bag, bool try_cursor, uint8
|
||||
}
|
||||
|
||||
// This is a mix of HasSpaceForItem and FindFreeSlot..due to existing coding behavior, it was better to add a new helper function...
|
||||
int16 EQEmu::InventoryProfile::FindFreeSlotForTradeItem(const ItemInstance* inst) {
|
||||
int16 EQEmu::InventoryProfile::FindFreeSlotForTradeItem(const ItemInstance* inst, int16 general_start, uint8 bag_start) {
|
||||
// Do not arbitrarily use this function..it is designed for use with Client::ResetTrade() and Client::FinishTrade().
|
||||
// If you have a need, use it..but, understand it is not a compatible replacement for InventoryProfile::FindFreeSlot().
|
||||
// If you have a need, use it..but, understand it is not a suitable replacement for InventoryProfile::FindFreeSlot().
|
||||
//
|
||||
// I'll probably implement a bitmask in the new inventory system to avoid having to adjust stack bias
|
||||
|
||||
if ((general_start < legacy::GENERAL_BEGIN) || (general_start > legacy::GENERAL_END))
|
||||
return INVALID_INDEX;
|
||||
if (bag_start >= inventory::ContainerCount)
|
||||
return INVALID_INDEX;
|
||||
|
||||
if (!inst || !inst->GetID())
|
||||
return INVALID_INDEX;
|
||||
|
||||
// step 1: find room for bags (caller should really ask for slots for bags first to avoid sending them to cursor..and bag item loss)
|
||||
if (inst->IsClassBag()) {
|
||||
for (int16 free_slot = legacy::GENERAL_BEGIN; free_slot <= legacy::GENERAL_END; ++free_slot) {
|
||||
for (int16 free_slot = general_start; free_slot <= legacy::GENERAL_END; ++free_slot) {
|
||||
if (!m_inv[free_slot])
|
||||
return free_slot;
|
||||
}
|
||||
@@ -656,7 +661,7 @@ int16 EQEmu::InventoryProfile::FindFreeSlotForTradeItem(const ItemInstance* inst
|
||||
|
||||
// step 2: find partial room for stackables
|
||||
if (inst->IsStackable()) {
|
||||
for (int16 free_slot = legacy::GENERAL_BEGIN; free_slot <= legacy::GENERAL_END; ++free_slot) {
|
||||
for (int16 free_slot = general_start; free_slot <= legacy::GENERAL_END; ++free_slot) {
|
||||
const ItemInstance* main_inst = m_inv[free_slot];
|
||||
|
||||
if (!main_inst)
|
||||
@@ -666,14 +671,15 @@ int16 EQEmu::InventoryProfile::FindFreeSlotForTradeItem(const ItemInstance* inst
|
||||
return free_slot;
|
||||
}
|
||||
|
||||
for (int16 free_slot = legacy::GENERAL_BEGIN; free_slot <= legacy::GENERAL_END; ++free_slot) {
|
||||
for (int16 free_slot = general_start; free_slot <= legacy::GENERAL_END; ++free_slot) {
|
||||
const ItemInstance* main_inst = m_inv[free_slot];
|
||||
|
||||
if (!main_inst)
|
||||
continue;
|
||||
|
||||
if (main_inst->IsClassBag()) { // if item-specific containers already have bad items, we won't fix it here...
|
||||
for (uint8 free_bag_slot = inventory::containerBegin; (free_bag_slot < main_inst->GetItem()->BagSlots) && (free_bag_slot < inventory::ContainerCount); ++free_bag_slot) {
|
||||
uint8 _bag_start = (free_slot > general_start) ? inventory::containerBegin : bag_start;
|
||||
for (uint8 free_bag_slot = _bag_start; (free_bag_slot < main_inst->GetItem()->BagSlots) && (free_bag_slot < inventory::ContainerCount); ++free_bag_slot) {
|
||||
const ItemInstance* sub_inst = main_inst->GetItem(free_bag_slot);
|
||||
|
||||
if (!sub_inst)
|
||||
@@ -688,13 +694,14 @@ int16 EQEmu::InventoryProfile::FindFreeSlotForTradeItem(const ItemInstance* inst
|
||||
|
||||
// step 3a: find room for container-specific items (ItemClassArrow)
|
||||
if (inst->GetItem()->ItemType == item::ItemTypeArrow) {
|
||||
for (int16 free_slot = legacy::GENERAL_BEGIN; free_slot <= legacy::GENERAL_END; ++free_slot) {
|
||||
for (int16 free_slot = general_start; free_slot <= legacy::GENERAL_END; ++free_slot) {
|
||||
const ItemInstance* main_inst = m_inv[free_slot];
|
||||
|
||||
if (!main_inst || (main_inst->GetItem()->BagType != item::BagTypeQuiver) || !main_inst->IsClassBag())
|
||||
continue;
|
||||
|
||||
for (uint8 free_bag_slot = inventory::containerBegin; (free_bag_slot < main_inst->GetItem()->BagSlots) && (free_bag_slot < inventory::ContainerCount); ++free_bag_slot) {
|
||||
uint8 _bag_start = (free_slot > general_start) ? inventory::containerBegin : bag_start;
|
||||
for (uint8 free_bag_slot = _bag_start; (free_bag_slot < main_inst->GetItem()->BagSlots) && (free_bag_slot < inventory::ContainerCount); ++free_bag_slot) {
|
||||
if (!main_inst->GetItem(free_bag_slot))
|
||||
return InventoryProfile::CalcSlotId(free_slot, free_bag_slot);
|
||||
}
|
||||
@@ -703,13 +710,14 @@ int16 EQEmu::InventoryProfile::FindFreeSlotForTradeItem(const ItemInstance* inst
|
||||
|
||||
// step 3b: find room for container-specific items (ItemClassSmallThrowing)
|
||||
if (inst->GetItem()->ItemType == item::ItemTypeSmallThrowing) {
|
||||
for (int16 free_slot = legacy::GENERAL_BEGIN; free_slot <= legacy::GENERAL_END; ++free_slot) {
|
||||
for (int16 free_slot = general_start; free_slot <= legacy::GENERAL_END; ++free_slot) {
|
||||
const ItemInstance* main_inst = m_inv[free_slot];
|
||||
|
||||
if (!main_inst || (main_inst->GetItem()->BagType != item::BagTypeBandolier) || !main_inst->IsClassBag())
|
||||
continue;
|
||||
|
||||
for (uint8 free_bag_slot = inventory::containerBegin; (free_bag_slot < main_inst->GetItem()->BagSlots) && (free_bag_slot < inventory::ContainerCount); ++free_bag_slot) {
|
||||
uint8 _bag_start = (free_slot > general_start) ? inventory::containerBegin : bag_start;
|
||||
for (uint8 free_bag_slot = _bag_start; (free_bag_slot < main_inst->GetItem()->BagSlots) && (free_bag_slot < inventory::ContainerCount); ++free_bag_slot) {
|
||||
if (!main_inst->GetItem(free_bag_slot))
|
||||
return InventoryProfile::CalcSlotId(free_slot, free_bag_slot);
|
||||
}
|
||||
@@ -717,21 +725,22 @@ int16 EQEmu::InventoryProfile::FindFreeSlotForTradeItem(const ItemInstance* inst
|
||||
}
|
||||
|
||||
// step 4: just find an empty slot
|
||||
for (int16 free_slot = legacy::GENERAL_BEGIN; free_slot <= legacy::GENERAL_END; ++free_slot) {
|
||||
for (int16 free_slot = general_start; free_slot <= legacy::GENERAL_END; ++free_slot) {
|
||||
const ItemInstance* main_inst = m_inv[free_slot];
|
||||
|
||||
if (!main_inst)
|
||||
return free_slot;
|
||||
}
|
||||
|
||||
for (int16 free_slot = legacy::GENERAL_BEGIN; free_slot <= legacy::GENERAL_END; ++free_slot) {
|
||||
for (int16 free_slot = general_start; free_slot <= legacy::GENERAL_END; ++free_slot) {
|
||||
const ItemInstance* main_inst = m_inv[free_slot];
|
||||
|
||||
if (main_inst && main_inst->IsClassBag()) {
|
||||
if ((main_inst->GetItem()->BagSize < inst->GetItem()->Size) || (main_inst->GetItem()->BagType == item::BagTypeBandolier) || (main_inst->GetItem()->BagType == item::BagTypeQuiver))
|
||||
continue;
|
||||
|
||||
for (uint8 free_bag_slot = inventory::containerBegin; (free_bag_slot < main_inst->GetItem()->BagSlots) && (free_bag_slot < inventory::ContainerCount); ++free_bag_slot) {
|
||||
uint8 _bag_start = (free_slot > general_start) ? inventory::containerBegin : bag_start;
|
||||
for (uint8 free_bag_slot = _bag_start; (free_bag_slot < main_inst->GetItem()->BagSlots) && (free_bag_slot < inventory::ContainerCount); ++free_bag_slot) {
|
||||
if (!main_inst->GetItem(free_bag_slot))
|
||||
return InventoryProfile::CalcSlotId(free_slot, free_bag_slot);
|
||||
}
|
||||
|
||||
@@ -155,7 +155,7 @@ namespace EQEmu
|
||||
|
||||
// Locate an available inventory slot
|
||||
int16 FindFreeSlot(bool for_bag, bool try_cursor, uint8 min_size = 0, bool is_arrow = false);
|
||||
int16 FindFreeSlotForTradeItem(const ItemInstance* inst);
|
||||
int16 FindFreeSlotForTradeItem(const ItemInstance* inst, int16 general_start = legacy::GENERAL_BEGIN, uint8 bag_start = inventory::containerBegin);
|
||||
|
||||
// Calculate slot_id for an item within a bag
|
||||
static int16 CalcSlotId(int16 slot_id); // Calc parent bag's slot_id
|
||||
|
||||
+19
-1
@@ -195,7 +195,7 @@ bool EQEmu::ItemData::IsClassBook() const
|
||||
|
||||
bool EQEmu::ItemData::IsType1HWeapon() const
|
||||
{
|
||||
return ((ItemType == item::ItemType1HBlunt) || (ItemType == item::ItemType1HSlash) || (ItemType == item::ItemType1HPiercing));
|
||||
return ((ItemType == item::ItemType1HBlunt) || (ItemType == item::ItemType1HSlash) || (ItemType == item::ItemType1HPiercing) || (ItemType == item::ItemTypeMartial));
|
||||
}
|
||||
|
||||
bool EQEmu::ItemData::IsType2HWeapon() const
|
||||
@@ -207,3 +207,21 @@ bool EQEmu::ItemData::IsTypeShield() const
|
||||
{
|
||||
return (ItemType == item::ItemTypeShield);
|
||||
}
|
||||
|
||||
bool EQEmu::ItemData::CheckLoreConflict(const ItemData* l_item, const ItemData* r_item)
|
||||
{
|
||||
if (!l_item || !r_item)
|
||||
return false;
|
||||
|
||||
if (!l_item->LoreGroup || !r_item->LoreGroup)
|
||||
return false;
|
||||
|
||||
if (l_item->LoreGroup == r_item->LoreGroup) {
|
||||
if ((l_item->LoreGroup == -1) && (l_item->ID != r_item->ID))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -538,6 +538,9 @@ namespace EQEmu
|
||||
bool IsType1HWeapon() const;
|
||||
bool IsType2HWeapon() const;
|
||||
bool IsTypeShield() const;
|
||||
|
||||
static bool CheckLoreConflict(const ItemData* l_item, const ItemData* r_item);
|
||||
bool CheckLoreConflict(const ItemData* item) const { return CheckLoreConflict(this, item); }
|
||||
};
|
||||
|
||||
} /*EQEmu*/
|
||||
|
||||
+21
-20
@@ -1182,17 +1182,17 @@ namespace RoF2
|
||||
// Leader
|
||||
//
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
|
||||
VARSTRUCT_ENCODE_STRING(Buffer, gu2->yourname);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // index
|
||||
VARSTRUCT_ENCODE_STRING(Buffer, gu2->yourname); // name
|
||||
VARSTRUCT_ENCODE_TYPE(uint16, Buffer, 0); // owner name of merc
|
||||
//VARSTRUCT_ENCODE_STRING(Buffer, "");
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // This is a string
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0x46); // Observed 0x41 and 0x46 here
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint16, Buffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // This is a string
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0x46); // level
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // group tank flag
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // group assist flag
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // group puller flag
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // offline
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // timestamp
|
||||
|
||||
int MemberNumber = 1;
|
||||
|
||||
@@ -1201,17 +1201,17 @@ namespace RoF2
|
||||
if (gu2->membername[i][0] == '\0')
|
||||
continue;
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, MemberNumber++);
|
||||
VARSTRUCT_ENCODE_STRING(Buffer, gu2->membername[i]);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, MemberNumber++); // index
|
||||
VARSTRUCT_ENCODE_STRING(Buffer, gu2->membername[i]); // name
|
||||
VARSTRUCT_ENCODE_TYPE(uint16, Buffer, 0); // merc flag
|
||||
//VARSTRUCT_ENCODE_STRING(Buffer, "");
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // This is a string
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0x41); // Observed 0x41 and 0x46 here
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // Low byte is Main Assist Flag
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint16, Buffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // owner name fo merc
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0x41); // level
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // group tank flag
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // group assist flag
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // group puller flag
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // offline
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // timestamp
|
||||
}
|
||||
|
||||
//Log.Hex(Logs::Netcode, outapp->pBuffer, outapp->size);
|
||||
@@ -5154,6 +5154,7 @@ namespace RoF2
|
||||
|
||||
IN(type);
|
||||
IN(invslot);
|
||||
IN(subslot);
|
||||
emu->window = (uint8)eq->window;
|
||||
strn0cpy(emu->txtfile, eq->txtfile, sizeof(emu->txtfile));
|
||||
|
||||
|
||||
@@ -2566,9 +2566,12 @@ struct GroupJoin_Struct_Live { // New for Live
|
||||
};
|
||||
|
||||
struct GroupJoin_Struct {
|
||||
/*000*/ char unknown000[64];
|
||||
/*000*/ char owner_name[64]; // merc
|
||||
/*064*/ char membername[64];
|
||||
/*128*/ uint8 unknown128[20]; // Leadership AA ?
|
||||
/*128*/ uint8 merc;
|
||||
/*129*/ uint8 padding129[3];
|
||||
/*132*/ uint32 level;
|
||||
/*136*/ uint8 unknown136[12]; // group ID most likely in here judging from like captures (unused by client)
|
||||
/*148*/
|
||||
};
|
||||
|
||||
@@ -2826,7 +2829,8 @@ struct BookText_Struct {
|
||||
struct BookRequest_Struct {
|
||||
/*0000*/ uint32 window; // where to display the text (0xFFFFFFFF means new window).
|
||||
/*0004*/ uint16 invslot; // Is the slot, but the RoF2 conversion causes it to fail. Turned to 0 since it isnt required anyway.
|
||||
/*0008*/ uint32 unknown006; // Seen FFFFFFFF
|
||||
/*0006*/ int16 subslot; // Inventory sub-slot (0-x)
|
||||
/*0008*/ uint16 unknown006; // Seen FFFF
|
||||
/*0010*/ uint16 unknown008; // seen 0000
|
||||
/*0012*/ uint32 type; // 0 = Scroll, 1 = Book, 2 = Item Info. Possibly others
|
||||
/*0016*/ uint32 unknown0012;
|
||||
|
||||
+1316
-43
File diff suppressed because it is too large
Load Diff
+735
@@ -113,6 +113,741 @@
|
||||
|
||||
#define PLAYER_RACE_ALL_MASK 65535
|
||||
|
||||
#define RT_ABHORRENT 193
|
||||
#define RT_AIR_ELEMENTAL 210
|
||||
#define RT_AIR_ELEMENTAL_2 475
|
||||
#define RT_AIR_MEPHIT 291
|
||||
#define RT_AKHEVA 230
|
||||
#define RT_AKHEVA_2 722
|
||||
#define RT_ALARAN 695
|
||||
#define RT_ALARAN_GHOST 708
|
||||
#define RT_ALARAN_SENTRY_STONE 703
|
||||
#define RT_ALLIGATOR 91
|
||||
#define RT_ALLIGATOR_2 479
|
||||
#define RT_AMYGDALAN 99
|
||||
#define RT_AMYGDALAN_2 663
|
||||
#define RT_ANEUK 395
|
||||
#define RT_ANIMATED_ARMOR 323
|
||||
#define RT_ANIMATED_HAND 166
|
||||
#define RT_ANIMATED_STATUE 442
|
||||
#define RT_ANIMATED_STATUE_2 448
|
||||
#define RT_APEXUS 637
|
||||
#define RT_ARACHNID 326
|
||||
#define RT_ARCANIST_OF_HATE 352
|
||||
#define RT_ARMADILLO 87
|
||||
#define RT_ARMOR_RACK 535
|
||||
#define RT_AVIAK 13
|
||||
#define RT_AVIAK_2 558
|
||||
#define RT_AVIAK_PULL_ALONG 711
|
||||
#define RT_AYONAE_RO 498
|
||||
#define RT_BANNER 500
|
||||
#define RT_BANNER_2 553
|
||||
#define RT_BANNER_3 554
|
||||
#define RT_BANNER_4 555
|
||||
#define RT_BANNER_5 556
|
||||
#define RT_BANNER_6 557
|
||||
#define RT_BANNER_7 586
|
||||
#define RT_BANNER_10TH_ANNIVERSARY 628
|
||||
#define RT_BANSHEE 250
|
||||
#define RT_BANSHEE_2 487
|
||||
#define RT_BANSHEE_3 488
|
||||
#define RT_BARBARIAN 2
|
||||
#define RT_BARBARIAN_2 90
|
||||
#define RT_BARREL 377
|
||||
#define RT_BARREL_BARGE_SHIP 546
|
||||
#define RT_BASILISK 436
|
||||
#define RT_BAT 34
|
||||
#define RT_BAT_2 260
|
||||
#define RT_BAT_3 416
|
||||
#define RT_BAZU 409
|
||||
#define RT_BEAR 43
|
||||
#define RT_BEAR_2 305
|
||||
#define RT_BEAR_3 480
|
||||
#define RT_BEAR_MOUNT 655
|
||||
#define RT_BEAR_TRAP 503
|
||||
#define RT_BEETLE 22
|
||||
#define RT_BEETLE_2 559
|
||||
#define RT_BEETLE_3 716
|
||||
#define RT_BEGGAR 55
|
||||
#define RT_BELLIKOS 638
|
||||
#define RT_BERTOXXULOUS 152
|
||||
#define RT_BERTOXXULOUS_2 255
|
||||
#define RT_BIXIE 79
|
||||
#define RT_BIXIE_2 520
|
||||
#define RT_BLIMP_SHIP 693
|
||||
#define RT_BLIND_DREAMER 669
|
||||
#define RT_BLOOD_RAVEN 279
|
||||
#define RT_BOAT 141
|
||||
#define RT_BOAT_2 533
|
||||
#define RT_BOLVIRK 486
|
||||
#define RT_BONE_GOLEM 362
|
||||
#define RT_BONE_GOLEM_2 491
|
||||
#define RT_BONES 383
|
||||
#define RT_BOOK_DERVISH 660
|
||||
#define RT_BOT_PORTAL 329
|
||||
#define RT_BOULDER 585
|
||||
#define RT_BOX 376
|
||||
#define RT_BRAXI 688
|
||||
#define RT_BRAXI_MOUNT 676
|
||||
#define RT_BRELL 640
|
||||
#define RT_BRELLS_FIRST_CREATION 639
|
||||
#define RT_BRISTLEBANE 153
|
||||
#define RT_BROKEN_CLOCKWORK 274
|
||||
#define RT_BRONTOTHERIUM 169
|
||||
#define RT_BROWNIE 15
|
||||
#define RT_BROWNIE_2 568
|
||||
#define RT_BUBONIAN 268
|
||||
#define RT_BUBONIAN_UNDERLING 269
|
||||
#define RT_BURYNAI 144
|
||||
#define RT_BURYNAI_2 602
|
||||
#define RT_CAKE_10TH_ANNIVERSARY 629
|
||||
#define RT_CAMPFIRE 567
|
||||
#define RT_CARRIER_HAND 721
|
||||
#define RT_CAT 713
|
||||
#define RT_CAZIC_THULE 95
|
||||
#define RT_CAZIC_THULE_2 670
|
||||
#define RT_CENTAUR 16
|
||||
#define RT_CENTAUR_2 521
|
||||
#define RT_CHEST 378
|
||||
#define RT_CHEST_2 589
|
||||
#define RT_CHEST_3 590
|
||||
#define RT_CHIMERA 412
|
||||
#define RT_CHIMERA_2 582
|
||||
#define RT_CHOKIDAI 356
|
||||
#define RT_CLAM 115
|
||||
#define RT_CLIKNAR_MOUNT 652
|
||||
#define RT_CLIKNAR_QUEEN 642
|
||||
#define RT_CLIKNAR_SOLDIER 643
|
||||
#define RT_CLIKNAR_WORKER 644
|
||||
#define RT_CLOCKWORK_BEETLE 276
|
||||
#define RT_CLOCKWORK_BOAR 472
|
||||
#define RT_CLOCKWORK_BOMB 504
|
||||
#define RT_CLOCKWORK_BRAIN 249
|
||||
#define RT_CLOCKWORK_GNOME 88
|
||||
#define RT_CLOCKWORK_GOLEM 248
|
||||
#define RT_CLOCKWORK_GUARDIAN 572
|
||||
#define RT_COCKATRICE 96
|
||||
#define RT_COFFIN 382
|
||||
#define RT_COFFIN_2 592
|
||||
#define RT_COIN_PURSE 427
|
||||
#define RT_COLDAIN 183
|
||||
#define RT_COLDAIN_2 645
|
||||
#define RT_COLDAIN_3 646
|
||||
#define RT_CORAL 460
|
||||
#define RT_CORATHUS 459
|
||||
#define RT_CRAB 302
|
||||
#define RT_CRAGBEAST 390
|
||||
#define RT_CRAGSLITHER 597
|
||||
#define RT_CROCODILE 259
|
||||
#define RT_CRYSTAL 591
|
||||
#define RT_CRYSTAL_SHARD 425
|
||||
#define RT_CRYSTAL_SPHERE 616
|
||||
#define RT_CRYSTAL_SPIDER 327
|
||||
#define RT_CRYSTALSKIN_AMBULOID 641
|
||||
#define RT_CRYSTALSKIN_SESSILOID 647
|
||||
#define RT_DAISY_MAN 97
|
||||
#define RT_DARK_ELF 6
|
||||
#define RT_DARK_ELF_2 77
|
||||
#define RT_DARK_LORD 466
|
||||
#define RT_DEMI_LICH 45
|
||||
#define RT_DEMON_VULTURE 620
|
||||
#define RT_DERVISH 100
|
||||
#define RT_DERVISH_2 372
|
||||
#define RT_DERVISH_3 431
|
||||
#define RT_DERVISH_4 704
|
||||
#define RT_DERVISH_VER_5 726
|
||||
#define RT_DERVISH_VER_6 727
|
||||
#define RT_DEVOURER 159
|
||||
#define RT_DIRE_WOLF 171
|
||||
#define RT_DISCORD_SHIP 404
|
||||
#define RT_DISCORDLING 418
|
||||
#define RT_DISEASED_FIEND 253
|
||||
#define RT_DJINN 126
|
||||
#define RT_DRACHNID 57
|
||||
#define RT_DRACHNID_2 461
|
||||
#define RT_DRACHNID_COCOON 462
|
||||
#define RT_DRACOLICH 604
|
||||
#define RT_DRAGLOCK 132
|
||||
#define RT_DRAGON 49
|
||||
#define RT_DRAGON_2 122
|
||||
#define RT_DRAGON_3 165
|
||||
#define RT_DRAGON_4 184
|
||||
#define RT_DRAGON_5 192
|
||||
#define RT_DRAGON_6 195
|
||||
#define RT_DRAGON_7 196
|
||||
#define RT_DRAGON_8 198
|
||||
#define RT_DRAGON_9 304
|
||||
#define RT_DRAGON_10 435
|
||||
#define RT_DRAGON_11 437
|
||||
#define RT_DRAGON_12 438
|
||||
#define RT_DRAGON_13 452
|
||||
#define RT_DRAGON_14 530
|
||||
#define RT_DRAGON_15 531
|
||||
#define RT_DRAGON_16 569
|
||||
#define RT_DRAGON_BONES 423
|
||||
#define RT_DRAGON_EGG 445
|
||||
#define RT_DRAGON_STATUE 446
|
||||
#define RT_DRAGORN 413
|
||||
#define RT_DRAGORN_BOX 421
|
||||
#define RT_DRAKE 89
|
||||
#define RT_DRAKE_2 430
|
||||
#define RT_DRAKE_3 432
|
||||
#define RT_DRAKKIN 522
|
||||
#define RT_DRIXIE 113
|
||||
#define RT_DROGMORE 348
|
||||
#define RT_DROLVARG 133
|
||||
#define RT_DRYAD 243
|
||||
#define RT_DWARF 8
|
||||
#define RT_DWARF_2 94
|
||||
#define RT_DYNAMITE_KEG 505
|
||||
#define RT_DYNLETH 532
|
||||
#define RT_EARTH_ELEMENTAL 209
|
||||
#define RT_EARTH_ELEMENTAL_2 476
|
||||
#define RT_EARTH_MEPHIT 292
|
||||
#define RT_EEL 35
|
||||
#define RT_EFREETI 101
|
||||
#define RT_EFREETI_2 320
|
||||
#define RT_ELDDAR 489
|
||||
#define RT_ELEMENTAL 75
|
||||
#define RT_ELK_HEAD 714
|
||||
#define RT_ELVEN_BOAT 544
|
||||
#define RT_ELVEN_GHOST 587
|
||||
#define RT_ENCHANTED_ARMOR 175
|
||||
#define RT_EROLLISI 150
|
||||
#define RT_ERUDITE 3
|
||||
#define RT_ERUDITE_2 78
|
||||
#define RT_ERUDITE_3 678
|
||||
#define RT_EVAN_TEST 204
|
||||
#define RT_EVIL_EYE 21
|
||||
#define RT_EVIL_EYE_2 375
|
||||
#define RT_EVIL_EYE_3 469
|
||||
#define RT_EXOSKELETON 570
|
||||
#define RT_EXPLOSIVE_CART 692
|
||||
#define RT_EYE 108
|
||||
#define RT_FAIRY 25
|
||||
#define RT_FAIRY_2 473
|
||||
#define RT_FALLEN_KNIGHT 719
|
||||
#define RT_FAUN 182
|
||||
#define RT_FAY_DRAKE 154
|
||||
#define RT_FENNIN_RO 284
|
||||
#define RT_FERAN 410
|
||||
#define RT_FERAN_MOUNT 623
|
||||
#define RT_FIEND 300
|
||||
#define RT_FIRE_ELEMENTAL 212
|
||||
#define RT_FIRE_ELEMENTAL_2 477
|
||||
#define RT_FIRE_MEPHIT 293
|
||||
#define RT_FISH 24
|
||||
#define RT_FISH_2 148
|
||||
#define RT_FLAG 501
|
||||
#define RT_FLOATING_ISLAND 596
|
||||
#define RT_FLOATING_SKULL 512
|
||||
#define RT_FLOATING_TOWER 691
|
||||
#define RT_FLY 245
|
||||
#define RT_FLYING_CARPET 720
|
||||
#define RT_FOREST_GIANT 490
|
||||
#define RT_FROG 343
|
||||
#define RT_FROG_2 603
|
||||
#define RT_FROGLOK 26
|
||||
#define RT_FROGLOK_2 27
|
||||
#define RT_FROGLOK_3 330
|
||||
#define RT_FROGLOK_GHOST 371
|
||||
#define RT_FROGLOK_SKELETON 349
|
||||
#define RT_FUNGAL_FIEND 218
|
||||
#define RT_FUNGUS_PATCH 463
|
||||
#define RT_FUNGUSMAN 28
|
||||
#define RT_GALORIAN 228
|
||||
#define RT_GARGOYLE 29
|
||||
#define RT_GARGOYLE_2 464
|
||||
#define RT_GASBAG 30
|
||||
#define RT_GELATINOUS_CUBE 31
|
||||
#define RT_GELATINOUS_CUBE_2 712
|
||||
#define RT_GELIDRAN 417
|
||||
#define RT_GENARI 648
|
||||
#define RT_GEONID 178
|
||||
#define RT_GHOST 32
|
||||
#define RT_GHOST_2 117
|
||||
#define RT_GHOST_3 118
|
||||
#define RT_GHOST_4 334
|
||||
#define RT_GHOST_SHIP 114
|
||||
#define RT_GHOST_SHIP_2 552
|
||||
#define RT_GHOUL 33
|
||||
#define RT_GHOUL_2 571
|
||||
#define RT_GIANT 18
|
||||
#define RT_GIANT_2 140
|
||||
#define RT_GIANT_3 188
|
||||
#define RT_GIANT_4 189
|
||||
#define RT_GIANT_5 306
|
||||
#define RT_GIANT_6 307
|
||||
#define RT_GIANT_7 308
|
||||
#define RT_GIANT_8 309
|
||||
#define RT_GIANT_9 310
|
||||
#define RT_GIANT_10 311
|
||||
#define RT_GIANT_11 312
|
||||
#define RT_GIANT_12 453
|
||||
#define RT_GIANT_13 523
|
||||
#define RT_GIANT_CLOCKWORK 275
|
||||
#define RT_GIANT_RALLOSIAN_MATS 626
|
||||
#define RT_GIANT_SHADE 526
|
||||
#define RT_GIGYN 649
|
||||
#define RT_GINGERBREAD_MAN 666
|
||||
#define RT_GIRPLAN 419
|
||||
#define RT_GNOLL 39
|
||||
#define RT_GNOLL_2 524
|
||||
#define RT_GNOLL_3 617
|
||||
#define RT_GNOME 12
|
||||
#define RT_GNOMEWORK 457
|
||||
#define RT_GNOMISH_BALLOON 683
|
||||
#define RT_GNOMISH_BOAT 545
|
||||
#define RT_GNOMISH_HOVERING_TRANSPORT 685
|
||||
#define RT_GNOMISH_ROCKET_PACK 684
|
||||
#define RT_GOBLIN 40
|
||||
#define RT_GOBLIN_2 59
|
||||
#define RT_GOBLIN_3 137
|
||||
#define RT_GOBLIN_4 369
|
||||
#define RT_GOBLIN_5 433
|
||||
#define RT_GOD_LUCLIN_VER_2 728
|
||||
#define RT_GOD_LUCLIN_VER_3 729
|
||||
#define RT_GOD_LUCLIN_VER_4 731
|
||||
#define RT_GOD_OF_DISCORD 622
|
||||
#define RT_GOLEM 17
|
||||
#define RT_GOLEM_2 374
|
||||
#define RT_GOO 145
|
||||
#define RT_GOO_2 547
|
||||
#define RT_GOO_3 548
|
||||
#define RT_GOO_4 549
|
||||
#define RT_GORAL 687
|
||||
#define RT_GORAL_MOUNT 673
|
||||
#define RT_GORGON 121
|
||||
#define RT_GORILLA 41
|
||||
#define RT_GORILLA_2 560
|
||||
#define RT_GRANDFATHER_CLOCK 665
|
||||
#define RT_GREKEN_YOUNG 651
|
||||
#define RT_GREKEN_YOUNG_ADULT 650
|
||||
#define RT_GRENDLAEN 701
|
||||
#define RT_GRIEG_VENEFICUS 231
|
||||
#define RT_GRIFFIN 47
|
||||
#define RT_GRIFFIN_2 525
|
||||
#define RT_GRIMLING 202
|
||||
#define RT_GROUND_SHAKER 233
|
||||
#define RT_GUARD 44
|
||||
#define RT_GUARD_2 106
|
||||
#define RT_GUARD_3 112
|
||||
#define RT_GUARD_4 239
|
||||
#define RT_GUARD_OF_JUSTICE 251
|
||||
#define RT_GUARDIAN_CPU 593
|
||||
#define RT_HADAL 698
|
||||
#define RT_HAG 185
|
||||
#define RT_HALF_ELF 7
|
||||
#define RT_HALFLING 11
|
||||
#define RT_HALFLING_2 81
|
||||
#define RT_HARPY 111
|
||||
#define RT_HARPY_2 527
|
||||
#define RT_HIGH_ELF 5
|
||||
#define RT_HIPPOGRIFF 186
|
||||
#define RT_HOLGRESH 168
|
||||
#define RT_HOLGRESH_2 715
|
||||
#define RT_HONEY_POT 536
|
||||
#define RT_HORSE 216
|
||||
#define RT_HORSE_2 492
|
||||
#define RT_HORSE_3 518
|
||||
#define RT_HOVERING_PLATFORM 699
|
||||
#define RT_HRAQUIS 261
|
||||
#define RT_HUMAN 1
|
||||
#define RT_HUMAN_2 67
|
||||
#define RT_HUMAN_3 71
|
||||
#define RT_HUMAN_4 566
|
||||
#define RT_HUMAN_GHOST 588
|
||||
#define RT_HUVUL 400
|
||||
#define RT_HYDRA_CRYSTAL 615
|
||||
#define RT_HYDRA_MOUNT 631
|
||||
#define RT_HYDRA_NPC 632
|
||||
#define RT_HYNID 388
|
||||
#define RT_ICE_SPECTRE 174
|
||||
#define RT_IKAAV 394
|
||||
#define RT_IKSAR 128
|
||||
#define RT_IKSAR_2 139
|
||||
#define RT_IKSAR_GHOST 605
|
||||
#define RT_IKSAR_GOLEM 160
|
||||
#define RT_IKSAR_SKELETON 606
|
||||
#define RT_IKSAR_SPIRIT 147
|
||||
#define RT_IMP 46
|
||||
#define RT_INNORUUK 123
|
||||
#define RT_INSECT 370
|
||||
#define RT_INTERACTIVE_OBJECT 2250
|
||||
#define RT_INVISIBLE_MAN 127
|
||||
#define RT_INVISIBLE_MAN_2 681
|
||||
#define RT_INVISIBLE_MAN_3 690
|
||||
#define RT_INVISIBLE_MAN_OF_ZOMM 600
|
||||
#define RT_IXT 393
|
||||
#define RT_JOKESTER 384
|
||||
#define RT_JUM_JUM_BUCKET 537
|
||||
#define RT_JUNK_BEAST 273
|
||||
#define RT_KANGON 689
|
||||
#define RT_KANGON_MOUNT 677
|
||||
#define RT_KARANA 278
|
||||
#define RT_KEDGE 103
|
||||
#define RT_KEDGE_2 561
|
||||
#define RT_KERRAN 23
|
||||
#define RT_KERRAN_2 562
|
||||
#define RT_KIRIN 434
|
||||
#define RT_KIRIN_2 583
|
||||
#define RT_KNIGHT_OF_HATE 351
|
||||
#define RT_KNIGHT_OF_PESTILENCE 266
|
||||
#define RT_KOBOLD 48
|
||||
#define RT_KOBOLD_2 455
|
||||
#define RT_KRAKEN 315
|
||||
#define RT_KYV 396
|
||||
#define RT_LAUNCH 73
|
||||
#define RT_LAVA_ROCK 447
|
||||
#define RT_LAVA_SPIDER 450
|
||||
#define RT_LAVA_SPIDER_QUEEN 451
|
||||
#define RT_LEECH 104
|
||||
#define RT_LEPERTOLOTH 267
|
||||
#define RT_LIGHTCRAWLER 223
|
||||
#define RT_LIGHTNING_WARRIOR 407
|
||||
#define RT_LION 50
|
||||
#define RT_LIZARD_MAN 51
|
||||
#define RT_LUCLIN 724
|
||||
#define RT_LUGGALD 345
|
||||
#define RT_LUGGALD_2 346
|
||||
#define RT_LUGGALDS 347
|
||||
#define RT_MALARIAN 265
|
||||
#define RT_MAMMOTH 107
|
||||
#define RT_MAMMOTH_2 528
|
||||
#define RT_MAN_EATING_PLANT 162
|
||||
#define RT_MANSION 595
|
||||
#define RT_MANTICORE 172
|
||||
#define RT_MANTRAP 573
|
||||
#define RT_MARIONETTE 659
|
||||
#define RT_MASTRUQ 402
|
||||
#define RT_MATA_MURAM 406
|
||||
#define RT_MEDIUM_PLANT 541
|
||||
#define RT_MEPHIT 607
|
||||
#define RT_MERCHANT_SHIP 550
|
||||
#define RT_MERMAID 110
|
||||
#define RT_MIMIC 52
|
||||
#define RT_MINI_POM 252
|
||||
#define RT_MINOTAUR 53
|
||||
#define RT_MINOTAUR_2 420
|
||||
#define RT_MINOTAUR_3 470
|
||||
#define RT_MINOTAUR_4 574
|
||||
#define RT_MITHANIEL_MARR 296
|
||||
#define RT_MORELL_THULE 658
|
||||
#define RT_MOSQUITO 134
|
||||
#define RT_MOUTH_OF_INSANITY 281
|
||||
#define RT_MUDDITE 608
|
||||
#define RT_MUMMY 368
|
||||
#define RT_MURAMITE_ARMOR_PILE 424
|
||||
#define RT_MURKGLIDER 414
|
||||
#define RT_MURKGLIDER_EGG_SAC 429
|
||||
#define RT_MUTNA 401
|
||||
#define RT_NEKHON 614
|
||||
#define RT_NETHERBIAN 229
|
||||
#define RT_NIGHTMARE 287
|
||||
#define RT_NIGHTMARE_GARGOYLE 280
|
||||
#define RT_NIGHTMARE_GOBLIN 277
|
||||
#define RT_NIGHTMARE_MEPHIT 294
|
||||
#define RT_NIGHTMARE_UNICORN 517
|
||||
#define RT_NIGHTMARE_UNICORN_2 519
|
||||
#define RT_NIGHTMARE_WRAITH 264
|
||||
#define RT_NIHIL 385
|
||||
#define RT_NILBORIEN 317
|
||||
#define RT_NOC 397
|
||||
#define RT_NYMPH 242
|
||||
#define RT_OGRE 10
|
||||
#define RT_OGRE_2 93
|
||||
#define RT_OGRE_NPC_MALE 624
|
||||
#define RT_ORB 730
|
||||
#define RT_ORC 54
|
||||
#define RT_ORC_2 458
|
||||
#define RT_OTHMIR 190
|
||||
#define RT_OWLBEAR 206
|
||||
#define RT_PARASITIC_SCAVENGER 700
|
||||
#define RT_PEGASUS 125
|
||||
#define RT_PEGASUS_2 493
|
||||
#define RT_PEGASUS_3 732
|
||||
#define RT_PHOENIX 303
|
||||
#define RT_PIRANHA 74
|
||||
#define RT_PIRATE 335
|
||||
#define RT_PIRATE_2 336
|
||||
#define RT_PIRATE_3 337
|
||||
#define RT_PIRATE_4 338
|
||||
#define RT_PIRATE_5 339
|
||||
#define RT_PIRATE_6 340
|
||||
#define RT_PIRATE_7 341
|
||||
#define RT_PIRATE_8 342
|
||||
#define RT_PIRATE_SHIP 551
|
||||
#define RT_PIXIE 56
|
||||
#define RT_POISON_FROG 316
|
||||
#define RT_PORTAL 426
|
||||
#define RT_POWDER_KEG 636
|
||||
#define RT_PRESSURE_PLATE 506
|
||||
#define RT_PUFFER_SPORE 507
|
||||
#define RT_PUMA 76
|
||||
#define RT_PUMA_2 439
|
||||
#define RT_PUMA_3 584
|
||||
#define RT_PUSLING 270
|
||||
#define RT_PYRILEN 411
|
||||
#define RT_RA_TUK 398
|
||||
#define RT_RABBIT 668
|
||||
#define RT_RALLOS_ZEK 66
|
||||
#define RT_RALLOS_ZEK_2 288
|
||||
#define RT_RALLOS_ZEK_MINION 325
|
||||
#define RT_RAPTOR 163
|
||||
#define RT_RAPTOR_2 609
|
||||
#define RT_RAPTOR_MOUNT 680
|
||||
#define RT_RAT 36
|
||||
#define RT_RAT_2 415
|
||||
#define RT_RAT_MOUNT 656
|
||||
#define RT_RATMAN 156
|
||||
#define RT_RATMAN_2 718
|
||||
#define RT_REANIMATED_HAND 80
|
||||
#define RT_RECUSO 237
|
||||
#define RT_REGENERATION_POOL 705
|
||||
#define RT_RELIC_CASE 707
|
||||
#define RT_RHINO_BEETLE 207
|
||||
#define RT_RHINOCEROS 135
|
||||
#define RT_ROBOCOPTER_OF_ZOMM 601
|
||||
#define RT_ROCK_PILE 428
|
||||
#define RT_ROCKHOPPER 200
|
||||
#define RT_RONNIE_TEST 197
|
||||
#define RT_ROOT_TENTACLE 509
|
||||
#define RT_ROT_DOG_MOUNT 672
|
||||
#define RT_ROTDOG 662
|
||||
#define RT_ROTOCOPTER 577
|
||||
#define RT_ROWBOAT 502
|
||||
#define RT_ROYAL_GUARD 667
|
||||
#define RT_RUJARKIAN_ORC 361
|
||||
#define RT_RUJARKIAN_ORC_2 366
|
||||
#define RT_RUNED_ORB 422
|
||||
#define RT_RUNIC_SYMBOL 510
|
||||
#define RT_SABER_TOOTHED_CAT 119
|
||||
#define RT_SALTPETTER_BOMB 511
|
||||
#define RT_SAND_ELF 364
|
||||
#define RT_SANDMAN 664
|
||||
#define RT_SARNAK 131
|
||||
#define RT_SARNAK_2 610
|
||||
#define RT_SARNAK_GOLEM 164
|
||||
#define RT_SARNAK_SPIRIT 146
|
||||
#define RT_SARYRN 283
|
||||
#define RT_SATYR 529
|
||||
#define RT_SCALED_WOLF 481
|
||||
#define RT_SCARECROW 82
|
||||
#define RT_SCARECROW_2 575
|
||||
#define RT_SCARLET_CHEETAH 221
|
||||
#define RT_SCLERA_MOUNT 675
|
||||
#define RT_SCORPION 129
|
||||
#define RT_SCORPION_2 149
|
||||
#define RT_SCORPION_3 611
|
||||
#define RT_SCRYKIN 495
|
||||
#define RT_SEA_TURTLE 194
|
||||
#define RT_SEAHORSE 116
|
||||
#define RT_SELYRAH 686
|
||||
#define RT_SELYRAH_MOUNT 674
|
||||
#define RT_SERU 236
|
||||
#define RT_SERVANT_OF_SHADOW 723
|
||||
#define RT_SESSILOID_MOUNT 657
|
||||
#define RT_SHADE 224
|
||||
#define RT_SHADE_2 373
|
||||
#define RT_SHADE_3 576
|
||||
#define RT_SHADEL 205
|
||||
#define RT_SHAMBLING_MOUND 494
|
||||
#define RT_SHARK 61
|
||||
#define RT_SHIKNAR 199
|
||||
#define RT_SHILISKIN 467
|
||||
#define RT_SHIP 72
|
||||
#define RT_SHIP_IN_A_BOTTLE 702
|
||||
#define RT_SHISSAR 217
|
||||
#define RT_SHISSAR_2 563
|
||||
#define RT_SHRIEKER 227
|
||||
#define RT_SIREN 187
|
||||
#define RT_SIREN_2 564
|
||||
#define RT_SKELETAL_HORSE 282
|
||||
#define RT_SKELETON 60
|
||||
#define RT_SKELETON_2 367
|
||||
#define RT_SKELETON_3 484
|
||||
#define RT_SKUNK 83
|
||||
#define RT_SKYSTRIDER 709
|
||||
#define RT_SMALL_PLANT 540
|
||||
#define RT_SNAKE 37
|
||||
#define RT_SNAKE_2 468
|
||||
#define RT_SNAKE_ELEMENTAL 84
|
||||
#define RT_SNOW_DERVISH 170
|
||||
#define RT_SNOW_RABBIT 176
|
||||
#define RT_SOKOKAR 618
|
||||
#define RT_SOKOKAR_MOUNT 625
|
||||
#define RT_SOKOKAR_W_SADDLE 627
|
||||
#define RT_SOLUSEK_RO 58
|
||||
#define RT_SOLUSEK_RO_2 247
|
||||
#define RT_SOLUSEK_RO_GUARD 254
|
||||
#define RT_SONIC_WOLF 232
|
||||
#define RT_SOUL_DEVOURER 286
|
||||
#define RT_SPECTRE 85
|
||||
#define RT_SPECTRE_2 485
|
||||
#define RT_SPELL_PARTICLE_1 599
|
||||
#define RT_SPHINX 86
|
||||
#define RT_SPHINX_2 565
|
||||
#define RT_SPIDER 38
|
||||
#define RT_SPIDER_2 440
|
||||
#define RT_SPIDER_EGG_SACK 449
|
||||
#define RT_SPIDER_MOUNT 654
|
||||
#define RT_SPIDER_QUEEN 441
|
||||
#define RT_SPIKE_TRAP 513
|
||||
#define RT_SPIRIT_WOLF 483
|
||||
#define RT_SPORALI 456
|
||||
#define RT_STONE_JUG 539
|
||||
#define RT_STONE_PYLON 619
|
||||
#define RT_STONE_RING 508
|
||||
#define RT_STONE_WORKER 387
|
||||
#define RT_STONE_WORKER_2 405
|
||||
#define RT_STONEGRABBER 220
|
||||
#define RT_STONEMITE 391
|
||||
#define RT_STORMRIDER 272
|
||||
#define RT_SUCCUBUS 408
|
||||
#define RT_SUCCULENT 167
|
||||
#define RT_SULLON_ZEK 499
|
||||
#define RT_SUN_REVENANT 226
|
||||
#define RT_SUNFLOWER 225
|
||||
#define RT_SWINETOR 696
|
||||
#define RT_SWORDFISH 105
|
||||
#define RT_SYNARCANA 363
|
||||
#define RT_TABLE 380
|
||||
#define RT_TADPOLE 102
|
||||
#define RT_TAELOSIAN 403
|
||||
#define RT_TALL_PLANT 542
|
||||
#define RT_TALLON_ZEK 290
|
||||
#define RT_TANETH 399
|
||||
#define RT_TAREW_MARR 246
|
||||
#define RT_TEGI 215
|
||||
#define RT_TELEPORT_MAN 240
|
||||
#define RT_TELEPORTATION_STAND 706
|
||||
#define RT_TELMIRA 653
|
||||
#define RT_TENTACLE_TERROR 68
|
||||
#define RT_TENTACLE_TERROR_2 578
|
||||
#define RT_TERRIS_THULE 257
|
||||
#define RT_TEST_OBJECT 301
|
||||
#define RT_THE_RATHE 298
|
||||
#define RT_THE_TRIBUNAL 256
|
||||
#define RT_THOUGHT_HORROR 214
|
||||
#define RT_TIGER 63
|
||||
#define RT_TIN_SOLDIER 263
|
||||
#define RT_TOOLBOX 538
|
||||
#define RT_TOPIARY_LION 661
|
||||
#define RT_TOPIARY_LION_MOUNT 671
|
||||
#define RT_TORMENTOR 285
|
||||
#define RT_TOTEM 173
|
||||
#define RT_TOTEM_2 514
|
||||
#define RT_TRAKANON 19
|
||||
#define RT_TRANQUILION 262
|
||||
#define RT_TREANT 64
|
||||
#define RT_TREANT_2 244
|
||||
#define RT_TREANT_3 496
|
||||
#define RT_TRIBUNAL 151
|
||||
#define RT_TRIUMVIRATE 697
|
||||
#define RT_TROLL 9
|
||||
#define RT_TROLL_2 92
|
||||
#define RT_TROLL_3 331
|
||||
#define RT_TROLL_4 332
|
||||
#define RT_TROLL_5 333
|
||||
#define RT_TROLL_ZOMBIE 344
|
||||
#define RT_TRUSIK 386
|
||||
#define RT_TSETSIAN 612
|
||||
#define RT_TUMBLEWEED 694
|
||||
#define RT_TUNARE 62
|
||||
#define RT_TUREPTA 389
|
||||
#define RT_UKUN 392
|
||||
#define RT_ULTHORK 191
|
||||
#define RT_UNDEAD_CHOKIDAI 357
|
||||
#define RT_UNDEAD_FOOTMAN 324
|
||||
#define RT_UNDEAD_FROGLOK 350
|
||||
#define RT_UNDEAD_IKSAR 161
|
||||
#define RT_UNDEAD_KNIGHT 297
|
||||
#define RT_UNDEAD_SARNAK 155
|
||||
#define RT_UNDEAD_VEKSAR 358
|
||||
#define RT_UNDERBULK 201
|
||||
#define RT_UNICORN 124
|
||||
#define RT_UNKNOWN_RACE 0
|
||||
#define RT_UNKNOWN_RACE_2 142
|
||||
#define RT_UNKNOWN_RACE_3 143
|
||||
#define RT_UNKNOWN_RACE_4 179
|
||||
#define RT_UNKNOWN_RACE_5 180
|
||||
#define RT_UNKNOWN_RACE_6 443
|
||||
#define RT_UNKNOWN_RACE_7 444
|
||||
#define RT_VAH_SHIR 130
|
||||
#define RT_VAH_SHIR_2 238
|
||||
#define RT_VAH_SHIR_SKELETON 234
|
||||
#define RT_VALLON_ZEK 289
|
||||
#define RT_VALORIAN 318
|
||||
#define RT_VALORIAN_2 322
|
||||
#define RT_VAMPIRE 65
|
||||
#define RT_VAMPIRE_2 98
|
||||
#define RT_VAMPIRE_3 208
|
||||
#define RT_VAMPIRE_4 219
|
||||
#define RT_VAMPIRE_5 359
|
||||
#define RT_VAMPIRE_6 360
|
||||
#define RT_VAMPIRE_7 365
|
||||
#define RT_VAMPIRE_8 497
|
||||
#define RT_VASE 379
|
||||
#define RT_VEGEROG 258
|
||||
#define RT_VEKSAR 353
|
||||
#define RT_VEKSAR_2 354
|
||||
#define RT_VEKSAR_3 355
|
||||
#define RT_VENRIL_SATHIR 20
|
||||
#define RT_VINE_MAW 717
|
||||
#define RT_WAGON 621
|
||||
#define RT_WALRUS 177
|
||||
#define RT_WAR_BOAR 319
|
||||
#define RT_WAR_BOAR_2 321
|
||||
#define RT_WAR_WRAITH 313
|
||||
#define RT_WASP 109
|
||||
#define RT_WATER_ELEMENTAL 211
|
||||
#define RT_WATER_ELEMENTAL_2 478
|
||||
#define RT_WATER_MEPHIT 271
|
||||
#define RT_WATER_SPOUT 710
|
||||
#define RT_WEAPON_RACK 381
|
||||
#define RT_WEAPON_RACK_2 534
|
||||
#define RT_WEB 515
|
||||
#define RT_WEDDING_ALTAR 635
|
||||
#define RT_WEDDING_ARBOR 634
|
||||
#define RT_WEDDING_FLOWERS 633
|
||||
#define RT_WEREORC 579
|
||||
#define RT_WEREWOLF 14
|
||||
#define RT_WEREWOLF_2 241
|
||||
#define RT_WEREWOLF_3 454
|
||||
#define RT_WETFANG_MINNOW 213
|
||||
#define RT_WHIRLIGIG 682
|
||||
#define RT_WICKER_BASKET 516
|
||||
#define RT_WILL_O_WISP 69
|
||||
#define RT_WINE_CASK 543
|
||||
#define RT_WINE_CASK_2 630
|
||||
#define RT_WITHERAN 465
|
||||
#define RT_WITHERAN_2 474
|
||||
#define RT_WOLF 42
|
||||
#define RT_WOLF_2 120
|
||||
#define RT_WOLF_3 482
|
||||
#define RT_WOOD_ELF 4
|
||||
#define RT_WORG 580
|
||||
#define RT_WORG_2 594
|
||||
#define RT_WORM 203
|
||||
#define RT_WRETCH 235
|
||||
#define RT_WRULON 314
|
||||
#define RT_WRULON_2 598
|
||||
#define RT_WURM 158
|
||||
#define RT_WURM_2 613
|
||||
#define RT_WURM_MOUNT 679
|
||||
#define RT_WYVERN 157
|
||||
#define RT_WYVERN_2 581
|
||||
#define RT_XALGOZ 136
|
||||
#define RT_XARIC_THE_UNSPOKEN 725
|
||||
#define RT_XEGONY 299
|
||||
#define RT_YAKKAR 181
|
||||
#define RT_YETI 138
|
||||
#define RT_ZEBUXORUK 295
|
||||
#define RT_ZEBUXORUKS_CAGE 328
|
||||
#define RT_ZELNIAK 222
|
||||
#define RT_ZOMBIE 70
|
||||
#define RT_ZOMBIE_2 471
|
||||
|
||||
|
||||
const char* GetRaceIDName(uint16 race_id);
|
||||
const char* GetPlayerRaceName(uint32 player_race_value);
|
||||
|
||||
@@ -65,6 +65,15 @@ namespace EQEmu {
|
||||
return Real(0.0, 1.0) <= required;
|
||||
}
|
||||
|
||||
// same range as client's roll0
|
||||
// This is their main high level RNG function
|
||||
int Roll0(int max)
|
||||
{
|
||||
if (max - 1 > 0)
|
||||
return Int(0, max - 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// std::shuffle requires a RNG engine passed to it, so lets provide a wrapper to use our engine
|
||||
template<typename RandomAccessIterator>
|
||||
void Shuffle(RandomAccessIterator first, RandomAccessIterator last)
|
||||
|
||||
+31
-7
@@ -56,6 +56,7 @@ RULE_REAL(Character, GroupExpMultiplier, 0.5)
|
||||
RULE_REAL(Character, RaidExpMultiplier, 0.2)
|
||||
RULE_BOOL(Character, UseXPConScaling, true)
|
||||
RULE_INT(Character, ShowExpValues, 0) //0 - normal, 1 - Show raw experience values, 2 - Show raw experience values AND percent.
|
||||
RULE_INT(Character, GreenModifier, 20)
|
||||
RULE_INT(Character, LightBlueModifier, 40)
|
||||
RULE_INT(Character, BlueModifier, 90)
|
||||
RULE_INT(Character, WhiteModifier, 100)
|
||||
@@ -114,6 +115,7 @@ RULE_BOOL(Character, CheckCursorEmptyWhenLooting, true) // If true, a player can
|
||||
RULE_BOOL(Character, MaintainIntoxicationAcrossZones, true) // If true, alcohol effects are maintained across zoning and logging out/in.
|
||||
RULE_BOOL(Character, EnableDiscoveredItems, true) // If enabled, it enables EVENT_DISCOVER_ITEM and also saves character names and timestamps for the first time an item is discovered.
|
||||
RULE_BOOL(Character, EnableXTargetting, true) // Enable Extended Targetting Window, for users with UF and later clients.
|
||||
RULE_BOOL(Character, EnableAggroMeter, true) // Enable Aggro Meter, for users with RoF and later clients.
|
||||
RULE_BOOL(Character, KeepLevelOverMax, false) // Don't delevel a character that has somehow gone over the level cap
|
||||
RULE_INT(Character, FoodLossPerUpdate, 35) // How much food/water you lose per stamina update
|
||||
RULE_INT(Character, BaseInstrumentSoftCap, 36) // Softcap for instrument mods, 36 commonly referred to as "3.6" as well.
|
||||
@@ -148,6 +150,7 @@ RULE_INT(Character, AvoidanceCap, 750) // 750 Is a pretty good value, seen peopl
|
||||
RULE_BOOL(Character, AllowMQTarget, false) // Disables putting players in the 'hackers' list for targeting beyond the clip plane or attempting to target something untargetable
|
||||
RULE_BOOL(Character, UseOldBindWound, false) // Uses the original bind wound behavior
|
||||
RULE_BOOL(Character, GrantHoTTOnCreate, false) // Grant Health of Target's Target leadership AA on character creation
|
||||
RULE_BOOL(Character, UseOldConSystem, false) // Grant Health of Target's Target leadership AA on character creation
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY(Mercs)
|
||||
@@ -162,6 +165,8 @@ RULE_INT(Mercs, AggroRadius, 100) // Determines the distance from which a merc
|
||||
RULE_INT(Mercs, AggroRadiusPuller, 25) // Determines the distance from which a merc will aggro group member's target, if they have the group role of puller (also used to determine the distance at which a healer merc will begin healing a group member, if they have the group role of puller)
|
||||
RULE_INT(Mercs, ResurrectRadius, 50) // Determines the distance from which a healer merc will attempt to resurrect a group member's corpse
|
||||
RULE_INT(Mercs, ScaleRate, 100)
|
||||
RULE_BOOL(Mercs, MercsUsePathing, true) // Mercs will use node pathing when moving
|
||||
RULE_BOOL(Mercs, AllowMercSuspendInCombat, true)
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY(Guild)
|
||||
@@ -224,7 +229,9 @@ RULE_INT(World, PVPSettings, 0) // Sets the PVP settings for the server, 1 = Ral
|
||||
RULE_BOOL (World, IsGMPetitionWindowEnabled, false)
|
||||
RULE_INT (World, FVNoDropFlag, 0) // Sets the Firiona Vie settings on the client. If set to 2, the flag will be set for GMs only, allowing trading of no-drop items.
|
||||
RULE_BOOL (World, IPLimitDisconnectAll, false)
|
||||
RULE_BOOL(World, MaxClientsSimplifiedLogic, false) // New logic that only uses ExemptMaxClientsStatus and MaxClientsPerIP. Done on the loginserver. This mimics the P99-style special IP rules.
|
||||
RULE_INT (World, TellQueueSize, 20)
|
||||
RULE_BOOL(World, StartZoneSameAsBindOnCreation, true) //Should the start zone ALWAYS be the same location as your bind?
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY(Zone)
|
||||
@@ -258,6 +265,8 @@ RULE_BOOL(Zone, EnableLoggedOffReplenishments, true)
|
||||
RULE_INT(Zone, MinOfflineTimeToReplenishments, 21600) // 21600 seconds is 6 Hours
|
||||
RULE_BOOL(Zone, UseZoneController, true) // Enables the ability to use persistent quest based zone controllers (zone_controller.pl/lua)
|
||||
RULE_BOOL(Zone, EnableZoneControllerGlobals, false) // Enables the ability to use quest globals with the zone controller NPC
|
||||
RULE_INT(Zone, GlobalLootMultiplier, 1) // Sets Global Loot drop multiplier for database based drops, useful for double, triple loot etc.
|
||||
RULE_BOOL(Zone, IdleWhenEmpty, true) // Don't process NPCs while zone is empty. Defaults to true.
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY(Map)
|
||||
@@ -392,15 +401,13 @@ RULE_BOOL(Spells, NPCInnateProcOverride, true) // NPC innate procs override the
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY(Combat)
|
||||
RULE_INT(Combat, MeleeBaseCritChance, 0) //The base crit chance for non warriors, NOTE: This will apply to NPCs as well
|
||||
RULE_INT(Combat, WarBerBaseCritChance, 3) //The base crit chance for warriors and berserkers, only applies to clients
|
||||
RULE_INT(Combat, BerserkBaseCritChance, 6) //The bonus base crit chance you get when you're berserk
|
||||
RULE_INT(Combat, PetBaseCritChance, 0) // Pet Base crit chance
|
||||
RULE_INT(Combat, NPCBashKickLevel, 6) //The level that npcs can KICK/BASH
|
||||
RULE_INT(Combat, NPCBashKickStunChance, 15) //Percent chance that a bash/kick will stun
|
||||
RULE_INT(Combat, RogueCritThrowingChance, 25) //Rogue throwing crit bonus
|
||||
RULE_INT(Combat, RogueDeadlyStrikeChance, 80) //Rogue chance throwing from behind crit becomes a deadly strike
|
||||
RULE_INT(Combat, RogueDeadlyStrikeMod, 2) //Deadly strike modifier to crit damage
|
||||
RULE_INT(Combat, ClientBaseCritChance, 0) //The base crit chance for all clients, this will stack with warrior's/zerker's crit chance.
|
||||
RULE_INT(Combat, MeleeCritDifficulty, 8900) // lower is easier
|
||||
RULE_INT(Combat, ArcheryCritDifficulty, 3400) // lower is easier
|
||||
RULE_INT(Combat, ThrowingCritDifficulty, 1100) // lower is easier
|
||||
RULE_BOOL(Combat, NPCCanCrit, false) // true allows non PC pet NPCs to crit
|
||||
RULE_BOOL(Combat, UseIntervalAC, true)
|
||||
RULE_INT(Combat, PetAttackMagicLevel, 30)
|
||||
RULE_BOOL(Combat, EnableFearPathing, true)
|
||||
@@ -492,6 +499,7 @@ RULE_INT(Combat, NPCAssistCap, 5) // Maxiumium number of NPCs that will assist a
|
||||
RULE_INT(Combat, NPCAssistCapTimer, 6000) // Time in milliseconds a NPC will take to clear assist aggro cap space
|
||||
RULE_BOOL(Combat, UseRevampHandToHand, false) // use h2h revamped dmg/delays I believe this was implemented during SoF
|
||||
RULE_BOOL(Combat, ClassicMasterWu, false) // classic master wu uses a random special, modern doesn't
|
||||
RULE_INT(Combat, LevelToStopDamageCaps, 0) // 1 will effectively disable them, 20 should give basically same results as old incorrect system
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY(NPC)
|
||||
@@ -542,6 +550,20 @@ RULE_BOOL(TaskSystem, KeepOneRecordPerCompletedTask, true)
|
||||
RULE_BOOL(TaskSystem, EnableTaskProximity, true)
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
RULE_CATEGORY(Range)
|
||||
RULE_INT(Range, Say, 135)
|
||||
RULE_INT(Range, Emote, 135)
|
||||
RULE_INT(Range, BeginCast, 200)
|
||||
RULE_INT(Range, Anims, 135)
|
||||
RULE_INT(Range, SpellParticles, 135)
|
||||
RULE_INT(Range, DamageMessages, 50)
|
||||
RULE_INT(Range, SpellMessages, 75)
|
||||
RULE_INT(Range, SongMessages, 75)
|
||||
RULE_INT(Range, MobPositionUpdates, 600)
|
||||
RULE_INT(Range, CriticalDamage, 80)
|
||||
RULE_CATEGORY_END()
|
||||
|
||||
|
||||
#ifdef BOTS
|
||||
RULE_CATEGORY(Bots)
|
||||
RULE_INT(Bots, AAExpansion, 8) // Bots get AAs through this expansion
|
||||
@@ -557,6 +579,8 @@ RULE_BOOL(Bots, PreferNoManaCommandSpells, true) // Give sorting priority to new
|
||||
RULE_BOOL(Bots, QuestableSpawnLimit, false) // Optional quest method to manage bot spawn limits using the quest_globals name bot_spawn_limit, see: /bazaar/Aediles_Thrall.pl
|
||||
RULE_BOOL(Bots, QuestableSpells, false) // Anita Thrall's (Anita_Thrall.pl) Bot Spell Scriber quests.
|
||||
RULE_INT(Bots, SpawnLimit, 71) // Number of bots a character can have spawned at one time, You + 71 bots is a 12 group pseudo-raid (bots are not raidable at this time)
|
||||
RULE_BOOL(Bots, UpdatePositionWithTimer, false) // Sends a position update with every positive movement timer check
|
||||
RULE_BOOL(Bots, UsePathing, true) // Bots will use node pathing when moving
|
||||
RULE_BOOL(Bots, BotGroupXP, false) // Determines whether client gets xp for bots outside their group.
|
||||
RULE_BOOL(Bots, BotBardUseOutOfCombatSongs, true) // Determines whether bard bots use additional out of combat songs (optional script)
|
||||
RULE_BOOL(Bots, BotLevelsWithOwner, false) // Auto-updates spawned bots as owner levels/de-levels (false is original behavior)
|
||||
|
||||
@@ -663,6 +663,7 @@ struct UsertoWorldRequest_Struct {
|
||||
uint32 worldid;
|
||||
uint32 FromID;
|
||||
uint32 ToID;
|
||||
char IPAddr[64];
|
||||
};
|
||||
|
||||
struct UsertoWorldResponse_Struct {
|
||||
|
||||
+3
-2
@@ -1136,13 +1136,13 @@ const EQEmu::ItemData* SharedDatabase::IterateItems(uint32* id) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::string SharedDatabase::GetBook(const char *txtfile)
|
||||
std::string SharedDatabase::GetBook(const char *txtfile, int16 *language)
|
||||
{
|
||||
char txtfile2[20];
|
||||
std::string txtout;
|
||||
strcpy(txtfile2, txtfile);
|
||||
|
||||
std::string query = StringFormat("SELECT txtfile FROM books WHERE name = '%s'", txtfile2);
|
||||
std::string query = StringFormat("SELECT txtfile, language FROM books WHERE name = '%s'", txtfile2);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success()) {
|
||||
txtout.assign(" ",1);
|
||||
@@ -1157,6 +1157,7 @@ std::string SharedDatabase::GetBook(const char *txtfile)
|
||||
|
||||
auto row = results.begin();
|
||||
txtout.assign(row[0],strlen(row[0]));
|
||||
*language = static_cast<int16>(atoi(row[1]));
|
||||
|
||||
return txtout;
|
||||
}
|
||||
|
||||
+1
-1
@@ -94,7 +94,7 @@ class SharedDatabase : public Database
|
||||
bool SetStartingItems(PlayerProfile_Struct* pp, EQEmu::InventoryProfile* inv, uint32 si_race, uint32 si_class, uint32 si_deity, uint32 si_current_zone, char* si_name, int admin);
|
||||
|
||||
|
||||
std::string GetBook(const char *txtfile);
|
||||
std::string GetBook(const char *txtfile, int16 *language);
|
||||
|
||||
/*
|
||||
Item Methods
|
||||
|
||||
@@ -124,6 +124,57 @@ bool EQEmu::skills::IsCastingSkill(SkillType skill)
|
||||
}
|
||||
}
|
||||
|
||||
int32 EQEmu::skills::GetBaseDamage(SkillType skill)
|
||||
{
|
||||
switch (skill) {
|
||||
case SkillBash:
|
||||
return 2;
|
||||
case SkillDragonPunch:
|
||||
return 12;
|
||||
case SkillEagleStrike:
|
||||
return 7;
|
||||
case SkillFlyingKick:
|
||||
return 25;
|
||||
case SkillKick:
|
||||
return 3;
|
||||
case SkillRoundKick:
|
||||
return 5;
|
||||
case SkillTigerClaw:
|
||||
return 4;
|
||||
case SkillFrenzy:
|
||||
return 10;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool EQEmu::skills::IsMeleeDmg(SkillType skill)
|
||||
{
|
||||
switch (skill) {
|
||||
case Skill1HBlunt:
|
||||
case Skill1HSlashing:
|
||||
case Skill2HBlunt:
|
||||
case Skill2HSlashing:
|
||||
case SkillBackstab:
|
||||
case SkillBash:
|
||||
case SkillDragonPunch:
|
||||
case SkillEagleStrike:
|
||||
case SkillFlyingKick:
|
||||
case SkillHandtoHand:
|
||||
case SkillKick:
|
||||
case Skill1HPiercing:
|
||||
case SkillRiposte:
|
||||
case SkillRoundKick:
|
||||
case SkillThrowing:
|
||||
case SkillTigerClaw:
|
||||
case SkillFrenzy:
|
||||
case Skill2HPiercing:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const std::map<EQEmu::skills::SkillType, std::string>& EQEmu::skills::GetSkillTypeMap()
|
||||
{
|
||||
/* VS2013 code
|
||||
|
||||
@@ -166,6 +166,8 @@ namespace EQEmu
|
||||
float GetSkillMeleePushForce(SkillType skill);
|
||||
bool IsBardInstrumentSkill(SkillType skill);
|
||||
bool IsCastingSkill(SkillType skill);
|
||||
int32 GetBaseDamage(SkillType skill);
|
||||
bool IsMeleeDmg(SkillType skill);
|
||||
|
||||
extern const std::map<SkillType, std::string>& GetSkillTypeMap();
|
||||
|
||||
|
||||
+1
-1
@@ -940,7 +940,7 @@ bool IsRegularSingleTargetHealSpell(uint16 spell_id)
|
||||
{
|
||||
if(spells[spell_id].effectid[0] == 0 && spells[spell_id].base[0] > 0 &&
|
||||
spells[spell_id].targettype == ST_Target && spells[spell_id].buffduration == 0 &&
|
||||
!IsFastHealSpell(spell_id) && !IsCompleteHealSpell(spell_id) &&
|
||||
!IsCompleteHealSpell(spell_id) &&
|
||||
!IsHealOverTimeSpell(spell_id) && !IsGroupSpell(spell_id))
|
||||
return true;
|
||||
|
||||
|
||||
+83
-25
@@ -43,35 +43,93 @@
|
||||
|
||||
const int Z_AGGRO=10;
|
||||
|
||||
const int MobAISpellRange=100; // max range of buffs
|
||||
const int SpellType_Nuke=1;
|
||||
const int SpellType_Heal=2;
|
||||
const int SpellType_Root=4;
|
||||
const int SpellType_Buff=8;
|
||||
const int SpellType_Escape=16;
|
||||
const int SpellType_Pet=32;
|
||||
const int SpellType_Lifetap=64;
|
||||
const int SpellType_Snare=128;
|
||||
const int SpellType_DOT=256;
|
||||
const int SpellType_Dispel=512;
|
||||
const int SpellType_InCombatBuff=1024;
|
||||
const int SpellType_Mez=2048;
|
||||
const int SpellType_Charm=4096;
|
||||
const int SpellType_Slow = 8192;
|
||||
const int SpellType_Debuff = 16384;
|
||||
const int SpellType_Cure = 32768;
|
||||
const int SpellType_Resurrect = 65536;
|
||||
const uint32 MobAISpellRange=100; // max range of buffs
|
||||
|
||||
const int SpellTypes_Detrimental = SpellType_Nuke|SpellType_Root|SpellType_Lifetap|SpellType_Snare|SpellType_DOT|SpellType_Dispel|SpellType_Mez|SpellType_Charm|SpellType_Debuff|SpellType_Slow;
|
||||
const int SpellTypes_Beneficial = SpellType_Heal|SpellType_Buff|SpellType_Escape|SpellType_Pet|SpellType_InCombatBuff|SpellType_Cure;
|
||||
enum SpellTypes : uint32
|
||||
{
|
||||
SpellType_Nuke = (1 << 0),
|
||||
SpellType_Heal = (1 << 1),
|
||||
SpellType_Root = (1 << 2),
|
||||
SpellType_Buff = (1 << 3),
|
||||
SpellType_Escape = (1 << 4),
|
||||
SpellType_Pet = (1 << 5),
|
||||
SpellType_Lifetap = (1 << 6),
|
||||
SpellType_Snare = (1 << 7),
|
||||
SpellType_DOT = (1 << 8),
|
||||
SpellType_Dispel = (1 << 9),
|
||||
SpellType_InCombatBuff = (1 << 10),
|
||||
SpellType_Mez = (1 << 11),
|
||||
SpellType_Charm = (1 << 12),
|
||||
SpellType_Slow = (1 << 13),
|
||||
SpellType_Debuff = (1 << 14),
|
||||
SpellType_Cure = (1 << 15),
|
||||
SpellType_Resurrect = (1 << 16),
|
||||
SpellType_HateRedux = (1 << 17),
|
||||
SpellType_InCombatBuffSong = (1 << 18), // bard in-combat group/ae buffs
|
||||
SpellType_OutOfCombatBuffSong = (1 << 19), // bard out-of-combat group/ae buffs
|
||||
SpellType_PreCombatBuff = (1 << 20),
|
||||
SpellType_PreCombatBuffSong = (1 << 21),
|
||||
|
||||
#define SpellType_Any 0xFFFF
|
||||
SpellTypes_Detrimental = (SpellType_Nuke | SpellType_Root | SpellType_Lifetap | SpellType_Snare | SpellType_DOT | SpellType_Dispel | SpellType_Mez | SpellType_Charm | SpellType_Debuff | SpellType_Slow),
|
||||
SpellTypes_Beneficial = (SpellType_Heal | SpellType_Buff | SpellType_Escape | SpellType_Pet | SpellType_InCombatBuff | SpellType_Cure | SpellType_HateRedux | SpellType_InCombatBuffSong | SpellType_OutOfCombatBuffSong | SpellType_PreCombatBuff | SpellType_PreCombatBuffSong),
|
||||
|
||||
SpellType_Any = 0xFFFFFFFF
|
||||
};
|
||||
|
||||
|
||||
// These should not be used to determine spell category..
|
||||
// They are a graphical affects (effects?) index only
|
||||
// TODO: import sai list
|
||||
enum SpellAffectIndex {
|
||||
SAI_Calm = 12, // Lull and Alliance Spells
|
||||
SAI_Dispell_Sight = 14, // Dispells and Spells like Bind Sight
|
||||
SAI_Memory_Blur = 27,
|
||||
SAI_Calm_Song = 43 // Lull and Alliance Songs
|
||||
SAI_Summon_Mount_Unclass = -1,
|
||||
SAI_Direct_Damage = 0,
|
||||
SAI_Heal_Cure = 1,
|
||||
SAI_AC_Buff = 2,
|
||||
SAI_AE_Damage = 3,
|
||||
SAI_Summon = 4, // Summoned Pets and Items
|
||||
SAI_Sight = 5,
|
||||
SAI_Mana_Regen_Resist_Song = 6,
|
||||
SAI_Stat_Buff = 7,
|
||||
SAI_Vanish = 9, // Invisibility and Gate/Port
|
||||
SAI_Appearance = 10, // Illusion and Size
|
||||
SAI_Enchanter_Pet = 11,
|
||||
SAI_Calm = 12, // Lull and Alliance Spells
|
||||
SAI_Fear = 13,
|
||||
SAI_Dispell_Sight = 14, // Dispells and Spells like Bind Sight
|
||||
SAI_Stun = 15,
|
||||
SAI_Haste_Runspeed = 16, // Haste and SoW
|
||||
SAI_Combat_Slow = 17,
|
||||
SAI_Damage_Shield = 18,
|
||||
SAI_Cannibalize_Weapon_Proc = 19,
|
||||
SAI_Weaken = 20,
|
||||
SAI_Banish = 21,
|
||||
SAI_Blind_Poison = 22,
|
||||
SAI_Cold_DD = 23,
|
||||
SAI_Poison_Disease_DD = 24,
|
||||
SAI_Fire_DD = 25,
|
||||
SAI_Memory_Blur = 27,
|
||||
SAI_Gravity_Fling = 28,
|
||||
SAI_Suffocate = 29,
|
||||
SAI_Lifetap_Over_Time = 30,
|
||||
SAI_Fire_AE = 31,
|
||||
SAI_Cold_AE = 33,
|
||||
SAI_Poison_Disease_AE = 34,
|
||||
SAI_Teleport = 40,
|
||||
SAI_Direct_Damage_Song = 41,
|
||||
SAI_Combat_Buff_Song = 42,
|
||||
SAI_Calm_Song = 43, // Lull and Alliance Songs
|
||||
SAI_Firework = 45,
|
||||
SAI_Firework_AE = 46,
|
||||
SAI_Weather_Rocket = 47,
|
||||
SAI_Convert_Vitals = 50,
|
||||
SAI_NPC_Special_60 = 60,
|
||||
SAI_NPC_Special_61 = 61,
|
||||
SAI_NPC_Special_62 = 62,
|
||||
SAI_NPC_Special_63 = 63,
|
||||
SAI_NPC_Special_70 = 70,
|
||||
SAI_NPC_Special_71 = 71,
|
||||
SAI_NPC_Special_80 = 80,
|
||||
SAI_Trap_Lock = 88
|
||||
};
|
||||
enum RESISTTYPE
|
||||
{
|
||||
|
||||
+2
-2
@@ -30,9 +30,9 @@
|
||||
Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
|
||||
*/
|
||||
|
||||
#define CURRENT_BINARY_DATABASE_VERSION 9101
|
||||
#define CURRENT_BINARY_DATABASE_VERSION 9107
|
||||
#ifdef BOTS
|
||||
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9008
|
||||
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9015
|
||||
#else
|
||||
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 0 // must be 0
|
||||
#endif
|
||||
|
||||
@@ -99,9 +99,11 @@ bool Client::Process()
|
||||
}
|
||||
default:
|
||||
{
|
||||
char dump[64];
|
||||
app->build_header_dump(dump);
|
||||
Log.Out(Logs::General, Logs::Error, "Recieved unhandled application packet from the client: %s.", dump);
|
||||
if (Log.log_settings[Logs::Client_Server_Packet_Unhandled].is_category_enabled == 1) {
|
||||
char dump[64];
|
||||
app->build_header_dump(dump);
|
||||
Log.Out(Logs::General, Logs::Error, "Recieved unhandled application packet from the client: %s.", dump);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
var app = angular.module('app', ['nvd3']);
|
||||
|
||||
app.controller('MainCtrl', function($scope, $interval) {
|
||||
$scope.options = {
|
||||
chart: {
|
||||
type: 'discreteBarChart',
|
||||
height: 450,
|
||||
margin: {
|
||||
top: 20,
|
||||
right: 20,
|
||||
bottom: 50,
|
||||
left: 55
|
||||
},
|
||||
x: function(d) {
|
||||
return d.label;
|
||||
},
|
||||
y: function(d) {
|
||||
return d.value + (1e-10);
|
||||
},
|
||||
showValues: true,
|
||||
valueFormat: function(d) {
|
||||
return d3.format(',.2r')(d);
|
||||
},
|
||||
duration: 500,
|
||||
xAxis: {
|
||||
axisLabel: 'D1-D20'
|
||||
},
|
||||
yAxis: {
|
||||
axisLabel: 'Count'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
$scope.offense = 100;
|
||||
$scope.mitigation = 100;
|
||||
|
||||
$scope.data = [{
|
||||
key: "Cumulative Return",
|
||||
values: []
|
||||
}];
|
||||
|
||||
for (var i = 0; i < 20; ++i) {
|
||||
var value = {
|
||||
"label": i + 1,
|
||||
"value": 0
|
||||
};
|
||||
$scope.data[0].values.push(value);
|
||||
}
|
||||
|
||||
function addRoll(interval) {
|
||||
$scope.data[0].values[interval - 1].value += 1;
|
||||
}
|
||||
|
||||
var stop;
|
||||
$scope.clearData = function() {
|
||||
console.log('Clearing data');
|
||||
for (var i = 0; i < 20; ++i) {
|
||||
$scope.data[0].values[i].value = 0;
|
||||
}
|
||||
};
|
||||
|
||||
$scope.start = function() {
|
||||
if (angular.isDefined(stop))
|
||||
return;
|
||||
|
||||
stop = $interval(doCombatRound, 100);
|
||||
};
|
||||
|
||||
$scope.stop = function() {
|
||||
if (angular.isDefined(stop)) {
|
||||
$interval.cancel(stop);
|
||||
stop = undefined;
|
||||
}
|
||||
};
|
||||
|
||||
$scope.$on('$destroy', function() {
|
||||
$scope.stop();
|
||||
});
|
||||
|
||||
var damage_mods = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20];
|
||||
|
||||
function getRandomInt(min, max) {
|
||||
min = Math.ceil(min);
|
||||
max = Math.floor(max);
|
||||
return Math.floor(Math.random() * (max - min)) + min;
|
||||
}
|
||||
|
||||
function getRandom(min, max) {
|
||||
return Math.random() * (max - min) + min;
|
||||
}
|
||||
|
||||
function addChance(bucket, chance, value) {
|
||||
for (var i = 0; i < chance; ++i) {
|
||||
bucket.push(value);
|
||||
}
|
||||
}
|
||||
|
||||
function doCombatRound() {
|
||||
var offense = getRandomInt(0, $scope.offense + 5);
|
||||
var mitigation = getRandomInt(0, $scope.mitigation + 5);
|
||||
var avg = parseInt(($scope.offense + $scope.mitigation + 10) / 2);
|
||||
var index = parseInt((offense - mitigation) + (avg / 2));
|
||||
if (index < 0) {
|
||||
index = 0;
|
||||
}
|
||||
index = parseInt((index * 20) / avg);
|
||||
if (index >= 20)
|
||||
index = 19;
|
||||
if (index < 0)
|
||||
index = 0;
|
||||
var roll = damage_mods[index];
|
||||
addRoll(roll);
|
||||
};
|
||||
});
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
<!DOCTYPE html>
|
||||
<html ng-app="app">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Combat Visualization</title>
|
||||
<script>document.write('<base href="' + document.location + '" />');</script>
|
||||
<link rel="stylesheet" href="style.css" />
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.8.1/nv.d3.min.css"/>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js" charset="utf-8"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/nvd3/1.8.1/nv.d3.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-nvd3/1.0.5/angular-nvd3.min.js"></script>
|
||||
<script src="app.js"></script>
|
||||
</head>
|
||||
|
||||
<body ng-controller="MainCtrl">
|
||||
<nvd3 options="options" data="data"></nvd3>
|
||||
<button ng-click=clearData()>Clear Data</button>
|
||||
<button ng-click=start()>Start</button>
|
||||
<button ng-click=stop()>Stop</button>
|
||||
<div class="input-row">
|
||||
<label>Offense:</label>
|
||||
<input type="number" name="Offense" ng-model="offense"></input>
|
||||
</div>
|
||||
<div class="input-row">
|
||||
<label>Mitigation:</label>
|
||||
<input type="number" name="mitigation" ng-model="mitigation"></input>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,3 @@
|
||||
.input-row {
|
||||
padding: 8px;
|
||||
}
|
||||
@@ -359,6 +359,9 @@ OP_OpenContainer=0x654f
|
||||
OP_Marquee=0x288a
|
||||
OP_Fling=0x6b8e
|
||||
OP_CancelSneakHide=0x265f
|
||||
OP_AggroMeterLockTarget=0x70b7
|
||||
OP_AggroMeterTargetInfo=0x18fe
|
||||
OP_AggroMeterUpdate=0x75aa
|
||||
|
||||
OP_DzQuit=0x5fc8
|
||||
OP_DzListTimers=0x67b9
|
||||
|
||||
@@ -150,7 +150,7 @@ OP_GMZoneRequest=0x62ac
|
||||
OP_GMZoneRequest2=0x7e1a
|
||||
OP_GMGoto=0x7d8e
|
||||
OP_GMSearchCorpse=0x357c
|
||||
OP_GMHideMe=0x79c5
|
||||
OP_GMHideMe=0x2fab
|
||||
OP_GMDelCorpse=0x607e
|
||||
OP_GMApproval=0x6db5
|
||||
OP_GMToggle=0x2097
|
||||
@@ -360,6 +360,9 @@ OP_ItemRecastDelay=0x15a9
|
||||
OP_ResetAA=0x1669
|
||||
OP_Fling=0x6f80
|
||||
OP_CancelSneakHide=0x0927
|
||||
OP_AggroMeterLockTarget=0x1643
|
||||
OP_AggroMeterTargetInfo=0x16bc
|
||||
OP_AggroMeterUpdate=0x1781
|
||||
|
||||
# Expeditions
|
||||
OP_DzAddPlayer=0x4701
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
DELIMITER $$
|
||||
|
||||
DROP FUNCTION IF EXISTS `GetBodyTypeToken`;
|
||||
|
||||
-- This function converts a numeric body type to a string label based on server code designations
|
||||
-- Note: A preceeding '*' indicates a non-client verified token
|
||||
--
|
||||
-- example:
|
||||
-- SELECT `id`, `name`, GetBodyTypeToken(`bodytype`) FROM `npc_types` WHERE `id` IN ('116539', '154086', '164042');
|
||||
CREATE FUNCTION `GetBodyTypeToken` (`body_type` INT(11)) RETURNS VARCHAR(64)
|
||||
BEGIN
|
||||
DECLARE `token` VARCHAR(64) DEFAULT '';
|
||||
|
||||
CASE `body_type`
|
||||
WHEN '1' THEN SET `token` = 'BT_Humanoid';
|
||||
WHEN '2' THEN SET `token` = 'BT_Lycanthrope';
|
||||
WHEN '3' THEN SET `token` = 'BT_Undead';
|
||||
WHEN '4' THEN SET `token` = 'BT_Giant';
|
||||
WHEN '5' THEN SET `token` = 'BT_Construct';
|
||||
WHEN '6' THEN SET `token` = 'BT_Extraplanar';
|
||||
WHEN '7' THEN SET `token` = 'BT_Magical';
|
||||
WHEN '8' THEN SET `token` = '*BT_SummonedUndead';
|
||||
WHEN '9' THEN SET `token` = '*BT_RaidGiant';
|
||||
WHEN '11' THEN SET `token` = '*BT_NoTarget';
|
||||
WHEN '12' THEN SET `token` = 'BT_Vampyre';
|
||||
WHEN '13' THEN SET `token` = 'BT_Atenha_Ra';
|
||||
WHEN '14' THEN SET `token` = 'BT_Greater_Akheva';
|
||||
WHEN '15' THEN SET `token` = 'BT_Khati_Sha';
|
||||
WHEN '16' THEN SET `token` = '*BT_Seru';
|
||||
WHEN '18' THEN SET `token` = 'BT_Draz_Nurakk';
|
||||
WHEN '19' THEN SET `token` = 'BT_Zek';
|
||||
WHEN '20' THEN SET `token` = 'BT_Luggald';
|
||||
WHEN '21' THEN SET `token` = 'BT_Animal';
|
||||
WHEN '22' THEN SET `token` = 'BT_Insect';
|
||||
WHEN '23' THEN SET `token` = 'BT_Monster';
|
||||
WHEN '24' THEN SET `token` = 'BT_Elemental/*BT_Summoned';
|
||||
WHEN '25' THEN SET `token` = 'BT_Plant';
|
||||
WHEN '26' THEN SET `token` = 'BT_Dragon';
|
||||
WHEN '27' THEN SET `token` = '*BT_Summoned2';
|
||||
WHEN '28' THEN SET `token` = 'BT_Summoned_Creature/*BT_Summoned3';
|
||||
WHEN '30' THEN SET `token` = '*BT_VeliousDragon';
|
||||
WHEN '32' THEN SET `token` = '*BT_Dragon3';
|
||||
WHEN '33' THEN SET `token` = '*BT_Boxes';
|
||||
WHEN '34' THEN SET `token` = 'BT_Muramite';
|
||||
WHEN '60' THEN SET `token` = '*BT_NoTarget2';
|
||||
WHEN '63' THEN SET `token` = '*BT_SwarmPet';
|
||||
WHEN '66' THEN SET `token` = '*BT_InvisMan';
|
||||
WHEN '67' THEN SET `token` = '*BT_Special';
|
||||
ELSE SET `token` = 'BT_UNKNOWN_BODYTYPE';
|
||||
END CASE;
|
||||
|
||||
SET `token` = CONCAT(`token`, '(', `body_type`, ')');
|
||||
|
||||
RETURN `token`;
|
||||
END$$
|
||||
|
||||
DELIMITER ;
|
||||
@@ -0,0 +1,756 @@
|
||||
DELIMITER $$
|
||||
|
||||
DROP FUNCTION IF EXISTS `GetRaceToken`;
|
||||
|
||||
-- This function converts a numeric race id to a string label based on server code designations
|
||||
--
|
||||
-- example:
|
||||
-- SELECT `id`, `name`, GetRaceToken(`race`) FROM `npc_types` WHERE `id` IN ('644', '105153', '261131');
|
||||
CREATE FUNCTION `GetRaceToken` (`race_id` INT(11)) RETURNS VARCHAR(64)
|
||||
BEGIN
|
||||
DECLARE `token` VARCHAR(64) DEFAULT '';
|
||||
|
||||
CASE `race_id`
|
||||
WHEN '0' THEN SET `token` = 'UNKNOWN RACE';
|
||||
WHEN '1' THEN SET `token` = 'Human';
|
||||
WHEN '2' THEN SET `token` = 'Barbarian';
|
||||
WHEN '3' THEN SET `token` = 'Erudite';
|
||||
WHEN '4' THEN SET `token` = 'Wood Elf';
|
||||
WHEN '5' THEN SET `token` = 'High Elf';
|
||||
WHEN '6' THEN SET `token` = 'Dark Elf';
|
||||
WHEN '7' THEN SET `token` = 'Half Elf';
|
||||
WHEN '8' THEN SET `token` = 'Dwarf';
|
||||
WHEN '9' THEN SET `token` = 'Troll';
|
||||
WHEN '10' THEN SET `token` = 'Ogre';
|
||||
WHEN '11' THEN SET `token` = 'Halfling';
|
||||
WHEN '12' THEN SET `token` = 'Gnome';
|
||||
WHEN '13' THEN SET `token` = 'Aviak';
|
||||
WHEN '14' THEN SET `token` = 'Werewolf';
|
||||
WHEN '15' THEN SET `token` = 'Brownie';
|
||||
WHEN '16' THEN SET `token` = 'Centaur';
|
||||
WHEN '17' THEN SET `token` = 'Golem';
|
||||
WHEN '18' THEN SET `token` = 'Giant';
|
||||
WHEN '19' THEN SET `token` = 'Trakanon';
|
||||
WHEN '20' THEN SET `token` = 'Venril Sathir';
|
||||
WHEN '21' THEN SET `token` = 'Evil Eye';
|
||||
WHEN '22' THEN SET `token` = 'Beetle';
|
||||
WHEN '23' THEN SET `token` = 'Kerran';
|
||||
WHEN '24' THEN SET `token` = 'Fish';
|
||||
WHEN '25' THEN SET `token` = 'Fairy';
|
||||
WHEN '26' THEN SET `token` = 'Froglok';
|
||||
WHEN '27' THEN SET `token` = 'Froglok';
|
||||
WHEN '28' THEN SET `token` = 'Fungusman';
|
||||
WHEN '29' THEN SET `token` = 'Gargoyle';
|
||||
WHEN '30' THEN SET `token` = 'Gasbag';
|
||||
WHEN '31' THEN SET `token` = 'Gelatinous Cube';
|
||||
WHEN '32' THEN SET `token` = 'Ghost';
|
||||
WHEN '33' THEN SET `token` = 'Ghoul';
|
||||
WHEN '34' THEN SET `token` = 'Bat';
|
||||
WHEN '35' THEN SET `token` = 'Eel';
|
||||
WHEN '36' THEN SET `token` = 'Rat';
|
||||
WHEN '37' THEN SET `token` = 'Snake';
|
||||
WHEN '38' THEN SET `token` = 'Spider';
|
||||
WHEN '39' THEN SET `token` = 'Gnoll';
|
||||
WHEN '40' THEN SET `token` = 'Goblin';
|
||||
WHEN '41' THEN SET `token` = 'Gorilla';
|
||||
WHEN '42' THEN SET `token` = 'Wolf';
|
||||
WHEN '43' THEN SET `token` = 'Bear';
|
||||
WHEN '44' THEN SET `token` = 'Guard';
|
||||
WHEN '45' THEN SET `token` = 'Demi Lich';
|
||||
WHEN '46' THEN SET `token` = 'Imp';
|
||||
WHEN '47' THEN SET `token` = 'Griffin';
|
||||
WHEN '48' THEN SET `token` = 'Kobold';
|
||||
WHEN '49' THEN SET `token` = 'Dragon';
|
||||
WHEN '50' THEN SET `token` = 'Lion';
|
||||
WHEN '51' THEN SET `token` = 'Lizard Man';
|
||||
WHEN '52' THEN SET `token` = 'Mimic';
|
||||
WHEN '53' THEN SET `token` = 'Minotaur';
|
||||
WHEN '54' THEN SET `token` = 'Orc';
|
||||
WHEN '55' THEN SET `token` = 'Beggar';
|
||||
WHEN '56' THEN SET `token` = 'Pixie';
|
||||
WHEN '57' THEN SET `token` = 'Drachnid';
|
||||
WHEN '58' THEN SET `token` = 'Solusek Ro';
|
||||
WHEN '59' THEN SET `token` = 'Goblin';
|
||||
WHEN '60' THEN SET `token` = 'Skeleton';
|
||||
WHEN '61' THEN SET `token` = 'Shark';
|
||||
WHEN '62' THEN SET `token` = 'Tunare';
|
||||
WHEN '63' THEN SET `token` = 'Tiger';
|
||||
WHEN '64' THEN SET `token` = 'Treant';
|
||||
WHEN '65' THEN SET `token` = 'Vampire';
|
||||
WHEN '66' THEN SET `token` = 'Rallos Zek';
|
||||
WHEN '67' THEN SET `token` = 'Human';
|
||||
WHEN '68' THEN SET `token` = 'Tentacle Terror';
|
||||
WHEN '69' THEN SET `token` = 'Will-O-Wisp';
|
||||
WHEN '70' THEN SET `token` = 'Zombie';
|
||||
WHEN '71' THEN SET `token` = 'Human';
|
||||
WHEN '72' THEN SET `token` = 'Ship';
|
||||
WHEN '73' THEN SET `token` = 'Launch';
|
||||
WHEN '74' THEN SET `token` = 'Piranha';
|
||||
WHEN '75' THEN SET `token` = 'Elemental';
|
||||
WHEN '76' THEN SET `token` = 'Puma';
|
||||
WHEN '77' THEN SET `token` = 'Dark Elf';
|
||||
WHEN '78' THEN SET `token` = 'Erudite';
|
||||
WHEN '79' THEN SET `token` = 'Bixie';
|
||||
WHEN '80' THEN SET `token` = 'Reanimated Hand';
|
||||
WHEN '81' THEN SET `token` = 'Halfling';
|
||||
WHEN '82' THEN SET `token` = 'Scarecrow';
|
||||
WHEN '83' THEN SET `token` = 'Skunk';
|
||||
WHEN '84' THEN SET `token` = 'Snake Elemental';
|
||||
WHEN '85' THEN SET `token` = 'Spectre';
|
||||
WHEN '86' THEN SET `token` = 'Sphinx';
|
||||
WHEN '87' THEN SET `token` = 'Armadillo';
|
||||
WHEN '88' THEN SET `token` = 'Clockwork Gnome';
|
||||
WHEN '89' THEN SET `token` = 'Drake';
|
||||
WHEN '90' THEN SET `token` = 'Barbarian';
|
||||
WHEN '91' THEN SET `token` = 'Alligator';
|
||||
WHEN '92' THEN SET `token` = 'Troll';
|
||||
WHEN '93' THEN SET `token` = 'Ogre';
|
||||
WHEN '94' THEN SET `token` = 'Dwarf';
|
||||
WHEN '95' THEN SET `token` = 'Cazic Thule';
|
||||
WHEN '96' THEN SET `token` = 'Cockatrice';
|
||||
WHEN '97' THEN SET `token` = 'Daisy Man';
|
||||
WHEN '98' THEN SET `token` = 'Vampire';
|
||||
WHEN '99' THEN SET `token` = 'Amygdalan';
|
||||
WHEN '100' THEN SET `token` = 'Dervish';
|
||||
WHEN '101' THEN SET `token` = 'Efreeti';
|
||||
WHEN '102' THEN SET `token` = 'Tadpole';
|
||||
WHEN '103' THEN SET `token` = 'Kedge';
|
||||
WHEN '104' THEN SET `token` = 'Leech';
|
||||
WHEN '105' THEN SET `token` = 'Swordfish';
|
||||
WHEN '106' THEN SET `token` = 'Guard';
|
||||
WHEN '107' THEN SET `token` = 'Mammoth';
|
||||
WHEN '108' THEN SET `token` = 'Eye';
|
||||
WHEN '109' THEN SET `token` = 'Wasp';
|
||||
WHEN '110' THEN SET `token` = 'Mermaid';
|
||||
WHEN '111' THEN SET `token` = 'Harpy';
|
||||
WHEN '112' THEN SET `token` = 'Guard';
|
||||
WHEN '113' THEN SET `token` = 'Drixie';
|
||||
WHEN '114' THEN SET `token` = 'Ghost Ship';
|
||||
WHEN '115' THEN SET `token` = 'Clam';
|
||||
WHEN '116' THEN SET `token` = 'Seahorse';
|
||||
WHEN '117' THEN SET `token` = 'Ghost';
|
||||
WHEN '118' THEN SET `token` = 'Ghost';
|
||||
WHEN '119' THEN SET `token` = 'Saber-toothed Cat';
|
||||
WHEN '120' THEN SET `token` = 'Wolf';
|
||||
WHEN '121' THEN SET `token` = 'Gorgon';
|
||||
WHEN '122' THEN SET `token` = 'Dragon';
|
||||
WHEN '123' THEN SET `token` = 'Innoruuk';
|
||||
WHEN '124' THEN SET `token` = 'Unicorn';
|
||||
WHEN '125' THEN SET `token` = 'Pegasus';
|
||||
WHEN '126' THEN SET `token` = 'Djinn';
|
||||
WHEN '127' THEN SET `token` = 'Invisible Man';
|
||||
WHEN '128' THEN SET `token` = 'Iksar';
|
||||
WHEN '129' THEN SET `token` = 'Scorpion';
|
||||
WHEN '130' THEN SET `token` = 'Vah Shir';
|
||||
WHEN '131' THEN SET `token` = 'Sarnak';
|
||||
WHEN '132' THEN SET `token` = 'Draglock';
|
||||
WHEN '133' THEN SET `token` = 'Drolvarg';
|
||||
WHEN '134' THEN SET `token` = 'Mosquito';
|
||||
WHEN '135' THEN SET `token` = 'Rhinoceros';
|
||||
WHEN '136' THEN SET `token` = 'Xalgoz';
|
||||
WHEN '137' THEN SET `token` = 'Goblin';
|
||||
WHEN '138' THEN SET `token` = 'Yeti';
|
||||
WHEN '139' THEN SET `token` = 'Iksar';
|
||||
WHEN '140' THEN SET `token` = 'Giant';
|
||||
WHEN '141' THEN SET `token` = 'Boat';
|
||||
WHEN '142' THEN SET `token` = 'UNKNOWN RACE';
|
||||
WHEN '143' THEN SET `token` = 'UNKNOWN RACE';
|
||||
WHEN '144' THEN SET `token` = 'Burynai';
|
||||
WHEN '145' THEN SET `token` = 'Goo';
|
||||
WHEN '146' THEN SET `token` = 'Sarnak Spirit';
|
||||
WHEN '147' THEN SET `token` = 'Iksar Spirit';
|
||||
WHEN '148' THEN SET `token` = 'Fish';
|
||||
WHEN '149' THEN SET `token` = 'Scorpion';
|
||||
WHEN '150' THEN SET `token` = 'Erollisi';
|
||||
WHEN '151' THEN SET `token` = 'Tribunal';
|
||||
WHEN '152' THEN SET `token` = 'Bertoxxulous';
|
||||
WHEN '153' THEN SET `token` = 'Bristlebane';
|
||||
WHEN '154' THEN SET `token` = 'Fay Drake';
|
||||
WHEN '155' THEN SET `token` = 'Undead Sarnak';
|
||||
WHEN '156' THEN SET `token` = 'Ratman';
|
||||
WHEN '157' THEN SET `token` = 'Wyvern';
|
||||
WHEN '158' THEN SET `token` = 'Wurm';
|
||||
WHEN '159' THEN SET `token` = 'Devourer';
|
||||
WHEN '160' THEN SET `token` = 'Iksar Golem';
|
||||
WHEN '161' THEN SET `token` = 'Undead Iksar';
|
||||
WHEN '162' THEN SET `token` = 'Man-Eating Plant';
|
||||
WHEN '163' THEN SET `token` = 'Raptor';
|
||||
WHEN '164' THEN SET `token` = 'Sarnak Golem';
|
||||
WHEN '165' THEN SET `token` = 'Dragon';
|
||||
WHEN '166' THEN SET `token` = 'Animated Hand';
|
||||
WHEN '167' THEN SET `token` = 'Succulent';
|
||||
WHEN '168' THEN SET `token` = 'Holgresh';
|
||||
WHEN '169' THEN SET `token` = 'Brontotherium';
|
||||
WHEN '170' THEN SET `token` = 'Snow Dervish';
|
||||
WHEN '171' THEN SET `token` = 'Dire Wolf';
|
||||
WHEN '172' THEN SET `token` = 'Manticore';
|
||||
WHEN '173' THEN SET `token` = 'Totem';
|
||||
WHEN '174' THEN SET `token` = 'Ice Spectre';
|
||||
WHEN '175' THEN SET `token` = 'Enchanted Armor';
|
||||
WHEN '176' THEN SET `token` = 'Snow Rabbit';
|
||||
WHEN '177' THEN SET `token` = 'Walrus';
|
||||
WHEN '178' THEN SET `token` = 'Geonid';
|
||||
WHEN '179' THEN SET `token` = 'UNKNOWN RACE';
|
||||
WHEN '180' THEN SET `token` = 'UNKNOWN RACE';
|
||||
WHEN '181' THEN SET `token` = 'Yakkar';
|
||||
WHEN '182' THEN SET `token` = 'Faun';
|
||||
WHEN '183' THEN SET `token` = 'Coldain';
|
||||
WHEN '184' THEN SET `token` = 'Dragon';
|
||||
WHEN '185' THEN SET `token` = 'Hag';
|
||||
WHEN '186' THEN SET `token` = 'Hippogriff';
|
||||
WHEN '187' THEN SET `token` = 'Siren';
|
||||
WHEN '188' THEN SET `token` = 'Giant';
|
||||
WHEN '189' THEN SET `token` = 'Giant';
|
||||
WHEN '190' THEN SET `token` = 'Othmir';
|
||||
WHEN '191' THEN SET `token` = 'Ulthork';
|
||||
WHEN '192' THEN SET `token` = 'Dragon';
|
||||
WHEN '193' THEN SET `token` = 'Abhorrent';
|
||||
WHEN '194' THEN SET `token` = 'Sea Turtle';
|
||||
WHEN '195' THEN SET `token` = 'Dragon';
|
||||
WHEN '196' THEN SET `token` = 'Dragon';
|
||||
WHEN '197' THEN SET `token` = 'Ronnie Test';
|
||||
WHEN '198' THEN SET `token` = 'Dragon';
|
||||
WHEN '199' THEN SET `token` = 'Shik\'Nar';
|
||||
WHEN '200' THEN SET `token` = 'Rockhopper';
|
||||
WHEN '201' THEN SET `token` = 'Underbulk';
|
||||
WHEN '202' THEN SET `token` = 'Grimling';
|
||||
WHEN '203' THEN SET `token` = 'Worm';
|
||||
WHEN '204' THEN SET `token` = 'Evan Test';
|
||||
WHEN '205' THEN SET `token` = 'Shadel';
|
||||
WHEN '206' THEN SET `token` = 'Owlbear';
|
||||
WHEN '207' THEN SET `token` = 'Rhino Beetle';
|
||||
WHEN '208' THEN SET `token` = 'Vampire';
|
||||
WHEN '209' THEN SET `token` = 'Earth Elemental';
|
||||
WHEN '210' THEN SET `token` = 'Air Elemental';
|
||||
WHEN '211' THEN SET `token` = 'Water Elemental';
|
||||
WHEN '212' THEN SET `token` = 'Fire Elemental';
|
||||
WHEN '213' THEN SET `token` = 'Wetfang Minnow';
|
||||
WHEN '214' THEN SET `token` = 'Thought Horror';
|
||||
WHEN '215' THEN SET `token` = 'Tegi';
|
||||
WHEN '216' THEN SET `token` = 'Horse';
|
||||
WHEN '217' THEN SET `token` = 'Shissar';
|
||||
WHEN '218' THEN SET `token` = 'Fungal Fiend';
|
||||
WHEN '219' THEN SET `token` = 'Vampire';
|
||||
WHEN '220' THEN SET `token` = 'Stonegrabber';
|
||||
WHEN '221' THEN SET `token` = 'Scarlet Cheetah';
|
||||
WHEN '222' THEN SET `token` = 'Zelniak';
|
||||
WHEN '223' THEN SET `token` = 'Lightcrawler';
|
||||
WHEN '224' THEN SET `token` = 'Shade';
|
||||
WHEN '225' THEN SET `token` = 'Sunflower';
|
||||
WHEN '226' THEN SET `token` = 'Sun Revenant';
|
||||
WHEN '227' THEN SET `token` = 'Shrieker';
|
||||
WHEN '228' THEN SET `token` = 'Galorian';
|
||||
WHEN '229' THEN SET `token` = 'Netherbian';
|
||||
WHEN '230' THEN SET `token` = 'Akheva';
|
||||
WHEN '231' THEN SET `token` = 'Grieg Veneficus';
|
||||
WHEN '232' THEN SET `token` = 'Sonic Wolf';
|
||||
WHEN '233' THEN SET `token` = 'Ground Shaker';
|
||||
WHEN '234' THEN SET `token` = 'Vah Shir Skeleton';
|
||||
WHEN '235' THEN SET `token` = 'Wretch';
|
||||
WHEN '236' THEN SET `token` = 'Seru';
|
||||
WHEN '237' THEN SET `token` = 'Recuso';
|
||||
WHEN '238' THEN SET `token` = 'Vah Shir';
|
||||
WHEN '239' THEN SET `token` = 'Guard';
|
||||
WHEN '240' THEN SET `token` = 'Teleport Man';
|
||||
WHEN '241' THEN SET `token` = 'Werewolf';
|
||||
WHEN '242' THEN SET `token` = 'Nymph';
|
||||
WHEN '243' THEN SET `token` = 'Dryad';
|
||||
WHEN '244' THEN SET `token` = 'Treant';
|
||||
WHEN '245' THEN SET `token` = 'Fly';
|
||||
WHEN '246' THEN SET `token` = 'Tarew Marr';
|
||||
WHEN '247' THEN SET `token` = 'Solusek Ro';
|
||||
WHEN '248' THEN SET `token` = 'Clockwork Golem';
|
||||
WHEN '249' THEN SET `token` = 'Clockwork Brain';
|
||||
WHEN '250' THEN SET `token` = 'Banshee';
|
||||
WHEN '251' THEN SET `token` = 'Guard of Justice';
|
||||
WHEN '252' THEN SET `token` = 'Mini POM';
|
||||
WHEN '253' THEN SET `token` = 'Diseased Fiend';
|
||||
WHEN '254' THEN SET `token` = 'Solusek Ro Guard';
|
||||
WHEN '255' THEN SET `token` = 'Bertoxxulous';
|
||||
WHEN '256' THEN SET `token` = 'The Tribunal';
|
||||
WHEN '257' THEN SET `token` = 'Terris Thule';
|
||||
WHEN '258' THEN SET `token` = 'Vegerog';
|
||||
WHEN '259' THEN SET `token` = 'Crocodile';
|
||||
WHEN '260' THEN SET `token` = 'Bat';
|
||||
WHEN '261' THEN SET `token` = 'Hraquis';
|
||||
WHEN '262' THEN SET `token` = 'Tranquilion';
|
||||
WHEN '263' THEN SET `token` = 'Tin Soldier';
|
||||
WHEN '264' THEN SET `token` = 'Nightmare Wraith';
|
||||
WHEN '265' THEN SET `token` = 'Malarian';
|
||||
WHEN '266' THEN SET `token` = 'Knight of Pestilence';
|
||||
WHEN '267' THEN SET `token` = 'Lepertoloth';
|
||||
WHEN '268' THEN SET `token` = 'Bubonian';
|
||||
WHEN '269' THEN SET `token` = 'Bubonian Underling';
|
||||
WHEN '270' THEN SET `token` = 'Pusling';
|
||||
WHEN '271' THEN SET `token` = 'Water Mephit';
|
||||
WHEN '272' THEN SET `token` = 'Stormrider';
|
||||
WHEN '273' THEN SET `token` = 'Junk Beast';
|
||||
WHEN '274' THEN SET `token` = 'Broken Clockwork';
|
||||
WHEN '275' THEN SET `token` = 'Giant Clockwork';
|
||||
WHEN '276' THEN SET `token` = 'Clockwork Beetle';
|
||||
WHEN '277' THEN SET `token` = 'Nightmare Goblin';
|
||||
WHEN '278' THEN SET `token` = 'Karana';
|
||||
WHEN '279' THEN SET `token` = 'Blood Raven';
|
||||
WHEN '280' THEN SET `token` = 'Nightmare Gargoyle';
|
||||
WHEN '281' THEN SET `token` = 'Mouth of Insanity';
|
||||
WHEN '282' THEN SET `token` = 'Skeletal Horse';
|
||||
WHEN '283' THEN SET `token` = 'Saryrn';
|
||||
WHEN '284' THEN SET `token` = 'Fennin Ro';
|
||||
WHEN '285' THEN SET `token` = 'Tormentor';
|
||||
WHEN '286' THEN SET `token` = 'Soul Devourer';
|
||||
WHEN '287' THEN SET `token` = 'Nightmare';
|
||||
WHEN '288' THEN SET `token` = 'Rallos Zek';
|
||||
WHEN '289' THEN SET `token` = 'Vallon Zek';
|
||||
WHEN '290' THEN SET `token` = 'Tallon Zek';
|
||||
WHEN '291' THEN SET `token` = 'Air Mephit';
|
||||
WHEN '292' THEN SET `token` = 'Earth Mephit';
|
||||
WHEN '293' THEN SET `token` = 'Fire Mephit';
|
||||
WHEN '294' THEN SET `token` = 'Nightmare Mephit';
|
||||
WHEN '295' THEN SET `token` = 'Zebuxoruk';
|
||||
WHEN '296' THEN SET `token` = 'Mithaniel Marr';
|
||||
WHEN '297' THEN SET `token` = 'Undead Knight';
|
||||
WHEN '298' THEN SET `token` = 'The Rathe';
|
||||
WHEN '299' THEN SET `token` = 'Xegony';
|
||||
WHEN '300' THEN SET `token` = 'Fiend';
|
||||
WHEN '301' THEN SET `token` = 'Test Object';
|
||||
WHEN '302' THEN SET `token` = 'Crab';
|
||||
WHEN '303' THEN SET `token` = 'Phoenix';
|
||||
WHEN '304' THEN SET `token` = 'Dragon';
|
||||
WHEN '305' THEN SET `token` = 'Bear';
|
||||
WHEN '306' THEN SET `token` = 'Giant';
|
||||
WHEN '307' THEN SET `token` = 'Giant';
|
||||
WHEN '308' THEN SET `token` = 'Giant';
|
||||
WHEN '309' THEN SET `token` = 'Giant';
|
||||
WHEN '310' THEN SET `token` = 'Giant';
|
||||
WHEN '311' THEN SET `token` = 'Giant';
|
||||
WHEN '312' THEN SET `token` = 'Giant';
|
||||
WHEN '313' THEN SET `token` = 'War Wraith';
|
||||
WHEN '314' THEN SET `token` = 'Wrulon';
|
||||
WHEN '315' THEN SET `token` = 'Kraken';
|
||||
WHEN '316' THEN SET `token` = 'Poison Frog';
|
||||
WHEN '317' THEN SET `token` = 'Nilborien';
|
||||
WHEN '318' THEN SET `token` = 'Valorian';
|
||||
WHEN '319' THEN SET `token` = 'War Boar';
|
||||
WHEN '320' THEN SET `token` = 'Efreeti';
|
||||
WHEN '321' THEN SET `token` = 'War Boar';
|
||||
WHEN '322' THEN SET `token` = 'Valorian';
|
||||
WHEN '323' THEN SET `token` = 'Animated Armor';
|
||||
WHEN '324' THEN SET `token` = 'Undead Footman';
|
||||
WHEN '325' THEN SET `token` = 'Rallos Zek Minion';
|
||||
WHEN '326' THEN SET `token` = 'Arachnid';
|
||||
WHEN '327' THEN SET `token` = 'Crystal Spider';
|
||||
WHEN '328' THEN SET `token` = 'Zebuxoruk\'s Cage';
|
||||
WHEN '329' THEN SET `token` = 'BoT Portal';
|
||||
WHEN '330' THEN SET `token` = 'Froglok';
|
||||
WHEN '331' THEN SET `token` = 'Troll';
|
||||
WHEN '332' THEN SET `token` = 'Troll';
|
||||
WHEN '333' THEN SET `token` = 'Troll';
|
||||
WHEN '334' THEN SET `token` = 'Ghost';
|
||||
WHEN '335' THEN SET `token` = 'Pirate';
|
||||
WHEN '336' THEN SET `token` = 'Pirate';
|
||||
WHEN '337' THEN SET `token` = 'Pirate';
|
||||
WHEN '338' THEN SET `token` = 'Pirate';
|
||||
WHEN '339' THEN SET `token` = 'Pirate';
|
||||
WHEN '340' THEN SET `token` = 'Pirate';
|
||||
WHEN '341' THEN SET `token` = 'Pirate';
|
||||
WHEN '342' THEN SET `token` = 'Pirate';
|
||||
WHEN '343' THEN SET `token` = 'Frog';
|
||||
WHEN '344' THEN SET `token` = 'Troll Zombie';
|
||||
WHEN '345' THEN SET `token` = 'Luggald';
|
||||
WHEN '346' THEN SET `token` = 'Luggald';
|
||||
WHEN '347' THEN SET `token` = 'Luggalds';
|
||||
WHEN '348' THEN SET `token` = 'Drogmore';
|
||||
WHEN '349' THEN SET `token` = 'Froglok Skeleton';
|
||||
WHEN '350' THEN SET `token` = 'Undead Froglok';
|
||||
WHEN '351' THEN SET `token` = 'Knight of Hate';
|
||||
WHEN '352' THEN SET `token` = 'Arcanist of Hate';
|
||||
WHEN '353' THEN SET `token` = 'Veksar';
|
||||
WHEN '354' THEN SET `token` = 'Veksar';
|
||||
WHEN '355' THEN SET `token` = 'Veksar';
|
||||
WHEN '356' THEN SET `token` = 'Chokidai';
|
||||
WHEN '357' THEN SET `token` = 'Undead Chokidai';
|
||||
WHEN '358' THEN SET `token` = 'Undead Veksar';
|
||||
WHEN '359' THEN SET `token` = 'Vampire';
|
||||
WHEN '360' THEN SET `token` = 'Vampire';
|
||||
WHEN '361' THEN SET `token` = 'Rujarkian Orc';
|
||||
WHEN '362' THEN SET `token` = 'Bone Golem';
|
||||
WHEN '363' THEN SET `token` = 'Synarcana';
|
||||
WHEN '364' THEN SET `token` = 'Sand Elf';
|
||||
WHEN '365' THEN SET `token` = 'Vampire';
|
||||
WHEN '366' THEN SET `token` = 'Rujarkian Orc';
|
||||
WHEN '367' THEN SET `token` = 'Skeleton';
|
||||
WHEN '368' THEN SET `token` = 'Mummy';
|
||||
WHEN '369' THEN SET `token` = 'Goblin';
|
||||
WHEN '370' THEN SET `token` = 'Insect';
|
||||
WHEN '371' THEN SET `token` = 'Froglok Ghost';
|
||||
WHEN '372' THEN SET `token` = 'Dervish';
|
||||
WHEN '373' THEN SET `token` = 'Shade';
|
||||
WHEN '374' THEN SET `token` = 'Golem';
|
||||
WHEN '375' THEN SET `token` = 'Evil Eye';
|
||||
WHEN '376' THEN SET `token` = 'Box';
|
||||
WHEN '377' THEN SET `token` = 'Barrel';
|
||||
WHEN '378' THEN SET `token` = 'Chest';
|
||||
WHEN '379' THEN SET `token` = 'Vase';
|
||||
WHEN '380' THEN SET `token` = 'Table';
|
||||
WHEN '381' THEN SET `token` = 'Weapon Rack';
|
||||
WHEN '382' THEN SET `token` = 'Coffin';
|
||||
WHEN '383' THEN SET `token` = 'Bones';
|
||||
WHEN '384' THEN SET `token` = 'Jokester';
|
||||
WHEN '385' THEN SET `token` = 'Nihil';
|
||||
WHEN '386' THEN SET `token` = 'Trusik';
|
||||
WHEN '387' THEN SET `token` = 'Stone Worker';
|
||||
WHEN '388' THEN SET `token` = 'Hynid';
|
||||
WHEN '389' THEN SET `token` = 'Turepta';
|
||||
WHEN '390' THEN SET `token` = 'Cragbeast';
|
||||
WHEN '391' THEN SET `token` = 'Stonemite';
|
||||
WHEN '392' THEN SET `token` = 'Ukun';
|
||||
WHEN '393' THEN SET `token` = 'Ixt';
|
||||
WHEN '394' THEN SET `token` = 'Ikaav';
|
||||
WHEN '395' THEN SET `token` = 'Aneuk';
|
||||
WHEN '396' THEN SET `token` = 'Kyv';
|
||||
WHEN '397' THEN SET `token` = 'Noc';
|
||||
WHEN '398' THEN SET `token` = 'Ra`tuk';
|
||||
WHEN '399' THEN SET `token` = 'Taneth';
|
||||
WHEN '400' THEN SET `token` = 'Huvul';
|
||||
WHEN '401' THEN SET `token` = 'Mutna';
|
||||
WHEN '402' THEN SET `token` = 'Mastruq';
|
||||
WHEN '403' THEN SET `token` = 'Taelosian';
|
||||
WHEN '404' THEN SET `token` = 'Discord Ship';
|
||||
WHEN '405' THEN SET `token` = 'Stone Worker';
|
||||
WHEN '406' THEN SET `token` = 'Mata Muram';
|
||||
WHEN '407' THEN SET `token` = 'Lightning Warrior';
|
||||
WHEN '408' THEN SET `token` = 'Succubus';
|
||||
WHEN '409' THEN SET `token` = 'Bazu';
|
||||
WHEN '410' THEN SET `token` = 'Feran';
|
||||
WHEN '411' THEN SET `token` = 'Pyrilen';
|
||||
WHEN '412' THEN SET `token` = 'Chimera';
|
||||
WHEN '413' THEN SET `token` = 'Dragorn';
|
||||
WHEN '414' THEN SET `token` = 'Murkglider';
|
||||
WHEN '415' THEN SET `token` = 'Rat';
|
||||
WHEN '416' THEN SET `token` = 'Bat';
|
||||
WHEN '417' THEN SET `token` = 'Gelidran';
|
||||
WHEN '418' THEN SET `token` = 'Discordling';
|
||||
WHEN '419' THEN SET `token` = 'Girplan';
|
||||
WHEN '420' THEN SET `token` = 'Minotaur';
|
||||
WHEN '421' THEN SET `token` = 'Dragorn Box';
|
||||
WHEN '422' THEN SET `token` = 'Runed Orb';
|
||||
WHEN '423' THEN SET `token` = 'Dragon Bones';
|
||||
WHEN '424' THEN SET `token` = 'Muramite Armor Pile';
|
||||
WHEN '425' THEN SET `token` = 'Crystal Shard';
|
||||
WHEN '426' THEN SET `token` = 'Portal';
|
||||
WHEN '427' THEN SET `token` = 'Coin Purse';
|
||||
WHEN '428' THEN SET `token` = 'Rock Pile';
|
||||
WHEN '429' THEN SET `token` = 'Murkglider Egg Sac';
|
||||
WHEN '430' THEN SET `token` = 'Drake';
|
||||
WHEN '431' THEN SET `token` = 'Dervish';
|
||||
WHEN '432' THEN SET `token` = 'Drake';
|
||||
WHEN '433' THEN SET `token` = 'Goblin';
|
||||
WHEN '434' THEN SET `token` = 'Kirin';
|
||||
WHEN '435' THEN SET `token` = 'Dragon';
|
||||
WHEN '436' THEN SET `token` = 'Basilisk';
|
||||
WHEN '437' THEN SET `token` = 'Dragon';
|
||||
WHEN '438' THEN SET `token` = 'Dragon';
|
||||
WHEN '439' THEN SET `token` = 'Puma';
|
||||
WHEN '440' THEN SET `token` = 'Spider';
|
||||
WHEN '441' THEN SET `token` = 'Spider Queen';
|
||||
WHEN '442' THEN SET `token` = 'Animated Statue';
|
||||
WHEN '443' THEN SET `token` = 'UNKNOWN RACE';
|
||||
WHEN '444' THEN SET `token` = 'UNKNOWN RACE';
|
||||
WHEN '445' THEN SET `token` = 'Dragon Egg';
|
||||
WHEN '446' THEN SET `token` = 'Dragon Statue';
|
||||
WHEN '447' THEN SET `token` = 'Lava Rock';
|
||||
WHEN '448' THEN SET `token` = 'Animated Statue';
|
||||
WHEN '449' THEN SET `token` = 'Spider Egg Sack';
|
||||
WHEN '450' THEN SET `token` = 'Lava Spider';
|
||||
WHEN '451' THEN SET `token` = 'Lava Spider Queen';
|
||||
WHEN '452' THEN SET `token` = 'Dragon';
|
||||
WHEN '453' THEN SET `token` = 'Giant';
|
||||
WHEN '454' THEN SET `token` = 'Werewolf';
|
||||
WHEN '455' THEN SET `token` = 'Kobold';
|
||||
WHEN '456' THEN SET `token` = 'Sporali';
|
||||
WHEN '457' THEN SET `token` = 'Gnomework';
|
||||
WHEN '458' THEN SET `token` = 'Orc';
|
||||
WHEN '459' THEN SET `token` = 'Corathus';
|
||||
WHEN '460' THEN SET `token` = 'Coral';
|
||||
WHEN '461' THEN SET `token` = 'Drachnid';
|
||||
WHEN '462' THEN SET `token` = 'Drachnid Cocoon';
|
||||
WHEN '463' THEN SET `token` = 'Fungus Patch';
|
||||
WHEN '464' THEN SET `token` = 'Gargoyle';
|
||||
WHEN '465' THEN SET `token` = 'Witheran';
|
||||
WHEN '466' THEN SET `token` = 'Dark Lord';
|
||||
WHEN '467' THEN SET `token` = 'Shiliskin';
|
||||
WHEN '468' THEN SET `token` = 'Snake';
|
||||
WHEN '469' THEN SET `token` = 'Evil Eye';
|
||||
WHEN '470' THEN SET `token` = 'Minotaur';
|
||||
WHEN '471' THEN SET `token` = 'Zombie';
|
||||
WHEN '472' THEN SET `token` = 'Clockwork Boar';
|
||||
WHEN '473' THEN SET `token` = 'Fairy';
|
||||
WHEN '474' THEN SET `token` = 'Witheran';
|
||||
WHEN '475' THEN SET `token` = 'Air Elemental';
|
||||
WHEN '476' THEN SET `token` = 'Earth Elemental';
|
||||
WHEN '477' THEN SET `token` = 'Fire Elemental';
|
||||
WHEN '478' THEN SET `token` = 'Water Elemental';
|
||||
WHEN '479' THEN SET `token` = 'Alligator';
|
||||
WHEN '480' THEN SET `token` = 'Bear';
|
||||
WHEN '481' THEN SET `token` = 'Scaled Wolf';
|
||||
WHEN '482' THEN SET `token` = 'Wolf';
|
||||
WHEN '483' THEN SET `token` = 'Spirit Wolf';
|
||||
WHEN '484' THEN SET `token` = 'Skeleton';
|
||||
WHEN '485' THEN SET `token` = 'Spectre';
|
||||
WHEN '486' THEN SET `token` = 'Bolvirk';
|
||||
WHEN '487' THEN SET `token` = 'Banshee';
|
||||
WHEN '488' THEN SET `token` = 'Banshee';
|
||||
WHEN '489' THEN SET `token` = 'Elddar';
|
||||
WHEN '490' THEN SET `token` = 'Forest Giant';
|
||||
WHEN '491' THEN SET `token` = 'Bone Golem';
|
||||
WHEN '492' THEN SET `token` = 'Horse';
|
||||
WHEN '493' THEN SET `token` = 'Pegasus';
|
||||
WHEN '494' THEN SET `token` = 'Shambling Mound';
|
||||
WHEN '495' THEN SET `token` = 'Scrykin';
|
||||
WHEN '496' THEN SET `token` = 'Treant';
|
||||
WHEN '497' THEN SET `token` = 'Vampire';
|
||||
WHEN '498' THEN SET `token` = 'Ayonae Ro';
|
||||
WHEN '499' THEN SET `token` = 'Sullon Zek';
|
||||
WHEN '500' THEN SET `token` = 'Banner';
|
||||
WHEN '501' THEN SET `token` = 'Flag';
|
||||
WHEN '502' THEN SET `token` = 'Rowboat';
|
||||
WHEN '503' THEN SET `token` = 'Bear Trap';
|
||||
WHEN '504' THEN SET `token` = 'Clockwork Bomb';
|
||||
WHEN '505' THEN SET `token` = 'Dynamite Keg';
|
||||
WHEN '506' THEN SET `token` = 'Pressure Plate';
|
||||
WHEN '507' THEN SET `token` = 'Puffer Spore';
|
||||
WHEN '508' THEN SET `token` = 'Stone Ring';
|
||||
WHEN '509' THEN SET `token` = 'Root Tentacle';
|
||||
WHEN '510' THEN SET `token` = 'Runic Symbol';
|
||||
WHEN '511' THEN SET `token` = 'Saltpetter Bomb';
|
||||
WHEN '512' THEN SET `token` = 'Floating Skull';
|
||||
WHEN '513' THEN SET `token` = 'Spike Trap';
|
||||
WHEN '514' THEN SET `token` = 'Totem';
|
||||
WHEN '515' THEN SET `token` = 'Web';
|
||||
WHEN '516' THEN SET `token` = 'Wicker Basket';
|
||||
WHEN '517' THEN SET `token` = 'Nightmare/Unicorn';
|
||||
WHEN '518' THEN SET `token` = 'Horse';
|
||||
WHEN '519' THEN SET `token` = 'Nightmare/Unicorn';
|
||||
WHEN '520' THEN SET `token` = 'Bixie';
|
||||
WHEN '521' THEN SET `token` = 'Centaur';
|
||||
WHEN '522' THEN SET `token` = 'Drakkin';
|
||||
WHEN '523' THEN SET `token` = 'Giant';
|
||||
WHEN '524' THEN SET `token` = 'Gnoll';
|
||||
WHEN '525' THEN SET `token` = 'Griffin';
|
||||
WHEN '526' THEN SET `token` = 'Giant Shade';
|
||||
WHEN '527' THEN SET `token` = 'Harpy';
|
||||
WHEN '528' THEN SET `token` = 'Mammoth';
|
||||
WHEN '529' THEN SET `token` = 'Satyr';
|
||||
WHEN '530' THEN SET `token` = 'Dragon';
|
||||
WHEN '531' THEN SET `token` = 'Dragon';
|
||||
WHEN '532' THEN SET `token` = 'Dyn\'Leth';
|
||||
WHEN '533' THEN SET `token` = 'Boat';
|
||||
WHEN '534' THEN SET `token` = 'Weapon Rack';
|
||||
WHEN '535' THEN SET `token` = 'Armor Rack';
|
||||
WHEN '536' THEN SET `token` = 'Honey Pot';
|
||||
WHEN '537' THEN SET `token` = 'Jum Jum Bucket';
|
||||
WHEN '538' THEN SET `token` = 'Toolbox';
|
||||
WHEN '539' THEN SET `token` = 'Stone Jug';
|
||||
WHEN '540' THEN SET `token` = 'Small Plant';
|
||||
WHEN '541' THEN SET `token` = 'Medium Plant';
|
||||
WHEN '542' THEN SET `token` = 'Tall Plant';
|
||||
WHEN '543' THEN SET `token` = 'Wine Cask';
|
||||
WHEN '544' THEN SET `token` = 'Elven Boat';
|
||||
WHEN '545' THEN SET `token` = 'Gnomish Boat';
|
||||
WHEN '546' THEN SET `token` = 'Barrel Barge Ship';
|
||||
WHEN '547' THEN SET `token` = 'Goo';
|
||||
WHEN '548' THEN SET `token` = 'Goo';
|
||||
WHEN '549' THEN SET `token` = 'Goo';
|
||||
WHEN '550' THEN SET `token` = 'Merchant Ship';
|
||||
WHEN '551' THEN SET `token` = 'Pirate Ship';
|
||||
WHEN '552' THEN SET `token` = 'Ghost Ship';
|
||||
WHEN '553' THEN SET `token` = 'Banner';
|
||||
WHEN '554' THEN SET `token` = 'Banner';
|
||||
WHEN '555' THEN SET `token` = 'Banner';
|
||||
WHEN '556' THEN SET `token` = 'Banner';
|
||||
WHEN '557' THEN SET `token` = 'Banner';
|
||||
WHEN '558' THEN SET `token` = 'Aviak';
|
||||
WHEN '559' THEN SET `token` = 'Beetle';
|
||||
WHEN '560' THEN SET `token` = 'Gorilla';
|
||||
WHEN '561' THEN SET `token` = 'Kedge';
|
||||
WHEN '562' THEN SET `token` = 'Kerran';
|
||||
WHEN '563' THEN SET `token` = 'Shissar';
|
||||
WHEN '564' THEN SET `token` = 'Siren';
|
||||
WHEN '565' THEN SET `token` = 'Sphinx';
|
||||
WHEN '566' THEN SET `token` = 'Human';
|
||||
WHEN '567' THEN SET `token` = 'Campfire';
|
||||
WHEN '568' THEN SET `token` = 'Brownie';
|
||||
WHEN '569' THEN SET `token` = 'Dragon';
|
||||
WHEN '570' THEN SET `token` = 'Exoskeleton';
|
||||
WHEN '571' THEN SET `token` = 'Ghoul';
|
||||
WHEN '572' THEN SET `token` = 'Clockwork Guardian';
|
||||
WHEN '573' THEN SET `token` = 'Mantrap';
|
||||
WHEN '574' THEN SET `token` = 'Minotaur';
|
||||
WHEN '575' THEN SET `token` = 'Scarecrow';
|
||||
WHEN '576' THEN SET `token` = 'Shade';
|
||||
WHEN '577' THEN SET `token` = 'Rotocopter';
|
||||
WHEN '578' THEN SET `token` = 'Tentacle Terror';
|
||||
WHEN '579' THEN SET `token` = 'Wereorc';
|
||||
WHEN '580' THEN SET `token` = 'Worg';
|
||||
WHEN '581' THEN SET `token` = 'Wyvern';
|
||||
WHEN '582' THEN SET `token` = 'Chimera';
|
||||
WHEN '583' THEN SET `token` = 'Kirin';
|
||||
WHEN '584' THEN SET `token` = 'Puma';
|
||||
WHEN '585' THEN SET `token` = 'Boulder';
|
||||
WHEN '586' THEN SET `token` = 'Banner';
|
||||
WHEN '587' THEN SET `token` = 'Elven Ghost';
|
||||
WHEN '588' THEN SET `token` = 'Human Ghost';
|
||||
WHEN '589' THEN SET `token` = 'Chest';
|
||||
WHEN '590' THEN SET `token` = 'Chest';
|
||||
WHEN '591' THEN SET `token` = 'Crystal';
|
||||
WHEN '592' THEN SET `token` = 'Coffin';
|
||||
WHEN '593' THEN SET `token` = 'Guardian CPU';
|
||||
WHEN '594' THEN SET `token` = 'Worg';
|
||||
WHEN '595' THEN SET `token` = 'Mansion';
|
||||
WHEN '596' THEN SET `token` = 'Floating Island';
|
||||
WHEN '597' THEN SET `token` = 'Cragslither';
|
||||
WHEN '598' THEN SET `token` = 'Wrulon';
|
||||
WHEN '599' THEN SET `token` = 'Spell Particle 1';
|
||||
WHEN '600' THEN SET `token` = 'Invisible Man of Zomm';
|
||||
WHEN '601' THEN SET `token` = 'Robocopter of Zomm';
|
||||
WHEN '602' THEN SET `token` = 'Burynai';
|
||||
WHEN '603' THEN SET `token` = 'Frog';
|
||||
WHEN '604' THEN SET `token` = 'Dracolich';
|
||||
WHEN '605' THEN SET `token` = 'Iksar Ghost';
|
||||
WHEN '606' THEN SET `token` = 'Iksar Skeleton';
|
||||
WHEN '607' THEN SET `token` = 'Mephit';
|
||||
WHEN '608' THEN SET `token` = 'Muddite';
|
||||
WHEN '609' THEN SET `token` = 'Raptor';
|
||||
WHEN '610' THEN SET `token` = 'Sarnak';
|
||||
WHEN '611' THEN SET `token` = 'Scorpion';
|
||||
WHEN '612' THEN SET `token` = 'T THEN SET sian';
|
||||
WHEN '613' THEN SET `token` = 'Wurm';
|
||||
WHEN '614' THEN SET `token` = 'Nekhon';
|
||||
WHEN '615' THEN SET `token` = 'Hydra Crystal';
|
||||
WHEN '616' THEN SET `token` = 'Crystal Sphere';
|
||||
WHEN '617' THEN SET `token` = 'Gnoll';
|
||||
WHEN '618' THEN SET `token` = 'Sokokar';
|
||||
WHEN '619' THEN SET `token` = 'Stone Pylon';
|
||||
WHEN '620' THEN SET `token` = 'Demon Vulture';
|
||||
WHEN '621' THEN SET `token` = 'Wagon';
|
||||
WHEN '622' THEN SET `token` = 'God of Discord';
|
||||
WHEN '623' THEN SET `token` = 'Feran Mount';
|
||||
WHEN '624' THEN SET `token` = 'Ogre NPC - Male';
|
||||
WHEN '625' THEN SET `token` = 'Sokokar Mount';
|
||||
WHEN '626' THEN SET `token` = 'Giant (Rallosian mats)';
|
||||
WHEN '627' THEN SET `token` = 'Sokokar (w saddle)';
|
||||
WHEN '628' THEN SET `token` = '10th Anniversary Banner';
|
||||
WHEN '629' THEN SET `token` = '10th Anniversary Cake';
|
||||
WHEN '630' THEN SET `token` = 'Wine Cask';
|
||||
WHEN '631' THEN SET `token` = 'Hydra Mount';
|
||||
WHEN '632' THEN SET `token` = 'Hydra NPC';
|
||||
WHEN '633' THEN SET `token` = 'Wedding Flowers';
|
||||
WHEN '634' THEN SET `token` = 'Wedding Arbor';
|
||||
WHEN '635' THEN SET `token` = 'Wedding Altar';
|
||||
WHEN '636' THEN SET `token` = 'Powder Keg';
|
||||
WHEN '637' THEN SET `token` = 'Apexus';
|
||||
WHEN '638' THEN SET `token` = 'Bellikos';
|
||||
WHEN '639' THEN SET `token` = 'Brell\'s First Creation';
|
||||
WHEN '640' THEN SET `token` = 'Brell';
|
||||
WHEN '641' THEN SET `token` = 'Crystalskin Ambuloid';
|
||||
WHEN '642' THEN SET `token` = 'Cliknar Queen';
|
||||
WHEN '643' THEN SET `token` = 'Cliknar Soldier';
|
||||
WHEN '644' THEN SET `token` = 'Cliknar Worker';
|
||||
WHEN '645' THEN SET `token` = 'Coldain';
|
||||
WHEN '646' THEN SET `token` = 'Coldain';
|
||||
WHEN '647' THEN SET `token` = 'Crystalskin Sessiloid';
|
||||
WHEN '648' THEN SET `token` = 'Genari';
|
||||
WHEN '649' THEN SET `token` = 'Gigyn';
|
||||
WHEN '650' THEN SET `token` = 'Greken - Young Adult';
|
||||
WHEN '651' THEN SET `token` = 'Greken - Young';
|
||||
WHEN '652' THEN SET `token` = 'Cliknar Mount';
|
||||
WHEN '653' THEN SET `token` = 'Telmira';
|
||||
WHEN '654' THEN SET `token` = 'Spider Mount';
|
||||
WHEN '655' THEN SET `token` = 'Bear Mount';
|
||||
WHEN '656' THEN SET `token` = 'Rat Mount';
|
||||
WHEN '657' THEN SET `token` = 'Sessiloid Mount';
|
||||
WHEN '658' THEN SET `token` = 'Morell Thule';
|
||||
WHEN '659' THEN SET `token` = 'Marionette';
|
||||
WHEN '660' THEN SET `token` = 'Book Dervish';
|
||||
WHEN '661' THEN SET `token` = 'Topiary Lion';
|
||||
WHEN '662' THEN SET `token` = 'Rotdog';
|
||||
WHEN '663' THEN SET `token` = 'Amygdalan';
|
||||
WHEN '664' THEN SET `token` = 'Sandman';
|
||||
WHEN '665' THEN SET `token` = 'Grandfather Clock';
|
||||
WHEN '666' THEN SET `token` = 'Gingerbread Man';
|
||||
WHEN '667' THEN SET `token` = 'Royal Guard';
|
||||
WHEN '668' THEN SET `token` = 'Rabbit';
|
||||
WHEN '669' THEN SET `token` = 'Blind Dreamer';
|
||||
WHEN '670' THEN SET `token` = 'Cazic Thule';
|
||||
WHEN '671' THEN SET `token` = 'Topiary Lion Mount';
|
||||
WHEN '672' THEN SET `token` = 'Rot Dog Mount';
|
||||
WHEN '673' THEN SET `token` = 'Goral Mount';
|
||||
WHEN '674' THEN SET `token` = 'Selyrah Mount';
|
||||
WHEN '675' THEN SET `token` = 'Sclera Mount';
|
||||
WHEN '676' THEN SET `token` = 'Braxi Mount';
|
||||
WHEN '677' THEN SET `token` = 'Kangon Mount';
|
||||
WHEN '678' THEN SET `token` = 'Erudite';
|
||||
WHEN '679' THEN SET `token` = 'Wurm Mount';
|
||||
WHEN '680' THEN SET `token` = 'Raptor Mount';
|
||||
WHEN '681' THEN SET `token` = 'Invisible Man';
|
||||
WHEN '682' THEN SET `token` = 'Whirligig';
|
||||
WHEN '683' THEN SET `token` = 'Gnomish Balloon';
|
||||
WHEN '684' THEN SET `token` = 'Gnomish Rocket Pack';
|
||||
WHEN '685' THEN SET `token` = 'Gnomish Hovering Transport';
|
||||
WHEN '686' THEN SET `token` = 'Selyrah';
|
||||
WHEN '687' THEN SET `token` = 'Goral';
|
||||
WHEN '688' THEN SET `token` = 'Braxi';
|
||||
WHEN '689' THEN SET `token` = 'Kangon';
|
||||
WHEN '690' THEN SET `token` = 'Invisible Man';
|
||||
WHEN '691' THEN SET `token` = 'Floating Tower';
|
||||
WHEN '692' THEN SET `token` = 'Explosive Cart';
|
||||
WHEN '693' THEN SET `token` = 'Blimp Ship';
|
||||
WHEN '694' THEN SET `token` = 'Tumbleweed';
|
||||
WHEN '695' THEN SET `token` = 'Alaran';
|
||||
WHEN '696' THEN SET `token` = 'Swinetor';
|
||||
WHEN '697' THEN SET `token` = 'Triumvirate';
|
||||
WHEN '698' THEN SET `token` = 'Hadal';
|
||||
WHEN '699' THEN SET `token` = 'Hovering Platform';
|
||||
WHEN '700' THEN SET `token` = 'Parasitic Scavenger';
|
||||
WHEN '701' THEN SET `token` = 'Grendlaen';
|
||||
WHEN '702' THEN SET `token` = 'Ship in a Bottle';
|
||||
WHEN '703' THEN SET `token` = 'Alaran Sentry Stone';
|
||||
WHEN '704' THEN SET `token` = 'Dervish';
|
||||
WHEN '705' THEN SET `token` = 'Regeneration Pool';
|
||||
WHEN '706' THEN SET `token` = 'Teleportation Stand';
|
||||
WHEN '707' THEN SET `token` = 'Relic Case';
|
||||
WHEN '708' THEN SET `token` = 'Alaran Ghost';
|
||||
WHEN '709' THEN SET `token` = 'Skystrider';
|
||||
WHEN '710' THEN SET `token` = 'Water Spout';
|
||||
WHEN '711' THEN SET `token` = 'Aviak Pull Along';
|
||||
WHEN '712' THEN SET `token` = 'Gelatinous Cube';
|
||||
WHEN '713' THEN SET `token` = 'Cat';
|
||||
WHEN '714' THEN SET `token` = 'Elk Head';
|
||||
WHEN '715' THEN SET `token` = 'Holgresh';
|
||||
WHEN '716' THEN SET `token` = 'Beetle';
|
||||
WHEN '717' THEN SET `token` = 'Vine Maw';
|
||||
WHEN '718' THEN SET `token` = 'Ratman';
|
||||
WHEN '719' THEN SET `token` = 'Fallen Knight';
|
||||
WHEN '720' THEN SET `token` = 'Flying Carpet';
|
||||
WHEN '721' THEN SET `token` = 'Carrier Hand';
|
||||
WHEN '722' THEN SET `token` = 'Akheva';
|
||||
WHEN '723' THEN SET `token` = 'Servant of Shadow';
|
||||
WHEN '724' THEN SET `token` = 'Luclin';
|
||||
WHEN '725' THEN SET `token` = 'Xaric the Unspoken';
|
||||
WHEN '726' THEN SET `token` = 'Dervish (Ver. 5)';
|
||||
WHEN '727' THEN SET `token` = 'Dervish (Ver. 6)';
|
||||
WHEN '728' THEN SET `token` = 'God - Luclin (Ver. 2)';
|
||||
WHEN '729' THEN SET `token` = 'God - Luclin (Ver. 3)';
|
||||
WHEN '730' THEN SET `token` = 'Orb';
|
||||
WHEN '731' THEN SET `token` = 'God - Luclin (Ver. 4)';
|
||||
WHEN '732' THEN SET `token` = 'Pegasus';
|
||||
WHEN '2250' THEN SET `token` = 'Interactive Object';
|
||||
ELSE SET `token` = 'unk';
|
||||
END CASE;
|
||||
|
||||
SET `token` = CONCAT(`token`, '(', `race_id`, ')');
|
||||
|
||||
RETURN `token`;
|
||||
END$$
|
||||
|
||||
DELIMITER ;
|
||||
@@ -0,0 +1,71 @@
|
||||
DELIMITER $$
|
||||
|
||||
DROP FUNCTION IF EXISTS `GetSpellAffectIndexToken`;
|
||||
|
||||
-- This function converts a numeric spell affect index id to a string label based on server code designations
|
||||
--
|
||||
-- example:
|
||||
-- SELECT `id`, `name`, GetSpellAffectIndexToken(`SpellAffectIndex`) FROM `spells_new` WHERE `id` IN ('73', '2253', '2319');
|
||||
CREATE FUNCTION `GetSpellAffectIndexToken` (`affect_index_id` INT(11)) RETURNS VARCHAR(64)
|
||||
BEGIN
|
||||
DECLARE `token` VARCHAR(64) DEFAULT '';
|
||||
|
||||
CASE `affect_index_id`
|
||||
WHEN '-1' THEN SET `token` = 'SAI_Summon_Mount_Unclass';
|
||||
WHEN '0' THEN SET `token` = 'SAI_Direct_Damage';
|
||||
WHEN '1' THEN SET `token` = 'SAI_Heal_Cure';
|
||||
WHEN '2' THEN SET `token` = 'SAI_AC_Buff';
|
||||
WHEN '3' THEN SET `token` = 'SAI_AE_Damage';
|
||||
WHEN '4' THEN SET `token` = 'SAI_Summon';
|
||||
WHEN '5' THEN SET `token` = 'SAI_Sight';
|
||||
WHEN '6' THEN SET `token` = 'SAI_Mana_Regen_Resist_Song';
|
||||
WHEN '7' THEN SET `token` = 'SAI_Stat_Buff';
|
||||
WHEN '9' THEN SET `token` = 'SAI_Vanish';
|
||||
WHEN '10' THEN SET `token` = 'SAI_Appearance';
|
||||
WHEN '11' THEN SET `token` = 'SAI_Enchanter_Pet';
|
||||
WHEN '12' THEN SET `token` = 'SAI_Calm';
|
||||
WHEN '13' THEN SET `token` = 'SAI_Fear';
|
||||
WHEN '14' THEN SET `token` = 'SAI_Dispell_Sight';
|
||||
WHEN '15' THEN SET `token` = 'SAI_Stun';
|
||||
WHEN '16' THEN SET `token` = 'SAI_Haste_Runspeed';
|
||||
WHEN '17' THEN SET `token` = 'SAI_Combat_Slow';
|
||||
WHEN '18' THEN SET `token` = 'SAI_Damage_Shield';
|
||||
WHEN '19' THEN SET `token` = 'SAI_Cannibalize_Weapon_Proc';
|
||||
WHEN '20' THEN SET `token` = 'SAI_Weaken';
|
||||
WHEN '21' THEN SET `token` = 'SAI_Banish';
|
||||
WHEN '22' THEN SET `token` = 'SAI_Blind_Poison';
|
||||
WHEN '23' THEN SET `token` = 'SAI_Cold_DD';
|
||||
WHEN '24' THEN SET `token` = 'SAI_Poison_Disease_DD';
|
||||
WHEN '25' THEN SET `token` = 'SAI_Fire_DD';
|
||||
WHEN '27' THEN SET `token` = 'SAI_Memory_Blur';
|
||||
WHEN '28' THEN SET `token` = 'SAI_Gravity_Fling';
|
||||
WHEN '29' THEN SET `token` = 'SAI_Suffocate';
|
||||
WHEN '30' THEN SET `token` = 'SAI_Lifetap_Over_Time';
|
||||
WHEN '31' THEN SET `token` = 'SAI_Fire_AE';
|
||||
WHEN '33' THEN SET `token` = 'SAI_Cold_AE';
|
||||
WHEN '34' THEN SET `token` = 'SAI_Poison_Disease_AE';
|
||||
WHEN '40' THEN SET `token` = 'SAI_Teleport';
|
||||
WHEN '41' THEN SET `token` = 'SAI_Direct_Damage_Song';
|
||||
WHEN '42' THEN SET `token` = 'SAI_Combat_Buff_Song';
|
||||
WHEN '43' THEN SET `token` = 'SAI_Calm_Song';
|
||||
WHEN '45' THEN SET `token` = 'SAI_Firework';
|
||||
WHEN '46' THEN SET `token` = 'SAI_Firework_AE';
|
||||
WHEN '47' THEN SET `token` = 'SAI_Weather_Rocket';
|
||||
WHEN '50' THEN SET `token` = 'SAI_Convert_Vitals';
|
||||
WHEN '60' THEN SET `token` = 'SAI_NPC_Special_60';
|
||||
WHEN '61' THEN SET `token` = 'SAI_NPC_Special_61';
|
||||
WHEN '62' THEN SET `token` = 'SAI_NPC_Special_62';
|
||||
WHEN '63' THEN SET `token` = 'SAI_NPC_Special_63';
|
||||
WHEN '70' THEN SET `token` = 'SAI_NPC_Special_70';
|
||||
WHEN '71' THEN SET `token` = 'SAI_NPC_Special_71';
|
||||
WHEN '80' THEN SET `token` = 'SAI_NPC_Special_80';
|
||||
WHEN '88' THEN SET `token` = 'SAI_Lock_Trap';
|
||||
ELSE SET `token` = 'unk';
|
||||
END CASE;
|
||||
|
||||
SET `token` = CONCAT(`token`, '(', `affect_index_id`, ')');
|
||||
|
||||
RETURN `token`;
|
||||
END$$
|
||||
|
||||
DELIMITER ;
|
||||
@@ -0,0 +1,206 @@
|
||||
DELIMITER $$
|
||||
|
||||
DROP FUNCTION IF EXISTS `GetSpellCategoryToken`;
|
||||
|
||||
-- This function converts numeric spell category ids to a string label based on server code designations
|
||||
--
|
||||
-- example:
|
||||
-- SELECT `id`, `name`, GetSpellCategoryToken(`spell_category`) FROM `spells_new` WHERE `id` IN ('39', '129', '3468');
|
||||
CREATE FUNCTION `GetSpellCategoryToken` (`spell_category` INT(11)) RETURNS VARCHAR(256)
|
||||
BEGIN
|
||||
DECLARE `token` VARCHAR(256) DEFAULT '';
|
||||
|
||||
CASE `spell_category`
|
||||
WHEN '-99' THEN SET `token` = 'neg99#';
|
||||
WHEN '-1' THEN SET `token` = 'neg1#';
|
||||
WHEN '0' THEN SET `token` = CONCAT('#', `spell_category`);
|
||||
WHEN '1' THEN SET `token` = 'DD';
|
||||
WHEN '2' THEN SET `token` = 'DD_Undead';
|
||||
WHEN '3' THEN SET `token` = 'DD_Summoned';
|
||||
WHEN '4' THEN SET `token` = 'Lifetap_to_Self';
|
||||
WHEN '5' THEN SET `token` = 'DoT_Plant';
|
||||
WHEN '6' THEN SET `token` = 'DD_Body_Type';
|
||||
WHEN '7' THEN SET `token` = 'DoT';
|
||||
WHEN '8' THEN SET `token` = 'Divine_DoT';
|
||||
WHEN '9' THEN SET `token` = 'Lifetap_to_Self_2';
|
||||
WHEN '10' THEN SET `token` = 'AoE_DD';
|
||||
WHEN '11' THEN SET `token` = 'AoE_DD_Earth';
|
||||
WHEN '12' THEN SET `token` = 'AoE_DD_Nature';
|
||||
WHEN '13' THEN SET `token` = 'Bolt_Fire_Cold';
|
||||
WHEN '14' THEN SET `token` = 'Stun_Damage';
|
||||
WHEN '15' THEN SET `token` = 'Target_Stun';
|
||||
WHEN '16' THEN SET `token` = 'Group_Stun';
|
||||
WHEN '17' THEN SET `token` = 'Leech_to_Group';
|
||||
WHEN '18' THEN SET `token` = 'Siphon_Strength';
|
||||
WHEN '19' THEN SET `token` = 'Weapon_Proc';
|
||||
WHEN '20' THEN SET `token` = 'Target_Heal';
|
||||
WHEN '21' THEN SET `token` = 'Target_HoT';
|
||||
WHEN '22' THEN SET `token` = 'Group_Heal_Cure';
|
||||
WHEN '23' THEN SET `token` = 'Group_HoT';
|
||||
WHEN '24' THEN SET `token` = 'Target_Health_Regen';
|
||||
WHEN '25' THEN SET `token` = 'Group_Health_Regen';
|
||||
WHEN '26' THEN SET `token` = 'Pet_Heal';
|
||||
WHEN '27' THEN SET `token` = 'Resurrection';
|
||||
WHEN '28' THEN SET `token` = 'Dark_Empathy';
|
||||
WHEN '29' THEN SET `token` = 'Cure_Poison';
|
||||
WHEN '30' THEN SET `token` = 'Resolution';
|
||||
WHEN '32' THEN SET `token` = 'Blur';
|
||||
WHEN '34' THEN SET `token` = 'Hate_Buff';
|
||||
WHEN '35' THEN SET `token` = 'Attack_Speed_Buff';
|
||||
WHEN '36' THEN SET `token` = 'Pet_Combat_Buff';
|
||||
WHEN '37' THEN SET `token` = 'Attack_Speed_Buff_Song';
|
||||
WHEN '38' THEN SET `token` = 'Attack_Speed_Debuff';
|
||||
WHEN '39' THEN SET `token` = 'Attack_Speed_Debuff_2';
|
||||
WHEN '40' THEN SET `token` = 'Cannibalize';
|
||||
WHEN '41' THEN SET `token` = 'Target_Movement_Speed';
|
||||
WHEN '42' THEN SET `token` = 'Group_Movement_Speed';
|
||||
WHEN '43' THEN SET `token` = 'Wolf_Form';
|
||||
WHEN '44' THEN SET `token` = 'Elemental_Pet_Movement_Speed';
|
||||
WHEN '45' THEN SET `token` = 'Illusion';
|
||||
WHEN '46' THEN SET `token` = 'Dark_Pact';
|
||||
WHEN '47' THEN SET `token` = 'Form_of_the_Bear';
|
||||
WHEN '48' THEN SET `token` = 'Treeform';
|
||||
WHEN '49' THEN SET `token` = 'Dead_Man_Floating';
|
||||
WHEN '50' THEN SET `token` = 'Root';
|
||||
WHEN '51' THEN SET `token` = 'Summon_Pet';
|
||||
WHEN '52' THEN SET `token` = 'Summon_Corpse';
|
||||
WHEN '53' THEN SET `token` = 'Sense';
|
||||
WHEN '54' THEN SET `token` = 'Divine_Aura';
|
||||
WHEN '55' THEN SET `token` = 'Evacuate';
|
||||
WHEN '56' THEN SET `token` = 'Gate';
|
||||
WHEN '58' THEN SET `token` = 'Teleport_Bind';
|
||||
WHEN '59' THEN SET `token` = 'Shadow_Step';
|
||||
WHEN '60' THEN SET `token` = 'Enchant_Material';
|
||||
WHEN '61' THEN SET `token` = 'Summon_Common_Item';
|
||||
WHEN '62' THEN SET `token` = 'Fear';
|
||||
WHEN '63' THEN SET `token` = 'Fear_Animal';
|
||||
WHEN '64' THEN SET `token` = 'Fear_Undead';
|
||||
WHEN '65' THEN SET `token` = 'Damage_Shield';
|
||||
WHEN '66' THEN SET `token` = 'Resist_Buff_Song';
|
||||
WHEN '67' THEN SET `token` = CONCAT('#', `spell_category`);
|
||||
WHEN '68' THEN SET `token` = 'Damage_Shield_2';
|
||||
WHEN '69' THEN SET `token` = 'Resist_Redux';
|
||||
WHEN '70' THEN SET `token` = 'Resist_Buff';
|
||||
WHEN '71' THEN SET `token` = 'Warder';
|
||||
WHEN '72' THEN SET `token` = 'Familiar';
|
||||
WHEN '73' THEN SET `token` = 'Strength_Buff';
|
||||
WHEN '74' THEN SET `token` = 'Dexterity_Buff';
|
||||
WHEN '75' THEN SET `token` = 'Agility_Buff';
|
||||
WHEN '76' THEN SET `token` = 'Stamina_Buff';
|
||||
WHEN '77' THEN SET `token` = 'Intelligence_Wisdom_Buff';
|
||||
WHEN '78' THEN SET `token` = 'Charisma_Buff';
|
||||
WHEN '79' THEN SET `token` = 'Weaken';
|
||||
WHEN '80' THEN SET `token` = 'Invisibility_v_Undead';
|
||||
WHEN '81' THEN SET `token` = 'Invisibility_v_Animals';
|
||||
WHEN '82' THEN SET `token` = 'Invisibility';
|
||||
WHEN '83' THEN SET `token` = 'Damage_Absorbtion';
|
||||
WHEN '84' THEN SET `token` = 'Fizzle_Redux';
|
||||
WHEN '85' THEN SET `token` = 'Clarity';
|
||||
WHEN '86' THEN SET `token` = 'Gift_of_Magic';
|
||||
WHEN '87' THEN SET `token` = 'Mana_Drain';
|
||||
WHEN '88' THEN SET `token` = 'Mana_Subversion';
|
||||
WHEN '89' THEN SET `token` = 'Harvest_Mana';
|
||||
WHEN '90' THEN SET `token` = 'Hate_Redux';
|
||||
WHEN '91' THEN SET `token` = 'Increase_Aim';
|
||||
WHEN '92' THEN SET `token` = 'Combat_Buff';
|
||||
WHEN '93' THEN SET `token` = 'Bind_Sight';
|
||||
WHEN '94' THEN SET `token` = 'Enduring_Breath';
|
||||
WHEN '95' THEN SET `token` = 'Alliance';
|
||||
WHEN '96' THEN SET `token` = 'Charm';
|
||||
WHEN '97' THEN SET `token` = 'Strip_Enchantment';
|
||||
WHEN '98' THEN SET `token` = 'Lull';
|
||||
WHEN '99' THEN SET `token` = 'Mesmerize';
|
||||
WHEN '100' THEN SET `token` = 'Casting_Enhancement';
|
||||
WHEN '101' THEN SET `token` = 'Snare_Hamstring';
|
||||
WHEN '102' THEN SET `token` = 'Shackle';
|
||||
WHEN '105' THEN SET `token` = 'Feign_Death';
|
||||
WHEN '106' THEN SET `token` = 'Identify';
|
||||
WHEN '107' THEN SET `token` = 'Reclaim_Energy';
|
||||
WHEN '108' THEN SET `token` = 'Locate_Corpse';
|
||||
WHEN '109' THEN SET `token` = 'Call_of_the_Hero';
|
||||
WHEN '110' THEN SET `token` = 'Mana_Shield';
|
||||
WHEN '112' THEN SET `token` = 'Blind';
|
||||
WHEN '113' THEN SET `token` = 'Gravity_is_for_Suckers'; -- 'Levitation'
|
||||
WHEN '114' THEN SET `token` = 'Bard_Nerf';
|
||||
WHEN '115' THEN SET `token` = 'Divine_Intervention';
|
||||
WHEN '116' THEN SET `token` = 'Memory_Blur';
|
||||
WHEN '118' THEN SET `token` = 'Size_Change';
|
||||
WHEN '119' THEN SET `token` = 'Hate_Buff_2';
|
||||
WHEN '120' THEN SET `token` = CONCAT('#', `spell_category`);
|
||||
WHEN '121' THEN SET `token` = CONCAT('#', `spell_category`);
|
||||
WHEN '122' THEN SET `token` = CONCAT('#', `spell_category`);
|
||||
WHEN '125' THEN SET `token` = 'DD_Fire';
|
||||
WHEN '126' THEN SET `token` = 'DD_Cold';
|
||||
WHEN '127' THEN SET `token` = 'Bolt_Poison';
|
||||
WHEN '128' THEN SET `token` = 'Bolt_Disease';
|
||||
WHEN '129' THEN SET `token` = 'DoT_Fire';
|
||||
WHEN '130' THEN SET `token` = 'DoT_Cold';
|
||||
WHEN '131' THEN SET `token` = 'DoT_Poison';
|
||||
WHEN '132' THEN SET `token` = 'DoT_Disease';
|
||||
WHEN '133' THEN SET `token` = 'Destroy_Lock';
|
||||
WHEN '134' THEN SET `token` = 'Sense_Trap';
|
||||
WHEN '135' THEN SET `token` = 'Disarm_Trap';
|
||||
WHEN '136' THEN SET `token` = 'Destroy_Cursed_Lock';
|
||||
WHEN '137' THEN SET `token` = 'Sense_Cursed_Trap';
|
||||
WHEN '138' THEN SET `token` = 'Disarm_Cursed_Trap';
|
||||
WHEN '140' THEN SET `token` = 'Banish_Undead';
|
||||
WHEN '141' THEN SET `token` = 'Banish';
|
||||
WHEN '142' THEN SET `token` = 'AoE_DD_Fire_Column';
|
||||
WHEN '143' THEN SET `token` = 'AoE_DD_Cold_Column';
|
||||
WHEN '146' THEN SET `token` = 'AoE_DD_Fire';
|
||||
WHEN '147' THEN SET `token` = 'AoE_DD_Cold';
|
||||
WHEN '150' THEN SET `token` = 'AoE_DoT_Fire';
|
||||
WHEN '151' THEN SET `token` = 'AoE_DoT_Cold';
|
||||
WHEN '152' THEN SET `token` = 'AoE_DoT_Poison';
|
||||
WHEN '154' THEN SET `token` = 'AoE_Fear_Song';
|
||||
WHEN '155' THEN SET `token` = 'Target_Heal_2';
|
||||
WHEN '156' THEN SET `token` = 'Mana_to_HP';
|
||||
WHEN '157' THEN SET `token` = 'Symbiosis';
|
||||
WHEN '159' THEN SET `token` = 'Cure_Corruption';
|
||||
WHEN '160' THEN SET `token` = 'Remove_Curse';
|
||||
WHEN '161' THEN SET `token` = 'Cure';
|
||||
WHEN '162' THEN SET `token` = 'Cure_Blindness';
|
||||
WHEN '163' THEN SET `token` = 'Divine_Cure';
|
||||
WHEN '164' THEN SET `token` = CONCAT('#', `spell_category`);
|
||||
WHEN '165' THEN SET `token` = 'Magic_Combat_Buff';
|
||||
WHEN '166' THEN SET `token` = 'Nature_HP_Attack_Buff';
|
||||
WHEN '167' THEN SET `token` = 'Divine_HP_Buff';
|
||||
WHEN '168' THEN SET `token` = 'Divine_HP_AC_Buff';
|
||||
WHEN '169' THEN SET `token` = CONCAT('#', `spell_category`);
|
||||
WHEN '170' THEN SET `token` = 'Spell_Rune';
|
||||
WHEN '171' THEN SET `token` = 'Pet_Rune';
|
||||
WHEN '172' THEN SET `token` = 'Spell_Reflection';
|
||||
WHEN '173' THEN SET `token` = 'Damage_Shield_3';
|
||||
WHEN '174' THEN SET `token` = 'Vital_Regen';
|
||||
WHEN '175' THEN SET `token` = 'Aggro_Redux';
|
||||
WHEN '200' THEN SET `token` = 'Cantrips';
|
||||
WHEN '201' THEN SET `token` = CONCAT('#', `spell_category`);
|
||||
WHEN '202' THEN SET `token` = 'Combat_Buff_Song';
|
||||
WHEN '203' THEN SET `token` = 'Summon_Swarm';
|
||||
WHEN '204' THEN SET `token` = 'Summon_Air_Elemental';
|
||||
WHEN '205' THEN SET `token` = 'Summon_Water_Elemental';
|
||||
WHEN '206' THEN SET `token` = 'Summon_Fire_Elemental';
|
||||
WHEN '207' THEN SET `token` = 'Summon_Earth_Elemental';
|
||||
WHEN '208' THEN SET `token` = 'Monster_Summoning';
|
||||
WHEN '209' THEN SET `token` = 'Teleport_Antonica';
|
||||
WHEN '210' THEN SET `token` = 'Teleport_Odus';
|
||||
WHEN '211' THEN SET `token` = 'Teleport_Faydwer';
|
||||
WHEN '212' THEN SET `token` = 'Teleport_Combine';
|
||||
WHEN '213' THEN SET `token` = 'Teleport_Velious';
|
||||
WHEN '214' THEN SET `token` = 'Teleport_Luclin';
|
||||
WHEN '215' THEN SET `token` = 'Teleport_Planes';
|
||||
WHEN '216' THEN SET `token` = 'Teleport_Gates';
|
||||
WHEN '217' THEN SET `token` = 'Summon_Weapon';
|
||||
WHEN '218' THEN SET `token` = 'Summon_Jewelry';
|
||||
WHEN '219' THEN SET `token` = 'Summon_Sustenance';
|
||||
WHEN '220' THEN SET `token` = 'Summon_Armor';
|
||||
WHEN '999' THEN SET `token` = CONCAT('#', `spell_category`);
|
||||
ELSE SET `token` = 'unk';
|
||||
END CASE;
|
||||
|
||||
SET `token` = CONCAT(`token`, '(', `spell_category`, ')');
|
||||
|
||||
RETURN `token`;
|
||||
END$$
|
||||
|
||||
DELIMITER ;
|
||||
@@ -0,0 +1,519 @@
|
||||
DELIMITER $$
|
||||
|
||||
DROP FUNCTION IF EXISTS `GetSpellEffectToken`;
|
||||
|
||||
-- This function converts a numeric spell effect id to a string label based on server code designations
|
||||
--
|
||||
-- example:
|
||||
-- SELECT `id`, `name`, GetSpellEffectToken(`effectid1`), GetSpellEffectToken(`effectid2`) FROM `spells_new` WHERE `id` IN ('1011', '1602', '11091');
|
||||
CREATE FUNCTION `GetSpellEffectToken` (`effect_id` INT(11)) RETURNS VARCHAR(64)
|
||||
BEGIN
|
||||
DECLARE `token` VARCHAR(64) DEFAULT '';
|
||||
|
||||
CASE `effect_id`
|
||||
WHEN '0' THEN SET `token` = 'SE_CurrentHP';
|
||||
WHEN '1' THEN SET `token` = 'SE_ArmorClass';
|
||||
WHEN '2' THEN SET `token` = 'SE_ATK';
|
||||
WHEN '3' THEN SET `token` = 'SE_MovementSpeed';
|
||||
WHEN '4' THEN SET `token` = 'SE_STR';
|
||||
WHEN '5' THEN SET `token` = 'SE_DEX';
|
||||
WHEN '6' THEN SET `token` = 'SE_AGI';
|
||||
WHEN '7' THEN SET `token` = 'SE_STA';
|
||||
WHEN '8' THEN SET `token` = 'SE_INT';
|
||||
WHEN '9' THEN SET `token` = 'SE_WIS';
|
||||
WHEN '10' THEN SET `token` = 'SE_CHA';
|
||||
WHEN '11' THEN SET `token` = 'SE_AttackSpeed';
|
||||
WHEN '12' THEN SET `token` = 'SE_Invisibility';
|
||||
WHEN '13' THEN SET `token` = 'SE_SeeInvis';
|
||||
WHEN '14' THEN SET `token` = 'SE_WaterBreathing';
|
||||
WHEN '15' THEN SET `token` = 'SE_CurrentMana';
|
||||
WHEN '16' THEN SET `token` = 'NI_NPCFrenzy';
|
||||
WHEN '17' THEN SET `token` = 'NI_NPCAwareness';
|
||||
WHEN '18' THEN SET `token` = 'SE_Lull';
|
||||
WHEN '19' THEN SET `token` = 'SE_AddFaction';
|
||||
WHEN '20' THEN SET `token` = 'SE_Blind';
|
||||
WHEN '21' THEN SET `token` = 'SE_Stun';
|
||||
WHEN '22' THEN SET `token` = 'SE_Charm';
|
||||
WHEN '23' THEN SET `token` = 'SE_Fear';
|
||||
WHEN '24' THEN SET `token` = 'SE_Stamina';
|
||||
WHEN '25' THEN SET `token` = 'SE_BindAffinity';
|
||||
WHEN '26' THEN SET `token` = 'SE_Gate';
|
||||
WHEN '27' THEN SET `token` = 'SE_CancelMagic';
|
||||
WHEN '28' THEN SET `token` = 'SE_InvisVsUndead';
|
||||
WHEN '29' THEN SET `token` = 'SE_InvisVsAnimals';
|
||||
WHEN '30' THEN SET `token` = 'SE_ChangeFrenzyRad';
|
||||
WHEN '31' THEN SET `token` = 'SE_Mez';
|
||||
WHEN '32' THEN SET `token` = 'SE_SummonItem';
|
||||
WHEN '33' THEN SET `token` = 'SE_SummonPet';
|
||||
WHEN '34' THEN SET `token` = 'NI_Confuse';
|
||||
WHEN '35' THEN SET `token` = 'SE_DiseaseCounter';
|
||||
WHEN '36' THEN SET `token` = 'SE_PoisonCounter';
|
||||
WHEN '37' THEN SET `token` = 'NI_DetectHostile';
|
||||
WHEN '38' THEN SET `token` = 'NI_DetectMagic';
|
||||
WHEN '39' THEN SET `token` = 'NI_DetectPoison';
|
||||
WHEN '40' THEN SET `token` = 'SE_DivineAura';
|
||||
WHEN '41' THEN SET `token` = 'SE_Destroy';
|
||||
WHEN '42' THEN SET `token` = 'SE_ShadowStep';
|
||||
WHEN '43' THEN SET `token` = 'SE_Berserk';
|
||||
WHEN '44' THEN SET `token` = 'SE_Lycanthropy';
|
||||
WHEN '45' THEN SET `token` = 'SE_Vampirism';
|
||||
WHEN '46' THEN SET `token` = 'SE_ResistFire';
|
||||
WHEN '47' THEN SET `token` = 'SE_ResistCold';
|
||||
WHEN '48' THEN SET `token` = 'SE_ResistPoison';
|
||||
WHEN '49' THEN SET `token` = 'SE_ResistDisease';
|
||||
WHEN '50' THEN SET `token` = 'SE_ResistMagic';
|
||||
WHEN '51' THEN SET `token` = 'NI_DetectTraps';
|
||||
WHEN '52' THEN SET `token` = 'SE_SenseDead';
|
||||
WHEN '53' THEN SET `token` = 'SE_SenseSummoned';
|
||||
WHEN '54' THEN SET `token` = 'SE_SenseAnimals';
|
||||
WHEN '55' THEN SET `token` = 'SE_Rune';
|
||||
WHEN '56' THEN SET `token` = 'SE_TrueNorth';
|
||||
WHEN '57' THEN SET `token` = 'SE_Levitate';
|
||||
WHEN '58' THEN SET `token` = 'SE_Illusion';
|
||||
WHEN '59' THEN SET `token` = 'SE_DamageShield';
|
||||
WHEN '60' THEN SET `token` = 'NI_TransferItem';
|
||||
WHEN '61' THEN SET `token` = 'SE_Identify';
|
||||
WHEN '62' THEN SET `token` = 'NI_ItemID';
|
||||
WHEN '63' THEN SET `token` = 'SE_WipeHateList';
|
||||
WHEN '64' THEN SET `token` = 'SE_SpinTarget';
|
||||
WHEN '65' THEN SET `token` = 'SE_InfraVision';
|
||||
WHEN '66' THEN SET `token` = 'SE_UltraVision';
|
||||
WHEN '67' THEN SET `token` = 'SE_EyeOfZomm';
|
||||
WHEN '68' THEN SET `token` = 'SE_ReclaimPet';
|
||||
WHEN '69' THEN SET `token` = 'SE_TotalHP';
|
||||
WHEN '70' THEN SET `token` = 'NI_CorpseBomb';
|
||||
WHEN '71' THEN SET `token` = 'SE_NecPet';
|
||||
WHEN '72' THEN SET `token` = 'NI_PreserveCorpse';
|
||||
WHEN '73' THEN SET `token` = 'SE_BindSight';
|
||||
WHEN '74' THEN SET `token` = 'SE_FeignDeath';
|
||||
WHEN '75' THEN SET `token` = 'SE_VoiceGraft';
|
||||
WHEN '76' THEN SET `token` = 'SE_Sentinel';
|
||||
WHEN '77' THEN SET `token` = 'SE_LocateCorpse';
|
||||
WHEN '78' THEN SET `token` = 'SE_AbsorbMagicAtt';
|
||||
WHEN '79' THEN SET `token` = 'SE_CurrentHPOnce';
|
||||
WHEN '80' THEN SET `token` = 'NI_EnchantLight';
|
||||
WHEN '81' THEN SET `token` = 'SE_Revive';
|
||||
WHEN '82' THEN SET `token` = 'SE_SummonPC';
|
||||
WHEN '83' THEN SET `token` = 'SE_Teleport';
|
||||
WHEN '84' THEN SET `token` = 'SE_TossUp';
|
||||
WHEN '85' THEN SET `token` = 'SE_WeaponProc';
|
||||
WHEN '86' THEN SET `token` = 'SE_Harmony';
|
||||
WHEN '87' THEN SET `token` = 'SE_MagnifyVision';
|
||||
WHEN '88' THEN SET `token` = 'SE_Succor';
|
||||
WHEN '89' THEN SET `token` = 'SE_ModelSize';
|
||||
WHEN '90' THEN SET `token` = 'NI_Cloak';
|
||||
WHEN '91' THEN SET `token` = 'SE_SummonCorpse';
|
||||
WHEN '92' THEN SET `token` = 'SE_InstantHate';
|
||||
WHEN '93' THEN SET `token` = 'SE_StopRain';
|
||||
WHEN '94' THEN SET `token` = 'SE_NegateIfCombat';
|
||||
WHEN '95' THEN SET `token` = 'SE_Sacrifice';
|
||||
WHEN '96' THEN SET `token` = 'SE_Silence';
|
||||
WHEN '97' THEN SET `token` = 'SE_ManaPool';
|
||||
WHEN '98' THEN SET `token` = 'SE_AttackSpeed2';
|
||||
WHEN '99' THEN SET `token` = 'SE_Root';
|
||||
WHEN '100' THEN SET `token` = 'SE_HealOverTime';
|
||||
WHEN '101' THEN SET `token` = 'SE_CompleteHeal';
|
||||
WHEN '102' THEN SET `token` = 'SE_Fearless';
|
||||
WHEN '103' THEN SET `token` = 'SE_CallPet';
|
||||
WHEN '104' THEN SET `token` = 'SE_Translocate';
|
||||
WHEN '105' THEN SET `token` = 'SE_AntiGate';
|
||||
WHEN '106' THEN SET `token` = 'SE_SummonBSTPet';
|
||||
WHEN '107' THEN SET `token` = 'SE_AlterNPCLevel';
|
||||
WHEN '108' THEN SET `token` = 'SE_Familiar';
|
||||
WHEN '109' THEN SET `token` = 'SE_SummonItemIntoBag';
|
||||
WHEN '110' THEN SET `token` = 'NI_IncreaseArchery';
|
||||
WHEN '111' THEN SET `token` = 'SE_ResistAll';
|
||||
WHEN '112' THEN SET `token` = 'SE_CastingLevel';
|
||||
WHEN '113' THEN SET `token` = 'SE_SummonHorse';
|
||||
WHEN '114' THEN SET `token` = 'SE_ChangeAggro';
|
||||
WHEN '115' THEN SET `token` = 'SE_Hunger';
|
||||
WHEN '116' THEN SET `token` = 'SE_CurseCounter';
|
||||
WHEN '117' THEN SET `token` = 'SE_MagicWeapon';
|
||||
WHEN '118' THEN SET `token` = 'SE_Amplification';
|
||||
WHEN '119' THEN SET `token` = 'SE_AttackSpeed3';
|
||||
WHEN '120' THEN SET `token` = 'SE_HealRate';
|
||||
WHEN '121' THEN SET `token` = 'SE_ReverseDS';
|
||||
WHEN '122' THEN SET `token` = 'NI_ReduceSkill';
|
||||
WHEN '123' THEN SET `token` = 'SE_Screech';
|
||||
WHEN '124' THEN SET `token` = 'SE_ImprovedDamage';
|
||||
WHEN '125' THEN SET `token` = 'SE_ImprovedHeal';
|
||||
WHEN '126' THEN SET `token` = 'SE_SpellResistReduction';
|
||||
WHEN '127' THEN SET `token` = 'SE_IncreaseSpellHaste';
|
||||
WHEN '128' THEN SET `token` = 'SE_IncreaseSpellDuration';
|
||||
WHEN '129' THEN SET `token` = 'SE_IncreaseRange';
|
||||
WHEN '130' THEN SET `token` = 'SE_SpellHateMod';
|
||||
WHEN '131' THEN SET `token` = 'SE_ReduceReagentCost';
|
||||
WHEN '132' THEN SET `token` = 'SE_ReduceManaCost';
|
||||
WHEN '133' THEN SET `token` = 'SE_FcStunTimeMod';
|
||||
WHEN '134' THEN SET `token` = 'SE_LimitMaxLevel';
|
||||
WHEN '135' THEN SET `token` = 'SE_LimitResist';
|
||||
WHEN '136' THEN SET `token` = 'SE_LimitTarget';
|
||||
WHEN '137' THEN SET `token` = 'SE_LimitEffect';
|
||||
WHEN '138' THEN SET `token` = 'SE_LimitSpellType';
|
||||
WHEN '139' THEN SET `token` = 'SE_LimitSpell';
|
||||
WHEN '140' THEN SET `token` = 'SE_LimitMinDur';
|
||||
WHEN '141' THEN SET `token` = 'SE_LimitInstant';
|
||||
WHEN '142' THEN SET `token` = 'SE_LimitMinLevel';
|
||||
WHEN '143' THEN SET `token` = 'SE_LimitCastTimeMin';
|
||||
WHEN '144' THEN SET `token` = 'SE_LimitCastTimeMax';
|
||||
WHEN '145' THEN SET `token` = 'SE_Teleport2';
|
||||
WHEN '146' THEN SET `token` = 'NI_ElectricityResist';
|
||||
WHEN '147' THEN SET `token` = 'SE_PercentalHeal';
|
||||
WHEN '148' THEN SET `token` = 'SE_StackingCommand_Block';
|
||||
WHEN '149' THEN SET `token` = 'SE_StackingCommand_Overwrite';
|
||||
WHEN '150' THEN SET `token` = 'SE_DeathSave';
|
||||
WHEN '151' THEN SET `token` = 'SE_SuspendPet';
|
||||
WHEN '152' THEN SET `token` = 'SE_TemporaryPets';
|
||||
WHEN '153' THEN SET `token` = 'SE_BalanceHP';
|
||||
WHEN '154' THEN SET `token` = 'SE_DispelDetrimental';
|
||||
WHEN '155' THEN SET `token` = 'SE_SpellCritDmgIncrease';
|
||||
WHEN '156' THEN SET `token` = 'SE_IllusionCopy';
|
||||
WHEN '157' THEN SET `token` = 'SE_SpellDamageShield';
|
||||
WHEN '158' THEN SET `token` = 'SE_Reflect';
|
||||
WHEN '159' THEN SET `token` = 'SE_AllStats';
|
||||
WHEN '160' THEN SET `token` = 'NI_MakeDrunk';
|
||||
WHEN '161' THEN SET `token` = 'SE_MitigateSpellDamage';
|
||||
WHEN '162' THEN SET `token` = 'SE_MitigateMeleeDamage';
|
||||
WHEN '163' THEN SET `token` = 'SE_NegateAttacks';
|
||||
WHEN '164' THEN SET `token` = 'SE_AppraiseLDonChest';
|
||||
WHEN '165' THEN SET `token` = 'SE_DisarmLDoNTrap';
|
||||
WHEN '166' THEN SET `token` = 'SE_UnlockLDoNChest';
|
||||
WHEN '167' THEN SET `token` = 'SE_PetPowerIncrease';
|
||||
WHEN '168' THEN SET `token` = 'SE_MeleeMitigation';
|
||||
WHEN '169' THEN SET `token` = 'SE_CriticalHitChance';
|
||||
WHEN '170' THEN SET `token` = 'SE_SpellCritChance';
|
||||
WHEN '171' THEN SET `token` = 'SE_CrippBlowChance';
|
||||
WHEN '172' THEN SET `token` = 'SE_AvoidMeleeChance';
|
||||
WHEN '173' THEN SET `token` = 'SE_RiposteChance';
|
||||
WHEN '174' THEN SET `token` = 'SE_DodgeChance';
|
||||
WHEN '175' THEN SET `token` = 'SE_ParryChance';
|
||||
WHEN '176' THEN SET `token` = 'SE_DualWieldChance';
|
||||
WHEN '177' THEN SET `token` = 'SE_DoubleAttackChance';
|
||||
WHEN '178' THEN SET `token` = 'SE_MeleeLifetap';
|
||||
WHEN '179' THEN SET `token` = 'SE_AllInstrumentMod';
|
||||
WHEN '180' THEN SET `token` = 'SE_ResistSpellChance';
|
||||
WHEN '181' THEN SET `token` = 'SE_ResistFearChance';
|
||||
WHEN '182' THEN SET `token` = 'SE_HundredHands';
|
||||
WHEN '183' THEN SET `token` = 'SE_MeleeSkillCheck';
|
||||
WHEN '184' THEN SET `token` = 'SE_HitChance';
|
||||
WHEN '185' THEN SET `token` = 'SE_DamageModifier';
|
||||
WHEN '186' THEN SET `token` = 'SE_MinDamageModifier';
|
||||
WHEN '187' THEN SET `token` = 'SE_BalanceMana';
|
||||
WHEN '188' THEN SET `token` = 'SE_IncreaseBlockChance';
|
||||
WHEN '189' THEN SET `token` = 'SE_CurrentEndurance';
|
||||
WHEN '190' THEN SET `token` = 'SE_EndurancePool';
|
||||
WHEN '191' THEN SET `token` = 'SE_Amnesia';
|
||||
WHEN '192' THEN SET `token` = 'SE_Hate';
|
||||
WHEN '193' THEN SET `token` = 'SE_SkillAttack';
|
||||
WHEN '194' THEN SET `token` = 'SE_FadingMemories';
|
||||
WHEN '195' THEN SET `token` = 'SE_StunResist';
|
||||
WHEN '196' THEN SET `token` = 'SE_StrikeThrough';
|
||||
WHEN '197' THEN SET `token` = 'SE_SkillDamageTaken';
|
||||
WHEN '198' THEN SET `token` = 'SE_CurrentEnduranceOnce';
|
||||
WHEN '199' THEN SET `token` = 'SE_Taunt';
|
||||
WHEN '200' THEN SET `token` = 'SE_ProcChance';
|
||||
WHEN '201' THEN SET `token` = 'SE_RangedProc';
|
||||
WHEN '202' THEN SET `token` = 'SE_IllusionOther';
|
||||
WHEN '203' THEN SET `token` = 'SE_MassGroupBuff';
|
||||
WHEN '204' THEN SET `token` = 'SE_GroupFearImmunity';
|
||||
WHEN '205' THEN SET `token` = 'SE_Rampage';
|
||||
WHEN '206' THEN SET `token` = 'SE_AETaunt';
|
||||
WHEN '207' THEN SET `token` = 'SE_FleshToBone';
|
||||
WHEN '208' THEN SET `token` = 'NI_PurgePoison';
|
||||
WHEN '209' THEN SET `token` = 'SE_DispelBeneficial';
|
||||
WHEN '210' THEN SET `token` = 'NI_PetShield';
|
||||
WHEN '211' THEN SET `token` = 'SE_AEMelee';
|
||||
WHEN '212' THEN SET `token` = 'SE_FrenziedDevastation';
|
||||
WHEN '213' THEN SET `token` = 'SE_PetMaxHP';
|
||||
WHEN '214' THEN SET `token` = 'SE_MaxHPChange';
|
||||
WHEN '215' THEN SET `token` = 'SE_PetAvoidance';
|
||||
WHEN '216' THEN SET `token` = 'SE_Accuracy';
|
||||
WHEN '217' THEN SET `token` = 'SE_HeadShot';
|
||||
WHEN '218' THEN SET `token` = 'SE_PetCriticalHit';
|
||||
WHEN '219' THEN SET `token` = 'SE_SlayUndead';
|
||||
WHEN '220' THEN SET `token` = 'SE_SkillDamageAmount';
|
||||
WHEN '221' THEN SET `token` = 'SE_Packrat';
|
||||
WHEN '222' THEN SET `token` = 'SE_BlockBehind';
|
||||
WHEN '223' THEN SET `token` = 'SE_DoubleRiposte';
|
||||
WHEN '224' THEN SET `token` = 'SE_GiveDoubleRiposte';
|
||||
WHEN '225' THEN SET `token` = 'SE_GiveDoubleAttack';
|
||||
WHEN '226' THEN SET `token` = 'SE_TwoHandBash';
|
||||
WHEN '227' THEN SET `token` = 'SE_ReduceSkillTimer';
|
||||
WHEN '228' THEN SET `token` = 'SE_ReduceFallDamage';
|
||||
WHEN '229' THEN SET `token` = 'SE_PersistantCasting';
|
||||
WHEN '230' THEN SET `token` = 'SE_ExtendedShielding';
|
||||
WHEN '231' THEN SET `token` = 'SE_StunBashChance';
|
||||
WHEN '232' THEN SET `token` = 'SE_DivineSave';
|
||||
WHEN '233' THEN SET `token` = 'SE_Metabolism';
|
||||
WHEN '234' THEN SET `token` = 'SE_ReduceApplyPoisonTime';
|
||||
WHEN '235' THEN SET `token` = 'SE_ChannelChanceSpells';
|
||||
WHEN '236' THEN SET `token` = 'NI_FreePet';
|
||||
WHEN '237' THEN SET `token` = 'SE_GivePetGroupTarget';
|
||||
WHEN '238' THEN SET `token` = 'SE_IllusionPersistence';
|
||||
WHEN '239' THEN SET `token` = 'SE_FeignedCastOnChance';
|
||||
WHEN '240' THEN SET `token` = 'NI_StringUnbreakable';
|
||||
WHEN '241' THEN SET `token` = 'SE_ImprovedReclaimEnergy';
|
||||
WHEN '242' THEN SET `token` = 'SE_IncreaseChanceMemwipe';
|
||||
WHEN '243' THEN SET `token` = 'SE_CharmBreakChance';
|
||||
WHEN '244' THEN SET `token` = 'SE_RootBreakChance';
|
||||
WHEN '245' THEN SET `token` = 'SE_TrapCircumvention';
|
||||
WHEN '246' THEN SET `token` = 'SE_SetBreathLevel';
|
||||
WHEN '247' THEN SET `token` = 'SE_RaiseSkillCap';
|
||||
WHEN '248' THEN SET `token` = 'SE_SecondaryForte';
|
||||
WHEN '249' THEN SET `token` = 'SE_SecondaryDmgInc';
|
||||
WHEN '250' THEN SET `token` = 'SE_SpellProcChance';
|
||||
WHEN '251' THEN SET `token` = 'SE_ConsumeProjectile';
|
||||
WHEN '252' THEN SET `token` = 'SE_FrontalBackstabChance';
|
||||
WHEN '253' THEN SET `token` = 'SE_FrontalBackstabMinDmg';
|
||||
WHEN '254' THEN SET `token` = 'SE_Blank';
|
||||
WHEN '255' THEN SET `token` = 'SE_ShieldDuration';
|
||||
WHEN '256' THEN SET `token` = 'SE_ShroudofStealth';
|
||||
WHEN '257' THEN SET `token` = 'SE_PetDiscipline';
|
||||
WHEN '258' THEN SET `token` = 'SE_TripleBackstab';
|
||||
WHEN '259' THEN SET `token` = 'SE_CombatStability';
|
||||
WHEN '260' THEN SET `token` = 'SE_AddSingingMod';
|
||||
WHEN '261' THEN SET `token` = 'SE_SongModCap';
|
||||
WHEN '262' THEN SET `token` = 'SE_RaiseStatCap';
|
||||
WHEN '263' THEN SET `token` = 'SE_TradeSkillMastery';
|
||||
WHEN '264' THEN SET `token` = 'SE_HastenedAASkill';
|
||||
WHEN '265' THEN SET `token` = 'SE_MasteryofPast';
|
||||
WHEN '266' THEN SET `token` = 'SE_ExtraAttackChance';
|
||||
WHEN '267' THEN SET `token` = 'SE_PetDiscipline2';
|
||||
WHEN '268' THEN SET `token` = 'SE_ReduceTradeskillFail';
|
||||
WHEN '269' THEN SET `token` = 'SE_MaxBindWound';
|
||||
WHEN '270' THEN SET `token` = 'SE_BardSongRange';
|
||||
WHEN '271' THEN SET `token` = 'SE_BaseMovementSpeed';
|
||||
WHEN '272' THEN SET `token` = 'SE_CastingLevel2';
|
||||
WHEN '273' THEN SET `token` = 'SE_CriticalDoTChance';
|
||||
WHEN '274' THEN SET `token` = 'SE_CriticalHealChance';
|
||||
WHEN '275' THEN SET `token` = 'SE_CriticalMend';
|
||||
WHEN '276' THEN SET `token` = 'SE_Ambidexterity';
|
||||
WHEN '277' THEN SET `token` = 'SE_UnfailingDivinity';
|
||||
WHEN '278' THEN SET `token` = 'SE_FinishingBlow';
|
||||
WHEN '279' THEN SET `token` = 'SE_Flurry';
|
||||
WHEN '280' THEN SET `token` = 'SE_PetFlurry';
|
||||
WHEN '281' THEN SET `token` = 'SE_FeignedMinion';
|
||||
WHEN '282' THEN SET `token` = 'SE_ImprovedBindWound';
|
||||
WHEN '283' THEN SET `token` = 'SE_DoubleSpecialAttack';
|
||||
WHEN '284' THEN SET `token` = 'NI_LoHSetHeal';
|
||||
WHEN '285' THEN SET `token` = 'SE_NimbleEvasion';
|
||||
WHEN '286' THEN SET `token` = 'SE_FcDamageAmt';
|
||||
WHEN '287' THEN SET `token` = 'SE_SpellDurationIncByTic';
|
||||
WHEN '288' THEN SET `token` = 'SE_SkillAttackProc';
|
||||
WHEN '289' THEN SET `token` = 'SE_CastOnFadeEffect';
|
||||
WHEN '290' THEN SET `token` = 'SE_IncreaseRunSpeedCap';
|
||||
WHEN '291' THEN SET `token` = 'SE_Purify';
|
||||
WHEN '292' THEN SET `token` = 'SE_StrikeThrough2';
|
||||
WHEN '293' THEN SET `token` = 'SE_FrontalStunResist';
|
||||
WHEN '294' THEN SET `token` = 'SE_CriticalSpellChance';
|
||||
WHEN '295' THEN SET `token` = 'NI_ReduceTimerSpecial';
|
||||
WHEN '296' THEN SET `token` = 'SE_FcSpellVulnerability';
|
||||
WHEN '297' THEN SET `token` = 'SE_FcDamageAmtIncoming';
|
||||
WHEN '298' THEN SET `token` = 'SE_ChangeHeight';
|
||||
WHEN '299' THEN SET `token` = 'SE_WakeTheDead';
|
||||
WHEN '300' THEN SET `token` = 'SE_Doppelganger';
|
||||
WHEN '301' THEN SET `token` = 'SE_ArcheryDamageModifier';
|
||||
WHEN '302' THEN SET `token` = 'SE_FcDamagePctCrit';
|
||||
WHEN '303' THEN SET `token` = 'SE_FcDamageAmtCrit';
|
||||
WHEN '304' THEN SET `token` = 'SE_OffhandRiposteFail';
|
||||
WHEN '305' THEN SET `token` = 'SE_MitigateDamageShield';
|
||||
WHEN '306' THEN SET `token` = 'NI_ArmyOfTheDead';
|
||||
WHEN '307' THEN SET `token` = 'NI_Appraisal';
|
||||
WHEN '308' THEN SET `token` = 'SE_SuspendMinion';
|
||||
WHEN '309' THEN SET `token` = 'SE_GateCastersBindpoint';
|
||||
WHEN '310' THEN SET `token` = 'SE_ReduceReuseTimer';
|
||||
WHEN '311' THEN SET `token` = 'SE_LimitCombatSkills';
|
||||
WHEN '312' THEN SET `token` = 'SE_Sanctuary';
|
||||
WHEN '313' THEN SET `token` = 'SE_ForageAdditionalItems';
|
||||
WHEN '314' THEN SET `token` = 'SE_Invisibility2';
|
||||
WHEN '315' THEN SET `token` = 'SE_InvisVsUndead2';
|
||||
WHEN '316' THEN SET `token` = 'NI_ImprovedInvisAnimals';
|
||||
WHEN '317' THEN SET `token` = 'SE_ItemHPRegenCapIncrease';
|
||||
WHEN '318' THEN SET `token` = 'SE_ItemManaRegenCapIncrease';
|
||||
WHEN '319' THEN SET `token` = 'SE_CriticalHealOverTime';
|
||||
WHEN '320' THEN SET `token` = 'SE_ShieldBlock';
|
||||
WHEN '321' THEN SET `token` = 'SE_ReduceHate';
|
||||
WHEN '322' THEN SET `token` = 'SE_GateToHomeCity';
|
||||
WHEN '323' THEN SET `token` = 'SE_DefensiveProc';
|
||||
WHEN '324' THEN SET `token` = 'SE_HPToMana';
|
||||
WHEN '325' THEN SET `token` = 'SE_NoBreakAESneak';
|
||||
WHEN '326' THEN SET `token` = 'SE_SpellSlotIncrease';
|
||||
WHEN '327' THEN SET `token` = 'SE_MysticalAttune';
|
||||
WHEN '328' THEN SET `token` = 'SE_DelayDeath';
|
||||
WHEN '329' THEN SET `token` = 'SE_ManaAbsorbPercentDamage';
|
||||
WHEN '330' THEN SET `token` = 'SE_CriticalDamageMob';
|
||||
WHEN '331' THEN SET `token` = 'SE_Salvage';
|
||||
WHEN '332' THEN SET `token` = 'SE_SummonToCorpse';
|
||||
WHEN '333' THEN SET `token` = 'SE_CastOnRuneFadeEffect';
|
||||
WHEN '334' THEN SET `token` = 'SE_BardAEDot';
|
||||
WHEN '335' THEN SET `token` = 'SE_BlockNextSpellFocus';
|
||||
WHEN '336' THEN SET `token` = 'NI_IllusionaryTarget';
|
||||
WHEN '337' THEN SET `token` = 'SE_PercentXPIncrease';
|
||||
WHEN '338' THEN SET `token` = 'SE_SummonAndResAllCorpses';
|
||||
WHEN '339' THEN SET `token` = 'SE_TriggerOnCast';
|
||||
WHEN '340' THEN SET `token` = 'SE_SpellTrigger';
|
||||
WHEN '341' THEN SET `token` = 'SE_ItemAttackCapIncrease';
|
||||
WHEN '342' THEN SET `token` = 'SE_ImmuneFleeing';
|
||||
WHEN '343' THEN SET `token` = 'SE_InterruptCasting';
|
||||
WHEN '344' THEN SET `token` = 'SE_ChannelChanceItems';
|
||||
WHEN '345' THEN SET `token` = 'SE_AssassinateLevel';
|
||||
WHEN '346' THEN SET `token` = 'SE_HeadShotLevel';
|
||||
WHEN '347' THEN SET `token` = 'SE_DoubleRangedAttack';
|
||||
WHEN '348' THEN SET `token` = 'SE_LimitManaMin';
|
||||
WHEN '349' THEN SET `token` = 'SE_ShieldEquipDmgMod';
|
||||
WHEN '350' THEN SET `token` = 'SE_ManaBurn';
|
||||
WHEN '351' THEN SET `token` = 'NI_PersistentEffect';
|
||||
WHEN '352' THEN SET `token` = 'NI_IncreaseTrapCount';
|
||||
WHEN '353' THEN SET `token` = 'NI_AdditionalAura';
|
||||
WHEN '354' THEN SET `token` = 'NI_DeactivateAllTraps';
|
||||
WHEN '355' THEN SET `token` = 'NI_LearnTrap';
|
||||
WHEN '356' THEN SET `token` = 'NI_ChangeTriggerType';
|
||||
WHEN '357' THEN SET `token` = 'SE_FcMute';
|
||||
WHEN '358' THEN SET `token` = 'SE_CurrentManaOnce';
|
||||
WHEN '359' THEN SET `token` = 'NI_PassiveSenseTrap';
|
||||
WHEN '360' THEN SET `token` = 'SE_ProcOnKillShot';
|
||||
WHEN '361' THEN SET `token` = 'SE_SpellOnDeath';
|
||||
WHEN '362' THEN SET `token` = 'SE_PotionBeltSlots';
|
||||
WHEN '363' THEN SET `token` = 'SE_BandolierSlots';
|
||||
WHEN '364' THEN SET `token` = 'SE_TripleAttackChance';
|
||||
WHEN '365' THEN SET `token` = 'SE_ProcOnSpellKillShot';
|
||||
WHEN '366' THEN SET `token` = 'SE_GroupShielding';
|
||||
WHEN '367' THEN SET `token` = 'SE_SetBodyType';
|
||||
WHEN '368' THEN SET `token` = 'NI_FactionMod';
|
||||
WHEN '369' THEN SET `token` = 'SE_CorruptionCounter';
|
||||
WHEN '370' THEN SET `token` = 'SE_ResistCorruption';
|
||||
WHEN '371' THEN SET `token` = 'SE_AttackSpeed4';
|
||||
WHEN '372' THEN SET `token` = 'SE_ForageSkill';
|
||||
WHEN '373' THEN SET `token` = 'SE_CastOnFadeEffectAlways';
|
||||
WHEN '374' THEN SET `token` = 'SE_ApplyEffect';
|
||||
WHEN '375' THEN SET `token` = 'SE_DotCritDmgIncrease';
|
||||
WHEN '376' THEN SET `token` = 'NI_Fling';
|
||||
WHEN '377' THEN SET `token` = 'SE_CastOnFadeEffectNPC';
|
||||
WHEN '378' THEN SET `token` = 'SE_SpellEffectResistChance';
|
||||
WHEN '379' THEN SET `token` = 'SE_ShadowStepDirectional';
|
||||
WHEN '380' THEN SET `token` = 'SE_Knockdown';
|
||||
WHEN '381' THEN SET `token` = 'NI_KnockTowardCaster';
|
||||
WHEN '382' THEN SET `token` = 'SE_NegateSpellEffect';
|
||||
WHEN '383' THEN SET `token` = 'SE_SympatheticProc';
|
||||
WHEN '384' THEN SET `token` = 'SE_Leap';
|
||||
WHEN '385' THEN SET `token` = 'SE_LimitSpellGroup';
|
||||
WHEN '386' THEN SET `token` = 'SE_CastOnCurer';
|
||||
WHEN '387' THEN SET `token` = 'SE_CastOnCure';
|
||||
WHEN '388' THEN SET `token` = 'NI_SummonCorpseZone';
|
||||
WHEN '389' THEN SET `token` = 'SE_FcTimerRefresh';
|
||||
WHEN '390' THEN SET `token` = 'NI_FcTimerLockout';
|
||||
WHEN '391' THEN SET `token` = 'SE_LimitManaMax';
|
||||
WHEN '392' THEN SET `token` = 'SE_FcHealAmt';
|
||||
WHEN '393' THEN SET `token` = 'SE_FcHealPctIncoming';
|
||||
WHEN '394' THEN SET `token` = 'SE_FcHealAmtIncoming';
|
||||
WHEN '395' THEN SET `token` = 'SE_FcHealPctCritIncoming';
|
||||
WHEN '396' THEN SET `token` = 'SE_FcHealAmtCrit';
|
||||
WHEN '397' THEN SET `token` = 'SE_PetMeleeMitigation';
|
||||
WHEN '398' THEN SET `token` = 'SE_SwarmPetDuration';
|
||||
WHEN '399' THEN SET `token` = 'SE_FcTwincast';
|
||||
WHEN '400' THEN SET `token` = 'SE_HealGroupFromMana';
|
||||
WHEN '401' THEN SET `token` = 'SE_ManaDrainWithDmg';
|
||||
WHEN '402' THEN SET `token` = 'SE_EndDrainWithDmg';
|
||||
WHEN '403' THEN SET `token` = 'SE_LimitSpellClass';
|
||||
WHEN '404' THEN SET `token` = 'SE_LimitSpellSubclass';
|
||||
WHEN '405' THEN SET `token` = 'SE_TwoHandBluntBlock';
|
||||
WHEN '406' THEN SET `token` = 'SE_CastonNumHitFade';
|
||||
WHEN '407' THEN SET `token` = 'SE_CastonFocusEffect';
|
||||
WHEN '408' THEN SET `token` = 'SE_LimitHPPercent';
|
||||
WHEN '409' THEN SET `token` = 'SE_LimitManaPercent';
|
||||
WHEN '410' THEN SET `token` = 'SE_LimitEndPercent';
|
||||
WHEN '411' THEN SET `token` = 'SE_LimitClass';
|
||||
WHEN '412' THEN SET `token` = 'SE_LimitRace';
|
||||
WHEN '413' THEN SET `token` = 'SE_FcBaseEffects';
|
||||
WHEN '414' THEN SET `token` = 'SE_LimitCastingSkill';
|
||||
WHEN '415' THEN SET `token` = 'NI_FFItemClass';
|
||||
WHEN '416' THEN SET `token` = 'SE_ACv2';
|
||||
WHEN '417' THEN SET `token` = 'SE_ManaRegen_v2';
|
||||
WHEN '418' THEN SET `token` = 'SE_SkillDamageAmount2';
|
||||
WHEN '419' THEN SET `token` = 'SE_AddMeleeProc';
|
||||
WHEN '420' THEN SET `token` = 'SE_FcLimitUse';
|
||||
WHEN '421' THEN SET `token` = 'SE_FcIncreaseNumHits';
|
||||
WHEN '422' THEN SET `token` = 'SE_LimitUseMin';
|
||||
WHEN '423' THEN SET `token` = 'SE_LimitUseType';
|
||||
WHEN '424' THEN SET `token` = 'SE_GravityEffect';
|
||||
WHEN '425' THEN SET `token` = 'NI_Display';
|
||||
WHEN '426' THEN SET `token` = 'SE_IncreaseExtTargetWindow';
|
||||
WHEN '427' THEN SET `token` = 'SE_SkillProc';
|
||||
WHEN '428' THEN SET `token` = 'SE_LimitToSkill';
|
||||
WHEN '429' THEN SET `token` = 'SE_SkillProcSuccess';
|
||||
WHEN '430' THEN SET `token` = 'NI_PostEffect';
|
||||
WHEN '431' THEN SET `token` = 'NI_PostEffectData';
|
||||
WHEN '432' THEN SET `token` = 'NI_ExpandMaxActiveTrophyBen';
|
||||
WHEN '433' THEN SET `token` = 'SE_CriticalDotDecay';
|
||||
WHEN '434' THEN SET `token` = 'SE_CriticalHealDecay';
|
||||
WHEN '435' THEN SET `token` = 'SE_CriticalRegenDecay';
|
||||
WHEN '436' THEN SET `token` = 'NI_BeneficialCountDownHold';
|
||||
WHEN '437' THEN SET `token` = 'NI_TeleporttoAnchor';
|
||||
WHEN '438' THEN SET `token` = 'NI_TranslocatetoAnchor';
|
||||
WHEN '439' THEN SET `token` = 'SE_Assassinate';
|
||||
WHEN '440' THEN SET `token` = 'SE_FinishingBlowLvl';
|
||||
WHEN '441' THEN SET `token` = 'SE_DistanceRemoval';
|
||||
WHEN '442' THEN SET `token` = 'SE_TriggerOnReqTarget';
|
||||
WHEN '443' THEN SET `token` = 'SE_TriggerOnReqCaster';
|
||||
WHEN '444' THEN SET `token` = 'SE_ImprovedTaunt';
|
||||
WHEN '445' THEN SET `token` = 'NI_AddMercSlot';
|
||||
WHEN '446' THEN SET `token` = 'SE_AStacker';
|
||||
WHEN '447' THEN SET `token` = 'SE_BStacker';
|
||||
WHEN '448' THEN SET `token` = 'SE_CStacker';
|
||||
WHEN '449' THEN SET `token` = 'SE_DStacker';
|
||||
WHEN '450' THEN SET `token` = 'SE_MitigateDotDamage';
|
||||
WHEN '451' THEN SET `token` = 'SE_MeleeThresholdGuard';
|
||||
WHEN '452' THEN SET `token` = 'SE_SpellThresholdGuard';
|
||||
WHEN '453' THEN SET `token` = 'SE_TriggerMeleeThreshold';
|
||||
WHEN '454' THEN SET `token` = 'SE_TriggerSpellThreshold';
|
||||
WHEN '455' THEN SET `token` = 'SE_AddHatePct';
|
||||
WHEN '456' THEN SET `token` = 'SE_AddHateOverTimePct';
|
||||
WHEN '457' THEN SET `token` = 'SE_ResourceTap';
|
||||
WHEN '458' THEN SET `token` = 'SE_FactionModPct';
|
||||
WHEN '459' THEN SET `token` = 'SE_DamageModifier2';
|
||||
WHEN '460' THEN SET `token` = 'NI_Ff_Override_NotFocusable';
|
||||
WHEN '461' THEN SET `token` = 'SE_ImprovedDamage2';
|
||||
WHEN '462' THEN SET `token` = 'SE_FcDamageAmt2';
|
||||
WHEN '463' THEN SET `token` = 'NI_Shield_Target';
|
||||
WHEN '464' THEN SET `token` = 'SE_PC_Pet_Rampage';
|
||||
WHEN '465' THEN SET `token` = 'NI_PC_Pet_AE_Rampage';
|
||||
WHEN '466' THEN SET `token` = 'SE_PC_Pet_Flurry_Chance';
|
||||
WHEN '467' THEN SET `token` = 'NI_DS_Mitigation_Amount';
|
||||
WHEN '468' THEN SET `token` = 'NI_DS_Mitigation_Percentage';
|
||||
WHEN '469' THEN SET `token` = 'NI_Chance_Best_in_Spell_Grp';
|
||||
WHEN '470' THEN SET `token` = 'NI_Trigger_Best_in_Spell_Grp';
|
||||
WHEN '471' THEN SET `token` = 'NI_Double_Melee_Round';
|
||||
-- these are not defined
|
||||
WHEN '472' THEN SET `token` = 'NI_Buy_AA_Rank';
|
||||
WHEN '473' THEN SET `token` = 'NI_Double_Backstab_From_Front';
|
||||
WHEN '474' THEN SET `token` = 'NI_Pet_Crit_Melee_Damage_Pct';
|
||||
WHEN '475' THEN SET `token` = 'NI_Trigger_Spell_Non_Item';
|
||||
WHEN '476' THEN SET `token` = 'NI_Weapon_Stance';
|
||||
WHEN '477' THEN SET `token` = 'NI_Hatelist_To_Top_Index';
|
||||
WHEN '478' THEN SET `token` = 'NI_Hatelist_To_Tail_Index';
|
||||
WHEN '479' THEN SET `token` = 'NI_Ff_Value_Min';
|
||||
WHEN '480' THEN SET `token` = 'NI_Ff_Value_Max';
|
||||
WHEN '481' THEN SET `token` = 'NI_Fc_Cast_Spell_On_Land';
|
||||
WHEN '482' THEN SET `token` = 'NI_Skill_Base_Damage_Mod';
|
||||
WHEN '483' THEN SET `token` = 'NI_Fc_Spell_Damage_Pct_IncomingPC';
|
||||
WHEN '484' THEN SET `token` = 'NI_Fc_Spell_Damage_Amt_IncomingPC';
|
||||
WHEN '485' THEN SET `token` = 'NI_Ff_CasterClass';
|
||||
WHEN '486' THEN SET `token` = 'NI_Ff_Same_Caster';
|
||||
WHEN '487' THEN SET `token` = 'NI_Extend_Tradeskill_Cap';
|
||||
WHEN '488' THEN SET `token` = 'NI_Defender_Melee_Force_Pct';
|
||||
WHEN '489' THEN SET `token` = 'NI_Worn_Endurance_Regen_Cap';
|
||||
WHEN '490' THEN SET `token` = 'NI_Ff_ReuseTimeMin';
|
||||
WHEN '491' THEN SET `token` = 'NI_Ff_ReuseTimeMax';
|
||||
WHEN '492' THEN SET `token` = 'NI_Ff_Endurance_Min';
|
||||
WHEN '493' THEN SET `token` = 'NI_Ff_Endurance_Max';
|
||||
WHEN '494' THEN SET `token` = 'NI_Pet_Add_Atk';
|
||||
WHEN '495' THEN SET `token` = 'NI_Ff_DurationMax';
|
||||
ELSE SET `token` = 'unk';
|
||||
END CASE;
|
||||
|
||||
SET `token` = CONCAT(`token`, '(', `effect_id`, ')');
|
||||
|
||||
RETURN `token`;
|
||||
END$$
|
||||
|
||||
DELIMITER ;
|
||||
@@ -0,0 +1,171 @@
|
||||
DELIMITER $$
|
||||
|
||||
DROP FUNCTION IF EXISTS `GetSpellTargetTypeToken`;
|
||||
|
||||
-- This function converts a numeric spell target type to a string label based on server code designations
|
||||
-- Note: `cast_restriction` data taken from MacroQuest2 definitions
|
||||
--
|
||||
-- example:
|
||||
-- SELECT `id`, `name`, GetSpellTargetTypeToken(`targettype`, `CastRestriction`) FROM `spells_new` WHERE `id` IN ('6836', '10763', '25039');
|
||||
CREATE FUNCTION `GetSpellTargetTypeToken` (`target_type` INT(11), `cast_restriction` INT(11)) RETURNS VARCHAR(128)
|
||||
BEGIN
|
||||
DECLARE `token` VARCHAR(128) DEFAULT '';
|
||||
DECLARE `token2` VARCHAR(64) DEFAULT '';
|
||||
|
||||
CASE `target_type`
|
||||
WHEN '1' THEN SET `token` = 'ST_TargetOptional';
|
||||
WHEN '2' THEN SET `token` = 'ST_AEClientV1';
|
||||
WHEN '3' THEN SET `token` = 'ST_GroupTeleport';
|
||||
WHEN '4' THEN SET `token` = 'ST_AECaster';
|
||||
WHEN '5' THEN SET `token` = 'ST_Target';
|
||||
WHEN '6' THEN SET `token` = 'ST_Self';
|
||||
WHEN '8' THEN SET `token` = 'ST_AETarget';
|
||||
WHEN '9' THEN SET `token` = 'ST_Animal';
|
||||
WHEN '10' THEN SET `token` = 'ST_Undead';
|
||||
WHEN '11' THEN SET `token` = 'ST_Summoned';
|
||||
WHEN '13' THEN SET `token` = 'ST_Tap';
|
||||
WHEN '14' THEN SET `token` = 'ST_Pet';
|
||||
WHEN '15' THEN SET `token` = 'ST_Corpse';
|
||||
WHEN '16' THEN SET `token` = 'ST_Plant';
|
||||
WHEN '17' THEN SET `token` = 'ST_Giant';
|
||||
WHEN '18' THEN SET `token` = 'ST_Dragon';
|
||||
WHEN '20' THEN SET `token` = 'ST_TargetAETap';
|
||||
WHEN '24' THEN SET `token` = 'ST_UndeadAE';
|
||||
WHEN '25' THEN SET `token` = 'ST_SummonedAE';
|
||||
WHEN '32' THEN SET `token` = 'ST_AETargetHateList';
|
||||
WHEN '33' THEN SET `token` = 'ST_HateList';
|
||||
WHEN '34' THEN SET `token` = 'ST_LDoNChest_Cursed';
|
||||
WHEN '35' THEN SET `token` = 'ST_Muramite';
|
||||
WHEN '36' THEN SET `token` = 'ST_AreaClientOnly';
|
||||
WHEN '37' THEN SET `token` = 'ST_AreaNPCOnly';
|
||||
WHEN '38' THEN SET `token` = 'ST_SummonedPet';
|
||||
WHEN '39' THEN SET `token` = 'ST_GroupNoPets';
|
||||
WHEN '40' THEN SET `token` = 'ST_AEBard';
|
||||
WHEN '41' THEN SET `token` = 'ST_Group';
|
||||
WHEN '42' THEN SET `token` = 'ST_Directional';
|
||||
WHEN '43' THEN SET `token` = 'ST_GroupClientAndPet';
|
||||
WHEN '44' THEN SET `token` = 'ST_Beam';
|
||||
WHEN '45' THEN SET `token` = 'ST_Ring';
|
||||
WHEN '46' THEN SET `token` = 'ST_TargetsTarget';
|
||||
WHEN '47' THEN SET `token` = 'ST_PetMaster';
|
||||
WHEN '50' THEN SET `token` = 'ST_TargetAENoPlayersPets';
|
||||
ELSE SET `token` = 'unk';
|
||||
END CASE;
|
||||
|
||||
SET `token` = CONCAT(`token`, '(', `target_type`, ')');
|
||||
|
||||
CASE `cast_restriction`
|
||||
WHEN '0' THEN SET `token2` = 'None';
|
||||
WHEN '100' THEN SET `token2` = 'Only works on Animal or Humanoid';
|
||||
WHEN '101' THEN SET `token2` = 'Only works on Dragon';
|
||||
WHEN '102' THEN SET `token2` = 'Only works on Animal or Insect';
|
||||
WHEN '104' THEN SET `token2` = 'Only works on Animal';
|
||||
WHEN '105' THEN SET `token2` = 'Only works on Plant';
|
||||
WHEN '106' THEN SET `token2` = 'Only works on Giant';
|
||||
WHEN '108' THEN SET `token2` = 'Doesn\'t work on Animals or Humanoids';
|
||||
WHEN '109' THEN SET `token2` = 'Only works on Bixie';
|
||||
WHEN '110' THEN SET `token2` = 'Only works on Harpy';
|
||||
WHEN '111' THEN SET `token2` = 'Only works on Gnoll';
|
||||
WHEN '112' THEN SET `token2` = 'Only works on Sporali';
|
||||
WHEN '113' THEN SET `token2` = 'Only works on Kobold';
|
||||
WHEN '114' THEN SET `token2` = 'Only works on Shade';
|
||||
WHEN '115' THEN SET `token2` = 'Only works on Drakkin';
|
||||
WHEN '117' THEN SET `token2` = 'Only works on Animals or Plants';
|
||||
WHEN '118' THEN SET `token2` = 'Only works on Summoned';
|
||||
WHEN '119' THEN SET `token2` = 'Only works on Fire_Pet';
|
||||
WHEN '120' THEN SET `token2` = 'Only works on Undead';
|
||||
WHEN '121' THEN SET `token2` = 'Only works on Living';
|
||||
WHEN '122' THEN SET `token2` = 'Only works on Fairy';
|
||||
WHEN '123' THEN SET `token2` = 'Only works on Humanoid';
|
||||
WHEN '124' THEN SET `token2` = 'Undead HP Less Than 10%';
|
||||
WHEN '125' THEN SET `token2` = 'Clockwork HP Less Than 45%';
|
||||
WHEN '126' THEN SET `token2` = 'Wisp HP Less Than 10%';
|
||||
WHEN '190' THEN SET `token2` = 'Doesn\'t work on Raid Bosses';
|
||||
WHEN '191' THEN SET `token2` = 'Only works on Raid Bosses';
|
||||
WHEN '201' THEN SET `token2` = 'HP Above 75%';
|
||||
WHEN '203' THEN SET `token2` = 'HP Less Than 20%';
|
||||
WHEN '204' THEN SET `token2` = 'HP Less Than 50%';
|
||||
WHEN '216' THEN SET `token2` = 'Not In Combat';
|
||||
WHEN '221' THEN SET `token2` = 'At Least 1 Pet On Hatelist';
|
||||
WHEN '222' THEN SET `token2` = 'At Least 2 Pets On Hatelist';
|
||||
WHEN '223' THEN SET `token2` = 'At Least 3 Pets On Hatelist';
|
||||
WHEN '224' THEN SET `token2` = 'At Least 4 Pets On Hatelist';
|
||||
WHEN '225' THEN SET `token2` = 'At Least 5 Pets On Hatelist';
|
||||
WHEN '226' THEN SET `token2` = 'At Least 6 Pets On Hatelist';
|
||||
WHEN '227' THEN SET `token2` = 'At Least 7 Pets On Hatelist';
|
||||
WHEN '228' THEN SET `token2` = 'At Least 8 Pets On Hatelist';
|
||||
WHEN '229' THEN SET `token2` = 'At Least 9 Pets On Hatelist';
|
||||
WHEN '230' THEN SET `token2` = 'At Least 10 Pets On Hatelist';
|
||||
WHEN '231' THEN SET `token2` = 'At Least 11 Pets On Hatelist';
|
||||
WHEN '232' THEN SET `token2` = 'At Least 12 Pets On Hatelist';
|
||||
WHEN '233' THEN SET `token2` = 'At Least 13 Pets On Hatelist';
|
||||
WHEN '234' THEN SET `token2` = 'At Least 14 Pets On Hatelist';
|
||||
WHEN '235' THEN SET `token2` = 'At Least 15 Pets On Hatelist';
|
||||
WHEN '236' THEN SET `token2` = 'At Least 16 Pets On Hatelist';
|
||||
WHEN '237' THEN SET `token2` = 'At Least 17 Pets On Hatelist';
|
||||
WHEN '238' THEN SET `token2` = 'At Least 18 Pets On Hatelist';
|
||||
WHEN '239' THEN SET `token2` = 'At Least 19 Pets On Hatelist';
|
||||
WHEN '240' THEN SET `token2` = 'At Least 20 Pets On Hatelist';
|
||||
WHEN '250' THEN SET `token2` = 'HP Less Than 35%';
|
||||
WHEN '304' THEN SET `token2` = 'Chain Plate Classes';
|
||||
WHEN '399' THEN SET `token2` = 'HP Between 15 and 25%';
|
||||
WHEN '400' THEN SET `token2` = 'HP Between 1 and 25%';
|
||||
WHEN '401' THEN SET `token2` = 'HP Between 25 and 35%';
|
||||
WHEN '402' THEN SET `token2` = 'HP Between 35 and 45%';
|
||||
WHEN '403' THEN SET `token2` = 'HP Between 45 and 55%';
|
||||
WHEN '404' THEN SET `token2` = 'HP Between 55 and 65%';
|
||||
WHEN '412' THEN SET `token2` = 'HP Above 99%';
|
||||
WHEN '501' THEN SET `token2` = 'HP Below 5%';
|
||||
WHEN '502' THEN SET `token2` = 'HP Below 10%';
|
||||
WHEN '503' THEN SET `token2` = 'HP Below 15%';
|
||||
WHEN '504' THEN SET `token2` = 'HP Below 20%';
|
||||
WHEN '505' THEN SET `token2` = 'HP Below 25%';
|
||||
WHEN '506' THEN SET `token2` = 'HP Below 30%';
|
||||
WHEN '507' THEN SET `token2` = 'HP Below 35%';
|
||||
WHEN '508' THEN SET `token2` = 'HP Below 40%';
|
||||
WHEN '509' THEN SET `token2` = 'HP Below 45%';
|
||||
WHEN '510' THEN SET `token2` = 'HP Below 50%';
|
||||
WHEN '511' THEN SET `token2` = 'HP Below 55%';
|
||||
WHEN '512' THEN SET `token2` = 'HP Below 60%';
|
||||
WHEN '513' THEN SET `token2` = 'HP Below 65%';
|
||||
WHEN '514' THEN SET `token2` = 'HP Below 70%';
|
||||
WHEN '515' THEN SET `token2` = 'HP Below 75%';
|
||||
WHEN '516' THEN SET `token2` = 'HP Below 80%';
|
||||
WHEN '517' THEN SET `token2` = 'HP Below 85%';
|
||||
WHEN '518' THEN SET `token2` = 'HP Below 90%';
|
||||
WHEN '519' THEN SET `token2` = 'HP Below 95%';
|
||||
WHEN '521' THEN SET `token2` = 'Mana Below X%';
|
||||
WHEN '522' THEN SET `token2` = 'End Below 40%';
|
||||
WHEN '523' THEN SET `token2` = 'Mana Below 40%';
|
||||
WHEN '603' THEN SET `token2` = 'Only works on Undead2';
|
||||
WHEN '608' THEN SET `token2` = 'Only works on Undead3';
|
||||
WHEN '624' THEN SET `token2` = 'Only works on Summoned2';
|
||||
WHEN '701' THEN SET `token2` = 'Doesn\'t work on Pets';
|
||||
WHEN '818' THEN SET `token2` = 'Only works on Undead4';
|
||||
WHEN '819' THEN SET `token2` = 'Doesn\'t work on Undead4';
|
||||
WHEN '825' THEN SET `token2` = 'End Below 21%';
|
||||
WHEN '826' THEN SET `token2` = 'End Below 25%';
|
||||
WHEN '827' THEN SET `token2` = 'End Below 29%';
|
||||
WHEN '836' THEN SET `token2` = 'Only works on Regular Servers';
|
||||
WHEN '837' THEN SET `token2` = 'Doesn\'t work on Progression Servers';
|
||||
WHEN '842' THEN SET `token2` = 'Only works on Humanoid Level 84 Max';
|
||||
WHEN '843' THEN SET `token2` = 'Only works on Humanoid Level 86 Max';
|
||||
WHEN '844' THEN SET `token2` = 'Only works on Humanoid Level 88 Max';
|
||||
WHEN '1000' THEN SET `token2` = 'Between Level 1 and 75';
|
||||
WHEN '1001' THEN SET `token2` = 'Between Level 76 and 85';
|
||||
WHEN '1002' THEN SET `token2` = 'Between Level 86 and 95';
|
||||
WHEN '1003' THEN SET `token2` = 'Between Level 96 and 100';
|
||||
WHEN '1004' THEN SET `token2` = 'HP Less Than 80%';
|
||||
WHEN '38311' THEN SET `token2` = 'Mana Below 20%';
|
||||
WHEN '38312' THEN SET `token2` = 'Mana Below 10%';
|
||||
ELSE SET `token2` = 'unk';
|
||||
END CASE;
|
||||
|
||||
SET `token2` = CONCAT(`token2`, '(', `cast_restriction`, ')');
|
||||
|
||||
SET `token` = CONCAT(`token`, ':', `token2`);
|
||||
|
||||
RETURN `token`;
|
||||
END$$
|
||||
|
||||
DELIMITER ;
|
||||
@@ -0,0 +1,185 @@
|
||||
DELIMITER $$
|
||||
|
||||
DROP FUNCTION IF EXISTS `GetSpellTypeDescriptionToken`;
|
||||
|
||||
-- This function converts numeric spell type description ids to a string label based on server code designations
|
||||
--
|
||||
-- example:
|
||||
-- SELECT `id`, `name`, GetSpellTypeDescriptionToken(`typedescnum`) FROM `spells_new` WHERE `id` IN ('16', '42', '23214');
|
||||
CREATE FUNCTION `GetSpellTypeDescriptionToken` (`type_description_id` INT(11)) RETURNS VARCHAR(256)
|
||||
BEGIN
|
||||
DECLARE `token` VARCHAR(256) DEFAULT '';
|
||||
|
||||
CASE `type_description_id`
|
||||
WHEN '1' THEN SET `token` = 'Aegolism';
|
||||
WHEN '2' THEN SET `token` = 'Agility';
|
||||
WHEN '3' THEN SET `token` = 'Alliance';
|
||||
WHEN '4' THEN SET `token` = 'Animal';
|
||||
WHEN '5' THEN SET `token` = 'Antonica';
|
||||
WHEN '6' THEN SET `token` = 'Armor_Class';
|
||||
WHEN '7' THEN SET `token` = 'Attack';
|
||||
WHEN '8' THEN SET `token` = 'Bane';
|
||||
WHEN '9' THEN SET `token` = 'Blind';
|
||||
WHEN '10' THEN SET `token` = 'Block';
|
||||
WHEN '11' THEN SET `token` = 'Calm';
|
||||
WHEN '12' THEN SET `token` = 'Charisma';
|
||||
WHEN '13' THEN SET `token` = 'Charm';
|
||||
WHEN '14' THEN SET `token` = 'Cold';
|
||||
WHEN '15' THEN SET `token` = 'Combat_Abilities';
|
||||
WHEN '16' THEN SET `token` = 'Combat_Innates';
|
||||
WHEN '17' THEN SET `token` = 'Conversions';
|
||||
WHEN '18' THEN SET `token` = 'Create_Item';
|
||||
WHEN '19' THEN SET `token` = 'Cure';
|
||||
WHEN '20' THEN SET `token` = 'Damage_Over_Time';
|
||||
WHEN '21' THEN SET `token` = 'Damage_Shield';
|
||||
WHEN '22' THEN SET `token` = 'Defensive';
|
||||
WHEN '23' THEN SET `token` = 'Destroy';
|
||||
WHEN '24' THEN SET `token` = 'Dexterity';
|
||||
WHEN '25' THEN SET `token` = 'Direct_Damage';
|
||||
WHEN '26' THEN SET `token` = 'Disarm_Traps';
|
||||
WHEN '27' THEN SET `token` = 'Disciplines';
|
||||
WHEN '28' THEN SET `token` = 'Discord';
|
||||
WHEN '29' THEN SET `token` = 'Disease';
|
||||
WHEN '30' THEN SET `token` = 'Disempowering';
|
||||
WHEN '31' THEN SET `token` = 'Dispel';
|
||||
WHEN '32' THEN SET `token` = 'Duration_Heals';
|
||||
WHEN '33' THEN SET `token` = 'Duration_Tap';
|
||||
WHEN '34' THEN SET `token` = 'Enchant_Metal';
|
||||
WHEN '35' THEN SET `token` = 'Enthrall';
|
||||
WHEN '36' THEN SET `token` = 'Faydwer';
|
||||
WHEN '37' THEN SET `token` = 'Fear';
|
||||
WHEN '38' THEN SET `token` = 'Fire';
|
||||
WHEN '39' THEN SET `token` = 'Fizzle_Rate';
|
||||
WHEN '40' THEN SET `token` = 'Fumble';
|
||||
WHEN '41' THEN SET `token` = 'Haste';
|
||||
WHEN '42' THEN SET `token` = 'Heals';
|
||||
WHEN '43' THEN SET `token` = 'Health';
|
||||
WHEN '44' THEN SET `token` = 'Health_Mana';
|
||||
WHEN '45' THEN SET `token` = 'HP_Buffs';
|
||||
WHEN '46' THEN SET `token` = 'HP_type_one';
|
||||
WHEN '47' THEN SET `token` = 'HP_type_two';
|
||||
WHEN '48' THEN SET `token` = 'Illusion_Other';
|
||||
WHEN '49' THEN SET `token` = 'Illusion_Player';
|
||||
WHEN '50' THEN SET `token` = 'Imbue_Gem';
|
||||
WHEN '51' THEN SET `token` = 'Invisibility';
|
||||
WHEN '52' THEN SET `token` = 'Invulnerability';
|
||||
WHEN '53' THEN SET `token` = 'Jolt';
|
||||
WHEN '54' THEN SET `token` = 'Kunark';
|
||||
WHEN '55' THEN SET `token` = 'Levitate';
|
||||
WHEN '56' THEN SET `token` = 'Life_Flow';
|
||||
WHEN '57' THEN SET `token` = 'Luclin';
|
||||
WHEN '58' THEN SET `token` = 'Magic';
|
||||
WHEN '59' THEN SET `token` = 'Mana';
|
||||
WHEN '60' THEN SET `token` = 'Mana_Drain';
|
||||
WHEN '61' THEN SET `token` = 'Mana_Flow';
|
||||
WHEN '62' THEN SET `token` = 'Melee_Guard';
|
||||
WHEN '63' THEN SET `token` = 'Memory_Blur';
|
||||
WHEN '64' THEN SET `token` = 'Misc';
|
||||
WHEN '65' THEN SET `token` = 'Movement';
|
||||
WHEN '66' THEN SET `token` = 'Objects';
|
||||
WHEN '67' THEN SET `token` = 'Odus';
|
||||
WHEN '68' THEN SET `token` = 'Offensive';
|
||||
WHEN '69' THEN SET `token` = 'Pet';
|
||||
WHEN '70' THEN SET `token` = 'Pet_Haste';
|
||||
WHEN '71' THEN SET `token` = 'Pet_Misc_Buffs';
|
||||
WHEN '72' THEN SET `token` = 'Physical';
|
||||
WHEN '73' THEN SET `token` = 'Picklock';
|
||||
WHEN '74' THEN SET `token` = 'Plant';
|
||||
WHEN '75' THEN SET `token` = 'Poison';
|
||||
WHEN '76' THEN SET `token` = 'Power_Tap';
|
||||
WHEN '77' THEN SET `token` = 'Quick_Heal';
|
||||
WHEN '78' THEN SET `token` = 'Reflection';
|
||||
WHEN '79' THEN SET `token` = 'Regen';
|
||||
WHEN '80' THEN SET `token` = 'Resist_Buff';
|
||||
WHEN '81' THEN SET `token` = 'Resist_Debuffs';
|
||||
WHEN '82' THEN SET `token` = 'Resurrection';
|
||||
WHEN '83' THEN SET `token` = 'Root';
|
||||
WHEN '84' THEN SET `token` = 'Rune';
|
||||
WHEN '85' THEN SET `token` = 'Sense_Trap';
|
||||
WHEN '86' THEN SET `token` = 'Shadowstep';
|
||||
WHEN '87' THEN SET `token` = 'Shielding';
|
||||
WHEN '88' THEN SET `token` = 'Slow';
|
||||
WHEN '89' THEN SET `token` = 'Snare';
|
||||
WHEN '90' THEN SET `token` = 'Special';
|
||||
WHEN '91' THEN SET `token` = 'Spell_Focus';
|
||||
WHEN '92' THEN SET `token` = 'Spell_Guard';
|
||||
WHEN '93' THEN SET `token` = 'Spellshield';
|
||||
WHEN '94' THEN SET `token` = 'Stamina';
|
||||
WHEN '95' THEN SET `token` = 'Statistic_Buffs';
|
||||
WHEN '96' THEN SET `token` = 'Strength';
|
||||
WHEN '97' THEN SET `token` = 'Stun';
|
||||
WHEN '98' THEN SET `token` = 'Sum_Air';
|
||||
WHEN '99' THEN SET `token` = 'Sum_Animation';
|
||||
WHEN '100' THEN SET `token` = 'Sum_Earth';
|
||||
WHEN '101' THEN SET `token` = 'Sum_Familiar';
|
||||
WHEN '102' THEN SET `token` = 'Sum_Fire';
|
||||
WHEN '103' THEN SET `token` = 'Sum_Undead';
|
||||
WHEN '104' THEN SET `token` = 'Sum_Warder';
|
||||
WHEN '105' THEN SET `token` = 'Sum_Water';
|
||||
WHEN '106' THEN SET `token` = 'Summon_Armor';
|
||||
WHEN '107' THEN SET `token` = 'Summon_Focus';
|
||||
WHEN '108' THEN SET `token` = 'Summon_Food_Water';
|
||||
WHEN '109' THEN SET `token` = 'Summon_Utility';
|
||||
WHEN '110' THEN SET `token` = 'Summon_Weapon';
|
||||
WHEN '111' THEN SET `token` = 'Summoned';
|
||||
WHEN '112' THEN SET `token` = 'Symbol';
|
||||
WHEN '113' THEN SET `token` = 'Taelosia';
|
||||
WHEN '114' THEN SET `token` = 'Taps';
|
||||
WHEN '115' THEN SET `token` = 'Techniques';
|
||||
WHEN '116' THEN SET `token` = 'The_Planes';
|
||||
WHEN '117' THEN SET `token` = 'Timer_1';
|
||||
WHEN '118' THEN SET `token` = 'Timer_2';
|
||||
WHEN '119' THEN SET `token` = 'Timer_3';
|
||||
WHEN '120' THEN SET `token` = 'Timer_4';
|
||||
WHEN '121' THEN SET `token` = 'Timer_5';
|
||||
WHEN '122' THEN SET `token` = 'Timer_6';
|
||||
WHEN '123' THEN SET `token` = 'Transport';
|
||||
WHEN '124' THEN SET `token` = 'Undead';
|
||||
WHEN '125' THEN SET `token` = 'Utility_Beneficial';
|
||||
WHEN '126' THEN SET `token` = 'Utility_Detrimental';
|
||||
WHEN '127' THEN SET `token` = 'Velious';
|
||||
WHEN '128' THEN SET `token` = 'Visages';
|
||||
WHEN '129' THEN SET `token` = 'Vision';
|
||||
WHEN '130' THEN SET `token` = 'Wisdom_Intelligence';
|
||||
WHEN '131' THEN SET `token` = 'Traps';
|
||||
WHEN '132' THEN SET `token` = 'Auras';
|
||||
WHEN '133' THEN SET `token` = 'Endurance';
|
||||
WHEN '134' THEN SET `token` = 'Serpent\'s_Spine';
|
||||
WHEN '135' THEN SET `token` = 'Corruption';
|
||||
WHEN '136' THEN SET `token` = 'Learning';
|
||||
WHEN '137' THEN SET `token` = 'Chromatic';
|
||||
WHEN '138' THEN SET `token` = 'Prismatic';
|
||||
WHEN '139' THEN SET `token` = 'Sum_Swarm';
|
||||
WHEN '140' THEN SET `token` = 'Delayed';
|
||||
WHEN '141' THEN SET `token` = 'Temporary';
|
||||
WHEN '142' THEN SET `token` = 'Twincast';
|
||||
WHEN '143' THEN SET `token` = 'Sum_Bodyguard';
|
||||
WHEN '144' THEN SET `token` = 'Humanoid';
|
||||
WHEN '145' THEN SET `token` = 'Haste_Spell_Focus';
|
||||
WHEN '146' THEN SET `token` = 'Timer_7';
|
||||
WHEN '147' THEN SET `token` = 'Timer_8';
|
||||
WHEN '148' THEN SET `token` = 'Timer_9';
|
||||
WHEN '149' THEN SET `token` = 'Timer_10';
|
||||
WHEN '150' THEN SET `token` = 'Timer_11';
|
||||
WHEN '151' THEN SET `token` = 'Timer_12';
|
||||
WHEN '152' THEN SET `token` = 'Hatred';
|
||||
WHEN '153' THEN SET `token` = 'Fast';
|
||||
WHEN '154' THEN SET `token` = 'Illusion_Special';
|
||||
WHEN '155' THEN SET `token` = 'Timer_13';
|
||||
WHEN '156' THEN SET `token` = 'Timer_14';
|
||||
WHEN '157' THEN SET `token` = 'Timer_15';
|
||||
WHEN '158' THEN SET `token` = 'Timer_16';
|
||||
WHEN '159' THEN SET `token` = 'Timer_17';
|
||||
WHEN '160' THEN SET `token` = 'Timer_18';
|
||||
WHEN '161' THEN SET `token` = 'Timer_19';
|
||||
WHEN '162' THEN SET `token` = 'Timer_20';
|
||||
WHEN '163' THEN SET `token` = 'Alaris';
|
||||
ELSE SET `token` = 'unk';
|
||||
END CASE;
|
||||
|
||||
SET `token` = CONCAT(`token`, '(', `type_description_id`, ')');
|
||||
|
||||
RETURN `token`;
|
||||
END$$
|
||||
|
||||
DELIMITER ;
|
||||
@@ -334,7 +334,7 @@ sub build_linux_source {
|
||||
}
|
||||
print "Building EQEmu Server code. This will take a while.";
|
||||
|
||||
#::: Build
|
||||
#::: Build
|
||||
print `make`;
|
||||
|
||||
chdir ($current_directory);
|
||||
@@ -1340,7 +1340,7 @@ sub do_linux_login_server_setup {
|
||||
|
||||
get_remote_file($install_repository_request_url . "linux/login.ini", "login_template.ini");
|
||||
get_remote_file($install_repository_request_url . "linux/login_opcodes.conf", "login_opcodes.conf");
|
||||
get_remote_file($install_repository_request_url . "linux/login_opcodes.conf", "login_opcodes_sod.conf");
|
||||
get_remote_file($install_repository_request_url . "linux/login_opcodes_sod.conf", "login_opcodes_sod.conf");
|
||||
|
||||
get_installation_variables();
|
||||
my $db_name = $installation_variables{"mysql_eqemu_db_name"};
|
||||
|
||||
@@ -87,6 +87,7 @@ echo "mysql_eqemu_password:$eqemu_db_password" >> install_variables.txt
|
||||
|
||||
if [[ "$OS" == "Debian" ]]; then
|
||||
# Install pre-req packages
|
||||
apt-get -y update
|
||||
apt-get $apt_options install bash
|
||||
apt-get $apt_options install build-essential
|
||||
apt-get $apt_options install cmake
|
||||
@@ -105,6 +106,8 @@ if [[ "$OS" == "Debian" ]]; then
|
||||
apt-get $apt_options install libperl-dev
|
||||
apt-get $apt_options install libperl5i-perl
|
||||
apt-get $apt_options install libwtdbomysql-dev
|
||||
apt-get $apt_options install libmysqlclient-dev
|
||||
apt-get $apt_options install minizip
|
||||
apt-get $apt_options install lua5.1
|
||||
apt-get $apt_options install make
|
||||
apt-get $apt_options install mariadb-client
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
command_settings
|
||||
launcher
|
||||
rule_sets
|
||||
rule_values
|
||||
variables
|
||||
@@ -355,6 +355,12 @@
|
||||
9099|2016_08_27_ip_exemptions.sql|SHOW TABLES LIKE 'ip_exemptions'|empty|
|
||||
9100|2016_08_27_object_display_name.sql|SHOW COLUMNS FROM `object` LIKE 'display_name'|empty|
|
||||
9101|2016_12_01_pcnpc_only.sql|SHOW COLUMNS FROM `spells_new` LIKE 'pcnpc_only_flag'|empty|
|
||||
9102|2017_01_10_book_languages.sql|SHOW COLUMNS FROM `books` LIKE 'language'|empty|
|
||||
9103|2017_01_30_book_languages_fix.sql|SELECT `language` from `books` WHERE `language` IS NULL|not_empty|
|
||||
9104|2017_02_09_npc_spells_entries_type_update.sql|SHOW COLUMNS IN `npc_spells_entries` LIKE `type`|contains|smallint(5) unsigned
|
||||
9105|2017_02_15_bot_spells_entries.sql|SELECT `id` FROM `npc_spells_entries` WHERE `npc_spells_id` >= 701 AND `npc_spells_id` <= 712|not_empty|
|
||||
9106|2017_02_26_npc_spells_update_for_bots.sql|SELECT * FROM `npc_spells` WHERE `id` = '701' AND `name` = 'Cleric Bot'|not_empty|
|
||||
9107|2017_03_09_inventory_version.sql|SHOW TABLES LIKE 'inventory_version'|empty|
|
||||
|
||||
# Upgrade conditions:
|
||||
# This won't be needed after this system is implemented, but it is used database that are not
|
||||
|
||||
@@ -7,6 +7,13 @@
|
||||
9006|2016_04_12_bots_inventory_window.sql|SELECT `bot_command` FROM `bot_command_settings` WHERE `bot_command` LIKE 'inventorywindow'|empty|
|
||||
9007|2016_06_23_bots_camel_case_name_rule.sql|SELECT * FROM `rule_values` WHERE `rule_name` LIKE 'Bots:AllowCamelCaseNames'|empty|
|
||||
9008|2016_06_28_bots_inventory_charges_update.sql|SELECT * FROM `information_schema`.`COLUMNS` isc WHERE isc.`TABLE_SCHEMA` = DATABASE() AND isc.`TABLE_NAME` = 'bot_inventories' AND isc.`COLUMN_NAME` = 'inst_charges' AND isc.`DATA_TYPE` = 'tinyint'|not_empty|
|
||||
9009|2017_02_15_bots_bot_spells_entries.sql|SELECT `id` FROM `npc_spells_entries` WHERE `npc_spells_id` >= 701 AND `npc_spells_id` <= 712|not_empty|
|
||||
9010|2017_02_20_bots_bard_spell_update.sql|SELECT * FROM `bot_spells_entries` WHERE `npc_spells_id` = 711 AND (`type` & 0xFFFF0000) = 0xFFFF0000|empty|
|
||||
9011|2017_02_23_bots_spell_casting_chances.sql|SHOW TABLES LIKE 'bot_spell_casting_chances'|empty|
|
||||
9012|2017_02_26_bots_npc_spells_update_for_bots.sql|SELECT * FROM `npc_spells` WHERE `id` = '701' AND `name` = 'Cleric Bot'|not_empty|
|
||||
9013|2017_02_26_bots_spells_id_update_for_saved_bots.sql|SELECT * FROM `bot_data` WHERE `spells_id` >= '701' AND `spells_id` <= '712'|not_empty|
|
||||
9014|2017_02_26_bots_spells_id_update_for_bot_spells_entries.sql|SELECT * FROM `bot_spells_entries` WHERE `npc_spells_id` >= '701' AND `npc_spells_id` <= '712'|not_empty|
|
||||
9015|2017_02_26_bots_spell_casting_chances_update.sql|SHOW COLUMNS FROM `bot_spell_casting_chances` LIKE 'value'|not_empty|
|
||||
|
||||
# Upgrade conditions:
|
||||
# This won't be needed after this system is implemented, but it is used database that are not
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Bots:UpdatePositionWithTimer', 'true', 'Sends a position update with every positive movement timer check');
|
||||
@@ -0,0 +1 @@
|
||||
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Bots:UsePathing', 'false', 'Bots will use node pathing when moving');
|
||||
@@ -0,0 +1,29 @@
|
||||
-- Delete any existing `bots_spells_entries` table
|
||||
DROP TABLE IF EXISTS `bots_spells_entries`;
|
||||
|
||||
-- Create new bot spells entries table (new table does not have spells_id_spellid constraint)
|
||||
CREATE TABLE `bot_spells_entries` (
|
||||
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`npc_spells_id` INT(11) NOT NULL DEFAULT '0',
|
||||
`spellid` SMALLINT(5) NOT NULL DEFAULT '0',
|
||||
`type` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`minlevel` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`maxlevel` TINYINT(3) UNSIGNED NOT NULL DEFAULT '255',
|
||||
`manacost` SMALLINT(5) NOT NULL DEFAULT '-1',
|
||||
`recast_delay` INT(11) NOT NULL DEFAULT '-1',
|
||||
`priority` SMALLINT(5) NOT NULL DEFAULT '0',
|
||||
`resist_adjust` INT(11) NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
)
|
||||
COLLATE='latin1_swedish_ci'
|
||||
ENGINE=InnoDB
|
||||
AUTO_INCREMENT=1
|
||||
;
|
||||
|
||||
-- Copy bots spells into new table
|
||||
INSERT INTO `bot_spells_entries` (`npc_spells_id`, `spellid`, `type`, `minlevel`, `maxlevel`, `manacost`, `recast_delay`, `priority`, `resist_adjust`)
|
||||
SELECT `npc_spells_id`, `spellid`, `type`, `minlevel`, `maxlevel`, `manacost`, `recast_delay`, `priority`, `resist_adjust`
|
||||
FROM `npc_spells_entries` WHERE `npc_spells_id` >= '701' AND `npc_spells_id` <= '712';
|
||||
|
||||
-- Delete bot spells from old table
|
||||
DELETE FROM `npc_spells_entries` WHERE `npc_spells_id` >= '701' AND `npc_spells_id` <= '712';
|
||||
@@ -0,0 +1,153 @@
|
||||
DELETE FROM `bot_spells_entries` WHERE `npc_spells_id` = '711';
|
||||
|
||||
INSERT INTO `bot_spells_entries`(`npc_spells_id`,`spellid`,`type`,`minlevel`,`maxlevel`,`manacost`,`recast_delay`,`priority`,`resist_adjust`) VALUES
|
||||
|
||||
-- versioning entry
|
||||
('711', '0', '4294901760', '0', '0', '-1', '-1', '0', NULL), -- 0xFFFF0000
|
||||
|
||||
-- nuke
|
||||
('711', '704', '1', '12', '54', '-1', '-1', '1', NULL),
|
||||
('711', '1747', '1', '55', '127', '-1', '-1', '1', NULL),
|
||||
|
||||
-- escape
|
||||
('711', '1749', '16', '60', '127', '-1', '-1', '1', NULL),
|
||||
|
||||
-- dot
|
||||
('711', '743', '256', '38', '64', '-1', '-1', '1', NULL),
|
||||
('711', '3367', '256', '65', '69', '-1', '-1', '1', NULL),
|
||||
('711', '5385', '256', '70', '79', '-1', '-1', '1', NULL),
|
||||
('711', '14074', '256', '80', '84', '-1', '-1', '1', NULL),
|
||||
('711', '18059', '256', '85', '89', '-1', '-1', '1', NULL),
|
||||
('711', '26084', '256', '90', '94', '-1', '-1', '1', NULL),
|
||||
('711', '29182', '256', '95', '127', '-1', '-1', '1', NULL),
|
||||
('711', '3566', '256', '50', '62', '-1', '-1', '2', NULL),
|
||||
('711', '3370', '256', '63', '67', '-1', '-1', '2', NULL),
|
||||
('711', '5378', '256', '68', '77', '-1', '-1', '2', NULL),
|
||||
('711', '14071', '256', '78', '82', '-1', '-1', '2', NULL),
|
||||
('711', '18056', '256', '83', '87', '-1', '-1', '2', NULL),
|
||||
('711', '26033', '256', '88', '92', '-1', '-1', '2', NULL),
|
||||
('711', '29128', '256', '93', '127', '-1', '-1', '2', NULL),
|
||||
('711', '744', '256', '46', '62', '-1', '-1', '3', NULL),
|
||||
('711', '3373', '256', '63', '66', '-1', '-1', '3', NULL),
|
||||
('711', '5379', '256', '67', '76', '-1', '-1', '3', NULL),
|
||||
('711', '14068', '256', '77', '81', '-1', '-1', '3', NULL),
|
||||
('711', '18053', '256', '82', '86', '-1', '-1', '3', NULL),
|
||||
('711', '26003', '256', '87', '91', '-1', '-1', '3', NULL),
|
||||
('711', '29101', '256', '92', '127', '-1', '-1', '3', NULL),
|
||||
('711', '3567', '256', '42', '60', '-1', '-1', '4', NULL),
|
||||
('711', '3363', '256', '61', '65', '-1', '-1', '4', NULL),
|
||||
('711', '5371', '256', '66', '75', '-1', '-1', '4', NULL),
|
||||
('711', '14065', '256', '76', '80', '-1', '-1', '4', NULL),
|
||||
('711', '18050', '256', '81', '85', '-1', '-1', '4', NULL),
|
||||
('711', '25976', '256', '86', '90', '-1', '-1', '4', NULL),
|
||||
('711', '29077', '256', '91', '127', '-1', '-1', '4', NULL),
|
||||
('711', '707', '256', '30', '59', '-1', '-1', '5', NULL),
|
||||
('711', '4210', '256', '60', '127', '-1', '-1', '5', NULL),
|
||||
|
||||
-- slow
|
||||
('711', '738', '8192', '23', '50', '-1', '-1', '1', NULL),
|
||||
('711', '1751', '8192', '51', '59', '-1', '-1', '1', NULL),
|
||||
('711', '1748', '8192', '60', '63', '-1', '-1', '1', NULL),
|
||||
('711', '3066', '8192', '64', '127', '-1', '-1', '1', NULL),
|
||||
('711', '738', '8192', '51', '63', '-1', '-1', '2', NULL),
|
||||
('711', '1751', '8192', '64', '127', '-1', '-1', '2', NULL),
|
||||
('711', '738', '8192', '64', '127', '-1', '-1', '3', NULL),
|
||||
|
||||
-- cure
|
||||
('711', '3682', '32768', '45', '85', '-1', '-1', '1', NULL),
|
||||
('711', '25958', '32768', '86', '90', '-1', '-1', '1', NULL),
|
||||
('711', '29059', '32768', '91', '127', '-1', '-1', '1', NULL),
|
||||
('711', '3681', '32768', '52', '127', '-1', '-1', '2', NULL),
|
||||
('711', '10448', '32768', '74', '78', '-1', '-1', '3', NULL),
|
||||
('711', '14029', '32768', '79', '83', '-1', '-1', '3', NULL),
|
||||
('711', '18023', '32768', '84', '127', '-1', '-1', '3', NULL),
|
||||
|
||||
-- hate redux
|
||||
('711', '1754', '131072', '53', '127', '-1', '-1', '1', NULL),
|
||||
('711', '10436', '131072', '73', '127', '-1', '-1', '2', NULL),
|
||||
|
||||
-- in-combat buff songs
|
||||
('711', '2606', '262144', '52', '59', '-1', '-1', '1', NULL),
|
||||
('711', '2610', '262144', '60', '127', '-1', '-1', '1', NULL),
|
||||
('711', '700', '262144', '1', '9', '-1', '-1', '2', NULL),
|
||||
('711', '701', '262144', '10', '35', '-1', '-1', '2', NULL),
|
||||
('711', '740', '262144', '36', '41', '-1', '-1', '2', NULL),
|
||||
('711', '702', '262144', '42', '49', '-1', '-1', '2', NULL),
|
||||
('711', '747', '262144', '50', '61', '-1', '-1', '2', NULL),
|
||||
('711', '3374', '262144', '62', '64', '-1', '-1', '2', NULL),
|
||||
('711', '4871', '262144', '65', '67', '-1', '-1', '2', NULL),
|
||||
('711', '5376', '262144', '68', '78', '-1', '-1', '2', NULL),
|
||||
('711', '14080', '262144', '79', '83', '-1', '-1', '2', NULL),
|
||||
('711', '18065', '262144', '84', '88', '-1', '-1', '2', NULL),
|
||||
('711', '26042', '262144', '89', '93', '-1', '-1', '2', NULL),
|
||||
('711', '29143', '262144', '94', '127', '-1', '-1', '2', NULL),
|
||||
('711', '7', '262144', '6', '19', '-1', '-1', '2', NULL),
|
||||
('711', '1287', '262144', '20', '31', '-1', '-1', '3', NULL),
|
||||
('711', '723', '262144', '32', '33', '-1', '-1', '3', NULL),
|
||||
('711', '1448', '262144', '34', '54', '-1', '-1', '3', NULL),
|
||||
('711', '1759', '262144', '55', '61', '-1', '-1', '3', NULL),
|
||||
('711', '3651', '262144', '62', '66', '-1', '-1', '3', NULL),
|
||||
('711', '5377', '262144', '67', '70', '-1', '-1', '3', NULL),
|
||||
('711', '10421', '262144', '71', '75', '-1', '-1', '3', NULL),
|
||||
('711', '14008', '262144', '76', '80', '-1', '-1', '3', NULL),
|
||||
('711', '18008', '262144', '81', '87', '-1', '-1', '3', NULL),
|
||||
('711', '26015', '262144', '88', '92', '-1', '-1', '3', NULL),
|
||||
('711', '29107', '262144', '93', '127', '-1', '-1', '3', NULL),
|
||||
('711', '734', '262144', '7', '8', '-1', '-1', '4', NULL),
|
||||
('711', '710', '262144', '9', '12', '-1', '-1', '4', NULL),
|
||||
('711', '711', '262144', '13', '16', '-1', '-1', '4', NULL),
|
||||
('711', '709', '262144', '17', '40', '-1', '-1', '4', NULL),
|
||||
('711', '714', '262144', '41', '46', '-1', '-1', '4', NULL),
|
||||
('711', '748', '262144', '47', '57', '-1', '-1', '4', NULL),
|
||||
('711', '1763', '262144', '58', '72', '-1', '-1', '4', NULL),
|
||||
('711', '11881', '262144', '73', '77', '-1', '-1', '4', NULL),
|
||||
('711', '14056', '262144', '78', '82', '-1', '-1', '4', NULL),
|
||||
('711', '18041', '262144', '83', '87', '-1', '-1', '4', NULL),
|
||||
('711', '26027', '262144', '88', '92', '-1', '-1', '4', NULL),
|
||||
('711', '29122', '262144', '93', '127', '-1', '-1', '4', NULL),
|
||||
('711', '734', '262144', '9', '24', '-1', '-1', '5', NULL),
|
||||
('711', '712', '262144', '25', '28', '-1', '-1', '5', NULL),
|
||||
('711', '715', '262144', '29', '32', '-1', '-1', '5', NULL),
|
||||
('711', '713', '262144', '33', '36', '-1', '-1', '5', NULL),
|
||||
('711', '716', '262144', '37', '44', '-1', '-1', '5', NULL),
|
||||
('711', '4083', '262144', '45', '52', '-1', '-1', '5', NULL),
|
||||
('711', '4084', '262144', '53', '63', '-1', '-1', '5', NULL),
|
||||
('711', '3362', '262144', '64', '64', '-1', '-1', '5', NULL),
|
||||
('711', '4872', '262144', '65', '68', '-1', '-1', '5', NULL),
|
||||
('711', '5382', '262144', '69', '75', '-1', '-1', '5', NULL),
|
||||
('711', '14062', '262144', '76', '80', '-1', '-1', '5', NULL),
|
||||
('711', '18047', '262144', '81', '85', '-1', '-1', '5', NULL),
|
||||
('711', '25961', '262144', '86', '90', '-1', '-1', '5', NULL),
|
||||
('711', '29062', '262144', '91', '127', '-1', '-1', '5', NULL),
|
||||
('711', '734', '262144', '25', '43', '-1', '-1', '6', NULL),
|
||||
('711', '4085', '262144', '44', '51', '-1', '-1', '6', NULL),
|
||||
('711', '4086', '262144', '52', '62', '-1', '-1', '6', NULL),
|
||||
('711', '4087', '262144', '63', '68', '-1', '-1', '6', NULL),
|
||||
('711', '5374', '262144', '69', '71', '-1', '-1', '6', NULL),
|
||||
('711', '10439', '262144', '72', '76', '-1', '-1', '6', NULL),
|
||||
('711', '14020', '262144', '77', '81', '-1', '-1', '6', NULL),
|
||||
('711', '18014', '262144', '82', '86', '-1', '-1', '6', NULL),
|
||||
('711', '25991', '262144', '87', '127', '-1', '-1', '6', NULL),
|
||||
('711', '734', '262144', '30', '82', '-1', '-1', '7', NULL),
|
||||
('711', '18020', '262144', '83', '127', '-1', '-1', '7', NULL),
|
||||
('711', '734', '262144', '83', '127', '-1', '-1', '8', NULL),
|
||||
('711', '2603', '262144', '30', '127', '-1', '-1', '9', NULL),
|
||||
|
||||
-- out-of-combat buff songs
|
||||
('711', '7', '524288', '6', '19', '-1', '-1', '1', NULL),
|
||||
('711', '1287', '524288', '20', '31', '-1', '-1', '1', NULL),
|
||||
('711', '723', '524288', '32', '33', '-1', '-1', '1', NULL),
|
||||
('711', '1448', '524288', '34', '54', '-1', '-1', '1', NULL),
|
||||
('711', '1759', '524288', '55', '61', '-1', '-1', '1', NULL),
|
||||
('711', '3651', '524288', '62', '66', '-1', '-1', '1', NULL),
|
||||
('711', '5377', '524288', '67', '70', '-1', '-1', '1', NULL),
|
||||
('711', '10421', '524288', '71', '75', '-1', '-1', '1', NULL),
|
||||
('711', '14008', '524288', '76', '80', '-1', '-1', '1', NULL),
|
||||
('711', '18008', '524288', '81', '87', '-1', '-1', '1', NULL),
|
||||
('711', '26015', '524288', '88', '92', '-1', '-1', '1', NULL),
|
||||
('711', '29107', '524288', '93', '127', '-1', '-1', '1', NULL),
|
||||
('711', '717', '524288', '5', '29', '-1', '-1','2', NULL),
|
||||
('711', '2603', '524288', '30', '127', '-1', '-1','2', NULL),
|
||||
('711', '717', '524288', '30', '48', '-1', '-1','3', NULL),
|
||||
('711', '2605', '524288', '49', '127', '-1', '-1','3', NULL),
|
||||
('711', '2602', '524288', '15', '127', '-1', '-1','4', NULL);
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,19 @@
|
||||
-- Re-ordered entries according to actual class values and added melee types (for future expansion)
|
||||
DELETE FROM `npc_spells` WHERE `id` >= '701' AND `id` <= '712';
|
||||
|
||||
INSERT INTO `npc_spells` VALUES (3001, 'Warrior Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
INSERT INTO `npc_spells` VALUES (3002, 'Cleric Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
INSERT INTO `npc_spells` VALUES (3003, 'Paladin Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
INSERT INTO `npc_spells` VALUES (3004, 'Ranger Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
INSERT INTO `npc_spells` VALUES (3005, 'Shadowknight Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
INSERT INTO `npc_spells` VALUES (3006, 'Druid Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
INSERT INTO `npc_spells` VALUES (3007, 'Monk Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
INSERT INTO `npc_spells` VALUES (3008, 'Bard Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
INSERT INTO `npc_spells` VALUES (3009, 'Rogue Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
INSERT INTO `npc_spells` VALUES (3010, 'Shaman Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
INSERT INTO `npc_spells` VALUES (3011, 'Necromancer Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
INSERT INTO `npc_spells` VALUES (3012, 'Wizard Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
INSERT INTO `npc_spells` VALUES (3013, 'Magician Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
INSERT INTO `npc_spells` VALUES (3014, 'Enchanter Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
INSERT INTO `npc_spells` VALUES (3015, 'Beastlord Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
INSERT INTO `npc_spells` VALUES (3016, 'Berserker Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
File diff suppressed because it is too large
Load Diff
+13
@@ -0,0 +1,13 @@
|
||||
-- Update npc_spells_id to new values
|
||||
UPDATE `bot_spells_entries` SET `npc_spells_id` = '3002' WHERE `npc_spells_id` = '701';
|
||||
UPDATE `bot_spells_entries` SET `npc_spells_id` = '3012' WHERE `npc_spells_id` = '702';
|
||||
UPDATE `bot_spells_entries` SET `npc_spells_id` = '3011' WHERE `npc_spells_id` = '703';
|
||||
UPDATE `bot_spells_entries` SET `npc_spells_id` = '3013' WHERE `npc_spells_id` = '704';
|
||||
UPDATE `bot_spells_entries` SET `npc_spells_id` = '3014' WHERE `npc_spells_id` = '705';
|
||||
UPDATE `bot_spells_entries` SET `npc_spells_id` = '3010' WHERE `npc_spells_id` = '706';
|
||||
UPDATE `bot_spells_entries` SET `npc_spells_id` = '3006' WHERE `npc_spells_id` = '707';
|
||||
UPDATE `bot_spells_entries` SET `npc_spells_id` = '3003' WHERE `npc_spells_id` = '708';
|
||||
UPDATE `bot_spells_entries` SET `npc_spells_id` = '3005' WHERE `npc_spells_id` = '709';
|
||||
UPDATE `bot_spells_entries` SET `npc_spells_id` = '3004' WHERE `npc_spells_id` = '710';
|
||||
UPDATE `bot_spells_entries` SET `npc_spells_id` = '3008' WHERE `npc_spells_id` = '711';
|
||||
UPDATE `bot_spells_entries` SET `npc_spells_id` = '3015' WHERE `npc_spells_id` = '712';
|
||||
@@ -0,0 +1,17 @@
|
||||
-- Update spells_id to new values
|
||||
UPDATE `bot_data` SET `spells_id` = '3001' WHERE `class` = '1';
|
||||
UPDATE `bot_data` SET `spells_id` = '3002' WHERE `class` = '2';
|
||||
UPDATE `bot_data` SET `spells_id` = '3003' WHERE `class` = '3';
|
||||
UPDATE `bot_data` SET `spells_id` = '3004' WHERE `class` = '4';
|
||||
UPDATE `bot_data` SET `spells_id` = '3005' WHERE `class` = '5';
|
||||
UPDATE `bot_data` SET `spells_id` = '3006' WHERE `class` = '6';
|
||||
UPDATE `bot_data` SET `spells_id` = '3007' WHERE `class` = '7';
|
||||
UPDATE `bot_data` SET `spells_id` = '3008' WHERE `class` = '8';
|
||||
UPDATE `bot_data` SET `spells_id` = '3009' WHERE `class` = '9';
|
||||
UPDATE `bot_data` SET `spells_id` = '3010' WHERE `class` = '10';
|
||||
UPDATE `bot_data` SET `spells_id` = '3011' WHERE `class` = '11';
|
||||
UPDATE `bot_data` SET `spells_id` = '3012' WHERE `class` = '12';
|
||||
UPDATE `bot_data` SET `spells_id` = '3013' WHERE `class` = '13';
|
||||
UPDATE `bot_data` SET `spells_id` = '3014' WHERE `class` = '14';
|
||||
UPDATE `bot_data` SET `spells_id` = '3015' WHERE `class` = '15';
|
||||
UPDATE `bot_data` SET `spells_id` = '3016' WHERE `class` = '16';
|
||||
@@ -0,0 +1,25 @@
|
||||
update npc_types set attack_speed=0, atk=ceil(1.7*level), accuracy=ceil(1.7*level) where (name like 'Swarm%' or name like '%skel%' or name like 'BLpet%' or name like 'Sum%')
|
||||
and id >510 and id <860;
|
||||
update npc_types set attack_speed=0, atk=ceil(0.5*level), accuracy=ceil(0.5*level) where name like 'SumFire%';
|
||||
update npc_types set attack_speed=0, atk=ceil(1.775*level), accuracy=ceil(1.775*level) where name like 'SumAir%';
|
||||
update npc_types set attack_speed=0, atk=ceil(1.775*level), accuracy=ceil(1.775*level) where name like 'SumEarth%';
|
||||
update npc_types set attack_speed=0, atk=ceil(2.26*level), accuracy=ceil(2.26*level),gender=2,size=3 where name like 'BestialAid%';
|
||||
update npc_types set attack_speed=0, atk=ceil(2.26*level), accuracy=ceil(2.26*level),gender=2,size=3 where name like 'RagingServant%';
|
||||
|
||||
|
||||
update npc_types n
|
||||
set ac=
|
||||
ceil(case
|
||||
when level < 3 then level*2+2
|
||||
when level < 15 and level >=3 then level*3
|
||||
when id >= 200000 and id < 224000 then 200*.5+level
|
||||
else level * 4.1 end
|
||||
* (case when raid_target=1 then 1.4 else 1 end) + (case when raid_target=1 then level*1.4 else 0 end))
|
||||
+ 4*ifnull((select min(expansion)from zone where zoneidnumber=floor(n.id/1000)),5)
|
||||
,str=ceil((level * 4.1)*.75) + case when raid_target=1 then level else 0 end + 4*ifnull((select min(expansion)from zone where zoneidnumber=floor(n.id/1000)),5)
|
||||
,sta=ceil((level * 4.1)*.75) + case when raid_target=1 then level else 0 end + 4*ifnull((select min(expansion)from zone where zoneidnumber=floor(n.id/1000)),5)
|
||||
,agi=ceil((level * 4.1)*.75) + case when raid_target=1 then level else 0 end + 4*ifnull((select min(expansion)from zone where zoneidnumber=floor(n.id/1000)),5)
|
||||
,_int=ceil((level * 4.1)*.75) + case when raid_target=1 then level else 0 end + 4*ifnull((select min(expansion)from zone where zoneidnumber=floor(n.id/1000)),5)
|
||||
,dex=ceil((level * 4.1)*.75) + case when raid_target=1 then level else 0 end + 4*ifnull((select min(expansion)from zone where zoneidnumber=floor(n.id/1000)),5)
|
||||
,wis=ceil((level * 4.1)*.75) + case when raid_target=1 then level else 0 end + 4*ifnull((select min(expansion)from zone where zoneidnumber=floor(n.id/1000)),5)
|
||||
,cha=ceil((level * 4.1)*.75) + case when raid_target=1 then level else 0 end + 4*ifnull((select min(expansion)from zone where zoneidnumber=floor(n.id/1000)),5);
|
||||
@@ -0,0 +1,2 @@
|
||||
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Combat:LevelToStopDamageCaps', '0', '1 will effectively disable them, 20 should give basically same results as old incorrect system.');
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
INSERT INTO `rule_values` VALUES (1, 'Range:SongMessages', '75', 'The packet range in which song messages are sent');
|
||||
INSERT INTO `rule_values` VALUES (1, 'Range:Emote', '135', 'The packet range in which emote messages are sent');
|
||||
INSERT INTO `rule_values` VALUES (1, 'Range:BeginCast', '200', 'The packet range in which begin cast messages are sent');
|
||||
INSERT INTO `rule_values` VALUES (1, 'Range:Anims', '135', 'The packet range in which animations are sent');
|
||||
INSERT INTO `rule_values` VALUES (1, 'Range:DamageMessages', '50', 'The packet range in which damage messages are sent (non-crit)');
|
||||
INSERT INTO `rule_values` VALUES (1, 'Range:SpellMessages', '75', 'The packet range in which spell damage messages are sent');
|
||||
INSERT INTO `rule_values` VALUES (1, 'Range:Say', '135', 'The range that is required before /say or hail messages will work to an NPC');
|
||||
INSERT INTO `rule_values` VALUES (1, 'Range:SpellParticles', '135', 'The packet range in which spell particles are sent');
|
||||
INSERT INTO `rule_values` VALUES (1, 'Range:MobPositionUpdates', '600', 'The packet range in which mob position updates are sent');
|
||||
INSERT INTO `rule_values` VALUES (1, 'Range:CriticalDamage', '80', 'The packet range in which critical hit messages are sent');
|
||||
@@ -0,0 +1 @@
|
||||
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Mercs:MercsUsePathing', 'false', 'Mercs will use node pathing when moving');
|
||||
@@ -0,0 +1,15 @@
|
||||
alter table books add language int not null default 0;
|
||||
|
||||
drop table if exists reading_is_fundamental;
|
||||
|
||||
create table reading_is_fundamental
|
||||
(
|
||||
filename varchar(32),
|
||||
language int
|
||||
);
|
||||
|
||||
insert into reading_is_fundamental (select items.filename, items.booktype from items where items.filename != "" group by filename);
|
||||
|
||||
update books set books.language = (select language from reading_is_fundamental r where r.filename = books.name);
|
||||
|
||||
drop table reading_is_fundamental;
|
||||
@@ -0,0 +1,4 @@
|
||||
UPDATE `books` SET `language` = '0' WHERE `language` IS NULL;
|
||||
|
||||
ALTER TABLE `books` MODIFY COLUMN `language` INT NOT NULL DEFAULT '0';
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
ALTER TABLE `npc_spells_entries` MODIFY COLUMN `type` INT(10) UNSIGNED NOT NULL DEFAULT '0';
|
||||
@@ -0,0 +1,31 @@
|
||||
-- Delete any existing `bots_spells_entries` table
|
||||
DROP TABLE IF EXISTS `bots_spells_entries`;
|
||||
|
||||
-- Create new bot spells entries table (new table does not have spells_id_spellid constraint)
|
||||
CREATE TABLE `bot_spells_entries` (
|
||||
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`npc_spells_id` INT(11) NOT NULL DEFAULT '0',
|
||||
`spellid` SMALLINT(5) NOT NULL DEFAULT '0',
|
||||
`type` INT(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`minlevel` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`maxlevel` TINYINT(3) UNSIGNED NOT NULL DEFAULT '255',
|
||||
`manacost` SMALLINT(5) NOT NULL DEFAULT '-1',
|
||||
`recast_delay` INT(11) NOT NULL DEFAULT '-1',
|
||||
`priority` SMALLINT(5) NOT NULL DEFAULT '0',
|
||||
`resist_adjust` INT(11) NULL DEFAULT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
)
|
||||
COLLATE='latin1_swedish_ci'
|
||||
ENGINE=InnoDB
|
||||
AUTO_INCREMENT=1
|
||||
;
|
||||
|
||||
-- Copy bots spells into new table
|
||||
INSERT INTO `bot_spells_entries` (`npc_spells_id`, `spellid`, `type`, `minlevel`, `maxlevel`, `manacost`, `recast_delay`, `priority`, `resist_adjust`)
|
||||
SELECT `npc_spells_id`, `spellid`, `type`, `minlevel`, `maxlevel`, `manacost`, `recast_delay`, `priority`, `resist_adjust`
|
||||
FROM `npc_spells_entries` WHERE `npc_spells_id` >= '701' AND `npc_spells_id` <= '712';
|
||||
|
||||
-- Delete bot spells from old table
|
||||
DELETE FROM `npc_spells_entries` WHERE `npc_spells_id` >= '701' AND `npc_spells_id` <= '712';
|
||||
|
||||
-- Admins can remove this new table if they are 100% certain they will never use bots
|
||||
@@ -0,0 +1,19 @@
|
||||
-- Re-ordered entries according to actual class values and added melee types (for future expansion)
|
||||
DELETE FROM `npc_spells` WHERE `id` >= '701' AND `id` <= '712';
|
||||
|
||||
INSERT INTO `npc_spells` VALUES (3001, 'Warrior Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
INSERT INTO `npc_spells` VALUES (3002, 'Cleric Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
INSERT INTO `npc_spells` VALUES (3003, 'Paladin Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
INSERT INTO `npc_spells` VALUES (3004, 'Ranger Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
INSERT INTO `npc_spells` VALUES (3005, 'Shadowknight Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
INSERT INTO `npc_spells` VALUES (3006, 'Druid Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
INSERT INTO `npc_spells` VALUES (3007, 'Monk Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
INSERT INTO `npc_spells` VALUES (3008, 'Bard Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
INSERT INTO `npc_spells` VALUES (3009, 'Rogue Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
INSERT INTO `npc_spells` VALUES (3010, 'Shaman Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
INSERT INTO `npc_spells` VALUES (3011, 'Necromancer Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
INSERT INTO `npc_spells` VALUES (3012, 'Wizard Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
INSERT INTO `npc_spells` VALUES (3013, 'Magician Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
INSERT INTO `npc_spells` VALUES (3014, 'Enchanter Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
INSERT INTO `npc_spells` VALUES (3015, 'Beastlord Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
INSERT INTO `npc_spells` VALUES (3016, 'Berserker Bot', 0, -1, 3, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
@@ -0,0 +1,11 @@
|
||||
DROP TABLE IF EXISTS `inventory_version`;
|
||||
|
||||
CREATE TABLE `inventory_version` (
|
||||
`version` INT(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`step` INT(11) UNSIGNED NOT NULL DEFAULT '0'
|
||||
)
|
||||
COLLATE='latin1_swedish_ci'
|
||||
ENGINE=MyISAM
|
||||
;
|
||||
|
||||
INSERT INTO `inventory_version` VALUES (2, 0);
|
||||
@@ -0,0 +1,100 @@
|
||||
aa_ability
|
||||
aa_actions
|
||||
aa_effects
|
||||
aa_required_level_cost
|
||||
aa_ranks
|
||||
aa_rank_effects
|
||||
aa_rank_prereqs
|
||||
activities
|
||||
adventure_template
|
||||
adventure_template_entry
|
||||
adventure_template_entry_flavor
|
||||
altadv_vars
|
||||
alternate_currency
|
||||
base_data
|
||||
blocked_spells
|
||||
books
|
||||
char_create_combinations
|
||||
char_create_point_allocations
|
||||
class_skill
|
||||
damageshieldtypes
|
||||
doors
|
||||
faction_list
|
||||
faction_list_mod
|
||||
fear_hints
|
||||
fishing
|
||||
forage
|
||||
goallists
|
||||
graveyard
|
||||
grid
|
||||
grid_entries
|
||||
ground_spawns
|
||||
horses
|
||||
instance_list
|
||||
items
|
||||
ldon_trap_templates
|
||||
ldon_trap_entries
|
||||
level_exp_mods
|
||||
lootdrop
|
||||
lootdrop_entries
|
||||
loottable
|
||||
loottable_entries
|
||||
merc_armorinfo
|
||||
merc_weaponinfo
|
||||
merc_stats
|
||||
merc_merchant_entries
|
||||
merc_merchant_template_entries
|
||||
merc_merchant_templates
|
||||
merc_stance_entries
|
||||
merc_templates
|
||||
merc_npc_types
|
||||
merc_name_types
|
||||
merc_subtypes
|
||||
merc_types
|
||||
merc_spell_list_entries
|
||||
merc_spell_lists
|
||||
merc_buffs
|
||||
mercs
|
||||
merc_inventory
|
||||
merchantlist
|
||||
npc_emotes
|
||||
npc_faction
|
||||
npc_faction_entries
|
||||
npc_spells
|
||||
npc_spells_entries
|
||||
npc_spells_effects
|
||||
npc_spells_effects_entries
|
||||
npc_types
|
||||
npc_types_metadata
|
||||
npc_types_tint
|
||||
object
|
||||
pets
|
||||
pets_equipmentset
|
||||
pets_equipmentset_entries
|
||||
proximities
|
||||
races
|
||||
saylink
|
||||
skill_caps
|
||||
spawn2
|
||||
spawn_conditions
|
||||
spawn_condition_values
|
||||
spawn_events
|
||||
spawnentry
|
||||
spawngroup
|
||||
spells_new
|
||||
start_zones
|
||||
starting_items
|
||||
tasks
|
||||
tasksets
|
||||
titles
|
||||
tradeskill_recipe
|
||||
tradeskill_recipe_entries
|
||||
traps
|
||||
tribute_levels
|
||||
tributes
|
||||
veteran_reward_templates
|
||||
zone
|
||||
zone_points
|
||||
zone_server
|
||||
zone_state_dump
|
||||
zoneserver_auth
|
||||
@@ -0,0 +1,92 @@
|
||||
aa_timers
|
||||
account
|
||||
account_flags
|
||||
account_ip
|
||||
account_rewards
|
||||
adventure_details
|
||||
adventure_members
|
||||
adventure_stats
|
||||
Banned_IPs
|
||||
bugs
|
||||
buyer
|
||||
char_recipe_list
|
||||
character_data
|
||||
character_currency
|
||||
character_alternate_abilities
|
||||
character_bind
|
||||
character_corpses
|
||||
character_corpse_items
|
||||
character_languages
|
||||
character_lookup
|
||||
character_skills
|
||||
character_spells
|
||||
character_memmed_spells
|
||||
character_disciplines
|
||||
character_material
|
||||
character_tribute
|
||||
character_bandolier
|
||||
character_potionbelt
|
||||
character_inspect_messages
|
||||
character_leadership_abilities
|
||||
character_activities
|
||||
character_alt_currency
|
||||
character_buffs
|
||||
character_enabledtasks
|
||||
character_pet_buffs
|
||||
character_pet_info
|
||||
character_pet_inventory
|
||||
character_tasks
|
||||
chatchannels
|
||||
completed_tasks
|
||||
discovered_items
|
||||
eventlog
|
||||
faction_values
|
||||
friends
|
||||
gm_ips
|
||||
group_id
|
||||
group_leaders
|
||||
guilds
|
||||
guild_bank
|
||||
guild_ranks
|
||||
guild_relations
|
||||
guild_members
|
||||
hackers
|
||||
instance_list_player
|
||||
inventory
|
||||
item_tick
|
||||
keyring
|
||||
launcher_zones
|
||||
lfguild
|
||||
mail
|
||||
merchantlist_temp
|
||||
name_filter
|
||||
object_contents
|
||||
petitions
|
||||
player_titlesets
|
||||
qs_player_move_record
|
||||
qs_player_move_record_entries
|
||||
qs_player_npc_kill_record
|
||||
qs_player_npc_kill_record_entries
|
||||
qs_player_speech
|
||||
qs_player_trade_record
|
||||
qs_player_trade_record_entries
|
||||
qs_merchant_transaction_record
|
||||
qs_merchant_transaction_record_entries
|
||||
qs_player_delete_record
|
||||
qs_player_delete_record_entries
|
||||
qs_player_handin_record
|
||||
qs_player_handin_record_entries
|
||||
qs_player_aa_rate_hourly
|
||||
qs_player_events
|
||||
quest_globals
|
||||
raid_details
|
||||
raid_leaders
|
||||
raid_members
|
||||
reports
|
||||
respawn_times
|
||||
sharedbank
|
||||
spell_globals
|
||||
timers
|
||||
trader
|
||||
trader_audit
|
||||
zone_flags
|
||||
+14
-6
@@ -1022,6 +1022,12 @@ bool Client::HandlePacket(const EQApplicationPacket *app) {
|
||||
eqs->Close();
|
||||
return true;
|
||||
}
|
||||
case OP_WorldLogout:
|
||||
{
|
||||
eqs->Close();
|
||||
cle->SetOnline(CLE_Status_Offline); //allows this player to log in again without an ip restriction.
|
||||
return false;
|
||||
}
|
||||
case OP_ZoneChange:
|
||||
{
|
||||
// HoT sends this to world while zoning and wants it echoed back.
|
||||
@@ -1552,12 +1558,14 @@ bool Client::OPCharCreate(char *name, CharCreate_Struct *cc)
|
||||
database.GetSafePoints(pp.zone_id, 0, &pp.x, &pp.y, &pp.z);
|
||||
}
|
||||
|
||||
/* Will either be the same as home or tutorial */
|
||||
pp.binds[0].zoneId = pp.zone_id;
|
||||
pp.binds[0].x = pp.x;
|
||||
pp.binds[0].y = pp.y;
|
||||
pp.binds[0].z = pp.z;
|
||||
pp.binds[0].heading = pp.heading;
|
||||
/* Will either be the same as home or tutorial if enabled. */
|
||||
if(RuleB(World, StartZoneSameAsBindOnCreation)) {
|
||||
pp.binds[0].zoneId = pp.zone_id;
|
||||
pp.binds[0].x = pp.x;
|
||||
pp.binds[0].y = pp.y;
|
||||
pp.binds[0].z = pp.z;
|
||||
pp.binds[0].heading = pp.heading;
|
||||
}
|
||||
|
||||
Log.Out(Logs::Detail, Logs::World_Server,"Current location: %s (%d) %0.2f, %0.2f, %0.2f, %0.2f",
|
||||
database.GetZoneName(pp.zone_id), pp.zone_id, pp.x, pp.y, pp.z, pp.heading);
|
||||
|
||||
+18
-1
@@ -214,6 +214,24 @@ void ClientList::GetCLEIP(uint32 iIP) {
|
||||
}
|
||||
}
|
||||
|
||||
uint32 ClientList::GetCLEIPCount(uint32 iIP) {
|
||||
ClientListEntry* countCLEIPs = 0;
|
||||
LinkedListIterator<ClientListEntry*> iterator(clientlist);
|
||||
|
||||
int IPInstances = 0;
|
||||
iterator.Reset();
|
||||
|
||||
while (iterator.MoreElements()) {
|
||||
countCLEIPs = iterator.GetData();
|
||||
if ((countCLEIPs->GetIP() == iIP) && ((countCLEIPs->Admin() < (RuleI(World, ExemptMaxClientsStatus))) || (RuleI(World, ExemptMaxClientsStatus) < 0)) && countCLEIPs->Online() >= CLE_Status_Online) { // If the IP matches, and the connection admin status is below the exempt status, or exempt status is less than 0 (no-one is exempt)
|
||||
IPInstances++; // Increment the occurences of this IP address
|
||||
}
|
||||
iterator.Advance();
|
||||
}
|
||||
|
||||
return IPInstances;
|
||||
}
|
||||
|
||||
void ClientList::DisconnectByIP(uint32 iIP) {
|
||||
ClientListEntry* countCLEIPs = 0;
|
||||
LinkedListIterator<ClientListEntry*> iterator(clientlist);
|
||||
@@ -252,7 +270,6 @@ ClientListEntry* ClientList::FindCharacter(const char* name) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
ClientListEntry* ClientList::FindCLEByAccountID(uint32 iAccID) {
|
||||
LinkedListIterator<ClientListEntry*> iterator(clientlist);
|
||||
|
||||
|
||||
@@ -56,6 +56,7 @@ public:
|
||||
ClientListEntry* FindCLEByCharacterID(uint32 iCharID);
|
||||
ClientListEntry* GetCLE(uint32 iID);
|
||||
void GetCLEIP(uint32 iIP);
|
||||
uint32 GetCLEIPCount(uint32 iLSAccountID);
|
||||
void DisconnectByIP(uint32 iIP);
|
||||
void EnforceSessionLimit(uint32 iLSAccountID);
|
||||
void CLCheckStale();
|
||||
|
||||
+21
-3
@@ -68,7 +68,7 @@ void CatchSignal(int sig_num);
|
||||
Console::Console(EmuTCPConnection* itcpc)
|
||||
: WorldTCPConnection(),
|
||||
timeout_timer(RuleI(Console, SessionTimeOut)),
|
||||
prompt_timer(1000)
|
||||
prompt_timer(1)
|
||||
{
|
||||
tcpc = itcpc;
|
||||
tcpc->SetEcho(true);
|
||||
@@ -224,9 +224,27 @@ bool Console::Process() {
|
||||
}
|
||||
//if we have not gotten the special markers after this timer, send login prompt
|
||||
if(prompt_timer.Check()) {
|
||||
struct in_addr in;
|
||||
in.s_addr = GetIP();
|
||||
|
||||
std::string connecting_ip = inet_ntoa(in);
|
||||
|
||||
SendMessage(2, StringFormat("Establishing connection from IP: %s Port: %d", inet_ntoa(in), GetPort()).c_str());
|
||||
|
||||
if (connecting_ip.find("127.0.0.1") != std::string::npos) {
|
||||
SendMessage(2, StringFormat("Connecting established from local host, auto assuming admin").c_str());
|
||||
state = CONSOLE_STATE_CONNECTED;
|
||||
tcpc->SetEcho(false);
|
||||
admin = 255;
|
||||
SendPrompt();
|
||||
}
|
||||
else {
|
||||
if (tcpc->GetMode() == EmuTCPConnection::modeConsole)
|
||||
tcpc->Send((const uchar*) "Username: ", strlen("Username: "));
|
||||
}
|
||||
|
||||
prompt_timer.Disable();
|
||||
if(tcpc->GetMode() == EmuTCPConnection::modeConsole)
|
||||
tcpc->Send((const uchar*) "Username: ", strlen("Username: "));
|
||||
|
||||
}
|
||||
|
||||
if (timeout_timer.Check()) {
|
||||
|
||||
@@ -134,11 +134,26 @@ bool LoginServer::Process() {
|
||||
if( (int32)numplayers >= x && x != -1 && x != 255 && status < 80)
|
||||
utwrs->response = -3;
|
||||
|
||||
|
||||
if (pack->size == sizeof(UsertoWorldRequest_Struct))
|
||||
{
|
||||
uint32 decimalIP = inet_addr(utwr->IPAddr);
|
||||
|
||||
if (RuleB(World, MaxClientsSimplifiedLogic)) {
|
||||
if (client_list.GetCLEIPCount(decimalIP) >= (RuleI(World, MaxClientsPerIP))) {
|
||||
if ((status < (RuleI(World, ExemptMaxClientsStatus))) || (RuleI(World, ExemptMaxClientsStatus) < 0)) {
|
||||
utwrs->response = -4;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(status == -1)
|
||||
utwrs->response = -1;
|
||||
if(status == -2)
|
||||
utwrs->response = -2;
|
||||
|
||||
|
||||
utwrs->worldid = utwr->worldid;
|
||||
SendPacket(outpack);
|
||||
delete outpack;
|
||||
|
||||
+4
-1
@@ -353,7 +353,7 @@ bool WorldDatabase::GetStartZone(PlayerProfile_Struct* in_pp, CharCreate_Struct*
|
||||
in_pp->x = in_pp->y = in_pp->z = in_pp->heading = in_pp->zone_id = 0;
|
||||
in_pp->binds[0].x = in_pp->binds[0].y = in_pp->binds[0].z = in_pp->binds[0].zoneId = in_pp->binds[0].instance_id = 0;
|
||||
// see if we have an entry for start_zone. We can support both titanium & SOF+ by having two entries per class/race/deity combo with different zone_ids
|
||||
std::string query = StringFormat("SELECT x, y, z, heading, start_zone, bind_id FROM start_zones WHERE zone_id = %i "
|
||||
std::string query = StringFormat("SELECT x, y, z, heading, start_zone, bind_id, bind_x, bind_y, bind_z FROM start_zones WHERE zone_id = %i "
|
||||
"AND player_class = %i AND player_deity = %i AND player_race = %i",
|
||||
in_cc->start_zone, in_cc->class_, in_cc->deity, in_cc->race);
|
||||
auto results = QueryDatabase(query);
|
||||
@@ -376,6 +376,9 @@ bool WorldDatabase::GetStartZone(PlayerProfile_Struct* in_pp, CharCreate_Struct*
|
||||
in_pp->heading = atof(row[3]);
|
||||
in_pp->zone_id = atoi(row[4]);
|
||||
in_pp->binds[0].zoneId = atoi(row[5]);
|
||||
in_pp->binds[0].x = atof(row[6]);
|
||||
in_pp->binds[0].y = atof(row[7]);
|
||||
in_pp->binds[0].z = atof(row[8]);
|
||||
}
|
||||
|
||||
if(in_pp->x == 0 && in_pp->y == 0 && in_pp->z == 0)
|
||||
|
||||
@@ -4,6 +4,7 @@ SET(zone_sources
|
||||
aa.cpp
|
||||
aa_ability.cpp
|
||||
aggro.cpp
|
||||
aggromanager.cpp
|
||||
attack.cpp
|
||||
beacon.cpp
|
||||
bonuses.cpp
|
||||
@@ -122,6 +123,7 @@ SET(zone_sources
|
||||
water_map_v2.cpp
|
||||
waypoints.cpp
|
||||
worldserver.cpp
|
||||
xtargetautohaters.cpp
|
||||
zone.cpp
|
||||
zone_config.cpp
|
||||
zonedb.cpp
|
||||
@@ -131,6 +133,7 @@ SET(zone_sources
|
||||
SET(zone_headers
|
||||
aa.h
|
||||
aa_ability.h
|
||||
aggromanager.h
|
||||
basic_functions.h
|
||||
beacon.h
|
||||
bot.h
|
||||
@@ -215,6 +218,7 @@ SET(zone_headers
|
||||
water_map_v1.h
|
||||
water_map_v2.h
|
||||
worldserver.h
|
||||
xtargetautohaters.h
|
||||
zone.h
|
||||
zone_config.h
|
||||
zonedb.h
|
||||
|
||||
@@ -42,6 +42,10 @@ void Mob::TemporaryPets(uint16 spell_id, Mob *targ, const char *name_override, u
|
||||
|
||||
//Dook- swarms and wards
|
||||
|
||||
// do nothing if it's a corpse
|
||||
if (targ != nullptr && targ->IsCorpse())
|
||||
return;
|
||||
|
||||
PetRecord record;
|
||||
if(!database.GetPetEntry(spells[spell_id].teleport_zone, &record))
|
||||
{
|
||||
|
||||
+7
-7
@@ -158,7 +158,7 @@ void NPC::DescribeAggro(Client *towho, Mob *mob, bool verbose) {
|
||||
|
||||
if (RuleB(Aggro, UseLevelAggro))
|
||||
{
|
||||
if (GetLevel() < 18 && mob->GetLevelCon(GetLevel()) == CON_GREEN && GetBodyType() != 3)
|
||||
if (GetLevel() < 18 && mob->GetLevelCon(GetLevel()) == CON_GRAY && GetBodyType() != 3)
|
||||
{
|
||||
towho->Message(0, "...%s is red to me (basically)", mob->GetName(), dist2, iAggroRange2);
|
||||
return;
|
||||
@@ -166,7 +166,7 @@ void NPC::DescribeAggro(Client *towho, Mob *mob, bool verbose) {
|
||||
}
|
||||
else
|
||||
{
|
||||
if(GetINT() > RuleI(Aggro, IntAggroThreshold) && mob->GetLevelCon(GetLevel()) == CON_GREEN ) {
|
||||
if(GetINT() > RuleI(Aggro, IntAggroThreshold) && mob->GetLevelCon(GetLevel()) == CON_GRAY ) {
|
||||
towho->Message(0, "...%s is red to me (basically)", mob->GetName(),
|
||||
dist2, iAggroRange2);
|
||||
return;
|
||||
@@ -253,7 +253,7 @@ bool Mob::CheckWillAggro(Mob *mob) {
|
||||
//sometimes if a client has some lag while zoning into a dangerous place while either invis or a GM
|
||||
//they will aggro mobs even though it's supposed to be impossible, to lets make sure we've finished connecting
|
||||
if (mob->IsClient()) {
|
||||
if (!mob->CastToClient()->ClientFinishedLoading() || mob->CastToClient()->IsHoveringForRespawn())
|
||||
if (!mob->CastToClient()->ClientFinishedLoading() || mob->CastToClient()->IsHoveringForRespawn() || mob->CastToClient()->zoning)
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -339,7 +339,7 @@ bool Mob::CheckWillAggro(Mob *mob) {
|
||||
( GetLevel() >= 18 )
|
||||
||(GetBodyType() == 3)
|
||||
||( mob->IsClient() && mob->CastToClient()->IsSitting() )
|
||||
||( mob->GetLevelCon(GetLevel()) != CON_GREEN )
|
||||
||( mob->GetLevelCon(GetLevel()) != CON_GRAY)
|
||||
|
||||
)
|
||||
&&
|
||||
@@ -372,7 +372,7 @@ bool Mob::CheckWillAggro(Mob *mob) {
|
||||
(
|
||||
( GetINT() <= RuleI(Aggro, IntAggroThreshold) )
|
||||
||( mob->IsClient() && mob->CastToClient()->IsSitting() )
|
||||
||( mob->GetLevelCon(GetLevel()) != CON_GREEN )
|
||||
||( mob->GetLevelCon(GetLevel()) != CON_GRAY)
|
||||
|
||||
)
|
||||
&&
|
||||
@@ -449,7 +449,7 @@ int EntityList::GetHatedCount(Mob *attacker, Mob *exclude)
|
||||
if (mob->IsFeared() || mob->IsMezzed())
|
||||
continue;
|
||||
|
||||
if (attacker->GetLevelCon(mob->GetLevel()) == CON_GREEN)
|
||||
if (attacker->GetLevelCon(mob->GetLevel()) == CON_GRAY)
|
||||
continue;
|
||||
|
||||
if (!mob->CheckAggro(attacker))
|
||||
@@ -508,7 +508,7 @@ void EntityList::AIYellForHelp(Mob* sender, Mob* attacker) {
|
||||
{
|
||||
//if they are in range, make sure we are not green...
|
||||
//then jump in if they are our friend
|
||||
if(mob->GetLevel() >= 50 || attacker->GetLevelCon(mob->GetLevel()) != CON_GREEN)
|
||||
if(mob->GetLevel() >= 50 || attacker->GetLevelCon(mob->GetLevel()) != CON_GRAY)
|
||||
{
|
||||
bool useprimfaction = false;
|
||||
if(mob->GetPrimaryFaction() == sender->CastToNPC()->GetPrimaryFaction())
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
#include "aggromanager.h"
|
||||
|
||||
AggroMeter::AggroMeter() : lock_id(0), target_id(0), secondary_id(0), lock_changed(false)
|
||||
{
|
||||
for (int i = 0; i < AT_Max; ++i) {
|
||||
data[i].type = i;
|
||||
data[i].pct = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
#ifndef AGGROMANAGER_H
|
||||
#define AGGROMANAGER_H
|
||||
|
||||
#include "../common/types.h"
|
||||
#include <assert.h>
|
||||
#include <cstddef>
|
||||
|
||||
class AggroMeter
|
||||
{
|
||||
public:
|
||||
enum AggroTypes {
|
||||
AT_Player,
|
||||
AT_Secondary,
|
||||
AT_Group1,
|
||||
AT_Group2,
|
||||
AT_Group3,
|
||||
AT_Group4,
|
||||
AT_Group5,
|
||||
AT_XTarget1,
|
||||
AT_XTarget2,
|
||||
AT_XTarget3,
|
||||
AT_XTarget4,
|
||||
AT_XTarget5,
|
||||
AT_XTarget6,
|
||||
AT_XTarget7,
|
||||
AT_XTarget8,
|
||||
AT_XTarget9,
|
||||
AT_XTarget10,
|
||||
AT_XTarget11,
|
||||
AT_XTarget12,
|
||||
AT_XTarget13,
|
||||
AT_XTarget14,
|
||||
AT_XTarget15,
|
||||
AT_XTarget16,
|
||||
AT_XTarget17,
|
||||
AT_XTarget18,
|
||||
AT_XTarget19,
|
||||
AT_XTarget20,
|
||||
AT_Max
|
||||
};
|
||||
|
||||
private:
|
||||
struct AggroData {
|
||||
int16 type;
|
||||
int16 pct;
|
||||
};
|
||||
|
||||
AggroData data[AT_Max];
|
||||
int lock_id; // we set this
|
||||
int target_id; // current target or if PC targeted, their Target
|
||||
// so secondary depends on if we have aggro or not
|
||||
// When we are the current target, this will be the 2nd person on list
|
||||
// When we are not tanking, this will be the current tank
|
||||
int secondary_id;
|
||||
|
||||
// so we need some easy way to detect the client changing but still delaying the packet
|
||||
bool lock_changed;
|
||||
public:
|
||||
AggroMeter();
|
||||
~AggroMeter() {}
|
||||
|
||||
inline void set_lock_id(int in) { lock_id = in; lock_changed = true; }
|
||||
inline bool update_lock() { bool ret = lock_changed; lock_changed = false; return ret; }
|
||||
inline void set_target_id(int in) { target_id = in; }
|
||||
inline void set_secondary_id(int in) { secondary_id = in; }
|
||||
// returns true when changed
|
||||
inline bool set_pct(AggroTypes t, int pct) { assert(t >= AT_Player && t < AT_Max); if (data[t].pct == pct) return false; data[t].pct = pct; return true; }
|
||||
|
||||
inline int get_lock_id() const { return lock_id; }
|
||||
inline int get_target_id() const { return target_id; }
|
||||
inline int get_secondary_id() const { return secondary_id; }
|
||||
inline int get_pct(AggroTypes t) const { assert(t >= AT_Player && t < AT_Max); return data[t].pct; }
|
||||
// the ID of the spawn for player entry depends on lock_id
|
||||
inline int get_player_aggro_id() const { return lock_id ? lock_id : target_id; }
|
||||
// fuck it, lets just use a buffer the size of the largest to work with
|
||||
const inline size_t max_packet_size() const { return sizeof(uint8) + sizeof(uint32) + sizeof(uint8) + (sizeof(uint8) + sizeof(uint16)) * AT_Max; }
|
||||
};
|
||||
|
||||
|
||||
#endif /* !AGGROMANAGER_H */
|
||||
+1356
-885
File diff suppressed because it is too large
Load Diff
+2
-2
@@ -35,9 +35,9 @@ public:
|
||||
|
||||
//abstract virtual function implementations requird by base abstract class
|
||||
virtual bool Death(Mob* killerMob, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill) { return true; }
|
||||
virtual void Damage(Mob* from, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false, int special = 0) { return; }
|
||||
virtual void Damage(Mob* from, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false, eSpecialAttacks special = eSpecialAttacks::None) { return; }
|
||||
virtual bool Attack(Mob* other, int Hand = EQEmu::inventory::slotPrimary, bool FromRiposte = false, bool IsStrikethrough = false, bool IsFromSpell = false,
|
||||
ExtraAttackOptions *opts = nullptr, int special = 0) { return false; }
|
||||
ExtraAttackOptions *opts = nullptr) { return false; }
|
||||
virtual bool HasRaid() { return false; }
|
||||
virtual bool HasGroup() { return false; }
|
||||
virtual Raid* GetRaid() { return 0; }
|
||||
|
||||
+35
-20
@@ -46,6 +46,7 @@ void Mob::CalcBonuses()
|
||||
CalcMaxHP();
|
||||
CalcMaxMana();
|
||||
SetAttackTimer();
|
||||
CalcAC();
|
||||
|
||||
rooted = FindType(SE_Root);
|
||||
}
|
||||
@@ -669,6 +670,10 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
|
||||
}
|
||||
|
||||
switch (effect) {
|
||||
case SE_ACv2:
|
||||
case SE_ArmorClass:
|
||||
newbon->AC += base1;
|
||||
break;
|
||||
// Note: AA effects that use accuracy are skill limited, while spell effect is not.
|
||||
case SE_Accuracy:
|
||||
// Bad data or unsupported new skill
|
||||
@@ -1308,8 +1313,9 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
|
||||
}
|
||||
|
||||
case SE_HeadShotLevel: {
|
||||
if (newbon->HSLevel < base1)
|
||||
newbon->HSLevel = base1;
|
||||
if (newbon->HSLevel[0] < base1)
|
||||
newbon->HSLevel[0] = base1;
|
||||
newbon->HSLevel[1] = base2;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1322,8 +1328,10 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
|
||||
}
|
||||
|
||||
case SE_AssassinateLevel: {
|
||||
if (newbon->AssassinateLevel < base1)
|
||||
newbon->AssassinateLevel = base1;
|
||||
if (newbon->AssassinateLevel[0] < base1) {
|
||||
newbon->AssassinateLevel[0] = base1;
|
||||
newbon->AssassinateLevel[1] = base2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1381,7 +1389,7 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
|
||||
}
|
||||
|
||||
case SE_MeleeMitigation:
|
||||
newbon->MeleeMitigationEffect -= base1;
|
||||
newbon->MeleeMitigationEffect += base1;
|
||||
break;
|
||||
|
||||
case SE_ATK:
|
||||
@@ -1527,9 +1535,6 @@ void Mob::CalcSpellBonuses(StatBonuses* newbon)
|
||||
}
|
||||
}
|
||||
|
||||
// THIS IS WRONG, leaving for now
|
||||
//this prolly suffer from roundoff error slightly...
|
||||
newbon->AC = newbon->AC * 10 / 34; //ratio determined impirically from client.
|
||||
if (GetClass() == BARD)
|
||||
newbon->ManaRegen = 0; // Bards do not get mana regen from spells.
|
||||
}
|
||||
@@ -1927,8 +1932,8 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
|
||||
break;
|
||||
|
||||
case SE_MeleeMitigation:
|
||||
//for some reason... this value is negative for increased mitigation
|
||||
new_bonus->MeleeMitigationEffect -= effect_value;
|
||||
// This value is negative because it counteracts another SPA :P
|
||||
new_bonus->MeleeMitigationEffect += effect_value;
|
||||
break;
|
||||
|
||||
case SE_CriticalHitChance:
|
||||
@@ -3024,8 +3029,10 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
|
||||
|
||||
case SE_HeadShotLevel:
|
||||
{
|
||||
if(new_bonus->HSLevel < effect_value)
|
||||
new_bonus->HSLevel = effect_value;
|
||||
if(new_bonus->HSLevel[0] < effect_value) {
|
||||
new_bonus->HSLevel[0] = effect_value;
|
||||
new_bonus->HSLevel[1] = base2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -3040,8 +3047,10 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
|
||||
|
||||
case SE_AssassinateLevel:
|
||||
{
|
||||
if(new_bonus->AssassinateLevel < effect_value)
|
||||
new_bonus->AssassinateLevel = effect_value;
|
||||
if(new_bonus->AssassinateLevel[0] < effect_value) {
|
||||
new_bonus->AssassinateLevel[0] = effect_value;
|
||||
new_bonus->AssassinateLevel[1] = base2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -4647,9 +4656,12 @@ void Mob::NegateSpellsBonuses(uint16 spell_id)
|
||||
break;
|
||||
|
||||
case SE_HeadShotLevel:
|
||||
spellbonuses.HSLevel = effect_value;
|
||||
aabonuses.HSLevel = effect_value;
|
||||
itembonuses.HSLevel = effect_value;
|
||||
spellbonuses.HSLevel[0] = effect_value;
|
||||
aabonuses.HSLevel[0] = effect_value;
|
||||
itembonuses.HSLevel[0] = effect_value;
|
||||
spellbonuses.HSLevel[1] = effect_value;
|
||||
aabonuses.HSLevel[1] = effect_value;
|
||||
itembonuses.HSLevel[1] = effect_value;
|
||||
break;
|
||||
|
||||
case SE_Assassinate:
|
||||
@@ -4662,9 +4674,12 @@ void Mob::NegateSpellsBonuses(uint16 spell_id)
|
||||
break;
|
||||
|
||||
case SE_AssassinateLevel:
|
||||
spellbonuses.AssassinateLevel = effect_value;
|
||||
aabonuses.AssassinateLevel = effect_value;
|
||||
itembonuses.AssassinateLevel = effect_value;
|
||||
spellbonuses.AssassinateLevel[0] = effect_value;
|
||||
aabonuses.AssassinateLevel[0] = effect_value;
|
||||
itembonuses.AssassinateLevel[0] = effect_value;
|
||||
spellbonuses.AssassinateLevel[1] = effect_value;
|
||||
aabonuses.AssassinateLevel[1] = effect_value;
|
||||
itembonuses.AssassinateLevel[1] = effect_value;
|
||||
break;
|
||||
|
||||
case SE_FinishingBlow:
|
||||
|
||||
+1087
-885
File diff suppressed because it is too large
Load Diff
+98
-29
@@ -38,7 +38,9 @@
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#define BOT_DEFAULT_FOLLOW_DISTANCE 184
|
||||
#define BOT_FOLLOW_DISTANCE_DEFAULT 184 // as DSq value (~13.565 units)
|
||||
#define BOT_FOLLOW_DISTANCE_DEFAULT_MAX 2500 // as DSq value (50 units)
|
||||
#define BOT_FOLLOW_DISTANCE_WALK 1000 // as DSq value (~31.623 units)
|
||||
|
||||
extern WorldServer worldserver;
|
||||
|
||||
@@ -47,8 +49,6 @@ const int MaxSpellTimer = 15;
|
||||
const int MaxDisciplineTimer = 10;
|
||||
const int DisciplineReuseStart = MaxSpellTimer + 1;
|
||||
const int MaxTimer = MaxSpellTimer + MaxDisciplineTimer;
|
||||
const int MaxStances = 7;
|
||||
const int MaxSpellTypes = 16;
|
||||
|
||||
enum BotStanceType {
|
||||
BotStancePassive,
|
||||
@@ -58,7 +58,8 @@ enum BotStanceType {
|
||||
BotStanceAggressive,
|
||||
BotStanceBurn,
|
||||
BotStanceBurnAE,
|
||||
BotStanceUnknown
|
||||
BotStanceUnknown,
|
||||
MaxStances = BotStanceUnknown
|
||||
};
|
||||
|
||||
#define BOT_STANCE_COUNT 8
|
||||
@@ -125,9 +126,55 @@ enum SpellTypeIndex {
|
||||
SpellType_CharmIndex,
|
||||
SpellType_SlowIndex,
|
||||
SpellType_DebuffIndex,
|
||||
SpellType_CureIndex
|
||||
SpellType_CureIndex,
|
||||
SpellType_ResurrectIndex,
|
||||
SpellType_HateReduxIndex,
|
||||
SpellType_InCombatBuffSongIndex,
|
||||
SpellType_OutOfCombatBuffSongIndex,
|
||||
SpellType_PreCombatBuffIndex,
|
||||
SpellType_PreCombatBuffSongIndex,
|
||||
MaxSpellTypes
|
||||
};
|
||||
|
||||
// nHSND negative Healer/Slower/Nuker/Doter
|
||||
// pH positive Healer
|
||||
// pS positive Slower
|
||||
// pHS positive Healer/Slower
|
||||
// pN positive Nuker
|
||||
// pHN positive Healer/Nuker
|
||||
// pSN positive Slower/Nuker
|
||||
// pHSN positive Healer/Slower/Nuker
|
||||
// pD positive Doter
|
||||
// pHD positive Healer/Doter
|
||||
// pSD positive Slower/Doter
|
||||
// pHSD positive Healer/Slower/Doter
|
||||
// pND positive Nuker/Doter
|
||||
// pHND positive Healer/Nuker/Doter
|
||||
// pSND positive Slower/Nuker/Doter
|
||||
// pHSND positive Healer/Slower/Nuker/Doter
|
||||
// cntHSND count Healer/Slower/Nuker/Doter
|
||||
enum BotCastingChanceConditional : uint8
|
||||
{
|
||||
nHSND = 0,
|
||||
pH,
|
||||
pS,
|
||||
pHS,
|
||||
pN,
|
||||
pHN,
|
||||
pSN,
|
||||
pHSN,
|
||||
pD,
|
||||
pHD,
|
||||
pSD,
|
||||
pHSD,
|
||||
pND,
|
||||
pHND,
|
||||
pSND,
|
||||
pHSND,
|
||||
cntHSND = 16
|
||||
};
|
||||
|
||||
|
||||
class Bot : public NPC {
|
||||
friend class Mob;
|
||||
public:
|
||||
@@ -206,9 +253,9 @@ public:
|
||||
|
||||
//abstract virtual function implementations requird by base abstract class
|
||||
virtual bool Death(Mob* killerMob, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill);
|
||||
virtual void Damage(Mob* from, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false, int special = 0);
|
||||
virtual void Damage(Mob* from, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false, eSpecialAttacks special = eSpecialAttacks::None);
|
||||
virtual bool Attack(Mob* other, int Hand = EQEmu::inventory::slotPrimary, bool FromRiposte = false, bool IsStrikethrough = false, bool IsFromSpell = false,
|
||||
ExtraAttackOptions *opts = nullptr, int special = 0);
|
||||
ExtraAttackOptions *opts = nullptr);
|
||||
virtual bool HasRaid() { return (GetRaid() ? true : false); }
|
||||
virtual bool HasGroup() { return (GetGroup() ? true : false); }
|
||||
virtual Raid* GetRaid() { return entity_list.GetRaidByMob(this); }
|
||||
@@ -235,11 +282,11 @@ public:
|
||||
virtual void Depop();
|
||||
void CalcBotStats(bool showtext = true);
|
||||
uint16 BotGetSpells(int spellslot) { return AIspells[spellslot].spellid; }
|
||||
uint16 BotGetSpellType(int spellslot) { return AIspells[spellslot].type; }
|
||||
uint32 BotGetSpellType(int spellslot) { return AIspells[spellslot].type; }
|
||||
uint16 BotGetSpellPriority(int spellslot) { return AIspells[spellslot].priority; }
|
||||
virtual float GetProcChances(float ProcBonus, uint16 hand);
|
||||
virtual int GetHandToHandDamage(void);
|
||||
virtual bool TryFinishingBlow(Mob *defender, EQEmu::skills::SkillType skillinuse);
|
||||
virtual bool TryFinishingBlow(Mob *defender, int &damage);
|
||||
virtual void DoRiposte(Mob* defender);
|
||||
inline virtual int32 GetATK() const { return ATK + itembonuses.ATK + spellbonuses.ATK + ((GetSTR() + GetSkill(EQEmu::skills::SkillOffense)) * 9 / 10); }
|
||||
inline virtual int32 GetATKBonus() const { return itembonuses.ATK + spellbonuses.ATK; }
|
||||
@@ -248,13 +295,12 @@ public:
|
||||
uint16 GetPrimarySkillValue();
|
||||
uint16 MaxSkill(EQEmu::skills::SkillType skillid, uint16 class_, uint16 level) const;
|
||||
inline uint16 MaxSkill(EQEmu::skills::SkillType skillid) const { return MaxSkill(skillid, GetClass(), GetLevel()); }
|
||||
virtual int GetBaseSkillDamage(EQEmu::skills::SkillType skill, Mob *target = nullptr);
|
||||
virtual void DoSpecialAttackDamage(Mob *who, EQEmu::skills::SkillType skill, int32 max_damage, int32 min_damage = 1, int32 hate_override = -1, int ReuseTime = 10, bool HitChance = false);
|
||||
virtual void TryBackstab(Mob *other,int ReuseTime = 10);
|
||||
virtual void RogueBackstab(Mob* other, bool min_damage = false, int ReuseTime = 10);
|
||||
virtual void RogueAssassinate(Mob* other);
|
||||
virtual void DoClassAttacks(Mob *target, bool IsRiposte=false);
|
||||
virtual bool TryHeadShot(Mob* defender, EQEmu::skills::SkillType skillInUse);
|
||||
virtual void DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, EQEmu::skills::SkillType skillinuse, int16 chance_mod = 0, int16 focus = 0, bool CanRiposte = false, int ReuseTime = 0);
|
||||
virtual void ApplySpecialAttackMod(EQEmu::skills::SkillType skill, int32 &dmg, int32 &mindmg);
|
||||
bool CanDoSpecialAttack(Mob *other);
|
||||
virtual int32 CheckAggroAmount(uint16 spellid);
|
||||
@@ -289,14 +335,15 @@ public:
|
||||
void Stand();
|
||||
bool IsSitting();
|
||||
bool IsStanding();
|
||||
bool IsBotCasterCombatRange(Mob *target);
|
||||
bool CalculateNewPosition2(float x, float y, float z, float speed, bool checkZ = true) ;
|
||||
int GetBotWalkspeed() const { return (int)((float)_GetWalkSpeed() * 1.786f); } // 1.25 / 0.7 = 1.7857142857142857142857142857143
|
||||
int GetBotRunspeed() const { return (int)((float)_GetRunSpeed() * 1.786f); }
|
||||
bool IsBotCasterAtCombatRange(Mob *target);
|
||||
bool UseDiscipline(uint32 spell_id, uint32 target);
|
||||
uint8 GetNumberNeedingHealedInGroup(uint8 hpr, bool includePets);
|
||||
bool GetNeedsCured(Mob *tar);
|
||||
bool GetNeedsHateRedux(Mob *tar);
|
||||
bool HasOrMayGetAggro();
|
||||
void SetDefaultBotStance();
|
||||
void CalcChanceToCast();
|
||||
|
||||
inline virtual int32 GetMaxStat();
|
||||
inline virtual int32 GetMaxResist();
|
||||
@@ -350,7 +397,7 @@ public:
|
||||
void DoEnduranceUpkeep(); //does the endurance upkeep
|
||||
|
||||
// AI Methods
|
||||
virtual bool AICastSpell(Mob* tar, uint8 iChance, uint16 iSpellTypes);
|
||||
virtual bool AICastSpell(Mob* tar, uint8 iChance, uint32 iSpellTypes);
|
||||
virtual bool AI_EngagedCastCheck();
|
||||
virtual bool AI_PursueCastCheck();
|
||||
virtual bool AI_IdleCastCheck();
|
||||
@@ -414,10 +461,13 @@ public:
|
||||
static int32 GetDisciplineRecastTimer(Bot *caster, int timer_index);
|
||||
static bool CheckDisciplineRecastTimers(Bot *caster, int timer_index);
|
||||
static uint32 GetDisciplineRemainingTime(Bot *caster, int timer_index);
|
||||
|
||||
static std::list<BotSpell> GetBotSpellsForSpellEffect(Bot* botCaster, int spellEffect);
|
||||
static std::list<BotSpell> GetBotSpellsForSpellEffectAndTargetType(Bot* botCaster, int spellEffect, SpellTargetType targetType);
|
||||
static std::list<BotSpell> GetBotSpellsBySpellType(Bot* botCaster, uint16 spellType);
|
||||
static BotSpell GetFirstBotSpellBySpellType(Bot* botCaster, uint16 spellType);
|
||||
static std::list<BotSpell> GetBotSpellsBySpellType(Bot* botCaster, uint32 spellType);
|
||||
static std::list<BotSpell_wPriority> GetPrioritizedBotSpellsBySpellType(Bot* botCaster, uint32 spellType);
|
||||
|
||||
static BotSpell GetFirstBotSpellBySpellType(Bot* botCaster, uint32 spellType);
|
||||
static BotSpell GetBestBotSpellForFastHeal(Bot* botCaster);
|
||||
static BotSpell GetBestBotSpellForHealOverTime(Bot* botCaster);
|
||||
static BotSpell GetBestBotSpellForPercentageHeal(Bot* botCaster);
|
||||
@@ -428,6 +478,7 @@ public:
|
||||
static BotSpell GetBestBotSpellForGroupHeal(Bot* botCaster);
|
||||
static BotSpell GetBestBotSpellForMagicBasedSlow(Bot* botCaster);
|
||||
static BotSpell GetBestBotSpellForDiseaseBasedSlow(Bot* botCaster);
|
||||
|
||||
static Mob* GetFirstIncomingMobToMez(Bot* botCaster, BotSpell botSpell);
|
||||
static BotSpell GetBestBotSpellForMez(Bot* botCaster);
|
||||
static BotSpell GetBestBotMagicianPetSpell(Bot* botCaster);
|
||||
@@ -438,17 +489,12 @@ public:
|
||||
static BotSpell GetDebuffBotSpell(Bot* botCaster, Mob* target);
|
||||
static BotSpell GetBestBotSpellForCure(Bot* botCaster, Mob* target);
|
||||
static BotSpell GetBestBotSpellForResistDebuff(Bot* botCaster, Mob* target);
|
||||
|
||||
static NPCType CreateDefaultNPCTypeStructForBot(std::string botName, std::string botLastName, uint8 botLevel, uint16 botRace, uint8 botClass, uint8 gender);
|
||||
|
||||
// Static Bot Group Methods
|
||||
static bool AddBotToGroup(Bot* bot, Group* group);
|
||||
static bool RemoveBotFromGroup(Bot* bot, Group* group);
|
||||
static bool GroupHasClass(Group* group, uint8 classId);
|
||||
static bool GroupHasClericClass(Group* group) { return GroupHasClass(group, CLERIC); }
|
||||
static bool GroupHasDruidClass(Group* group) { return GroupHasClass(group, DRUID); }
|
||||
static bool GroupHasShamanClass(Group* group) { return GroupHasClass(group, SHAMAN); }
|
||||
static bool GroupHasEnchanterClass(Group* group) { return GroupHasClass(group, ENCHANTER); }
|
||||
static bool GroupHasPriestClass(Group* group) { return GroupHasClass(group, CLERIC | DRUID | SHAMAN); }
|
||||
static void BotGroupSay(Mob *speaker, const char *msg, ...);
|
||||
|
||||
// "GET" Class Methods
|
||||
@@ -467,9 +513,20 @@ public:
|
||||
bool GetRangerAutoWeaponSelect() { return _rangerAutoWeaponSelect; }
|
||||
BotRoleType GetBotRole() { return _botRole; }
|
||||
BotStanceType GetBotStance() { return _botStance; }
|
||||
uint8 GetChanceToCastBySpellType(uint16 spellType);
|
||||
bool IsGroupPrimaryHealer();
|
||||
bool IsGroupPrimarySlower();
|
||||
uint8 GetChanceToCastBySpellType(uint32 spellType);
|
||||
|
||||
bool IsGroupHealer() { return m_CastingRoles.GroupHealer; }
|
||||
bool IsGroupSlower() { return m_CastingRoles.GroupSlower; }
|
||||
bool IsGroupNuker() { return m_CastingRoles.GroupNuker; }
|
||||
bool IsGroupDoter() { return m_CastingRoles.GroupDoter; }
|
||||
static void UpdateGroupCastingRoles(const Group* group, bool disband = false);
|
||||
|
||||
//bool IsRaidHealer() { return m_CastingRoles.RaidHealer; }
|
||||
//bool IsRaidSlower() { return m_CastingRoles.RaidSlower; }
|
||||
//bool IsRaidNuker() { return m_CastingRoles.RaidNuker; }
|
||||
//bool IsRaidDoter() { return m_CastingRoles.RaidDoter; }
|
||||
//static void UpdateRaidCastingRoles(const Raid* raid, bool disband = false);
|
||||
|
||||
bool IsBotCaster() { return IsCasterClass(GetClass()); }
|
||||
bool IsBotINTCaster() { return IsINTCasterClass(GetClass()); }
|
||||
bool IsBotWISCaster() { return IsWISCasterClass(GetClass()); }
|
||||
@@ -503,7 +560,6 @@ public:
|
||||
|
||||
bool GetAltOutOfCombatBehavior() { return _altoutofcombatbehavior;}
|
||||
bool GetShowHelm() { return _showhelm; }
|
||||
inline virtual int32 GetAC() const { return AC; }
|
||||
inline virtual int32 GetSTR() const { return STR; }
|
||||
inline virtual int32 GetSTA() const { return STA; }
|
||||
inline virtual int32 GetDEX() const { return DEX; }
|
||||
@@ -599,7 +655,7 @@ public:
|
||||
|
||||
// Publicized private functions
|
||||
static NPCType FillNPCTypeStruct(uint32 botSpellsID, std::string botName, std::string botLastName, uint8 botLevel, uint16 botRace, uint8 botClass, uint8 gender, float size, uint32 face, uint32 hairStyle, uint32 hairColor, uint32 eyeColor, uint32 eyeColor2, uint32 beardColor, uint32 beard, uint32 drakkinHeritage, uint32 drakkinTattoo, uint32 drakkinDetails, int32 hp, int32 mana, int32 mr, int32 cr, int32 dr, int32 fr, int32 pr, int32 corrup, int32 ac, uint32 str, uint32 sta, uint32 dex, uint32 agi, uint32 _int, uint32 wis, uint32 cha, uint32 attack);
|
||||
void BotRemoveEquipItem(int slot);
|
||||
void BotRemoveEquipItem(int16 slot);
|
||||
void RemoveBotItemBySlot(uint32 slotID, std::string* errorMessage);
|
||||
uint32 GetTotalPlayTime();
|
||||
|
||||
@@ -634,6 +690,16 @@ protected:
|
||||
virtual bool AIDoSpellCast(uint8 i, Mob* tar, int32 mana_cost, uint32* oDontDoAgainBefore = 0);
|
||||
virtual float GetMaxMeleeRangeToTarget(Mob* target);
|
||||
|
||||
BotCastingRoles& GetCastingRoles() { return m_CastingRoles; }
|
||||
void SetGroupHealer(bool flag = true) { m_CastingRoles.GroupHealer = flag; }
|
||||
void SetGroupSlower(bool flag = true) { m_CastingRoles.GroupSlower = flag; }
|
||||
void SetGroupNuker(bool flag = true) { m_CastingRoles.GroupNuker = flag; }
|
||||
void SetGroupDoter(bool flag = true) { m_CastingRoles.GroupDoter = flag; }
|
||||
//void SetRaidHealer(bool flag = true) { m_CastingRoles.RaidHealer = flag; }
|
||||
//void SetRaidSlower(bool flag = true) { m_CastingRoles.RaidSlower = flag; }
|
||||
//void SetRaidNuker(bool flag = true) { m_CastingRoles.RaidNuker = flag; }
|
||||
//void SetRaidDoter(bool flag = true) { m_CastingRoles.RaidDoter = flag; }
|
||||
|
||||
private:
|
||||
// Class Members
|
||||
uint32 _botID;
|
||||
@@ -670,7 +736,10 @@ private:
|
||||
uint32 timers[MaxTimer];
|
||||
bool _hasBeenSummoned;
|
||||
glm::vec3 m_PreSummonLocation;
|
||||
uint8 _spellCastingChances[MaxStances][MaxSpellTypes];
|
||||
|
||||
Timer evade_timer; // can be moved to pTimers at some point
|
||||
|
||||
BotCastingRoles m_CastingRoles;
|
||||
|
||||
std::shared_ptr<HealRotation> m_member_of_heal_rotation;
|
||||
|
||||
|
||||
@@ -436,6 +436,8 @@ public:
|
||||
case 10:
|
||||
if (spells[spell_id].effectdescnum != 65)
|
||||
break;
|
||||
if (IsEffectInSpell(spell_id, SE_NegateIfCombat))
|
||||
break;
|
||||
entry_prototype = new STMovementSpeedEntry();
|
||||
entry_prototype->SafeCastToMovementSpeed()->group = BCSpells::IsGroupType(target_type);
|
||||
break;
|
||||
@@ -4548,7 +4550,7 @@ void bot_subcommand_bot_follow_distance(Client *c, const Seperator *sep)
|
||||
}
|
||||
const int ab_mask = ActionableBots::ABM_NoFilter;
|
||||
|
||||
uint32 bfd = BOT_DEFAULT_FOLLOW_DISTANCE;
|
||||
uint32 bfd = BOT_FOLLOW_DISTANCE_DEFAULT;
|
||||
bool set_flag = false;
|
||||
int ab_arg = 2;
|
||||
|
||||
@@ -4559,6 +4561,10 @@ void bot_subcommand_bot_follow_distance(Client *c, const Seperator *sep)
|
||||
}
|
||||
|
||||
bfd = atoi(sep->arg[2]);
|
||||
if (bfd < 1)
|
||||
bfd = 1;
|
||||
if (bfd > BOT_FOLLOW_DISTANCE_DEFAULT_MAX)
|
||||
bfd = BOT_FOLLOW_DISTANCE_DEFAULT_MAX;
|
||||
set_flag = true;
|
||||
ab_arg = 3;
|
||||
}
|
||||
@@ -5115,7 +5121,6 @@ void bot_subcommand_bot_stance(Client *c, const Seperator *sep)
|
||||
|
||||
if (!current_flag) {
|
||||
bot_iter->SetBotStance(bst);
|
||||
bot_iter->CalcChanceToCast();
|
||||
bot_iter->Save();
|
||||
}
|
||||
|
||||
@@ -5146,6 +5151,7 @@ void bot_subcommand_bot_summon(Client *c, const Seperator *sep)
|
||||
bot_iter->WipeHateList();
|
||||
bot_iter->SetTarget(bot_iter->GetBotOwner());
|
||||
bot_iter->Warp(glm::vec3(c->GetPosition()));
|
||||
bot_iter->DoAnim(0);
|
||||
|
||||
if (!bot_iter->HasPet())
|
||||
continue;
|
||||
@@ -5394,6 +5400,7 @@ void bot_subcommand_bot_update(Client *c, const Seperator *sep)
|
||||
|
||||
bot_iter->SetPetChooser(false);
|
||||
bot_iter->CalcBotStats((sbl.size() == 1));
|
||||
bot_iter->SendAppearancePacket(AT_WhoLevel, bot_iter->GetLevel(), true, true);
|
||||
++bot_count;
|
||||
}
|
||||
|
||||
|
||||
+84
-3
@@ -82,6 +82,66 @@ bool BotDatabase::LoadBotCommandSettings(std::map<std::string, std::pair<uint8,
|
||||
return true;
|
||||
}
|
||||
|
||||
static uint8 spell_casting_chances[MaxSpellTypes][PLAYER_CLASS_COUNT][MaxStances][cntHSND];
|
||||
|
||||
bool BotDatabase::LoadBotSpellCastingChances()
|
||||
{
|
||||
memset(spell_casting_chances, 0, sizeof(spell_casting_chances));
|
||||
|
||||
query =
|
||||
"SELECT"
|
||||
" `spell_type_index`,"
|
||||
" `class_id`,"
|
||||
" `stance_index`,"
|
||||
" `nHSND_value`,"
|
||||
" `pH_value`,"
|
||||
" `pS_value`,"
|
||||
" `pHS_value`,"
|
||||
" `pN_value`,"
|
||||
" `pHN_value`,"
|
||||
" `pSN_value`,"
|
||||
" `pHSN_value`,"
|
||||
" `pD_value`,"
|
||||
" `pHD_value`,"
|
||||
" `pSD_value`,"
|
||||
" `pHSD_value`,"
|
||||
" `pND_value`,"
|
||||
" `pHND_value`,"
|
||||
" `pSND_value`,"
|
||||
" `pHSND_value`"
|
||||
"FROM"
|
||||
" `bot_spell_casting_chances`";
|
||||
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success() || !results.RowCount())
|
||||
return false;
|
||||
|
||||
for (auto row = results.begin(); row != results.end(); ++row) {
|
||||
uint8 spell_type_index = atoi(row[0]);
|
||||
if (spell_type_index >= MaxSpellTypes)
|
||||
continue;
|
||||
uint8 class_index = atoi(row[1]);
|
||||
if (class_index < WARRIOR || class_index > BERSERKER)
|
||||
continue;
|
||||
--class_index;
|
||||
uint8 stance_index = atoi(row[2]);
|
||||
if (stance_index >= MaxStances)
|
||||
continue;
|
||||
|
||||
for (uint8 conditional_index = nHSND; conditional_index < cntHSND; ++conditional_index) {
|
||||
uint8 value = atoi(row[3 + conditional_index]);
|
||||
if (!value)
|
||||
continue;
|
||||
if (value > 100)
|
||||
value = 100;
|
||||
|
||||
spell_casting_chances[spell_type_index][class_index][stance_index][conditional_index] = value;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* Bot functions */
|
||||
bool BotDatabase::QueryNameAvailablity(const std::string& bot_name, bool& available_flag)
|
||||
@@ -334,7 +394,13 @@ bool BotDatabase::LoadBot(const uint32 bot_id, Bot*& loaded_bot)
|
||||
loaded_bot = new Bot(bot_id, atoi(row[0]), atoi(row[1]), atof(row[14]), atoi(row[6]), tempNPCStruct);
|
||||
if (loaded_bot) {
|
||||
loaded_bot->SetShowHelm((atoi(row[43]) > 0 ? true : false));
|
||||
loaded_bot->SetFollowDistance(atoi(row[44]));
|
||||
uint32 bfd = atoi(row[44]);
|
||||
if (bfd < 1)
|
||||
bfd = 1;
|
||||
if (bfd > BOT_FOLLOW_DISTANCE_DEFAULT_MAX)
|
||||
bfd = BOT_FOLLOW_DISTANCE_DEFAULT_MAX;
|
||||
loaded_bot->SetFollowDistance(bfd);
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -471,7 +537,7 @@ bool BotDatabase::SaveNewBot(Bot* bot_inst, uint32& bot_id)
|
||||
bot_inst->GetPR(),
|
||||
bot_inst->GetDR(),
|
||||
bot_inst->GetCorrup(),
|
||||
BOT_DEFAULT_FOLLOW_DISTANCE
|
||||
BOT_FOLLOW_DISTANCE_DEFAULT
|
||||
);
|
||||
auto results = QueryDatabase(query);
|
||||
if (!results.Success())
|
||||
@@ -617,7 +683,8 @@ bool BotDatabase::LoadBuffs(Bot* bot_inst)
|
||||
" `caston_x`,"
|
||||
" `caston_y`,"
|
||||
" `caston_z`,"
|
||||
" `extra_di_chance`"
|
||||
" `extra_di_chance`,"
|
||||
" `instrument_mod`"
|
||||
" FROM `bot_buffs`"
|
||||
" WHERE `bot_id` = '%u'",
|
||||
bot_inst->GetBotID()
|
||||
@@ -657,6 +724,7 @@ bool BotDatabase::LoadBuffs(Bot* bot_inst)
|
||||
bot_buffs[buff_count].caston_y = atoi(row[14]);
|
||||
bot_buffs[buff_count].caston_z = atoi(row[15]);
|
||||
bot_buffs[buff_count].ExtraDIChance = atoi(row[16]);
|
||||
bot_buffs[buff_count].instrument_mod = atoi(row[17]);
|
||||
bot_buffs[buff_count].casterid = 0;
|
||||
++buff_count;
|
||||
}
|
||||
@@ -2709,6 +2777,19 @@ bool BotDatabase::DeleteAllHealRotations(const uint32 owner_id)
|
||||
|
||||
|
||||
/* Bot miscellaneous functions */
|
||||
uint8 BotDatabase::GetSpellCastingChance(uint8 spell_type_index, uint8 class_index, uint8 stance_index, uint8 conditional_index) // class_index is 0-based
|
||||
{
|
||||
if (spell_type_index >= MaxSpellTypes)
|
||||
return 0;
|
||||
if (class_index >= PLAYER_CLASS_COUNT)
|
||||
return 0;
|
||||
if (stance_index >= MaxStances)
|
||||
return 0;
|
||||
if (conditional_index >= cntHSND)
|
||||
return 0;
|
||||
|
||||
return spell_casting_chances[spell_type_index][class_index][stance_index][conditional_index];
|
||||
}
|
||||
|
||||
|
||||
/* fail::Bot functions */
|
||||
|
||||
@@ -50,6 +50,7 @@ public:
|
||||
bool Connect(const char* host, const char* user, const char* passwd, const char* database, uint32 port);
|
||||
|
||||
bool LoadBotCommandSettings(std::map<std::string, std::pair<uint8, std::vector<std::string>>> &bot_command_settings);
|
||||
bool LoadBotSpellCastingChances();
|
||||
|
||||
|
||||
/* Bot functions */
|
||||
@@ -183,6 +184,7 @@ public:
|
||||
bool DeleteAllHealRotations(const uint32 owner_id);
|
||||
|
||||
/* Bot miscellaneous functions */
|
||||
uint8 GetSpellCastingChance(uint8 spell_type_index, uint8 class_index, uint8 stance_index, uint8 conditional_index);
|
||||
|
||||
|
||||
class fail {
|
||||
|
||||
@@ -56,6 +56,21 @@ struct BotSpell {
|
||||
int16 ManaCost;
|
||||
};
|
||||
|
||||
struct BotSpell_wPriority : public BotSpell {
|
||||
uint8 Priority;
|
||||
};
|
||||
|
||||
struct BotCastingRoles {
|
||||
bool GroupHealer;
|
||||
bool GroupSlower;
|
||||
bool GroupNuker;
|
||||
bool GroupDoter;
|
||||
//bool RaidHealer;
|
||||
//bool RaidSlower;
|
||||
//bool RaidNuker;
|
||||
//bool RaidDoter;
|
||||
};
|
||||
|
||||
struct BotAA {
|
||||
uint32 aa_id;
|
||||
uint8 req_level;
|
||||
|
||||
+457
-1192
File diff suppressed because it is too large
Load Diff
+396
-81
@@ -33,6 +33,7 @@ extern volatile bool RunLoops;
|
||||
|
||||
#include "../common/eqemu_logsys.h"
|
||||
#include "../common/features.h"
|
||||
#include "../common/emu_legacy.h"
|
||||
#include "../common/spdat.h"
|
||||
#include "../common/guilds.h"
|
||||
#include "../common/rulesys.h"
|
||||
@@ -153,6 +154,7 @@ Client::Client(EQStreamInterface* ieqs)
|
||||
afk_toggle_timer(250),
|
||||
helm_toggle_timer(250),
|
||||
light_update_timer(600),
|
||||
aggro_meter_timer(AGGRO_METER_UPDATE_MS),
|
||||
m_Proximity(FLT_MAX, FLT_MAX, FLT_MAX), //arbitrary large number
|
||||
m_ZoneSummonLocation(-2.0f,-2.0f,-2.0f),
|
||||
m_AutoAttackPosition(0.0f, 0.0f, 0.0f, 0.0f),
|
||||
@@ -309,6 +311,8 @@ Client::Client(EQStreamInterface* ieqs)
|
||||
}
|
||||
MaxXTargets = 5;
|
||||
XTargetAutoAddHaters = true;
|
||||
m_autohatermgr.SetOwner(this, nullptr, nullptr);
|
||||
m_activeautohatermgr = &m_autohatermgr;
|
||||
LoadAccountFlags();
|
||||
|
||||
initial_respawn_selection = 0;
|
||||
@@ -1095,7 +1099,7 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s
|
||||
CheckLDoNHail(GetTarget());
|
||||
CheckEmoteHail(GetTarget(), message);
|
||||
|
||||
if(DistanceSquaredNoZ(m_Position, GetTarget()->GetPosition()) <= 200) {
|
||||
if(DistanceSquaredNoZ(m_Position, GetTarget()->GetPosition()) <= RuleI(Range, Say)) {
|
||||
NPC *tar = GetTarget()->CastToNPC();
|
||||
parse->EventNPC(EVENT_SAY, tar->CastToNPC(), this, message, language);
|
||||
|
||||
@@ -1107,7 +1111,7 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (DistanceSquaredNoZ(m_Position, GetTarget()->GetPosition()) <= 200) {
|
||||
if (DistanceSquaredNoZ(m_Position, GetTarget()->GetPosition()) <= RuleI(Range, Say)) {
|
||||
parse->EventNPC(EVENT_AGGRO_SAY, GetTarget()->CastToNPC(), this, message, language);
|
||||
}
|
||||
}
|
||||
@@ -1136,7 +1140,7 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s
|
||||
char *Buffer = (char *)es;
|
||||
Buffer += 4;
|
||||
snprintf(Buffer, sizeof(Emote_Struct) - 4, "%s %s", GetName(), message);
|
||||
entity_list.QueueCloseClients(this, outapp, true, 100, 0, true, FilterSocials);
|
||||
entity_list.QueueCloseClients(this, outapp, true, RuleI(Range, Emote), 0, true, FilterSocials);
|
||||
safe_delete(outapp);
|
||||
break;
|
||||
}
|
||||
@@ -1998,6 +2002,7 @@ void Client::SetGM(bool toggle) {
|
||||
}
|
||||
|
||||
void Client::ReadBook(BookRequest_Struct *book) {
|
||||
int16 book_language=0;
|
||||
char *txtfile = book->txtfile;
|
||||
|
||||
if(txtfile[0] == '0' && txtfile[1] == '\0') {
|
||||
@@ -2005,7 +2010,7 @@ void Client::ReadBook(BookRequest_Struct *book) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::string booktxt2 = database.GetBook(txtfile);
|
||||
std::string booktxt2 = database.GetBook(txtfile, &book_language);
|
||||
int length = booktxt2.length();
|
||||
|
||||
if (booktxt2[0] != '\0') {
|
||||
@@ -2016,21 +2021,47 @@ void Client::ReadBook(BookRequest_Struct *book) {
|
||||
|
||||
BookText_Struct *out = (BookText_Struct *) outapp->pBuffer;
|
||||
out->window = book->window;
|
||||
if (ClientVersion() >= EQEmu::versions::ClientVersion::SoF)
|
||||
{
|
||||
const EQEmu::ItemInstance *inst = m_inv[book->invslot];
|
||||
|
||||
|
||||
if (ClientVersion() >= EQEmu::versions::ClientVersion::SoF) {
|
||||
// Find out what slot the book was read from.
|
||||
// SoF+ need to look up book type for the output message.
|
||||
int16 read_from_slot;
|
||||
|
||||
if (book->subslot >= 0) {
|
||||
uint16 offset;
|
||||
offset = (book->invslot-23) * 10; // How many packs to skip.
|
||||
read_from_slot = 251 + offset + book->subslot;
|
||||
}
|
||||
else {
|
||||
read_from_slot = book->invslot -1;
|
||||
}
|
||||
|
||||
const EQEmu::ItemInstance *inst = 0;
|
||||
|
||||
if (read_from_slot <= EQEmu::legacy::SLOT_PERSONAL_BAGS_END)
|
||||
{
|
||||
inst = m_inv[read_from_slot];
|
||||
}
|
||||
|
||||
if(inst)
|
||||
out->type = inst->GetItem()->Book;
|
||||
else
|
||||
out->type = book->type;
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
out->type = book->type;
|
||||
}
|
||||
out->invslot = book->invslot;
|
||||
|
||||
memcpy(out->booktext, booktxt2.c_str(), length);
|
||||
|
||||
if (book_language > 0 && book_language < MAX_PP_LANGUAGE) {
|
||||
if (m_pp.languages[book_language] < 100) {
|
||||
GarbleMessage(out->booktext, (100 - m_pp.languages[book_language]));
|
||||
}
|
||||
}
|
||||
|
||||
QueuePacket(outapp);
|
||||
safe_delete(outapp);
|
||||
}
|
||||
@@ -2311,7 +2342,7 @@ bool Client::CheckIncreaseSkill(EQEmu::skills::SkillType skillid, Mob *against_w
|
||||
if(against_who)
|
||||
{
|
||||
if(against_who->GetSpecialAbility(IMMUNE_AGGRO) || against_who->IsClient() ||
|
||||
GetLevelCon(against_who->GetLevel()) == CON_GREEN)
|
||||
GetLevelCon(against_who->GetLevel()) == CON_GRAY)
|
||||
{
|
||||
//false by default
|
||||
if( !mod_can_increase_skill(skillid, against_who) ) { return(false); }
|
||||
@@ -4131,6 +4162,18 @@ bool Client::GroupFollow(Client* inviter) {
|
||||
}
|
||||
if (raid->RaidCount() < MAX_RAID_MEMBERS)
|
||||
{
|
||||
// okay, so we now have a single client (this) joining a group in a raid
|
||||
// And they're not already in the raid (which is above and doesn't need xtarget shit)
|
||||
if (!GetXTargetAutoMgr()->empty()) {
|
||||
raid->GetXTargetAutoMgr()->merge(*GetXTargetAutoMgr());
|
||||
GetXTargetAutoMgr()->clear();
|
||||
RemoveAutoXTargets();
|
||||
}
|
||||
|
||||
SetXTargetAutoMgr(GetXTargetAutoMgr());
|
||||
if (!GetXTargetAutoMgr()->empty())
|
||||
SetDirtyAutoHaters();
|
||||
|
||||
if (raid->GroupCount(groupToUse) < 6)
|
||||
{
|
||||
raid->SendRaidCreate(this);
|
||||
@@ -4206,7 +4249,9 @@ bool Client::GroupFollow(Client* inviter) {
|
||||
inviter->SendGroupLeaderChangePacket(inviter->GetName());
|
||||
inviter->SendGroupJoinAcknowledge();
|
||||
}
|
||||
|
||||
group->GetXTargetAutoMgr()->merge(*inviter->GetXTargetAutoMgr());
|
||||
inviter->GetXTargetAutoMgr()->clear();
|
||||
inviter->SetXTargetAutoMgr(group->GetXTargetAutoMgr());
|
||||
}
|
||||
|
||||
if (!group)
|
||||
@@ -5868,20 +5913,20 @@ void Client::SendGroupCreatePacket()
|
||||
|
||||
char *Buffer = (char *)outapp->pBuffer;
|
||||
// Header
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 1);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // Null Leader name
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // group ID probably
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 1); // count of members in packet
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // Null Leader name, shouldn't be null besides this case
|
||||
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // Member 0
|
||||
VARSTRUCT_ENCODE_STRING(Buffer, GetName());
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // This is a string
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, GetLevel());
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint16, Buffer, 0);
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // Member 0, index
|
||||
VARSTRUCT_ENCODE_STRING(Buffer, GetName()); // group member name
|
||||
VARSTRUCT_ENCODE_TYPE(uint16, Buffer, 0); // merc flag
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // owner name (if merc)
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, GetLevel()); // level
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // group tank flag
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // group assist flag
|
||||
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // group puller flag
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // offline flag
|
||||
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // timestamp
|
||||
|
||||
FastQueuePacket(&outapp);
|
||||
}
|
||||
@@ -6863,16 +6908,46 @@ void Client::SendStatsWindow(Client* client, bool use_window)
|
||||
indP + "Wind: " + itoa(GetWindMod()) + "<br>";
|
||||
}
|
||||
|
||||
EQEmu::skills::SkillType skill = EQEmu::skills::SkillHandtoHand;
|
||||
auto *inst = GetInv().GetItem(EQEmu::inventory::slotPrimary);
|
||||
if (inst && inst->IsClassCommon()) {
|
||||
switch (inst->GetItem()->ItemType) {
|
||||
case EQEmu::item::ItemType1HSlash:
|
||||
skill = EQEmu::skills::Skill1HSlashing;
|
||||
break;
|
||||
case EQEmu::item::ItemType2HSlash:
|
||||
skill = EQEmu::skills::Skill2HSlashing;
|
||||
break;
|
||||
case EQEmu::item::ItemType1HPiercing:
|
||||
skill = EQEmu::skills::Skill1HPiercing;
|
||||
break;
|
||||
case EQEmu::item::ItemType1HBlunt:
|
||||
skill = EQEmu::skills::Skill1HBlunt;
|
||||
break;
|
||||
case EQEmu::item::ItemType2HBlunt:
|
||||
skill = EQEmu::skills::Skill2HBlunt;
|
||||
break;
|
||||
case EQEmu::item::ItemType2HPiercing:
|
||||
if (ClientVersion() < EQEmu::versions::ClientVersion::RoF2)
|
||||
skill = EQEmu::skills::Skill1HPiercing;
|
||||
else
|
||||
skill = EQEmu::skills::Skill2HPiercing;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::ostringstream final_string;
|
||||
final_string <<
|
||||
/* C/L/R */ indP << "Class: " << class_Name << indS << "Level: " << static_cast<int>(GetLevel()) << indS << "Race: " << race_Name << "<br>" <<
|
||||
/* Runes */ indP << "Rune: " << rune_number << indL << indS << "Spell Rune: " << magic_rune_number << "<br>" <<
|
||||
/* HP/M/E */ HME_row <<
|
||||
/* DS */ indP << "DS: " << (itembonuses.DamageShield + spellbonuses.DamageShield*-1) << " (Spell: " << (spellbonuses.DamageShield*-1) << " + Item: " << itembonuses.DamageShield << " / " << RuleI(Character, ItemDamageShieldCap) << ")<br>" <<
|
||||
/* Atk */ indP << "<c \"#CCFF00\">ATK: " << GetTotalATK() << "</c><br>" <<
|
||||
/* Atk2 */ indP << "- Base: " << GetATKRating() << " | Item: " << itembonuses.ATK << " (" << RuleI(Character, ItemATKCap) << ")~Used: " << (itembonuses.ATK * 1.342) << " | Spell: " << spellbonuses.ATK << "<br>" <<
|
||||
/* AC */ indP << "<c \"#CCFF00\">AC: " << CalcAC() << "</c><br>" <<
|
||||
/* AC2 */ indP << "- Mit: " << GetACMit() << " | Avoid: " << GetACAvoid() << " | Spell: " << spellbonuses.AC << " | Shield: " << shield_ac << "<br>" <<
|
||||
/* Atk */ indP << "<c \"#CCFF00\">tohit: " << compute_tohit(skill) << " / " << GetTotalToHit(skill, 0) << "</c><br>" <<
|
||||
/* Atk2 */ indP << "- Offense: " << offense(skill) << " | Item: " << itembonuses.ATK << " (" << RuleI(Character, ItemATKCap) << ")~Used: " << (itembonuses.ATK * 1.342) << " | Spell: " << spellbonuses.ATK << "<br>" <<
|
||||
/* AC */ indP << "<c \"#CCFF00\">mitigation AC: " << GetMitigationAC() << "</c><br>" <<
|
||||
/* AC2 */ indP << "- defense: " << compute_defense() << " / " << GetTotalDefense() << " | Spell: " << spellbonuses.AC << " | Shield: " << shield_ac << "<br>" <<
|
||||
/* Haste */ indP << "<c \"#CCFF00\">Haste: " << GetHaste() << "</c><br>" <<
|
||||
/* Haste2 */ indP << " - Item: " << itembonuses.haste << " + Spell: " << (spellbonuses.haste + spellbonuses.hastetype2) << " (Cap: " << RuleI(Character, HasteCap) << ") | Over: " << (spellbonuses.hastetype3 + ExtraHaste) << "<br>" <<
|
||||
/* RunSpeed*/ indP << "<c \"#CCFF00\">Runspeed: " << GetRunspeed() << "</c><br>" <<
|
||||
@@ -6910,7 +6985,9 @@ void Client::SendStatsWindow(Client* client, bool use_window)
|
||||
client->Message(15, "~~~~~ %s %s ~~~~~", GetCleanName(), GetLastName());
|
||||
client->Message(0, " Level: %i Class: %i Race: %i DS: %i/%i Size: %1.1f Weight: %.1f/%d ", GetLevel(), GetClass(), GetRace(), GetDS(), RuleI(Character, ItemDamageShieldCap), GetSize(), (float)CalcCurrentWeight() / 10.0f, GetSTR());
|
||||
client->Message(0, " HP: %i/%i HP Regen: %i/%i",GetHP(), GetMaxHP(), CalcHPRegen(), CalcHPRegenCap());
|
||||
client->Message(0, " AC: %i ( Mit.: %i + Avoid.: %i + Spell: %i ) | Shield AC: %i", CalcAC(), GetACMit(), GetACAvoid(), spellbonuses.AC, shield_ac);
|
||||
client->Message(0, " compute_tohit: %i TotalToHit: %i", compute_tohit(skill), GetTotalToHit(skill, 0));
|
||||
client->Message(0, " compute_defense: %i TotalDefense: %i", compute_defense(), GetTotalDefense());
|
||||
client->Message(0, " offense: %i mitigation ac: %i", offense(skill), GetMitigationAC());
|
||||
if(CalcMaxMana() > 0)
|
||||
client->Message(0, " Mana: %i/%i Mana Regen: %i/%i", GetMana(), GetMaxMana(), CalcManaRegen(), CalcManaRegenCap());
|
||||
client->Message(0, " End.: %i/%i End. Regen: %i/%i",GetEndurance(), GetMaxEndurance(), CalcEnduranceRegen(), CalcEnduranceRegenCap());
|
||||
@@ -7111,12 +7188,12 @@ void Client::UpdateClientXTarget(Client *c)
|
||||
}
|
||||
}
|
||||
|
||||
// IT IS NOT SAFE TO CALL THIS IF IT'S NOT INITIAL AGGRO
|
||||
void Client::AddAutoXTarget(Mob *m, bool send)
|
||||
{
|
||||
if(!XTargettingAvailable() || !XTargetAutoAddHaters)
|
||||
return;
|
||||
m_activeautohatermgr->increment_count(m);
|
||||
|
||||
if(IsXTarget(m))
|
||||
if (!XTargettingAvailable() || !XTargetAutoAddHaters || IsXTarget(m))
|
||||
return;
|
||||
|
||||
for(int i = 0; i < GetMaxXTargets(); ++i)
|
||||
@@ -7135,60 +7212,15 @@ void Client::AddAutoXTarget(Mob *m, bool send)
|
||||
|
||||
void Client::RemoveXTarget(Mob *m, bool OnlyAutoSlots)
|
||||
{
|
||||
if (!XTargettingAvailable())
|
||||
return;
|
||||
|
||||
bool HadFreeAutoSlotsBefore = false;
|
||||
|
||||
int FreedAutoSlots = 0;
|
||||
|
||||
if (m->GetID() == 0)
|
||||
return;
|
||||
|
||||
m_activeautohatermgr->decrement_count(m);
|
||||
// now we may need to clean up our CurrentTargetNPC entries
|
||||
for (int i = 0; i < GetMaxXTargets(); ++i) {
|
||||
if (OnlyAutoSlots && XTargets[i].Type != Auto)
|
||||
continue;
|
||||
|
||||
if (XTargets[i].ID == m->GetID()) {
|
||||
if (XTargets[i].Type == CurrentTargetNPC)
|
||||
XTargets[i].Type = Auto;
|
||||
|
||||
if (XTargets[i].Type == Auto)
|
||||
++FreedAutoSlots;
|
||||
|
||||
if (XTargets[i].Type == CurrentTargetNPC && XTargets[i].ID == m->GetID()) {
|
||||
XTargets[i].Type = Auto;
|
||||
XTargets[i].ID = 0;
|
||||
XTargets[i].dirty = true;
|
||||
} else {
|
||||
if (XTargets[i].Type == Auto && XTargets[i].ID == 0)
|
||||
HadFreeAutoSlotsBefore = true;
|
||||
}
|
||||
}
|
||||
|
||||
// move shit up! If the removed NPC was in a CurrentTargetNPC slot it becomes Auto
|
||||
// and we need to potentially fill it
|
||||
std::queue<int> empty_slots;
|
||||
for (int i = 0; i < GetMaxXTargets(); ++i) {
|
||||
if (XTargets[i].Type != Auto)
|
||||
continue;
|
||||
|
||||
if (XTargets[i].ID == 0) {
|
||||
empty_slots.push(i);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (XTargets[i].ID != 0 && !empty_slots.empty()) {
|
||||
int temp = empty_slots.front();
|
||||
std::swap(XTargets[i], XTargets[temp]);
|
||||
XTargets[i].dirty = XTargets[temp].dirty = true;
|
||||
empty_slots.pop();
|
||||
empty_slots.push(i);
|
||||
}
|
||||
}
|
||||
// If there are more mobs aggro on us than we had auto-hate slots, add one of those haters into the slot(s) we
|
||||
// just freed up.
|
||||
if (!HadFreeAutoSlotsBefore && FreedAutoSlots)
|
||||
entity_list.RefreshAutoXTargets(this);
|
||||
SendXTargetUpdates();
|
||||
}
|
||||
|
||||
void Client::UpdateXTargetType(XTargetType Type, Mob *m, const char *Name)
|
||||
@@ -7345,6 +7377,123 @@ void Client::ShowXTargets(Client *c)
|
||||
|
||||
for(int i = 0; i < GetMaxXTargets(); ++i)
|
||||
c->Message(0, "Xtarget Slot: %i, Type: %2i, ID: %4i, Name: %s", i, XTargets[i].Type, XTargets[i].ID, XTargets[i].Name);
|
||||
auto &list = GetXTargetAutoMgr()->get_list();
|
||||
// yeah, I kept having to do something for debugging to tell if managers were the same object or not :P
|
||||
// so lets use the address as an "ID"
|
||||
c->Message(0, "XTargetAutoMgr ID %p size %d", GetXTargetAutoMgr(), list.size());
|
||||
int count = 0;
|
||||
for (auto &e : list) {
|
||||
c->Message(0, "spawn id %d count %d", e.spawn_id, e.count);
|
||||
count++;
|
||||
if (count == 20) { // lets not spam too many ...
|
||||
c->Message(0, " ... ");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Client::ProcessXTargetAutoHaters()
|
||||
{
|
||||
if (!XTargettingAvailable())
|
||||
return;
|
||||
|
||||
// move shit up! If the removed NPC was in a CurrentTargetNPC slot it becomes Auto
|
||||
// and we need to potentially fill it
|
||||
std::queue<int> empty_slots;
|
||||
for (int i = 0; i < GetMaxXTargets(); ++i) {
|
||||
if (XTargets[i].Type != Auto)
|
||||
continue;
|
||||
|
||||
if (XTargets[i].ID != 0 && !GetXTargetAutoMgr()->contains_mob(XTargets[i].ID)) {
|
||||
XTargets[i].ID = 0;
|
||||
XTargets[i].dirty = true;
|
||||
}
|
||||
|
||||
if (XTargets[i].ID == 0) {
|
||||
empty_slots.push(i);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (XTargets[i].ID != 0 && !empty_slots.empty()) {
|
||||
int temp = empty_slots.front();
|
||||
std::swap(XTargets[i], XTargets[temp]);
|
||||
XTargets[i].dirty = XTargets[temp].dirty = true;
|
||||
empty_slots.pop();
|
||||
empty_slots.push(i);
|
||||
}
|
||||
}
|
||||
// okay, now we need to check if we have any empty slots and if we have aggro
|
||||
// We make the assumption that if we shuffled the NPCs up that they're still on the aggro
|
||||
// list in the same order. We could probably do this better and try to calc if
|
||||
// there are new NPCs for our empty slots on the manager, but ahhh fuck it.
|
||||
if (!empty_slots.empty() && !GetXTargetAutoMgr()->empty() && XTargetAutoAddHaters) {
|
||||
auto &haters = GetXTargetAutoMgr()->get_list();
|
||||
for (auto &e : haters) {
|
||||
auto *mob = entity_list.GetMob(e.spawn_id);
|
||||
if (mob && !IsXTarget(mob)) {
|
||||
auto slot = empty_slots.front();
|
||||
empty_slots.pop();
|
||||
XTargets[slot].dirty = true;
|
||||
XTargets[slot].ID = mob->GetID();
|
||||
strn0cpy(XTargets[slot].Name, mob->GetCleanName(), 64);
|
||||
}
|
||||
if (empty_slots.empty())
|
||||
break;
|
||||
}
|
||||
}
|
||||
m_dirtyautohaters = false;
|
||||
SendXTargetUpdates();
|
||||
}
|
||||
|
||||
// This function is called when a client is added to a group
|
||||
// Group leader joining isn't handled by this function
|
||||
void Client::JoinGroupXTargets(Group *g)
|
||||
{
|
||||
if (!g)
|
||||
return;
|
||||
|
||||
if (!GetXTargetAutoMgr()->empty()) {
|
||||
g->GetXTargetAutoMgr()->merge(*GetXTargetAutoMgr());
|
||||
GetXTargetAutoMgr()->clear();
|
||||
RemoveAutoXTargets();
|
||||
}
|
||||
|
||||
SetXTargetAutoMgr(g->GetXTargetAutoMgr());
|
||||
|
||||
if (!GetXTargetAutoMgr()->empty())
|
||||
SetDirtyAutoHaters();
|
||||
}
|
||||
|
||||
// This function is called when a client leaves a group
|
||||
void Client::LeaveGroupXTargets(Group *g)
|
||||
{
|
||||
if (!g)
|
||||
return;
|
||||
|
||||
SetXTargetAutoMgr(nullptr); // this will set it back to our manager
|
||||
RemoveAutoXTargets();
|
||||
entity_list.RefreshAutoXTargets(this); // this will probably break the temporal ordering, but whatever
|
||||
// We now have a rebuilt, valid auto hater manager, so we need to demerge from the groups
|
||||
if (!GetXTargetAutoMgr()->empty()) {
|
||||
GetXTargetAutoMgr()->demerge(*g->GetXTargetAutoMgr()); // this will remove entries where we only had aggro
|
||||
SetDirtyAutoHaters();
|
||||
}
|
||||
}
|
||||
|
||||
// This function is called when a client leaves a group
|
||||
void Client::LeaveRaidXTargets(Raid *r)
|
||||
{
|
||||
if (!r)
|
||||
return;
|
||||
|
||||
SetXTargetAutoMgr(nullptr); // this will set it back to our manager
|
||||
RemoveAutoXTargets();
|
||||
entity_list.RefreshAutoXTargets(this); // this will probably break the temporal ordering, but whatever
|
||||
// We now have a rebuilt, valid auto hater manager, so we need to demerge from the groups
|
||||
if (!GetXTargetAutoMgr()->empty()) {
|
||||
GetXTargetAutoMgr()->demerge(*r->GetXTargetAutoMgr()); // this will remove entries where we only had aggro
|
||||
SetDirtyAutoHaters();
|
||||
}
|
||||
}
|
||||
|
||||
void Client::SetMaxXTargets(uint8 NewMax)
|
||||
@@ -8623,3 +8772,169 @@ void Client::CheckRegionTypeChanges()
|
||||
else if (GetPVP())
|
||||
SetPVP(false, false);
|
||||
}
|
||||
|
||||
void Client::ProcessAggroMeter()
|
||||
{
|
||||
if (!AggroMeterAvailable()) {
|
||||
aggro_meter_timer.Disable();
|
||||
return;
|
||||
}
|
||||
|
||||
// we need to decide if we need to send OP_AggroMeterTargetInfo now
|
||||
// This packet sends the current lock target ID and the current target ID
|
||||
// target ID will be either our target or our target of target when we're targeting a PC
|
||||
bool send_targetinfo = false;
|
||||
auto cur_tar = GetTarget();
|
||||
|
||||
// probably should have PVP rules ...
|
||||
if (cur_tar && cur_tar != this) {
|
||||
if (cur_tar->IsNPC() && !cur_tar->IsPetOwnerClient() && cur_tar->GetID() != m_aggrometer.get_target_id()) {
|
||||
m_aggrometer.set_target_id(cur_tar->GetID());
|
||||
send_targetinfo = true;
|
||||
} else if ((cur_tar->IsPetOwnerClient() || cur_tar->IsClient()) && cur_tar->GetTarget() && cur_tar->GetTarget()->GetID() != m_aggrometer.get_target_id()) {
|
||||
m_aggrometer.set_target_id(cur_tar->GetTarget()->GetID());
|
||||
send_targetinfo = true;
|
||||
}
|
||||
} else if (m_aggrometer.get_target_id()) {
|
||||
m_aggrometer.set_target_id(0);
|
||||
send_targetinfo = true;
|
||||
}
|
||||
|
||||
if (m_aggrometer.update_lock())
|
||||
send_targetinfo = true;
|
||||
|
||||
if (send_targetinfo) {
|
||||
auto app = new EQApplicationPacket(OP_AggroMeterTargetInfo, sizeof(uint32) * 2);
|
||||
app->WriteUInt32(m_aggrometer.get_lock_id());
|
||||
app->WriteUInt32(m_aggrometer.get_target_id());
|
||||
FastQueuePacket(&app);
|
||||
}
|
||||
|
||||
// we could just calculate how big the packet would need to be ... but it's easier this way :P should be 87 bytes
|
||||
auto app = new EQApplicationPacket(OP_AggroMeterUpdate, m_aggrometer.max_packet_size());
|
||||
|
||||
cur_tar = entity_list.GetMob(m_aggrometer.get_target_id());
|
||||
|
||||
// first we must check the secondary
|
||||
// TODO: lock target should affect secondary as well
|
||||
bool send = false;
|
||||
Mob *secondary = nullptr;
|
||||
bool has_aggro = false;
|
||||
if (cur_tar) {
|
||||
if (cur_tar->GetTarget() == this) {// we got aggro
|
||||
secondary = cur_tar->GetSecondaryHate(this);
|
||||
has_aggro = true;
|
||||
} else {
|
||||
secondary = cur_tar->CheckAggro(cur_tar->GetTarget()) ? cur_tar->GetTarget() : nullptr; // make sure they are targeting for aggro reasons
|
||||
}
|
||||
}
|
||||
|
||||
if (secondary && secondary->GetID() != m_aggrometer.get_secondary_id()) {
|
||||
m_aggrometer.set_secondary_id(secondary->GetID());
|
||||
app->WriteUInt8(1);
|
||||
app->WriteUInt32(m_aggrometer.get_secondary_id());
|
||||
send = true;
|
||||
} else if (!secondary && m_aggrometer.get_secondary_id()) {
|
||||
m_aggrometer.set_secondary_id(0);
|
||||
app->WriteUInt8(1);
|
||||
app->WriteUInt32(0);
|
||||
send = true;
|
||||
} else { // might not need to send in this case
|
||||
app->WriteUInt8(0);
|
||||
}
|
||||
|
||||
auto count_offset = app->GetWritePosition();
|
||||
app->WriteUInt8(0);
|
||||
|
||||
int count = 0;
|
||||
auto add_entry = [&app, &count, this](AggroMeter::AggroTypes i) {
|
||||
count++;
|
||||
app->WriteUInt8(i);
|
||||
app->WriteUInt16(m_aggrometer.get_pct(i));
|
||||
};
|
||||
// TODO: Player entry should either be lock or yourself, ignoring lock for now
|
||||
// player, secondary, and group depend on your target/lock
|
||||
if (cur_tar) {
|
||||
if (m_aggrometer.set_pct(AggroMeter::AT_Player, cur_tar->GetHateRatio(cur_tar->GetTarget(), this)))
|
||||
add_entry(AggroMeter::AT_Player);
|
||||
|
||||
if (m_aggrometer.set_pct(AggroMeter::AT_Secondary, has_aggro ? cur_tar->GetHateRatio(this, secondary) : secondary ? 100 : 0))
|
||||
add_entry(AggroMeter::AT_Secondary);
|
||||
|
||||
// fuuuuuuuuuuuuuuuuuuuuuuuucckkkkkkkkkkkkkkk raids
|
||||
if (IsRaidGrouped()) {
|
||||
auto raid = GetRaid();
|
||||
if (raid) {
|
||||
auto gid = raid->GetGroup(this);
|
||||
if (gid < 12) {
|
||||
int at_id = AggroMeter::AT_Group1;
|
||||
for (int i = 0; i < MAX_RAID_MEMBERS; ++i) {
|
||||
if (raid->members[i].member && raid->members[i].member != this && raid->members[i].GroupNumber == gid) {
|
||||
if (m_aggrometer.set_pct(static_cast<AggroMeter::AggroTypes>(at_id), cur_tar->GetHateRatio(cur_tar->GetTarget(), raid->members[i].member)))
|
||||
add_entry(static_cast<AggroMeter::AggroTypes>(at_id));
|
||||
at_id++;
|
||||
if (at_id > AggroMeter::AT_Group5)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (IsGrouped()) {
|
||||
auto group = GetGroup();
|
||||
if (group) {
|
||||
int at_id = AggroMeter::AT_Group1;
|
||||
for (int i = 0; i < MAX_GROUP_MEMBERS; ++i) {
|
||||
if (group->members[i] && group->members[i] != this) {
|
||||
if (m_aggrometer.set_pct(static_cast<AggroMeter::AggroTypes>(at_id), cur_tar->GetHateRatio(cur_tar->GetTarget(), group->members[i])))
|
||||
add_entry(static_cast<AggroMeter::AggroTypes>(at_id));
|
||||
at_id++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else { // we might need to clear out some data now
|
||||
if (m_aggrometer.set_pct(AggroMeter::AT_Player, 0))
|
||||
add_entry(AggroMeter::AT_Player);
|
||||
if (m_aggrometer.set_pct(AggroMeter::AT_Secondary, 0))
|
||||
add_entry(AggroMeter::AT_Secondary);
|
||||
if (m_aggrometer.set_pct(AggroMeter::AT_Group1, 0))
|
||||
add_entry(AggroMeter::AT_Group1);
|
||||
if (m_aggrometer.set_pct(AggroMeter::AT_Group2, 0))
|
||||
add_entry(AggroMeter::AT_Group2);
|
||||
if (m_aggrometer.set_pct(AggroMeter::AT_Group3, 0))
|
||||
add_entry(AggroMeter::AT_Group3);
|
||||
if (m_aggrometer.set_pct(AggroMeter::AT_Group4, 0))
|
||||
add_entry(AggroMeter::AT_Group4);
|
||||
if (m_aggrometer.set_pct(AggroMeter::AT_Group5, 0))
|
||||
add_entry(AggroMeter::AT_Group5);
|
||||
}
|
||||
|
||||
// now to go over our xtargets
|
||||
// if the entry is an NPC it's our hate relative to the NPCs current tank
|
||||
// if it's a PC, it's their hate relative to our current target
|
||||
for (int i = 0; i < GetMaxXTargets(); ++i) {
|
||||
if (XTargets[i].ID) {
|
||||
auto mob = entity_list.GetMob(XTargets[i].ID);
|
||||
if (mob) {
|
||||
int ratio = 0;
|
||||
if (mob->IsNPC())
|
||||
ratio = mob->GetHateRatio(mob->GetTarget(), this);
|
||||
else if (cur_tar)
|
||||
ratio = cur_tar->GetHateRatio(cur_tar->GetTarget(), mob);
|
||||
if (m_aggrometer.set_pct(static_cast<AggroMeter::AggroTypes>(AggroMeter::AT_XTarget1 + i), ratio))
|
||||
add_entry(static_cast<AggroMeter::AggroTypes>(AggroMeter::AT_XTarget1 + i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (send || count) {
|
||||
app->size = app->GetWritePosition(); // this should be safe, although not recommended
|
||||
// but this way we can have a smaller buffer created for the packet dispatched to the client w/o resizing this one
|
||||
app->SetWritePosition(count_offset);
|
||||
app->WriteUInt8(count);
|
||||
FastQueuePacket(&app);
|
||||
} else {
|
||||
safe_delete(app);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+24
-9
@@ -48,6 +48,8 @@ namespace EQEmu
|
||||
#include "../common/inventory_profile.h"
|
||||
#include "../common/guilds.h"
|
||||
//#include "../common/item_data.h"
|
||||
#include "xtargetautohaters.h"
|
||||
#include "aggromanager.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "merc.h"
|
||||
@@ -221,18 +223,18 @@ public:
|
||||
|
||||
//abstract virtual function implementations required by base abstract class
|
||||
virtual bool Death(Mob* killerMob, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill);
|
||||
virtual void Damage(Mob* from, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false, int special = 0);
|
||||
virtual void Damage(Mob* from, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false, eSpecialAttacks special = eSpecialAttacks::None);
|
||||
virtual bool Attack(Mob* other, int Hand = EQEmu::inventory::slotPrimary, bool FromRiposte = false, bool IsStrikethrough = false, bool IsFromSpell = false,
|
||||
ExtraAttackOptions *opts = nullptr, int special = 0);
|
||||
ExtraAttackOptions *opts = nullptr);
|
||||
virtual bool HasRaid() { return (GetRaid() ? true : false); }
|
||||
virtual bool HasGroup() { return (GetGroup() ? true : false); }
|
||||
virtual Raid* GetRaid() { return entity_list.GetRaidByClient(this); }
|
||||
virtual Group* GetGroup() { return entity_list.GetGroupByClient(this); }
|
||||
virtual inline bool IsBerserk() { return berserk; }
|
||||
virtual int32 GetMeleeMitDmg(Mob *attacker, int32 damage, int32 minhit, float mit_rating, float atk_rating);
|
||||
virtual void SetAttackTimer();
|
||||
int GetQuiverHaste(int delay);
|
||||
void DoAttackRounds(Mob *target, int hand, bool IsFromSpell = false);
|
||||
int DoDamageCaps(int base_damage);
|
||||
|
||||
void AI_Init();
|
||||
void AI_Start(uint32 iMoveDelay = 0);
|
||||
@@ -418,8 +420,6 @@ public:
|
||||
|
||||
virtual void CalcBonuses();
|
||||
//these are all precalculated now
|
||||
inline virtual int32 GetAC() const { return AC; }
|
||||
inline virtual int32 GetATK() const { return ATK + itembonuses.ATK + spellbonuses.ATK + ((GetSTR() + GetSkill(EQEmu::skills::SkillOffense)) * 9 / 10); }
|
||||
inline virtual int32 GetATKBonus() const { return itembonuses.ATK + spellbonuses.ATK; }
|
||||
inline virtual int GetHaste() const { return Haste; }
|
||||
int GetRawACNoShield(int &shield_ac) const;
|
||||
@@ -1124,9 +1124,21 @@ public:
|
||||
void RemoveGroupXTargets();
|
||||
void RemoveAutoXTargets();
|
||||
void ShowXTargets(Client *c);
|
||||
inline XTargetAutoHaters *GetXTargetAutoMgr() { return m_activeautohatermgr; } // will be either raid or group or self
|
||||
inline void SetXTargetAutoMgr(XTargetAutoHaters *in) { if (in) m_activeautohatermgr = in; else m_activeautohatermgr = &m_autohatermgr; }
|
||||
inline void SetDirtyAutoHaters() { m_dirtyautohaters = true; }
|
||||
void ProcessXTargetAutoHaters(); // fixes up our auto haters
|
||||
void JoinGroupXTargets(Group *g);
|
||||
void LeaveGroupXTargets(Group *g);
|
||||
void LeaveRaidXTargets(Raid *r);
|
||||
bool GroupFollow(Client* inviter);
|
||||
inline bool GetRunMode() const { return runmode; }
|
||||
|
||||
inline bool AggroMeterAvailable() const { return ((m_ClientVersionBit & EQEmu::versions::bit_RoF2AndLater)) && RuleB(Character, EnableAggroMeter); } // RoF untested
|
||||
inline void SetAggroMeterLock(int in) { m_aggrometer.set_lock_id(in); }
|
||||
|
||||
void ProcessAggroMeter(); // builds packet and sends
|
||||
|
||||
void InitializeMercInfo();
|
||||
bool CheckCanSpawnMerc(uint32 template_id);
|
||||
bool CheckCanHireMerc(Mob* merchant, uint32 template_id);
|
||||
@@ -1292,7 +1304,7 @@ private:
|
||||
void OPGMEndTraining(const EQApplicationPacket *app);
|
||||
void OPGMTrainSkill(const EQApplicationPacket *app);
|
||||
void OPGMSummon(const EQApplicationPacket *app);
|
||||
void OPCombatAbility(const EQApplicationPacket *app);
|
||||
void OPCombatAbility(const CombatAbility_Struct *ca_atk);
|
||||
|
||||
// Bandolier Methods
|
||||
void CreateBandolier(const EQApplicationPacket *app);
|
||||
@@ -1301,9 +1313,6 @@ private:
|
||||
|
||||
void HandleTraderPriceUpdate(const EQApplicationPacket *app);
|
||||
|
||||
int32 CalcAC();
|
||||
int32 GetACMit();
|
||||
int32 GetACAvoid();
|
||||
int32 CalcATK();
|
||||
int32 CalcItemATKCap();
|
||||
int32 CalcHaste();
|
||||
@@ -1467,6 +1476,7 @@ private:
|
||||
Timer afk_toggle_timer;
|
||||
Timer helm_toggle_timer;
|
||||
Timer light_update_timer;
|
||||
Timer aggro_meter_timer;
|
||||
|
||||
glm::vec3 m_Proximity;
|
||||
|
||||
@@ -1551,8 +1561,13 @@ private:
|
||||
|
||||
uint8 MaxXTargets;
|
||||
bool XTargetAutoAddHaters;
|
||||
bool m_dirtyautohaters;
|
||||
|
||||
struct XTarget_Struct XTargets[XTARGET_HARDCAP];
|
||||
XTargetAutoHaters m_autohatermgr;
|
||||
XTargetAutoHaters *m_activeautohatermgr;
|
||||
|
||||
AggroMeter m_aggrometer;
|
||||
|
||||
Timer ItemTickTimer;
|
||||
Timer ItemQuestTimer;
|
||||
|
||||
@@ -1025,111 +1025,6 @@ int32 Client::acmod()
|
||||
return 0;
|
||||
};
|
||||
|
||||
// This is a testing formula for AC, the value this returns should be the same value as the one the client shows...
|
||||
// ac1 and ac2 are probably the damage migitation and damage avoidance numbers, not sure which is which.
|
||||
// I forgot to include the iksar defense bonus and i cant find my notes now...
|
||||
// AC from spells are not included (cant even cast spells yet..)
|
||||
int32 Client::CalcAC()
|
||||
{
|
||||
// new formula
|
||||
int avoidance = (acmod() + ((GetSkill(EQEmu::skills::SkillDefense) + itembonuses.HeroicAGI / 10) * 16) / 9);
|
||||
if (avoidance < 0) {
|
||||
avoidance = 0;
|
||||
}
|
||||
|
||||
if (RuleB(Character, EnableAvoidanceCap)) {
|
||||
if (avoidance > RuleI(Character, AvoidanceCap)) {
|
||||
avoidance = RuleI(Character, AvoidanceCap);
|
||||
}
|
||||
}
|
||||
|
||||
int mitigation = 0;
|
||||
if (m_pp.class_ == WIZARD || m_pp.class_ == MAGICIAN || m_pp.class_ == NECROMANCER || m_pp.class_ == ENCHANTER) {
|
||||
//something is wrong with this, naked casters have the wrong natural AC
|
||||
// mitigation = (spellbonuses.AC/3) + (GetSkill(DEFENSE)/2) + (itembonuses.AC+1);
|
||||
mitigation = (GetSkill(EQEmu::skills::SkillDefense) + itembonuses.HeroicAGI / 10) / 4 + (itembonuses.AC + 1);
|
||||
//this might be off by 4..
|
||||
mitigation -= 4;
|
||||
}
|
||||
else {
|
||||
// mitigation = (spellbonuses.AC/4) + (GetSkill(DEFENSE)/3) + ((itembonuses.AC*4)/3);
|
||||
mitigation = (GetSkill(EQEmu::skills::SkillDefense) + itembonuses.HeroicAGI / 10) / 3 + ((itembonuses.AC * 4) / 3);
|
||||
if (m_pp.class_ == MONK) {
|
||||
mitigation += GetLevel() * 13 / 10; //the 13/10 might be wrong, but it is close...
|
||||
}
|
||||
}
|
||||
int displayed = 0;
|
||||
displayed += ((avoidance + mitigation) * 1000) / 847; //natural AC
|
||||
//Iksar AC, untested
|
||||
if (GetRace() == IKSAR) {
|
||||
displayed += 12;
|
||||
int iksarlevel = GetLevel();
|
||||
iksarlevel -= 10;
|
||||
if (iksarlevel > 25) {
|
||||
iksarlevel = 25;
|
||||
}
|
||||
if (iksarlevel > 0) {
|
||||
displayed += iksarlevel * 12 / 10;
|
||||
}
|
||||
}
|
||||
// Shield AC bonus for HeroicSTR
|
||||
if (itembonuses.HeroicSTR) {
|
||||
bool equiped = CastToClient()->m_inv.GetItem(EQEmu::inventory::slotSecondary);
|
||||
if (equiped) {
|
||||
uint8 shield = CastToClient()->m_inv.GetItem(EQEmu::inventory::slotSecondary)->GetItem()->ItemType;
|
||||
if (shield == EQEmu::item::ItemTypeShield) {
|
||||
displayed += itembonuses.HeroicSTR / 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
//spell AC bonuses are added directly to natural total
|
||||
displayed += spellbonuses.AC;
|
||||
AC = displayed;
|
||||
return (AC);
|
||||
}
|
||||
|
||||
int32 Client::GetACMit()
|
||||
{
|
||||
int mitigation = 0;
|
||||
if (m_pp.class_ == WIZARD || m_pp.class_ == MAGICIAN || m_pp.class_ == NECROMANCER || m_pp.class_ == ENCHANTER) {
|
||||
mitigation = (GetSkill(EQEmu::skills::SkillDefense) + itembonuses.HeroicAGI / 10) / 4 + (itembonuses.AC + 1);
|
||||
mitigation -= 4;
|
||||
}
|
||||
else {
|
||||
mitigation = (GetSkill(EQEmu::skills::SkillDefense) + itembonuses.HeroicAGI / 10) / 3 + ((itembonuses.AC * 4) / 3);
|
||||
if (m_pp.class_ == MONK) {
|
||||
mitigation += GetLevel() * 13 / 10; //the 13/10 might be wrong, but it is close...
|
||||
}
|
||||
}
|
||||
// Shield AC bonus for HeroicSTR
|
||||
if (itembonuses.HeroicSTR) {
|
||||
bool equiped = CastToClient()->m_inv.GetItem(EQEmu::inventory::slotSecondary);
|
||||
if (equiped) {
|
||||
uint8 shield = CastToClient()->m_inv.GetItem(EQEmu::inventory::slotSecondary)->GetItem()->ItemType;
|
||||
if (shield == EQEmu::item::ItemTypeShield) {
|
||||
mitigation += itembonuses.HeroicSTR / 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (mitigation * 1000 / 847);
|
||||
}
|
||||
|
||||
int32 Client::GetACAvoid()
|
||||
{
|
||||
int32 avoidance = (acmod() + ((GetSkill(EQEmu::skills::SkillDefense) + itembonuses.HeroicAGI / 10) * 16) / 9);
|
||||
if (avoidance < 0) {
|
||||
avoidance = 0;
|
||||
}
|
||||
|
||||
if (RuleB(Character, EnableAvoidanceCap)) {
|
||||
if ((avoidance * 1000 / 847) > RuleI(Character, AvoidanceCap)) {
|
||||
return RuleI(Character, AvoidanceCap);
|
||||
}
|
||||
}
|
||||
|
||||
return (avoidance * 1000 / 847);
|
||||
}
|
||||
|
||||
int32 Client::CalcMaxMana()
|
||||
{
|
||||
switch (GetCasterClass()) {
|
||||
|
||||
+192
-43
@@ -120,6 +120,7 @@ void MapOpcodes()
|
||||
ConnectedOpcodes[OP_AdventureMerchantSell] = &Client::Handle_OP_AdventureMerchantSell;
|
||||
ConnectedOpcodes[OP_AdventureRequest] = &Client::Handle_OP_AdventureRequest;
|
||||
ConnectedOpcodes[OP_AdventureStatsRequest] = &Client::Handle_OP_AdventureStatsRequest;
|
||||
ConnectedOpcodes[OP_AggroMeterLockTarget] = &Client::Handle_OP_AggroMeterLockTarget;
|
||||
ConnectedOpcodes[OP_AltCurrencyMerchantRequest] = &Client::Handle_OP_AltCurrencyMerchantRequest;
|
||||
ConnectedOpcodes[OP_AltCurrencyPurchase] = &Client::Handle_OP_AltCurrencyPurchase;
|
||||
ConnectedOpcodes[OP_AltCurrencyReclaim] = &Client::Handle_OP_AltCurrencyReclaim;
|
||||
@@ -575,6 +576,11 @@ void Client::CompleteConnect()
|
||||
}
|
||||
}
|
||||
raid->SendGroupLeadershipAA(this, grpID); // this may get sent an extra time ...
|
||||
|
||||
SetXTargetAutoMgr(raid->GetXTargetAutoMgr());
|
||||
if (!GetXTargetAutoMgr()->empty())
|
||||
SetDirtyAutoHaters();
|
||||
|
||||
if (raid->IsLocked())
|
||||
raid->SendRaidLockTo(this);
|
||||
}
|
||||
@@ -1548,8 +1554,8 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
|
||||
// we purchased a new one while out-of-zone.
|
||||
if (group->IsLeader(this))
|
||||
group->SendLeadershipAAUpdate();
|
||||
|
||||
}
|
||||
JoinGroupXTargets(group);
|
||||
group->UpdatePlayer(this);
|
||||
LFG = false;
|
||||
}
|
||||
@@ -2395,6 +2401,17 @@ void Client::Handle_OP_AdventureStatsRequest(const EQApplicationPacket *app)
|
||||
FastQueuePacket(&outapp);
|
||||
}
|
||||
|
||||
void Client::Handle_OP_AggroMeterLockTarget(const EQApplicationPacket *app)
|
||||
{
|
||||
if (app->size < sizeof(uint32)) {
|
||||
Log.Out(Logs::General, Logs::Error, "Handle_OP_AggroMeterLockTarget had a packet that was too small.");
|
||||
return;
|
||||
}
|
||||
|
||||
SetAggroMeterLock(app->ReadUInt32(0));
|
||||
ProcessAggroMeter();
|
||||
}
|
||||
|
||||
void Client::Handle_OP_AltCurrencyMerchantRequest(const EQApplicationPacket *app)
|
||||
{
|
||||
VERIFY_PACKET_LENGTH(OP_AltCurrencyMerchantRequest, app, uint32);
|
||||
@@ -3878,10 +3895,19 @@ void Client::Handle_OP_BuffRemoveRequest(const EQApplicationPacket *app)
|
||||
|
||||
Mob *m = nullptr;
|
||||
|
||||
if (brrs->EntityID == GetID())
|
||||
if (brrs->EntityID == GetID()) {
|
||||
m = this;
|
||||
else if (brrs->EntityID == GetPetID())
|
||||
}
|
||||
else if (brrs->EntityID == GetPetID()) {
|
||||
m = GetPet();
|
||||
}
|
||||
#ifdef BOTS
|
||||
else {
|
||||
Mob* bot_test = entity_list.GetMob(brrs->EntityID);
|
||||
if (bot_test && bot_test->IsBot() && bot_test->GetOwner() == this)
|
||||
m = bot_test;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!m)
|
||||
return;
|
||||
@@ -4346,7 +4372,7 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app)
|
||||
new EQApplicationPacket(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct));
|
||||
PlayerPositionUpdateServer_Struct* ppus = (PlayerPositionUpdateServer_Struct*)outapp->pBuffer;
|
||||
boat->MakeSpawnUpdate(ppus);
|
||||
entity_list.QueueCloseClients(boat,outapp,true,300,this,false);
|
||||
entity_list.QueueCloseClients(boat, outapp, true, 300, this, false);
|
||||
safe_delete(outapp);
|
||||
// update the boat's position on the server, without sending an update
|
||||
boat->GMMove(ppu->x_pos, ppu->y_pos, ppu->z_pos, EQ19toFloat(ppu->heading), false);
|
||||
@@ -4580,9 +4606,9 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app)
|
||||
PlayerPositionUpdateServer_Struct* ppu = (PlayerPositionUpdateServer_Struct*)outapp->pBuffer;
|
||||
MakeSpawnUpdate(ppu);
|
||||
if (gmhideme)
|
||||
entity_list.QueueClientsStatus(this,outapp,true,Admin(),250);
|
||||
entity_list.QueueClientsStatus(this, outapp, true, Admin(), 250);
|
||||
else
|
||||
entity_list.QueueCloseClients(this,outapp,true,300,nullptr,false);
|
||||
entity_list.QueueCloseClients(this, outapp, true, 300, nullptr, false);
|
||||
safe_delete(outapp);
|
||||
}
|
||||
|
||||
@@ -4622,7 +4648,8 @@ void Client::Handle_OP_CombatAbility(const EQApplicationPacket *app)
|
||||
std::cout << "Wrong size on OP_CombatAbility. Got: " << app->size << ", Expected: " << sizeof(CombatAbility_Struct) << std::endl;
|
||||
return;
|
||||
}
|
||||
OPCombatAbility(app);
|
||||
auto ca_atk = (CombatAbility_Struct *)app->pBuffer;
|
||||
OPCombatAbility(ca_atk);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -4701,12 +4728,22 @@ void Client::Handle_OP_Consider(const EQApplicationPacket *app)
|
||||
else
|
||||
con->faction = 1;
|
||||
con->level = GetLevelCon(tmob->GetLevel());
|
||||
|
||||
if (ClientVersion() <= EQEmu::versions::ClientVersion::Titanium) {
|
||||
if (con->level == CON_GRAY) {
|
||||
con->level = CON_GREEN;
|
||||
}
|
||||
if (con->level == CON_WHITE) {
|
||||
con->level = CON_WHITE_TITANIUM;
|
||||
}
|
||||
}
|
||||
|
||||
if (zone->IsPVPZone()) {
|
||||
if (!tmob->IsNPC())
|
||||
con->pvpcon = tmob->CastToClient()->GetPVP();
|
||||
}
|
||||
|
||||
// Mongrel: If we're feigned show NPC as indifferent
|
||||
// If we're feigned show NPC as indifferent
|
||||
if (tmob->IsNPC())
|
||||
{
|
||||
if (GetFeigned())
|
||||
@@ -4752,6 +4789,7 @@ void Client::Handle_OP_Consider(const EQApplicationPacket *app)
|
||||
case CON_BLUE:
|
||||
color = 4;
|
||||
break;
|
||||
case CON_WHITE_TITANIUM:
|
||||
case CON_WHITE:
|
||||
color = 10;
|
||||
break;
|
||||
@@ -4761,7 +4799,17 @@ void Client::Handle_OP_Consider(const EQApplicationPacket *app)
|
||||
case CON_RED:
|
||||
color = 13;
|
||||
break;
|
||||
case CON_GRAY:
|
||||
color = 6;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ClientVersion() <= EQEmu::versions::ClientVersion::Titanium) {
|
||||
if (color == 6) {
|
||||
color = 2;
|
||||
}
|
||||
}
|
||||
|
||||
SendColoredText(color, std::string("This creature would take an army to defeat!"));
|
||||
}
|
||||
safe_delete(outapp);
|
||||
@@ -5461,7 +5509,7 @@ void Client::Handle_OP_Emote(const EQApplicationPacket *app)
|
||||
}
|
||||
else
|
||||
*/
|
||||
entity_list.QueueCloseClients(this, outapp, true, 100, 0, true, FilterSocials);
|
||||
entity_list.QueueCloseClients(this, outapp, true, RuleI(Range, Emote), 0, true, FilterSocials);
|
||||
|
||||
safe_delete(outapp);
|
||||
return;
|
||||
@@ -6488,12 +6536,43 @@ void Client::Handle_OP_GroupDisband(const EQApplicationPacket *app)
|
||||
if (!group) //We must recheck this here.. incase the final bot disbanded the party..otherwise we crash
|
||||
return;
|
||||
#endif
|
||||
Mob* memberToDisband = GetTarget();
|
||||
|
||||
if (!memberToDisband)
|
||||
memberToDisband = entity_list.GetMob(gd->name2);
|
||||
|
||||
if (memberToDisband) {
|
||||
auto group2 = memberToDisband->GetGroup();
|
||||
if (group2 != group) // they're not in our group!
|
||||
memberToDisband = this;
|
||||
}
|
||||
|
||||
if (group->GroupCount() < 3)
|
||||
{
|
||||
group->DisbandGroup();
|
||||
if (GetMerc())
|
||||
GetMerc()->Suspend();
|
||||
if (!RuleB(Mercs, AllowMercSuspendInCombat)) {
|
||||
if (GetMerc())
|
||||
{
|
||||
Mob* mercOwner = GetMerc()->GetOwner();
|
||||
if (mercOwner && mercOwner->IsClient()) {
|
||||
if (mercOwner->CastToClient()->CheckCanSpawnMerc(mercOwner->CastToClient()->GetMercInfo().MercTemplateID)) {
|
||||
group->DisbandGroup();
|
||||
GetMerc()->Suspend();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
group->DisbandGroup();
|
||||
if (GetMerc())
|
||||
GetMerc()->Suspend();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
group->DisbandGroup();
|
||||
if (GetMerc())
|
||||
GetMerc()->Suspend();
|
||||
}
|
||||
}
|
||||
else if (group->IsLeader(this) && GetTarget() == nullptr)
|
||||
{
|
||||
@@ -6504,12 +6583,33 @@ void Client::Handle_OP_GroupDisband(const EQApplicationPacket *app)
|
||||
}
|
||||
else
|
||||
{
|
||||
group->DisbandGroup();
|
||||
if (GetMerc())
|
||||
GetMerc()->Suspend();
|
||||
if (!RuleB(Mercs, AllowMercSuspendInCombat)) {
|
||||
if (GetMerc())
|
||||
{
|
||||
Mob* mercOwner = GetMerc()->GetOwner();
|
||||
if (mercOwner && mercOwner->IsClient()) {
|
||||
if (mercOwner->CastToClient()->CheckCanSpawnMerc(mercOwner->CastToClient()->GetMercInfo().MercTemplateID)) {
|
||||
group->DisbandGroup();
|
||||
GetMerc()->Suspend();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
group->DisbandGroup();
|
||||
if (GetMerc())
|
||||
GetMerc()->Suspend();
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
group->DisbandGroup();
|
||||
if (GetMerc())
|
||||
GetMerc()->Suspend();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (group->IsLeader(this) && GetTarget() == this)
|
||||
else if (group->IsLeader(this) && (GetTarget() == this || memberToDisband == this))
|
||||
{
|
||||
LeaveGroup();
|
||||
if (GetMerc() && !GetMerc()->IsSuspended())
|
||||
@@ -6519,19 +6619,12 @@ void Client::Handle_OP_GroupDisband(const EQApplicationPacket *app)
|
||||
}
|
||||
else
|
||||
{
|
||||
Mob* memberToDisband = nullptr;
|
||||
memberToDisband = GetTarget();
|
||||
|
||||
if (!memberToDisband)
|
||||
memberToDisband = entity_list.GetMob(gd->name2);
|
||||
|
||||
if (memberToDisband)
|
||||
{
|
||||
if (group->IsLeader(this))
|
||||
{
|
||||
// the group leader can kick other members out of the group...
|
||||
if (memberToDisband->IsClient())
|
||||
{
|
||||
if (memberToDisband->IsClient()) {
|
||||
group->DelMember(memberToDisband, false);
|
||||
Client* memberClient = memberToDisband->CastToClient();
|
||||
Merc* memberMerc = memberToDisband->CastToClient()->GetMerc();
|
||||
@@ -6540,9 +6633,19 @@ void Client::Handle_OP_GroupDisband(const EQApplicationPacket *app)
|
||||
memberMerc->MercJoinClientGroup();
|
||||
}
|
||||
}
|
||||
else if (memberToDisband->IsMerc())
|
||||
{
|
||||
memberToDisband->CastToMerc()->Suspend();
|
||||
else if (memberToDisband->IsMerc()) {
|
||||
//Can only remove mercs that aren't in combat if the rule is set.
|
||||
if (!RuleB(Mercs, AllowMercSuspendInCombat)) {
|
||||
Mob* mercOwner = memberToDisband->CastToMerc()->GetOwner();
|
||||
if (mercOwner && mercOwner->IsClient()) {
|
||||
if (mercOwner->CastToClient()->CheckCanSpawnMerc(mercOwner->CastToClient()->GetMercInfo().MercTemplateID)) {
|
||||
memberToDisband->CastToMerc()->Suspend();
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
memberToDisband->CastToMerc()->Suspend();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -10805,7 +10908,8 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app)
|
||||
}
|
||||
}
|
||||
}
|
||||
g->DisbandGroup();
|
||||
g->JoinRaidXTarget(r);
|
||||
g->DisbandGroup(true);
|
||||
r->GroupUpdate(freeGroup);
|
||||
}
|
||||
else{
|
||||
@@ -10870,7 +10974,8 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app)
|
||||
}
|
||||
}
|
||||
}
|
||||
ig->DisbandGroup();
|
||||
ig->JoinRaidXTarget(r, true);
|
||||
ig->DisbandGroup(true);
|
||||
r->GroupUpdate(groupFree);
|
||||
groupFree = r->GetFreeGroup();
|
||||
}
|
||||
@@ -10923,10 +11028,11 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app)
|
||||
}
|
||||
}
|
||||
}
|
||||
g->DisbandGroup();
|
||||
g->JoinRaidXTarget(r);
|
||||
g->DisbandGroup(true);
|
||||
r->GroupUpdate(groupFree);
|
||||
}
|
||||
else
|
||||
else // target does not have a group
|
||||
{
|
||||
if (ig){
|
||||
r = new Raid(i);
|
||||
@@ -10980,14 +11086,15 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket *app)
|
||||
r->SendRaidCreate(this);
|
||||
r->SendMakeLeaderPacketTo(r->leadername, this);
|
||||
r->SendBulkRaid(this);
|
||||
ig->JoinRaidXTarget(r, true);
|
||||
r->AddMember(this);
|
||||
ig->DisbandGroup();
|
||||
ig->DisbandGroup(true);
|
||||
r->GroupUpdate(0);
|
||||
if (r->IsLocked()) {
|
||||
r->SendRaidLockTo(this);
|
||||
}
|
||||
}
|
||||
else{
|
||||
else{ // neither has a group
|
||||
r = new Raid(i);
|
||||
entity_list.AddRaid(r);
|
||||
r->SetRaidDetails();
|
||||
@@ -12418,14 +12525,33 @@ void Client::Handle_OP_ShopPlayerSell(const EQApplicationPacket *app)
|
||||
return;
|
||||
}
|
||||
|
||||
int cost_quantity = mp->quantity;
|
||||
uint32 cost_quantity = mp->quantity;
|
||||
if (inst->IsCharged())
|
||||
int cost_quantity = 1;
|
||||
uint32 cost_quantity = 1;
|
||||
|
||||
uint32 i;
|
||||
|
||||
if (RuleB(Merchant, UsePriceMod)) {
|
||||
for (i = 1; i <= cost_quantity; i++) {
|
||||
price = (uint32)((item->Price * i)*(RuleR(Merchant, BuyCostMod))*Client::CalcPriceMod(vendor, true) + 0.5); // need to round up, because client does it automatically when displaying price
|
||||
if (price > 4000000000) {
|
||||
cost_quantity = i;
|
||||
mp->quantity = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i = 1; i <= cost_quantity; i++) {
|
||||
price = (uint32)((item->Price * i)*(RuleR(Merchant, BuyCostMod)) + 0.5); // need to round up, because client does it automatically when displaying price
|
||||
if (price > 4000000000) {
|
||||
cost_quantity = i;
|
||||
mp->quantity = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (RuleB(Merchant, UsePriceMod))
|
||||
price = (int)((item->Price*cost_quantity)*(RuleR(Merchant, BuyCostMod))*Client::CalcPriceMod(vendor, true) + 0.5); // need to round up, because client does it automatically when displaying price
|
||||
else
|
||||
price = (int)((item->Price*cost_quantity)*(RuleR(Merchant, BuyCostMod)) + 0.5);
|
||||
AddMoneyToPP(price, false);
|
||||
|
||||
if (inst->IsStackable() || inst->IsCharged())
|
||||
@@ -12513,8 +12639,25 @@ void Client::Handle_OP_ShopPlayerSell(const EQApplicationPacket *app)
|
||||
// Now remove the item from the player, this happens regardless of outcome
|
||||
if (!inst->IsStackable())
|
||||
this->DeleteItemInInventory(mp->itemslot, 0, false);
|
||||
else
|
||||
this->DeleteItemInInventory(mp->itemslot, mp->quantity, false);
|
||||
else {
|
||||
// HACK: DeleteItemInInventory uses int8 for quantity type. There is no consistent use of types in code in this path so for now iteratively delete from inventory.
|
||||
if (mp->quantity > 255) {
|
||||
uint32 temp = mp->quantity;
|
||||
while (temp > 255 && temp != 0) {
|
||||
// Delete chunks of 255
|
||||
this->DeleteItemInInventory(mp->itemslot, 255, false);
|
||||
temp -= 255;
|
||||
}
|
||||
if (temp != 0) {
|
||||
// Delete remaining
|
||||
this->DeleteItemInInventory(mp->itemslot, temp, false);
|
||||
}
|
||||
}
|
||||
else {
|
||||
this->DeleteItemInInventory(mp->itemslot, mp->quantity, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//This forces the price to show up correctly for charged items.
|
||||
if (inst->IsCharged())
|
||||
@@ -12997,9 +13140,14 @@ void Client::Handle_OP_TargetCommand(const EQApplicationPacket *app)
|
||||
}
|
||||
}
|
||||
if (GetGM() || RuleB(Spells, AlwaysSendTargetsBuffs) || nt == this || inspect_buffs || (nt->IsClient() && !nt->CastToClient()->GetPVP()) ||
|
||||
(nt->IsPet() && nt->GetOwner() && nt->GetOwner()->IsClient() && !nt->GetOwner()->CastToClient()->GetPVP()) ||
|
||||
(nt->IsMerc() && nt->GetOwner() && nt->GetOwner()->IsClient() && !nt->GetOwner()->CastToClient()->GetPVP()))
|
||||
(nt->IsPet() && nt->GetOwner() && nt->GetOwner()->IsClient() && !nt->GetOwner()->CastToClient()->GetPVP()) ||
|
||||
#ifdef BOTS
|
||||
(nt->IsBot() && nt->GetOwner() && nt->GetOwner()->IsClient() && !nt->GetOwner()->CastToClient()->GetPVP()) || // TODO: bot pets
|
||||
#endif
|
||||
(nt->IsMerc() && nt->GetOwner() && nt->GetOwner()->IsClient() && !nt->GetOwner()->CastToClient()->GetPVP()))
|
||||
{
|
||||
nt->SendBuffsToClient(this);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -14086,6 +14234,7 @@ void Client::Handle_OP_XTargetAutoAddHaters(const EQApplicationPacket *app)
|
||||
}
|
||||
|
||||
XTargetAutoAddHaters = app->ReadUInt8(0);
|
||||
SetDirtyAutoHaters();
|
||||
}
|
||||
|
||||
void Client::Handle_OP_XTargetOpen(const EQApplicationPacket *app)
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
void Handle_OP_AdventureMerchantSell(const EQApplicationPacket *app);
|
||||
void Handle_OP_AdventureRequest(const EQApplicationPacket *app);
|
||||
void Handle_OP_AdventureStatsRequest(const EQApplicationPacket *app);
|
||||
void Handle_OP_AggroMeterLockTarget(const EQApplicationPacket *app);
|
||||
void Handle_OP_AltCurrencyMerchantRequest(const EQApplicationPacket *app);
|
||||
void Handle_OP_AltCurrencyPurchase(const EQApplicationPacket *app);
|
||||
void Handle_OP_AltCurrencyReclaim(const EQApplicationPacket *app);
|
||||
|
||||
@@ -681,6 +681,13 @@ bool Client::Process() {
|
||||
Message(0, "Your enemies have forgotten you!");
|
||||
}
|
||||
|
||||
if (client_state == CLIENT_CONNECTED) {
|
||||
if (m_dirtyautohaters)
|
||||
ProcessXTargetAutoHaters();
|
||||
if (aggro_meter_timer.Check())
|
||||
ProcessAggroMeter();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -10686,7 +10686,7 @@ void command_logs(Client *c, const Seperator *sep){
|
||||
/* We use a general 'is_category_enabled' now, let's update when we update any output settings
|
||||
This is used in hot places of code to check if its enabled in any way before triggering logs
|
||||
*/
|
||||
if (sep->arg[4] > 0){
|
||||
if (atoi(sep->arg[4]) > 0){
|
||||
Log.log_settings[atoi(sep->arg[3])].is_category_enabled = 1;
|
||||
}
|
||||
else{
|
||||
|
||||
+30
-3
@@ -31,9 +31,18 @@
|
||||
#define CON_GREEN 2
|
||||
#define CON_LIGHTBLUE 18
|
||||
#define CON_BLUE 4
|
||||
#define CON_WHITE 20
|
||||
#define CON_WHITE 10
|
||||
#define CON_WHITE_TITANIUM 20
|
||||
#define CON_YELLOW 15
|
||||
#define CON_RED 13
|
||||
#define CON_GRAY 6
|
||||
|
||||
#define DMG_BLOCKED -1
|
||||
#define DMG_PARRIED -2
|
||||
#define DMG_RIPOSTED -3
|
||||
#define DMG_DODGED -4
|
||||
#define DMG_INVULNERABLE -5
|
||||
#define DMG_RUNE -6
|
||||
|
||||
//Spell specialization parameters, not sure of a better place for them
|
||||
#define SPECIALIZE_FIZZLE 11 //% fizzle chance reduce at 200 specialized
|
||||
@@ -464,9 +473,9 @@ struct StatBonuses {
|
||||
int8 CriticalMend; // chance critical monk mend
|
||||
int32 ImprovedReclaimEnergy; // Modifies amount of mana returned from reclaim energy
|
||||
uint32 HeadShot[2]; // Headshot AA (Massive dmg vs humaniod w/ archery) 0= ? 1= Dmg
|
||||
uint8 HSLevel; // Max Level Headshot will be effective at.
|
||||
uint8 HSLevel[2]; // Max Level Headshot will be effective at. and chance mod
|
||||
uint32 Assassinate[2]; // Assassinate AA (Massive dmg vs humaniod w/ assassinate) 0= ? 1= Dmg
|
||||
uint8 AssassinateLevel; // Max Level Assassinate will be effective at.
|
||||
uint8 AssassinateLevel[2]; // Max Level Assassinate will be effective at.
|
||||
int32 PetMeleeMitigation; // Add AC to owner's pet.
|
||||
bool IllusionPersistence; // Causes illusions not to fade.
|
||||
uint16 extra_xtargets; // extra xtarget entries
|
||||
@@ -638,5 +647,23 @@ struct ExtraAttackOptions {
|
||||
|
||||
};
|
||||
|
||||
struct DamageTable {
|
||||
int32 max_extra; // max extra damage
|
||||
int32 chance; // chance not to apply?
|
||||
int32 minusfactor; // difficulty of rolling
|
||||
};
|
||||
|
||||
struct DamageHitInfo {
|
||||
//uint16 attacker; // id
|
||||
//uint16 defender; // id
|
||||
int base_damage;
|
||||
int min_damage;
|
||||
int damage_done;
|
||||
int offense;
|
||||
int tohit;
|
||||
int hand;
|
||||
EQEmu::skills::SkillType skill;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1087,7 +1087,6 @@ void Corpse::LootItem(Client *client, const EQApplicationPacket *app)
|
||||
}
|
||||
|
||||
if (!IsBeingLootedBy(client)) {
|
||||
client->Message(13, "Error: Corpse::LootItem: BeingLootedBy != client");
|
||||
client->QueuePacket(app);
|
||||
SendEndLootErrorPacket(client);
|
||||
return;
|
||||
|
||||
+2
-2
@@ -52,8 +52,8 @@ class Corpse : public Mob {
|
||||
|
||||
/* Corpse: General */
|
||||
virtual bool Death(Mob* killerMob, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill) { return true; }
|
||||
virtual void Damage(Mob* from, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false, int special = 0) { return; }
|
||||
virtual bool Attack(Mob* other, int Hand = EQEmu::inventory::slotPrimary, bool FromRiposte = false, bool IsStrikethrough = true, bool IsFromSpell = false, ExtraAttackOptions *opts = nullptr, int special = 0) { return false; }
|
||||
virtual void Damage(Mob* from, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false, eSpecialAttacks special = eSpecialAttacks::None) { return; }
|
||||
virtual bool Attack(Mob* other, int Hand = EQEmu::inventory::slotPrimary, bool FromRiposte = false, bool IsStrikethrough = true, bool IsFromSpell = false, ExtraAttackOptions *opts = nullptr) { return false; }
|
||||
virtual bool HasRaid() { return false; }
|
||||
virtual bool HasGroup() { return false; }
|
||||
virtual Raid* GetRaid() { return 0; }
|
||||
|
||||
+1
-1
@@ -795,7 +795,7 @@ void EntityList::AESpell(Mob *caster, Mob *center, uint16 spell_id, bool affect_
|
||||
continue;
|
||||
if (dist_targ < min_range2) //make sure they are in range
|
||||
continue;
|
||||
if (isnpc && curmob->IsNPC()) { //check npc->npc casting
|
||||
if (isnpc && curmob->IsNPC() && spells[spell_id].targettype != ST_AreaNPCOnly) { //check npc->npc casting
|
||||
FACTION_VALUE f = curmob->GetReverseFactionCon(caster);
|
||||
if (bad) {
|
||||
//affect mobs that are on our hate list, or
|
||||
|
||||
+2
-2
@@ -35,9 +35,9 @@ public:
|
||||
|
||||
//abstract virtual function implementations required by base abstract class
|
||||
virtual bool Death(Mob* killerMob, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill) { return true; }
|
||||
virtual void Damage(Mob* from, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false, int special = 0) { return; }
|
||||
virtual void Damage(Mob* from, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false, eSpecialAttacks special = eSpecialAttacks::None) { return; }
|
||||
virtual bool Attack(Mob* other, int Hand = EQEmu::inventory::slotPrimary, bool FromRiposte = false, bool IsStrikethrough = false, bool IsFromSpell = false,
|
||||
ExtraAttackOptions *opts = nullptr, int special = 0) {
|
||||
ExtraAttackOptions *opts = nullptr) {
|
||||
return false;
|
||||
}
|
||||
virtual bool HasRaid() { return false; }
|
||||
|
||||
+22
-12
@@ -408,10 +408,10 @@ void EntityList::RaidProcess()
|
||||
|
||||
void EntityList::DoorProcess()
|
||||
{
|
||||
#ifdef IDLE_WHEN_EMPTY
|
||||
if (numclients < 1)
|
||||
return;
|
||||
#endif
|
||||
if (RuleB(Zone, IdleWhenEmpty)) {
|
||||
if (numclients < 1)
|
||||
return;
|
||||
}
|
||||
if (door_list.empty()) {
|
||||
net.door_timer.Disable();
|
||||
return;
|
||||
@@ -477,7 +477,7 @@ void EntityList::MobProcess()
|
||||
|
||||
size_t sz = mob_list.size();
|
||||
|
||||
#ifdef IDLE_WHEN_EMPTY
|
||||
if (RuleB(Zone, IdleWhenEmpty)) {
|
||||
if (numclients > 0 ||
|
||||
mob->GetWanderType() == 4 || mob->GetWanderType() == 6) {
|
||||
// Normal processing, or assuring that spawns that should
|
||||
@@ -490,9 +490,11 @@ void EntityList::MobProcess()
|
||||
// At the very least, process that.
|
||||
mob_dead = mob->CastToNPC()->GetDepop();
|
||||
}
|
||||
#else
|
||||
}
|
||||
else
|
||||
{
|
||||
mob_dead = !mob->Process();
|
||||
#endif
|
||||
}
|
||||
size_t a_sz = mob_list.size();
|
||||
|
||||
if(a_sz > sz) {
|
||||
@@ -1404,15 +1406,15 @@ void EntityList::RemoveFromTargets(Mob *mob, bool RemoveFromXTargets)
|
||||
if (!m)
|
||||
continue;
|
||||
|
||||
m->RemoveFromHateList(mob);
|
||||
|
||||
if (RemoveFromXTargets) {
|
||||
if (m->IsClient())
|
||||
if (m->IsClient() && mob->CheckAggro(m))
|
||||
m->CastToClient()->RemoveXTarget(mob, false);
|
||||
// FadingMemories calls this function passing the client.
|
||||
else if (mob->IsClient())
|
||||
else if (mob->IsClient() && m->CheckAggro(mob))
|
||||
mob->CastToClient()->RemoveXTarget(m, false);
|
||||
}
|
||||
|
||||
m->RemoveFromHateList(mob);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2557,6 +2559,8 @@ void EntityList::RemoveFromHateLists(Mob *mob, bool settoone)
|
||||
it->second->RemoveFromHateList(mob);
|
||||
else
|
||||
it->second->SetHateAmountOnEnt(mob, 1);
|
||||
if (mob->IsClient())
|
||||
mob->CastToClient()->RemoveXTarget(it->second, false); // gotta do book keeping
|
||||
}
|
||||
++it;
|
||||
}
|
||||
@@ -2978,10 +2982,16 @@ void EntityList::Evade(Mob *who)
|
||||
//removes "targ" from all hate lists, including feigned, in the zone
|
||||
void EntityList::ClearAggro(Mob* targ)
|
||||
{
|
||||
Client *c = nullptr;
|
||||
if (targ->IsClient())
|
||||
c = targ->CastToClient();
|
||||
auto it = npc_list.begin();
|
||||
while (it != npc_list.end()) {
|
||||
if (it->second->CheckAggro(targ))
|
||||
if (it->second->CheckAggro(targ)) {
|
||||
if (c)
|
||||
c->RemoveXTarget(it->second, false);
|
||||
it->second->RemoveFromHateList(targ);
|
||||
}
|
||||
it->second->RemoveFromFeignMemory(targ->CastToClient()); //just in case we feigned
|
||||
++it;
|
||||
}
|
||||
|
||||
+2
-2
@@ -413,7 +413,7 @@ public:
|
||||
Mob* AICheckCloseAggro(Mob* sender, float iAggroRange, float iAssistRange);
|
||||
int GetHatedCount(Mob *attacker, Mob *exclude);
|
||||
void AIYellForHelp(Mob* sender, Mob* attacker);
|
||||
bool AICheckCloseBeneficialSpells(NPC* caster, uint8 iChance, float iRange, uint16 iSpellTypes);
|
||||
bool AICheckCloseBeneficialSpells(NPC* caster, uint8 iChance, float iRange, uint32 iSpellTypes);
|
||||
bool Merc_AICheckCloseBeneficialSpells(Merc* caster, uint8 iChance, float iRange, uint32 iSpellTypes);
|
||||
Mob* GetTargetForMez(Mob* caster);
|
||||
uint32 CheckNPCsClose(Mob *center);
|
||||
@@ -502,7 +502,7 @@ private:
|
||||
Bot* GetBotByBotName(std::string botName);
|
||||
std::list<Bot*> GetBotsByBotOwnerCharacterID(uint32 botOwnerCharacterID);
|
||||
|
||||
bool Bot_AICheckCloseBeneficialSpells(Bot* caster, uint8 iChance, float iRange, uint16 iSpellTypes); // TODO: Evaluate this closesly in hopes to eliminate
|
||||
bool Bot_AICheckCloseBeneficialSpells(Bot* caster, uint8 iChance, float iRange, uint32 iSpellTypes); // TODO: Evaluate this closesly in hopes to eliminate
|
||||
void ShowSpawnWindow(Client* client, int Distance, bool NamedOnly); // TODO: Implement ShowSpawnWindow in the bot class but it needs entity list stuff
|
||||
private:
|
||||
std::list<Bot*> bot_list;
|
||||
|
||||
+11
-4
@@ -101,9 +101,12 @@ uint32 Client::CalcEXP(uint8 conlevel) {
|
||||
if (conlevel != 0xFF) {
|
||||
switch (conlevel)
|
||||
{
|
||||
case CON_GREEN:
|
||||
case CON_GRAY:
|
||||
in_add_exp = 0;
|
||||
return 0;
|
||||
case CON_GREEN:
|
||||
in_add_exp = in_add_exp * RuleI(Character, GreenModifier) / 100;
|
||||
break;
|
||||
case CON_LIGHTBLUE:
|
||||
in_add_exp = in_add_exp * RuleI(Character, LightBlueModifier)/100;
|
||||
break;
|
||||
@@ -206,10 +209,14 @@ void Client::AddEXP(uint32 in_add_exp, uint8 conlevel, bool resexp) {
|
||||
if (conlevel != 0xFF && !resexp) {
|
||||
switch (conlevel)
|
||||
{
|
||||
case CON_GREEN:
|
||||
case CON_GRAY:
|
||||
add_exp = 0;
|
||||
add_aaxp = 0;
|
||||
return;
|
||||
case CON_GREEN:
|
||||
add_exp = add_exp * RuleI(Character, GreenModifier) / 100;
|
||||
add_aaxp = add_aaxp * RuleI(Character, GreenModifier) / 100;
|
||||
break;
|
||||
case CON_LIGHTBLUE:
|
||||
add_exp = add_exp * RuleI(Character, LightBlueModifier)/100;
|
||||
add_aaxp = add_aaxp * RuleI(Character, LightBlueModifier)/100;
|
||||
@@ -798,7 +805,7 @@ void Group::SplitExp(uint32 exp, Mob* other) {
|
||||
groupexp += (uint32)((float)exp * groupmod * (RuleR(Character, GroupExpMultiplier)));
|
||||
|
||||
int conlevel = Mob::GetLevelCon(maxlevel, other->GetLevel());
|
||||
if(conlevel == CON_GREEN)
|
||||
if(conlevel == CON_GRAY)
|
||||
return; //no exp for greenies...
|
||||
|
||||
if (membercount == 0)
|
||||
@@ -845,7 +852,7 @@ void Raid::SplitExp(uint32 exp, Mob* other) {
|
||||
groupexp = (uint32)((float)groupexp * (1.0f-(RuleR(Character, RaidExpMultiplier))));
|
||||
|
||||
int conlevel = Mob::GetLevelCon(maxlevel, other->GetLevel());
|
||||
if(conlevel == CON_GREEN)
|
||||
if(conlevel == CON_GRAY)
|
||||
return; //no exp for greenies...
|
||||
|
||||
if (membercount == 0)
|
||||
|
||||
+4
-1
@@ -72,9 +72,12 @@ void Mob::CheckFlee() {
|
||||
float run_ratio;
|
||||
switch(con) {
|
||||
//these values are not 100% researched
|
||||
case CON_GREEN:
|
||||
case CON_GRAY:
|
||||
run_ratio = fleeratio;
|
||||
break;
|
||||
case CON_GREEN:
|
||||
run_ratio = fleeratio * 9 / 10;
|
||||
break;
|
||||
case CON_LIGHTBLUE:
|
||||
run_ratio = fleeratio * 9 / 10;
|
||||
break;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user