Compare commits

...

65 Commits

Author SHA1 Message Date
JJ f0c6fa2a26 [Release] 22.29.1 (#3647)
* Update version.h

* Update Changelog

* Update CHANGELOG.md

* Update package.json
2023-10-21 18:36:38 -05:00
JJ ad6dbb7beb [DB] Fix manifest for blocked spells (#3646) 2023-10-21 18:01:57 -04:00
JJ 6ddbb41617 [Bug Fix] Verifying mail keys when none exist (#3645)
No need to verify mail key when none exist.
Seen in http://spire.akkadius.com/dev/release/22.28.0?id=12069
2023-10-21 13:33:24 -04:00
JJ 8a558f6a29 [Bug Fix] Hotfix command without hotfix name (#3644)
If no hotfix name is provided, the hotfix command won't need the empty string.
2023-10-21 13:33:16 -04:00
Alex King 0585be0360 [Bug Fix] Fix issue with subcommand settings not working (#3643)
* [Bug Fix] Fix issue with subcommand settings not working

# Notes
- We were checking for `arguments >= 2` when we should just be checking for if there are any arguments and comparing `sep.arg[0]` (the command) and `sep.arg[1]` (the subcommand) to our `command_subsettings` to see if it exists and if we pass the requirements.
- This fix will let operators properly set a subcommand to a lower or higher status level than the parent command.

* Remove debug message.
2023-10-20 21:33:05 -04:00
Akkadius 6927baef7f [Release] 22.29.0 2023-10-20 17:47:35 -05:00
Alex King 52d64781b5 [Feature] Add Expansion and Content Flag support to Blocked Spells (#3638)
* [Feature] Add Expansion and Content Flag support to Blocked Spells

# Notes
- Allows operators to filter blocked spells behind expansions or content flags.
- Requested in https://github.com/EQEmu/Server/issues/3582

* [Tradeskills] Add learned_by_item_id field (#3637)

* [Feature] Add Expansion and Content Flag support to Blocked Spells

- Allows operators to filter blocked spells behind expansions or content flags.
- Requested in https://github.com/EQEmu/Server/issues/3582

---------

Co-authored-by: Chris Miles <akkadius1@gmail.com>
2023-10-20 17:45:58 -05:00
Aeadoin 0667fe435f [Bug Fix] Fix crash when checking Bot Group/Raid membership (#3641)
* [Bug Fix] Fix crash when checking Bot Group/Raid membership

* Update bot.cpp

---------

Co-authored-by: Akkadius <akkadius1@gmail.com>
2023-10-20 17:45:41 -05:00
Chris Miles 9959070f24 [Perl] Static linker fix on Linux (#3642)
* Update CMakeLists.txt

* Update linux-build.sh

* test

* Test

* test

* brute force

* !?!

* Update CMakeLists.txt

* Update CMakeLists.txt

* Update CMakeLists.txt

* Update CMakeLists.txt

* Update CMakeLists.txt

* Remove testing

* Update linux-build.sh
2023-10-20 17:43:04 -05:00
Akkadius 2a91f08845 [22.28.1] Perl Linux build fix 2023-10-20 15:25:25 -05:00
Chris Miles adc64005f1 [Rules] Add rule to configure max number of procs per round Combat:MaxProcs (#3640) 2023-10-20 14:57:50 -04:00
Alex King 605480f1c4 [Bug Fix] Fix Finishing Blow Proc Chance (#3639)
# Notes
- We were double adding `spellbonuses` and not adding `itembonuses` per https://github.com/EQEmu/Server/issues/3636.
2023-10-19 16:19:43 -04:00
Chris Miles 3b95601c62 [Tradeskills] Add learned_by_item_id field (#3637) 2023-10-18 18:27:34 -05:00
Alex King a4f2ed28f1 [Feature] Add Bot Starting Items (#3634)
* [Feature] Add Bot Starting Items

# Notes
- This table is similar to the player starting items table, however it uses bitmasks.
- Allows operators to give bots gear on creation.
- `races` of `0` for all races.
- `classes` of `0` for all classes.

* Update bot.cpp

* Update database_update_manifest_bots.cpp
2023-10-17 18:00:41 -04:00
Akkadius e19b969541 [Release] 22.28.0 - Hotfix changelog 2023-10-15 21:56:55 -05:00
JJ 4241556f75 [Release] 22.28.0 (#3633)
* [Release] 22.28.0

* Update package.json

* Update CHANGELOG.md
2023-10-15 22:45:23 -04:00
Chris Miles 961332b40c [Crash] Fix crash in Mob::ShowBuffs (#3632) 2023-10-15 21:14:55 -05:00
Chris Miles a1a861e0c4 [Bots] Fix bot removal on zone, regression from #3611 (#3631) 2023-10-15 20:46:07 -04:00
JJ 4bbb1aa92f [Scripts] Update 13th Floor importer (#3630)
* [Scripts] Update 13th Floor importer

Overhaul to script.
- Now uses `eqemu_config.json`
- More descriptive during the process
- Accounts for adjustments (`idfile`, `prockunk1`)
- No longer needs to adjust `UNK132`

* [DB] Adjust `items` structure for import (#3629)

Our `items` table has 5 fields that need to adjust in order to pull data from 13th Floor.

* [DB] Update `version.h`
2023-10-15 20:45:50 -04:00
Alex King 1212ccefef [Quest API] Add target ID and spell exports to events (#3620)
* [Quest API] Add target ID and spell exports to events

# Notes
- Add `$spell` export to `EVENT_CAST`, `EVENT_CAST_BEGIN`, `EVENT_CAST_BEGIN`, `EVENT_ITEM_CLICK`, `EVENT_ITEM_CLICK_CAST`, `EVENT_ITEM_CLICK_CLIENT`, `EVENT_ITEM_CLICK_CAST_CLIENT`, `EVENT_SPELL_EFFECT_BUFF_TIC_BOT`, `EVENT_SPELL_EFFECT_BUFF_TIC_CLIENT`, `EVENT_SPELL_EFFECT_BUFF_TIC_NPC`, `EVENT_SPELL_EFFECT_BOT`, `EVENT_SPELL_EFFECT_CLIENT`, `EVENT_SPELL_EFFECT_NPC`, `EVENT_SPELL_FADE`, `EVENT_DEATH`, `EVENT_DEATH_COMPLETE`, `EVENT_DEATH_ZONE`, `EVENT_DAMAGE_GIVEN`, and `EVENT_DAMAGE_TAKEN` in Perl.
- Add `$target_id` export to `EVENT_CAST`, `EVENT_CAST_BEGIN`, and `EVENT_CAST_ON` in Perl.
- Add `e.target_id` export to `EVENT_CAST`, `EVENT_CAST_BEGIN`, and `EVENT_CAST_ON` in Lua.

* Add $target/e.target exports.

* Update spells.cpp
2023-10-15 19:40:25 -04:00
Aeadoin c203fec9b4 [Crash] Resolve crash when assigning empty raid note. (#3628)
* [Crash] Resolve crash when assigning empty raid note.

* const
2023-10-15 16:42:12 -04:00
Alex King 16ab1839e8 [Feature] Add Immune to Headshot Special Ability (#3624)
# Notes
- Allows mobs normally susceptible to Headshot to be made immune to it.
2023-10-13 21:43:33 -05:00
Mitch Freeman f5e4c6a127 [Feature] Update Raid Functions for Titanium and Underfoot (#3524)
* Update Raid Functions

Updated various raid features for:
Titanium
- Raid window now functional, including with BOTS
- Raid delegate assist/mark work
- Raid notes work
- Raid /rmark, /clearmarks work
Underfoot
- Raid window was already functional
- Raid delegate assist/mark work
- Raid notes work
- Raid /rmark, /clearmarks work

* Updates to resolve feedback

* Slight update for overlooked case in encode for RaidUpdate for clients above Ti.

* Updates to further address feedback.  Only updated translators for Ti/RoF2.  Once ok, I will update the others.

* Update linux-build.sh

* Final updates for other translators and the strncpy_s issue.

* Fix for strn0cpy in raids.cpp, translators, and defines.  Updated all in raids.cpp as well.

* Reveted defines change.

* Reverted accidental change

---------

Co-authored-by: Akkadius <akkadius1@gmail.com>
2023-10-13 21:42:27 -05:00
Alex King 166c87c931 [Bots] Adjust Bot Movement Speed (#3615)
# Notes
- Bots were having a hard time keeping up with players.
- Part of this was due to using walk until a certain distance.
- Another part was their ctor only having `0.7f` run speed versus our Mob sanity check of `1.25f`.
- We check movement stuff now before idle checks so bots are more likely to start moving earlier.
2023-10-13 20:16:06 -05:00
Alex King 345dd442dd [Quest API] Add GrantAllAAPoints() to Perl/Lua and Modify #grantaa (#3616)
# Command
- Add optional `level` argument to `#grantaa` so you can grant AAs up the specified level.

# Perl
- Add `$client->GrantAllAAPoints()`.
- Add `$client->GrantAllAAPoints(level)`.

# Lua
- Add `client:GrantAllAAPoints()`.
- Add `client:GrantAllAAPoints(level)`.

# Notes
- Grants all AA abilities up to client's current level or a specified level.
2023-10-13 20:13:55 -05:00
Alex King 565baec675 [Bug Fix] Fix #cast defaulting to cast time (#3617)
# Notes
- Defaulted to using cast time instead of instant.
2023-10-13 20:12:34 -05:00
Alex King 9884c442e9 [Crash] Fix Crash with #summon (#3618)
# Notes
- Not setting target to a default of `nullptr` or in this case `c` gave undefined behavior.
2023-10-13 20:12:01 -05:00
JJ ad0b5d6a1c [Scripts] Update 13th Floor script for legacy research tome bagtypes (#3621)
Legacy research tomes have the wrong bagtype (BACKPACK) blocking the clients from showing the combine button.
2023-10-13 20:10:35 -05:00
Alex King b82b32e1d2 [Feature] Add Immune to Assassinate Special Ability (#3622)
# Notes
- Allows mobs normally susceptible to Assassinate to be made immune to it.
2023-10-13 21:01:06 -04:00
dependabot[bot] 2fb72e5729 Bump golang.org/x/net in /utils/scripts/build/should-release (#3619)
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.7.0 to 0.17.0.
- [Commits](https://github.com/golang/net/compare/v0.7.0...v0.17.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-13 19:52:58 -05:00
Alex King 3791bc788f [Parser Fix] Fix SendIllusion Spire parsing (#3623)
# Notes
- Spire parses methods based on parameters being on the same line, so these were not being parse properly since they were newlines.
2023-10-13 19:41:28 -05:00
Alex King 833fa55fdf [Feature] Add Extra Kick Classes (#3613)
* [Feature] Add Extra Kick Classes

# Notes
- Allows operators to add extra classes to the "Kick" skill.
- Without this only Warrior, Ranger, Monk, Beastlord, and Berserker could kick.

* Remove gotos.
2023-10-11 14:33:23 -04:00
Chris Miles 4fc3c27715 [Release] 22.27.0 (#3614)
* [Release] 22.27.0

* Update bot.cpp
2023-10-07 15:11:21 -05:00
Chris Miles cea3ad6a42 [Crash] Fix crash in #movechar (#3612) 2023-10-07 14:00:27 -05:00
Chris Miles d8926cd5f3 [Crash] Fix dangling pointer crash observed in SendHPPacketsFrom (#3611)
* [Crash] Fix dangling pointer crash observed in SendHPPacketsFrom

* Update bot.cpp
2023-10-07 14:00:19 -05:00
Chris Miles efb03164c7 [Crash] Fix crash in CastSpell Quest API input cast (#3610) 2023-10-07 14:00:11 -05:00
Chris Miles 455eb2e6d9 [Crash] Fix CanUseAlternateAdvancementRank crash (#3609) 2023-10-07 14:00:04 -05:00
Chris Miles b5b0e53da2 [Crash] Fix #summon crash (#3608)
* [Crash] Summon crash fix

* [Crash] Fix summon crash
2023-10-07 13:59:56 -05:00
Chris Miles 68cb94b39c [Crash] Bot member zoned crash fix (#3607) 2023-10-07 13:59:47 -05:00
Chris Miles 3d95b6c184 [Crash] Fix rarer crash with File::Makedir (#3606) 2023-10-07 13:59:40 -05:00
Alex King 7db7631308 [Bug Fix] Fix #show group_info Popup (#3605)
# Notes
- Wasn't using `DialogueWindow::TableCell` so they weren't showing up.
- Fixed `red1` to `red_1` so it shows.
2023-10-04 14:40:05 -04:00
Akkadius f053cd3b56 [Hotfix] Ensure Linux builds report failures 2023-10-03 11:59:50 -05:00
Alex King cf27f2bc88 [Quest API] Add Caster ID Parameter to FindBuff in Perl/Lua (#3590)
* [Quest API] Add Caster ID Parameter to FindBuff in Perl/Lua

# Perl
- Add `$mob->FindBuff(spell_id, caster_id)`.

# Lua
- Add `mob:FindBuff(spell_id, caster_id)`.

# Notes
- Allows operators to check if the spell ID is cast by a specific entity ID.
- We don't use `Mob*` reference here since the mob may have died, left zone, etc.

* Formatting.
2023-09-29 19:38:36 -04:00
JJ 79918ebaba [Logs] Change pathing log messages from Error to Pathing. (#3604)
Change pathing log messages from `Error` to `Pathing`.
2023-09-29 11:54:52 -04:00
Paul Coene 2a648507f2 [Bug Fix] Fix swarm pet names to use '_' instead of ' ' (#3601) 2023-09-19 18:21:47 -04:00
Clayton Dunwell f395ee0508 [Bug Fix] Invis vs. Undead/Animal Breaks Charm for Pets (#3587)
* IVU & IVA break charm pets #2212

* fix typing

* fix tab spacing

* Formatting

* Formatting for CalcInvisibleLevel

---------

Co-authored-by: Akkadius <akkadius1@gmail.com>
2023-09-19 10:16:12 -04:00
Akkadius 7166fcc650 [Hotfix] Fix an issue with schema versioning for the AA update 2023-09-18 12:19:56 -05:00
Alex King ae8e58ddc5 [Release] 22.26.1 (#3599)
* [Release] 22.26.1

### Fixes

* Add Validation to #find, #set, and #show args ([#3598](https://github.com/EQEmu/Server/pull/3598)) @Kinglykrab 2023-09-17
2023-09-17 23:15:38 -04:00
Alex King 26e72c6857 [Bug Fix] Add Validation to #find, #set, and #show args (#3598)
# Notes
- We were not validating `sep->arg[i]` so we could possibly be pushing a `nullptr` in.
2023-09-17 21:20:27 -05:00
Chris Miles df1d740ae6 [Release] 22.26.0 (#3596) 2023-09-17 15:14:01 -05:00
Alex King d7e810232a [Bug Fix] Fix entity ID on death with #castspell (#3592)
# Notes
- Entities killed by a spell with #cast were not reporting their pre-death entity ID properly.
- Added an `entity_id_override` to `GetTargetDescription()` and added a pre-defined entity ID variable to the cast command so we can message the proper pre-death entity ID.
2023-09-17 13:40:31 -05:00
Alex King 9b992167f0 [Bug Fix] Fix Killed XYZH support in EVENT_DEATH in Perl. (#3591)
* [Bug Fix] Fix Killer XYZH support in EVENT_DEATH in Perl.

# Notes
- Fixes XYZH exports in Perl.

* Update embparser.cpp
2023-09-17 13:40:07 -05:00
Clayton Dunwell 65d4533568 [Bug Fix] Check for Song Skill Increase on Bard Pulse (#3586)
* check for song skill increase on bard pulse

* style changes

* fix spacing
2023-09-17 13:29:48 -05:00
Clayton Dunwell eb545a18a4 [Feature] Cleanup Group Split Money Logic (#3583)
* addresses #2498

* fix some logic #2498

* fixes #2498

* derpy derp derp #2498

* leave default argument to appease build

* Formatting

---------

Co-authored-by: Akkadius <akkadius1@gmail.com>
2023-09-17 13:22:26 -05:00
Alex King f2f0228aa4 [Quest API] Add XYZ/XYZH Overloads to Cross Zone Move Methods (#3581)
# Perl
- Add `quest::crosszonemoveplayerbycharid(character_id, zone_short_name, x, y, z)`.
- Add `quest::crosszonemoveplayerbycharid(character_id, zone_short_name, x, y, z, heading)`.
- Add `quest::crosszonemoveplayerbygroupid(group_id, zone_short_name, x, y, z)`.
- Add `quest::crosszonemoveplayerbygroupid(group_id, zone_short_name, x, y, z, heading)`.
- Add `quest::crosszonemoveplayerbyraidid(raid_id, zone_short_name, x, y, z)`.
- Add `quest::crosszonemoveplayerbyraidid(raid_id, zone_short_name, x, y, z, heading)`.
- Add `quest::crosszonemoveplayerbyguildid(guild_id, zone_short_name, x, y, z)`.
- Add `quest::crosszonemoveplayerbyguildid(guild_id, zone_short_name, x, y, z, heading)`.
- Add `quest::crosszonemoveplayerbyexpeditionid(expedition_id, zone_short_name, x, y, z)`.
- Add `quest::crosszonemoveplayerbyexpeditionid(expedition_id, zone_short_name, x, y, z, heading)`.
- Add `quest::crosszonemoveplayerbyclientname(client_name, zone_short_name, x, y, z)`.
- Add `quest::crosszonemoveplayerbyclientname(client_name, zone_short_name, x, y, z, heading)`.
- Add `quest::crosszonemoveinstancebycharid(character_id, zone_short_name, x, y, z)`.
- Add `quest::crosszonemoveinstancebycharid(character_id, zone_short_name, x, y, z, heading)`.
- Add `quest::crosszonemoveinstancebygroupid(group_id, zone_short_name, x, y, z)`.
- Add `quest::crosszonemoveinstancebygroupid(group_id, zone_short_name, x, y, z, heading)`.
- Add `quest::crosszonemoveinstancebyraidid(raid_id, zone_short_name, x, y, z)`.
- Add `quest::crosszonemoveinstancebyraidid(raid_id, zone_short_name, x, y, z, heading)`.
- Add `quest::crosszonemoveinstancebyguildid(guild_id, zone_short_name, x, y, z)`.
- Add `quest::crosszonemoveinstancebyguildid(guild_id, zone_short_name, x, y, z, heading)`.
- Add `quest::crosszonemoveinstancebyexpeditionid(expedition_id, zone_short_name, x, y, z)`.
- Add `quest::crosszonemoveinstancebyexpeditionid(expedition_id, zone_short_name, x, y, z, heading)`.
- Add `quest::crosszonemoveinstancebyclientname(client_name, zone_short_name, x, y, z)`.
- Add `quest::crosszonemoveinstancebyclientname(client_name, zone_short_name, x, y, z, heading)`.

# Lua
- Add `eq.cross_zone_move_player_by_char_id(character_id, zone_short_name, x, y, z)`.
- Add `eq.cross_zone_move_player_by_char_id(character_id, zone_short_name, x, y, z, heading)`.
- Add `eq.cross_zone_move_player_by_group_id(group_id, zone_short_name, x, y, z)`.
- Add `eq.cross_zone_move_player_by_group_id(group_id, zone_short_name, x, y, z, heading)`.
- Add `eq.cross_zone_move_player_by_raid_id(raid_id, zone_short_name, x, y, z)`.
- Add `eq.cross_zone_move_player_by_raid_id(raid_id, zone_short_name, x, y, z, heading)`.
- Add `eq.cross_zone_move_player_by_guild_id(guild_id, zone_short_name, x, y, z)`.
- Add `eq.cross_zone_move_player_by_guild_id(guild_id, zone_short_name, x, y, z, heading)`.
- Add `eq.cross_zone_move_player_by_expedition_id(expedition_id, zone_short_name, x, y, z)`.
- Add `eq.cross_zone_move_player_by_expedition_id(expedition_id, zone_short_name, x, y, z, heading)`.
- Add `eq.cross_zone_move_player_by_client_name(client_name, zone_short_name, x, y, z)`.
- Add `eq.cross_zone_move_player_by_client_name(client_name, zone_short_name, x, y, z, heading)`.
- Add `eq.cross_zone_move_instance_by_char_id(character_id, zone_short_name, x, y, z)`.
- Add `eq.cross_zone_move_instance_by_char_id(character_id, zone_short_name, x, y, z, heading)`.
- Add `eq.cross_zone_move_instance_by_group_id(group_id, zone_short_name, x, y, z)`.
- Add `eq.cross_zone_move_instance_by_group_id(group_id, zone_short_name, x, y, z, heading)`.
- Add `eq.cross_zone_move_instance_by_raid_id(raid_id, zone_short_name, x, y, z)`.
- Add `eq.cross_zone_move_instance_by_raid_id(raid_id, zone_short_name, x, y, z, heading)`.
- Add `eq.cross_zone_move_instance_by_guild_id(guild_id, zone_short_name, x, y, z)`.
- Add `eq.cross_zone_move_instance_by_guild_id(guild_id, zone_short_name, x, y, z, heading)`.
- Add `eq.cross_zone_move_instance_by_expedition_id(expedition_id, zone_short_name, x, y, z)`.
- Add `eq.cross_zone_move_instance_by_expedition_id(expedition_id, zone_short_name, x, y, z, heading)`.
- Add `eq.cross_zone_move_instance_by_client_name(client_name, zone_short_name, x, y, z)`.
- Add `eq.cross_zone_move_instance_by_client_name(client_name, zone_short_name, x, y, z, heading)`.

# Notes
- Allows operators to send players to specific coordinates across zones instead of always sending to safe coordinates.
2023-09-17 13:16:25 -05:00
Alex King 06337fe762 [Feature] Add Defensive Proc Rules for Level Gap Penalty (#3580)
# Notes
- Allows operators to modify the level gap penalty and level gap required for the penalty for defensive procs' level gap penalty.
- Setting `Spells:DefensiveProcPenaltyLevelGap` to `-1` will disable the penalty.
2023-09-17 13:15:51 -05:00
hg 604c7ad4ab [Feature] Add opcodes for Cast and Scribe book buttons (#3578)
This is just the packet framework for the Scribe button on recipe books
and the Cast Spell button on books that allow casting spells on
targets. It will need to be hooked up to a content implementation
2023-09-17 13:14:38 -05:00
Alex King bab16771aa [Quest API] Add ApplySpell() and SetBuffDuration() overloads to Perl/Lua (#3576)
# Perl
- Add `$bot->ApplySpell(spell_id, duration, level)`.
- Add `$bot->ApplySpell(spell_id, duration, level, allow_pets)`.
- Add `$bot->ApplySpellGroup(spell_id, duration, level)`.
- Add `$bot->ApplySpellGroup(spell_id, duration, level, allow_pets)`.
- Add `$bot->ApplySpellRaid(spell_id)`.
- Add `$bot->ApplySpellRaid(spell_id, duration)`.
- Add `$bot->ApplySpellRaid(spell_id, duration, level)`.
- Add `$bot->ApplySpellRaid(spell_id, duration, level, allow_pets)`.
- Add `$bot->ApplySpellRaid(spell_id, duration, level, allow_pets, is_raid_group_only)`.
- Add `$bot->SetSpellDuration(spell_id, duration, level)`.
- Add `$bot->SetSpellDuration(spell_id, duration, level, allow_pets)`.
- Add `$bot->SetSpellDurationGroup(spell_id, duration, level)`.
- Add `$bot->SetSpellDurationGroup(spell_id, duration, level, allow_pets)`.
- Add `$bot->SetSpellDurationRaid(spell_id)`.
- Add `$bot->SetSpellDurationRaid(spell_id, duration)`.
- Add `$bot->SetSpellDurationRaid(spell_id, duration, level)`.
- Add `$bot->SetSpellDurationRaid(spell_id, duration, level, allow_pets)`.
- Add `$bot->SetSpellDurationRaid(spell_id, duration, level, allow_pets, is_raid_group_only)`.
- Add `$client->ApplySpell(spell_id, duration, level)`.
- Add `$client->ApplySpell(spell_id, duration, level, allow_pets)`.
- Add `$client->ApplySpellGroup(spell_id, duration, level)`.
- Add `$client->ApplySpellGroup(spell_id, duration, level, allow_pets)`.
- Add `$client->ApplySpellRaid(spell_id, duration, level)`.
- Add `$client->ApplySpellRaid(spell_id, duration, level, allow_pets)`.
- Add `$client->ApplySpellRaid(spell_id, duration, level, allow_pets, is_raid_group_only)`.
- Add `$client->ApplySpellRaid(spell_id, duration, level, allow_pets, is_raid_group_only, allow_bots)`.
- Add `$client->SetSpellDuration(spell_id, duration, level)`.
- Add `$client->SetSpellDuration(spell_id, duration, level, allow_pets)`.
- Add `$client->SetSpellDurationGroup(spell_id, duration, level)`.
- Add `$client->SetSpellDurationGroup(spell_id, duration, level, allow_pets)`.
- Add `$client->SetSpellDurationRaid(spell_id, duration, level)`.
- Add `$client->SetSpellDurationRaid(spell_id, duration, level, allow_pets)`.
- Add `$client->SetSpellDurationRaid(spell_id, duration, level, allow_pets, is_raid_group_only)`.
- Add `$client->SetSpellDurationRaid(spell_id, duration, level, allow_pets, is_raid_group_only, allow_bots)`.
- Add `$mob->ApplySpellBuff(spell_id, duration, level)`.
- Add `$mob->SetSpellDuration(spell_id, duration, level)`.

# Lua
- Add `bot:ApplySpell(spell_id, duration, level)`.
- Add `bot:ApplySpell(spell_id, duration, level, allow_pets)`.
- Add `bot:ApplySpellGroup(spell_id, duration, level)`.
- Add `bot:ApplySpellGroup(spell_id, duration, level, allow_pets)`.
- Add `bot:ApplySpellRaid(spell_id)`.
- Add `bot:ApplySpellRaid(spell_id, duration)`.
- Add `bot:ApplySpellRaid(spell_id, duration, level)`.
- Add `bot:ApplySpellRaid(spell_id, duration, level, allow_pets)`.
- Add `bot:ApplySpellRaid(spell_id, duration, level, allow_pets, is_raid_group_only)`.
- Add `bot:SetSpellDuration(spell_id, duration, level)`.
- Add `bot:SetSpellDuration(spell_id, duration, level, allow_pets)`.
- Add `bot:SetSpellDurationGroup(spell_id, duration, level)`.
- Add `bot:SetSpellDurationGroup(spell_id, duration, level, allow_pets)`.
- Add `bot:SetSpellDurationRaid(spell_id, duration, level)`.
- Add `bot:SetSpellDurationRaid(spell_id, duration, level, allow_pets)`.
- Add `bot:SetSpellDurationRaid(spell_id, duration, level, allow_pets, is_raid_group_only)`.
- Add `client:ApplySpell(spell_id, duration, level)`.
- Add `client:ApplySpell(spell_id, duration, level, allow_pets)`.
- Add `client:ApplySpellGroup(spell_id, duration, level)`.
- Add `client:ApplySpellGroup(spell_id, duration, level, allow_pets)`.
- Add `client:ApplySpellRaid(spell_id, duration, level)`.
- Add `client:ApplySpellRaid(spell_id, duration, level, allow_pets)`.
- Add `client:ApplySpellRaid(spell_id, duration, level, allow_pets, is_raid_group_only)`.
- Add `client:ApplySpellRaid(spell_id, duration, level, allow_pets, is_raid_group_only, allow_bots)`.
- Add `client:SetSpellDuration(spell_id, duration, level)`.
- Add `client:SetSpellDuration(spell_id, duration, level, allow_pets)`.
- Add `client:SetSpellDurationGroup(spell_id, duration, level)`.
- Add `client:SetSpellDurationGroup(spell_id, duration, level, allow_pets)`.
- Add `client:SetSpellDurationRaid(spell_id, duration, level)`.
- Add `client:SetSpellDurationRaid(spell_id, duration, level, allow_pets)`.
- Add `client:SetSpellDurationRaid(spell_id, duration, level, allow_pets, is_raid_group_only)`.
- Add `client:SetSpellDurationRaid(spell_id, duration, level, allow_pets, is_raid_group_only, allow_bots)`.
- Add `mob:ApplySpellBuff(spell_id, duration, level)`.
- Add `mob:SetSpellDuration(spell_id, duration, level)`.

# Notes
- This allows operators to override the spell level.
2023-09-17 13:14:13 -05:00
Alex d3a414a048 [Fixes] AA System Fixes (#3572)
* -Always load AAs beyond our current expansion (Will need this for refunding invalid AAs).
-AAs beyond our current expansion will no longer be buyable or sendable to clients.

* #reload aa will now reload character aa data.

* Base Implementation of auto grant AA

* -Add DB manifest entry
-Made has already purchased fn a bit better
-Added auto grant to db entry

* -Added grantaa command.
-Reworked grantaa to not spam the client with packets, it still does spam messages because the feedback is important.

* Port suggested changes for Finish AA purchase.

---------

Co-authored-by: KimLS <KimLS@peqtgc.com>
2023-09-17 13:12:43 -05:00
Paul Coene e85a8db8c4 [Messages] Swarm pet normal damage messages were missing (#3594) 2023-09-17 08:26:09 -04:00
Fryguy 12cc3c90ea [Bug] Additional Wild Ramp param was causing an overflow it appears at least on local testing. (#3589)
* [Logging] Add logging to track down Wild Ramp issue

* [Bug] Additional Wild Ramp param was causing an overflow it appears at least on local testing.
2023-09-11 15:57:04 -05:00
Paul Coene 9c656bc498 [Messages] Remove duplicate message on tracking begin (#3574) 2023-09-11 08:27:25 -04:00
Fryguy bc337979bb [Logging] Add logging to track down Wild Ramp issue (#3588) 2023-09-10 21:02:44 -05:00
Paul Coene a64425ebe6 [Commands] npc_edit faction and #setfaction duplicate and incorrect. (#3577)
* [Commands] npc_edit faction and #setfaction duplicate and incorrect.

* Fix assignment
2023-09-02 21:21:48 -04:00
Alex King ca933fce45 [Bug Fix] Fix #set faction/#setfaction Command (#3575)
# Notes
- This was an oversight on my part in `#set` command consolidation.
2023-09-02 17:30:40 -04:00
100 changed files with 4870 additions and 1975 deletions
+153
View File
@@ -1,3 +1,156 @@
## [22.29.1] - 10/21/2023
### DB
* Fix manifest for blocked spells ([#3646](https://github.com/EQEmu/Server/pull/3646)) @joligario 2023-10-21
### Fixes
* Fix issue with subcommand settings not working ([#3643](https://github.com/EQEmu/Server/pull/3643)) @Kinglykrab 2023-10-21
* Hotfix command without hotfix name ([#3644](https://github.com/EQEmu/Server/pull/3644)) @joligario 2023-10-21
* Verifying mail keys when none exist ([#3645](https://github.com/EQEmu/Server/pull/3645)) @joligario 2023-10-21
## [22.29.0] - 10/20/2023
### Feature
* Add Expansion and Content Flag support to Blocked Spells ([#3638](https://github.com/EQEmu/Server/pull/3638)) @Kinglykrab 2023-10-20
### Fixes
* Fix crash when checking Bot Group/Raid membership ([#3641](https://github.com/EQEmu/Server/pull/3641)) @Aeadoin 2023-10-20
### Perl
* Static linker fix on Linux ([#3642](https://github.com/EQEmu/Server/pull/3642)) @Akkadius 2023-10-20
### Rules
* Add rule to configure max number of procs per round Combat:MaxProcs ([#3640](https://github.com/EQEmu/Server/pull/3640)) @Akkadius 2023-10-20
## [22.28.1] - 10/20/2023
### Build
* Perl Linux build fix
## [22.28.0] - 10/15/2023
### Bots
* Adjust Bot Movement Speed ([#3615](https://github.com/EQEmu/Server/pull/3615)) @Kinglykrab 2023-10-14
* Fix bot removal on zone, regression from #3611 ([#3631](https://github.com/EQEmu/Server/pull/3631)) @Akkadius 2023-10-16
### Crash
* Fix Crash with #summon ([#3618](https://github.com/EQEmu/Server/pull/3618)) @Kinglykrab 2023-10-14
* Fix crash in Mob::ShowBuffs ([#3632](https://github.com/EQEmu/Server/pull/3632)) @Akkadius 2023-10-16
* Resolve crash when assigning empty raid note. ([#3628](https://github.com/EQEmu/Server/pull/3628)) @Aeadoin 2023-10-15
### Feature
* Add Extra Kick Classes ([#3613](https://github.com/EQEmu/Server/pull/3613)) @Kinglykrab 2023-10-11
* Add Immune to Assassinate Special Ability ([#3622](https://github.com/EQEmu/Server/pull/3622)) @Kinglykrab 2023-10-14
* Add Immune to Headshot Special Ability ([#3624](https://github.com/EQEmu/Server/pull/3624)) @Kinglykrab 2023-10-14
* Update Raid Functions for Titanium and Underfoot ([#3524](https://github.com/EQEmu/Server/pull/3524)) @neckkola 2023-10-14
### Fixes
* Fix #cast defaulting to cast time ([#3617](https://github.com/EQEmu/Server/pull/3617)) @Kinglykrab 2023-10-14
### Parser Fix
* Fix SendIllusion Spire parsing ([#3623](https://github.com/EQEmu/Server/pull/3623)) @Kinglykrab 2023-10-14
### Quest API
* Add GrantAllAAPoints() to Perl/Lua and Modify #grantaa ([#3616](https://github.com/EQEmu/Server/pull/3616)) @Kinglykrab 2023-10-14
* Add target ID and spell exports to events ([#3620](https://github.com/EQEmu/Server/pull/3620)) @Kinglykrab 2023-10-15
### Scripts
* Update 13th Floor importer ([#3630](https://github.com/EQEmu/Server/pull/3630)) @joligario 2023-10-16
* Update 13th Floor script for legacy research tome bagtypes ([#3621](https://github.com/EQEmu/Server/pull/3621)) @joligario 2023-10-14
## [22.27.0] - 10/07/2023
### Crash
* Bot member zoned crash fix ([#3607](https://github.com/EQEmu/Server/pull/3607)) @Akkadius 2023-10-07
* Fix #summon crash ([#3608](https://github.com/EQEmu/Server/pull/3608)) @Akkadius 2023-10-07
* Fix CanUseAlternateAdvancementRank crash ([#3609](https://github.com/EQEmu/Server/pull/3609)) @Akkadius 2023-10-07
* Fix crash in #movechar ([#3612](https://github.com/EQEmu/Server/pull/3612)) @Akkadius 2023-10-07
* Fix crash in CastSpell Quest API input cast ([#3610](https://github.com/EQEmu/Server/pull/3610)) @Akkadius 2023-10-07
* Fix dangling pointer crash observed in SendHPPacketsFrom ([#3611](https://github.com/EQEmu/Server/pull/3611)) @Akkadius 2023-10-07
* Fix rarer crash with File::Makedir ([#3606](https://github.com/EQEmu/Server/pull/3606)) @Akkadius 2023-10-07
### Fixes
* Add Validation to #find, #set, and #show args ([#3598](https://github.com/EQEmu/Server/pull/3598)) @Kinglykrab 2023-09-18
* Ensure Linux builds report failures @Akkadius 2023-10-03
* Fix #show group_info Popup ([#3605](https://github.com/EQEmu/Server/pull/3605)) @Kinglykrab 2023-10-04
* Fix swarm pet names to use '_' instead of ' ' ([#3601](https://github.com/EQEmu/Server/pull/3601)) @noudess 2023-09-19
* Invis vs. Undead/Animal Breaks Charm for Pets ([#3587](https://github.com/EQEmu/Server/pull/3587)) @crdunwel 2023-09-19
### Logs
* Change pathing log messages from Error to Pathing. ([#3604](https://github.com/EQEmu/Server/pull/3604)) @joligario 2023-09-29
### Quest API
* Add Caster ID Parameter to FindBuff in Perl/Lua ([#3590](https://github.com/EQEmu/Server/pull/3590)) @Kinglykrab 2023-09-29
## [22.26.2] - 09/18/2023
### Fixes
* Fix an issue with schema versioning for the AA update
## [22.26.1] - 09/17/2023
### Fixes
* Add Validation to #find, #set, and #show args ([#3598](https://github.com/EQEmu/Server/pull/3598)) @Kinglykrab 2023-09-17
## [22.26.0] - 09/17/2023
### Bug
* Additional Wild Ramp param was causing an overflow it appears at least on local testing. ([#3589](https://github.com/EQEmu/Server/pull/3589)) @fryguy503 2023-09-11
### Commands
* npc_edit faction and #setfaction duplicate and incorrect. ([#3577](https://github.com/EQEmu/Server/pull/3577)) @noudess 2023-09-03
### Feature
* Add Defensive Proc Rules for Level Gap Penalty ([#3580](https://github.com/EQEmu/Server/pull/3580)) @Kinglykrab 2023-09-17
* Add opcodes for Cast and Scribe book buttons ([#3578](https://github.com/EQEmu/Server/pull/3578)) @hgtw 2023-09-17
* Cleanup Group Split Money Logic ([#3583](https://github.com/EQEmu/Server/pull/3583)) @crdunwel 2023-09-17
### Fixes
* AA System Fixes ([#3572](https://github.com/EQEmu/Server/pull/3572)) @KimLS 2023-09-17
* Check for Song Skill Increase on Bard Pulse ([#3586](https://github.com/EQEmu/Server/pull/3586)) @crdunwel 2023-09-17
* Fix #set faction/#setfaction Command ([#3575](https://github.com/EQEmu/Server/pull/3575)) @Kinglykrab 2023-09-02
* Fix Killed XYZH support in EVENT_DEATH in Perl. ([#3591](https://github.com/EQEmu/Server/pull/3591)) @Kinglykrab 2023-09-17
* Fix entity ID on death with #castspell ([#3592](https://github.com/EQEmu/Server/pull/3592)) @Kinglykrab 2023-09-17
* Zoning logging edge case safety @Akkadius 2023-08-29
### Logging
* Add logging to track down Wild Ramp issue ([#3588](https://github.com/EQEmu/Server/pull/3588)) @fryguy503 2023-09-11
### Messages
* Remove duplicate message on tracking begin ([#3574](https://github.com/EQEmu/Server/pull/3574)) @noudess 2023-09-11
* Swarm pet normal damage messages were missing ([#3594](https://github.com/EQEmu/Server/pull/3594)) @noudess 2023-09-17
### Quest API
* Add ApplySpell() and SetBuffDuration() overloads to Perl/Lua ([#3576](https://github.com/EQEmu/Server/pull/3576)) @Kinglykrab 2023-09-17
* Add XYZ/XYZH Overloads to Cross Zone Move Methods ([#3581](https://github.com/EQEmu/Server/pull/3581)) @Kinglykrab 2023-09-17
## [22.25.0] - 08/28/2023
### Bots
+7 -1
View File
@@ -23,7 +23,10 @@ IF (EQEMU_BUILD_STATIC)
SET(CMAKE_FIND_LIBRARY_SUFFIXES ".lib" ".a")
MESSAGE(STATUS "Building with static linking")
SET(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++")
ENDIF(EQEMU_BUILD_STATIC)
IF (UNIX)
SET(PERL_LIBRARY "/usr/lib/x86_64-linux-gnu/libperl.a")
ENDIF ()
ENDIF (EQEMU_BUILD_STATIC)
IF(MSVC)
ADD_DEFINITIONS(-D_CRT_SECURE_NO_WARNINGS)
@@ -389,6 +392,9 @@ IF(PERL_LIBRARY_ENABLED)
ADD_DEFINITIONS(-DEMBPERL)
ADD_DEFINITIONS(-DEMBPERL_PLUGIN)
ADD_DEFINITIONS(-DPERLBIND_NO_STRICT_SCALAR_TYPES)
IF (UNIX AND EQEMU_BUILD_STATIC)
SET(SERVER_LIBS ${SERVER_LIBS} libcrypt.a)
ENDIF ()
ENDIF()
ENDIF()
+1
View File
@@ -589,6 +589,7 @@ SET(common_headers
ptimer.h
queue.h
races.h
raid.h
random.h
rdtsc.h
rulesys.h
@@ -4930,6 +4930,57 @@ CREATE TABLE `character_stats_record` (
`updated_at` datetime DEFAULT NULL,
PRIMARY KEY (`character_id`)
);
)"
},
ManifestEntry{
.version = 9236,
.description = "2023_08_24_aa_ability_auto_grant.sql",
.check = "SHOW COLUMNS FROM `aa_ability` LIKE 'auto_grant_enabled';",
.condition = "empty",
.match = "",
.sql = R"(
ALTER TABLE `aa_ability` ADD COLUMN `auto_grant_enabled` TINYINT(4) NOT NULL DEFAULT '0' AFTER `reset_on_death`;
UPDATE `aa_ability` SET `auto_grant_enabled` = 1 WHERE `grant_only` = 0 AND `charges` = 0 AND `category` = -1;
)"
},
ManifestEntry{
.version = 9237,
.description = "2023_10_15_import_13th_floor.sql",
.check = "SHOW COLUMNS FROM `items` LIKE 'bardeffect';",
.condition = "contains",
.match = "mediumint",
.sql = R"(
ALTER TABLE `items`
MODIFY COLUMN `scriptfileid` MEDIUMINT(6) NOT NULL DEFAULT 0,
MODIFY COLUMN `powersourcecapacity` MEDIUMINT(7) NOT NULL DEFAULT 0,
MODIFY COLUMN `augdistiller` INT(11) UNSIGNED NOT NULL DEFAULT 0,
MODIFY COLUMN `scrollunk1` INT(11) UNSIGNED NOT NULL DEFAULT 0,
MODIFY COLUMN `bardeffect` MEDIUMINT(6) NOT NULL DEFAULT 0;
)"
},
ManifestEntry{
.version = 9238,
.description = "2023_10_18_tradeskill_add_learned_by_item_id.sql",
.check = "SHOW COLUMNS FROM `tradeskill_recipe` LIKE 'learned_by_item_id'",
.condition = "empty",
.match = "",
.sql = R"(
ALTER TABLE `tradeskill_recipe`
ADD COLUMN `learned_by_item_id` int(11) NOT NULL DEFAULT 0 AFTER `must_learn`;
)"
},
ManifestEntry{
.version = 9239,
.description = "2023_10_18_blocked_spells_expansions_content_flags.sql",
.check = "SHOW COLUMNS FROM `blocked_spells` LIKE 'min_expansion'",
.condition = "empty",
.match = "",
.sql = R"(
ALTER TABLE `blocked_spells`
ADD COLUMN `min_expansion` tinyint(4) NOT NULL DEFAULT -1 AFTER `description`,
ADD COLUMN `max_expansion` tinyint(4) NOT NULL DEFAULT -1 AFTER `min_expansion`,
ADD COLUMN `content_flags` varchar(100) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL AFTER `max_expansion`,
ADD COLUMN `content_flags_disabled` varchar(100) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL AFTER `content_flags`;
)"
},
@@ -61,6 +61,29 @@ DROP TABLE IF EXISTS `bot_group_members`;
SET FOREIGN_KEY_CHECKS = 1;
)",
},
ManifestEntry{
.version = 9040,
.description = "2023_11_16_bot_starting_items.sql",
.check = "SHOW TABLES LIKE 'bot_starting_items'",
.condition = "",
.match = "empty",
.sql = R"(
CREATE TABLE `bot_starting_items` (
`id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`races` int(11) UNSIGNED NOT NULL DEFAULT 0,
`classes` int(11) UNSIGNED NOT NULL DEFAULT 0,
`item_id` int(11) UNSIGNED NOT NULL DEFAULT 0,
`item_charges` tinyint(3) UNSIGNED NOT NULL DEFAULT 1,
`min_status` tinyint(3) UNSIGNED NOT NULL DEFAULT 0,
`slot_id` mediumint(9) NOT NULL DEFAULT -1,
`min_expansion` tinyint(4) NOT NULL DEFAULT -1,
`max_expansion` tinyint(4) NOT NULL DEFAULT -1,
`content_flags` varchar(100) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
`content_flags_disabled` varchar(100) CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE = InnoDB CHARACTER SET = latin1 COLLATE = latin1_swedish_ci;
)"
}
// -- template; copy/paste this when you need to create a new entry
// ManifestEntry{
// .version = 9228,
+1
View File
@@ -62,6 +62,7 @@ N(OP_BeginCast),
N(OP_Bind_Wound),
N(OP_BlockedBuffs),
N(OP_BoardBoat),
N(OP_BookButton),
N(OP_Buff),
N(OP_BuffCreate),
N(OP_BuffRemoveRequest),
+20 -6
View File
@@ -2559,7 +2559,10 @@ struct GMEmoteZone_Struct {
struct BookText_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 invslot; // Only used in SoF and later clients.
int32 target_id;
int8 can_cast;
int8 can_scribe;
char booktext[1]; // Variable Length
};
// This is the request to read a book.
@@ -2568,11 +2571,18 @@ struct BookText_Struct {
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.
int16 invslot; // Only used in Sof and later clients;
int32 target_id;
char txtfile[20];
};
// used by Scribe and CastSpell book buttons
struct BookButton_Struct
{
int16 invslot; // server slot
int32 target_id;
};
/*
** Object/Ground Spawn struct
** Used for Forges, Ovens, ground spawns, items dropped to ground, etc
@@ -4154,7 +4164,6 @@ struct RaidGeneral_Struct {
/*68*/ uint32 unknown1;
/*72*/ char leader_name[64];
/*136*/ uint32 parameter;
/*200*/ char note[64];
};
struct RaidAddMember_Struct {
@@ -4165,9 +4174,14 @@ struct RaidAddMember_Struct {
/*139*/ uint8 flags[5]; //no idea if these are needed...
};
struct RaidNote_Struct {
/*000*/ RaidGeneral_Struct general;
/*140*/ char note[64];
};
struct RaidMOTD_Struct {
/*000*/ RaidGeneral_Struct general; // leader_name and action only used
/*136*/ char motd[0]; // max size is 1024, but reply is variable
/*000*/ RaidGeneral_Struct general;
/*140*/ char motd[1024];
};
struct RaidLeadershipUpdate_Struct {
-2
View File
@@ -250,9 +250,7 @@ enum {
commandMovecharSelfOnly = 80, //below this == only self move allowed
commandMovecharToSpecials = 200, //ability to send people to cshom/load zones
commandCastSpecials = 100, //can cast special spells
commandInstacast = 100, //insta-cast all #casted spells
commandDoAnimOthers = 100, //can #doanim on others
commandLockZones = 101, //can lock or unlock zones
commandEditPlayerCorpses = 150, //can Edit Player Corpses
commandInterrogateInv = 100, //below this == only log on error state and self-only target dump
commandInvSnapshot = 150 //ability to clear/restore snapshots
+8 -2
View File
@@ -55,8 +55,14 @@ bool File::Exists(const std::string &name)
*/
void File::Makedir(const std::string &directory_name)
{
fs::create_directory(directory_name);
fs::permissions(directory_name, fs::perms::owner_all);
try {
fs::create_directory(directory_name);
fs::permissions(directory_name, fs::perms::owner_all);
}
catch (const fs::filesystem_error &ex) {
std::cout << "Failed to create directory: " << directory_name << std::endl;
std::cout << ex.what() << std::endl;
}
}
std::string File::FindEqemuConfigPath()
+135 -88
View File
@@ -34,6 +34,7 @@
#include "../rulesys.h"
#include "../path_manager.h"
#include "../races.h"
#include "../raid.h"
#include <iostream>
#include <sstream>
@@ -2608,88 +2609,124 @@ namespace RoF
ENCODE(OP_RaidJoin)
{
EQApplicationPacket *inapp = *p;
unsigned char * __emu_buffer = inapp->pBuffer;
RaidCreate_Struct *raid_create = (RaidCreate_Struct*)__emu_buffer;
EQApplicationPacket* inapp = *p;
*p = nullptr;
unsigned char* __emu_buffer = inapp->pBuffer;
RaidCreate_Struct* emu = (RaidCreate_Struct*)__emu_buffer;
auto outapp_create = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
structs::RaidGeneral_Struct *general = (structs::RaidGeneral_Struct*)outapp_create->pBuffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
structs::RaidGeneral_Struct* general = (structs::RaidGeneral_Struct*)outapp->pBuffer;
general->action = 8;
general->parameter = 1;
strn0cpy(general->leader_name, raid_create->leader_name, 64);
strn0cpy(general->player_name, raid_create->leader_name, 64);
general->action = raidCreate;
general->parameter = RaidCommandAcceptInvite;
strn0cpy(general->leader_name, emu->leader_name, sizeof(emu->leader_name));
strn0cpy(general->player_name, emu->leader_name, sizeof(emu->leader_name));
dest->FastQueuePacket(&outapp);
dest->FastQueuePacket(&outapp_create);
safe_delete(inapp);
}
ENCODE(OP_RaidUpdate)
{
EQApplicationPacket *inapp = *p;
EQApplicationPacket* inapp = *p;
*p = nullptr;
unsigned char * __emu_buffer = inapp->pBuffer;
RaidGeneral_Struct *raid_gen = (RaidGeneral_Struct*)__emu_buffer;
unsigned char* __emu_buffer = inapp->pBuffer;
RaidGeneral_Struct* raid_gen = (RaidGeneral_Struct*)__emu_buffer;
if (raid_gen->action == 0) // raid add has longer length than other raid updates
switch (raid_gen->action)
{
RaidAddMember_Struct* in_add_member = (RaidAddMember_Struct*)__emu_buffer;
case raidAdd:
{
RaidAddMember_Struct* emu = (RaidAddMember_Struct*)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidAddMember_Struct));
structs::RaidAddMember_Struct *add_member = (structs::RaidAddMember_Struct*)outapp->pBuffer;
structs::RaidAddMember_Struct* eq = (structs::RaidAddMember_Struct*)outapp->pBuffer;
add_member->raidGen.action = in_add_member->raidGen.action;
add_member->raidGen.parameter = in_add_member->raidGen.parameter;
strn0cpy(add_member->raidGen.leader_name, in_add_member->raidGen.leader_name, 64);
strn0cpy(add_member->raidGen.player_name, in_add_member->raidGen.player_name, 64);
add_member->_class = in_add_member->_class;
add_member->level = in_add_member->level;
add_member->isGroupLeader = in_add_member->isGroupLeader;
add_member->flags[0] = in_add_member->flags[0];
add_member->flags[1] = in_add_member->flags[1];
add_member->flags[2] = in_add_member->flags[2];
add_member->flags[3] = in_add_member->flags[3];
add_member->flags[4] = in_add_member->flags[4];
dest->FastQueuePacket(&outapp);
}
else if (raid_gen->action == 35)
{
RaidMOTD_Struct *inmotd = (RaidMOTD_Struct *)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct) +
strlen(inmotd->motd) + 1);
structs::RaidMOTD_Struct *outmotd = (structs::RaidMOTD_Struct *)outapp->pBuffer;
OUT(raidGen.action);
OUT(raidGen.parameter);
OUT_str(raidGen.leader_name);
OUT_str(raidGen.player_name);
OUT(_class);
OUT(level);
OUT(isGroupLeader);
OUT(flags[0]);
OUT(flags[1]);
OUT(flags[2]);
OUT(flags[3]);
OUT(flags[4]);
outmotd->general.action = inmotd->general.action;
strn0cpy(outmotd->general.player_name, inmotd->general.player_name, 64);
strn0cpy(outmotd->motd, inmotd->motd, strlen(inmotd->motd) + 1);
dest->FastQueuePacket(&outapp);
break;
}
else if (raid_gen->action == 14 || raid_gen->action == 30)
case raidSetMotd:
{
RaidLeadershipUpdate_Struct *inlaa = (RaidLeadershipUpdate_Struct *)__emu_buffer;
auto outapp =
new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct));
structs::RaidLeadershipUpdate_Struct *outlaa = (structs::RaidLeadershipUpdate_Struct *)outapp->pBuffer;
RaidMOTD_Struct* emu = (RaidMOTD_Struct*)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct));
structs::RaidMOTD_Struct* eq = (structs::RaidMOTD_Struct*)outapp->pBuffer;
OUT(general.action);
OUT_str(general.player_name);
OUT_str(general.leader_name);
OUT_str(motd);
outlaa->action = inlaa->action;
strn0cpy(outlaa->player_name, inlaa->player_name, 64);
strn0cpy(outlaa->leader_name, inlaa->leader_name, 64);
memcpy(&outlaa->raid, &inlaa->raid, sizeof(RaidLeadershipAA_Struct));
dest->FastQueuePacket(&outapp);
break;
}
else
case raidSetLeaderAbilities:
case raidMakeLeader:
{
RaidGeneral_Struct* in_raid_general = (RaidGeneral_Struct*)__emu_buffer;
RaidLeadershipUpdate_Struct* emu = (RaidLeadershipUpdate_Struct*)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct));
structs::RaidLeadershipUpdate_Struct* eq = (structs::RaidLeadershipUpdate_Struct*)outapp->pBuffer;
OUT(action);
OUT_str(player_name);
OUT_str(leader_name);
memcpy(&eq->raid, &emu->raid, sizeof(RaidLeadershipAA_Struct));
dest->FastQueuePacket(&outapp);
break;
}
case raidSetNote:
{
auto emu = (RaidNote_Struct*)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidNote_Struct));
auto eq = (structs::RaidNote_Struct*)outapp->pBuffer;
OUT(general.action);
OUT_str(general.leader_name);
OUT_str(general.player_name);
OUT_str(note);
dest->FastQueuePacket(&outapp);
break;
}
case raidNoRaid:
{
dest->QueuePacket(inapp);
break;
}
default:
{
RaidGeneral_Struct* emu = (RaidGeneral_Struct*)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
structs::RaidGeneral_Struct *raid_general = (structs::RaidGeneral_Struct*)outapp->pBuffer;
strn0cpy(raid_general->leader_name, in_raid_general->leader_name, 64);
strn0cpy(raid_general->player_name, in_raid_general->player_name, 64);
raid_general->action = in_raid_general->action;
raid_general->parameter = in_raid_general->parameter;
dest->FastQueuePacket(&outapp);
}
structs::RaidGeneral_Struct* eq = (structs::RaidGeneral_Struct*)outapp->pBuffer;
OUT(action);
OUT(parameter);
OUT_str(leader_name);
OUT_str(player_name);
dest->FastQueuePacket(&outapp);
break;
}
}
safe_delete(inapp);
}
@@ -4861,37 +4898,47 @@ namespace RoF
{
DECODE_LENGTH_ATLEAST(structs::RaidGeneral_Struct);
// This is a switch on the RaidGeneral action
switch (*(uint32 *)__packet->pBuffer) {
case 35: { // raidMOTD
// we don't have a nice macro for this
structs::RaidMOTD_Struct *__eq_buffer = (structs::RaidMOTD_Struct *)__packet->pBuffer;
__eq_buffer->motd[1023] = '\0';
size_t motd_size = strlen(__eq_buffer->motd) + 1;
__packet->size = sizeof(RaidMOTD_Struct) + motd_size;
__packet->pBuffer = new unsigned char[__packet->size];
RaidMOTD_Struct *emu = (RaidMOTD_Struct *)__packet->pBuffer;
structs::RaidMOTD_Struct *eq = (structs::RaidMOTD_Struct *)__eq_buffer;
strn0cpy(emu->general.player_name, eq->general.player_name, 64);
strn0cpy(emu->motd, eq->motd, motd_size);
IN(general.action);
IN(general.parameter);
FINISH_DIRECT_DECODE();
break;
}
case 36: { // raidPlayerNote unhandled
break;
}
default: {
DECODE_LENGTH_EXACT(structs::RaidGeneral_Struct);
SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct);
strn0cpy(emu->leader_name, eq->leader_name, 64);
strn0cpy(emu->player_name, eq->player_name, 64);
IN(action);
IN(parameter);
FINISH_DIRECT_DECODE();
break;
}
RaidGeneral_Struct* rgs = (RaidGeneral_Struct*)__packet->pBuffer;
switch (rgs->action)
{
case raidSetMotd:
{
SETUP_VAR_DECODE(RaidMOTD_Struct, structs::RaidMOTD_Struct, motd);
IN(general.action);
IN(general.parameter);
IN_str(general.leader_name);
IN_str(general.player_name);
IN_str(motd);
FINISH_VAR_DECODE();
break;
}
case raidSetNote:
{
SETUP_VAR_DECODE(RaidNote_Struct, structs::RaidNote_Struct, note);
IN(general.action);
IN(general.parameter);
IN_str(general.leader_name);
IN_str(general.player_name);
IN_str(note);
FINISH_VAR_DECODE();
break;
}
default:
{
SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct);
IN(action);
IN(parameter);
IN_str(leader_name);
IN_str(player_name);
FINISH_DIRECT_DECODE();
break;
}
}
}
+150 -102
View File
@@ -35,7 +35,7 @@
#include "../path_manager.h"
#include "../classes.h"
#include "../races.h"
#include "../../zone/raids.h"
#include "../raid.h"
#include <iostream>
#include <sstream>
@@ -2678,100 +2678,124 @@ namespace RoF2
ENCODE(OP_RaidJoin)
{
EQApplicationPacket *inapp = *p;
unsigned char * __emu_buffer = inapp->pBuffer;
RaidCreate_Struct *raid_create = (RaidCreate_Struct*)__emu_buffer;
EQApplicationPacket* inapp = *p;
*p = nullptr;
unsigned char* __emu_buffer = inapp->pBuffer;
RaidCreate_Struct* emu = (RaidCreate_Struct*)__emu_buffer;
auto outapp_create = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
structs::RaidGeneral_Struct *general = (structs::RaidGeneral_Struct*)outapp_create->pBuffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
structs::RaidGeneral_Struct* general = (structs::RaidGeneral_Struct*)outapp->pBuffer;
general->action = 8;
general->parameter = 1;
strn0cpy(general->leader_name, raid_create->leader_name, 64);
strn0cpy(general->player_name, raid_create->leader_name, 64);
general->action = raidCreate;
general->parameter = RaidCommandAcceptInvite;
strn0cpy(general->leader_name, emu->leader_name, sizeof(emu->leader_name));
strn0cpy(general->player_name, emu->leader_name, sizeof(emu->leader_name));
dest->FastQueuePacket(&outapp);
dest->FastQueuePacket(&outapp_create);
safe_delete(inapp);
}
ENCODE(OP_RaidUpdate)
{
EQApplicationPacket *inapp = *p;
EQApplicationPacket* inapp = *p;
*p = nullptr;
unsigned char * __emu_buffer = inapp->pBuffer;
RaidGeneral_Struct *raid_gen = (RaidGeneral_Struct*)__emu_buffer;
unsigned char* __emu_buffer = inapp->pBuffer;
RaidGeneral_Struct* raid_gen = (RaidGeneral_Struct*)__emu_buffer;
if (raid_gen->action == 0) // raid add has longer length than other raid updates
switch (raid_gen->action)
{
RaidAddMember_Struct* in_add_member = (RaidAddMember_Struct*)__emu_buffer;
case raidAdd:
{
RaidAddMember_Struct* emu = (RaidAddMember_Struct*)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidAddMember_Struct));
structs::RaidAddMember_Struct *add_member = (structs::RaidAddMember_Struct*)outapp->pBuffer;
structs::RaidAddMember_Struct* eq = (structs::RaidAddMember_Struct*)outapp->pBuffer;
add_member->raidGen.action = in_add_member->raidGen.action;
add_member->raidGen.parameter = in_add_member->raidGen.parameter;
strn0cpy(add_member->raidGen.leader_name, in_add_member->raidGen.leader_name, 64);
strn0cpy(add_member->raidGen.player_name, in_add_member->raidGen.player_name, 64);
add_member->_class = in_add_member->_class;
add_member->level = in_add_member->level;
add_member->isGroupLeader = in_add_member->isGroupLeader;
add_member->flags[0] = in_add_member->flags[0];
add_member->flags[1] = in_add_member->flags[1];
add_member->flags[2] = in_add_member->flags[2];
add_member->flags[3] = in_add_member->flags[3];
add_member->flags[4] = in_add_member->flags[4];
dest->FastQueuePacket(&outapp);
}
else if (raid_gen->action == 35)
{
RaidMOTD_Struct *inmotd = (RaidMOTD_Struct *)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct) +
strlen(inmotd->motd) + 1);
structs::RaidMOTD_Struct *outmotd = (structs::RaidMOTD_Struct *)outapp->pBuffer;
OUT(raidGen.action);
OUT(raidGen.parameter);
OUT_str(raidGen.leader_name);
OUT_str(raidGen.player_name);
OUT(_class);
OUT(level);
OUT(isGroupLeader);
OUT(flags[0]);
OUT(flags[1]);
OUT(flags[2]);
OUT(flags[3]);
OUT(flags[4]);
outmotd->general.action = inmotd->general.action;
strn0cpy(outmotd->general.player_name, inmotd->general.player_name, 64);
strn0cpy(outmotd->motd, inmotd->motd, strlen(inmotd->motd) + 1);
dest->FastQueuePacket(&outapp);
break;
}
else if (raid_gen->action == 14 || raid_gen->action == 30)
case raidSetMotd:
{
RaidLeadershipUpdate_Struct *inlaa = (RaidLeadershipUpdate_Struct *)__emu_buffer;
auto outapp =
new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct));
structs::RaidLeadershipUpdate_Struct *outlaa = (structs::RaidLeadershipUpdate_Struct *)outapp->pBuffer;
RaidMOTD_Struct* emu = (RaidMOTD_Struct*)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct));
structs::RaidMOTD_Struct* eq = (structs::RaidMOTD_Struct*)outapp->pBuffer;
OUT(general.action);
OUT_str(general.player_name);
OUT_str(general.leader_name);
OUT_str(motd);
outlaa->action = inlaa->action;
strn0cpy(outlaa->player_name, inlaa->player_name, 64);
strn0cpy(outlaa->leader_name, inlaa->leader_name, 64);
memcpy(&outlaa->raid, &inlaa->raid, sizeof(RaidLeadershipAA_Struct));
dest->FastQueuePacket(&outapp);
break;
}
else if (raid_gen->action == raidSetNote)
case raidSetLeaderAbilities:
case raidMakeLeader:
{
auto in_note = (RaidGeneral_Struct*)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(RaidGeneral_Struct));
auto note = (RaidGeneral_Struct*)outapp->pBuffer;
note->action = raidSetNote;
strn0cpy(note->leader_name, in_note->leader_name, sizeof(note->leader_name));
strn0cpy(note->player_name, in_note->player_name, sizeof(note->leader_name));
strn0cpy(note->note, in_note->note, sizeof(note->note));
dest->QueuePacket(outapp);
safe_delete(outapp);
RaidLeadershipUpdate_Struct* emu = (RaidLeadershipUpdate_Struct*)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct));
structs::RaidLeadershipUpdate_Struct* eq = (structs::RaidLeadershipUpdate_Struct*)outapp->pBuffer;
OUT(action);
OUT_str(player_name);
OUT_str(leader_name);
memcpy(&eq->raid, &emu->raid, sizeof(RaidLeadershipAA_Struct));
dest->FastQueuePacket(&outapp);
break;
}
else
case raidSetNote:
{
RaidGeneral_Struct* in_raid_general = (RaidGeneral_Struct*)__emu_buffer;
auto emu = (RaidNote_Struct*)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidNote_Struct));
auto eq = (structs::RaidNote_Struct*)outapp->pBuffer;
OUT(general.action);
OUT_str(general.leader_name);
OUT_str(general.player_name);
OUT_str(note);
dest->FastQueuePacket(&outapp);
break;
}
case raidNoRaid:
{
dest->QueuePacket(inapp);
break;
}
default:
{
RaidGeneral_Struct* emu = (RaidGeneral_Struct*)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
structs::RaidGeneral_Struct *raid_general = (structs::RaidGeneral_Struct*)outapp->pBuffer;
strn0cpy(raid_general->leader_name, in_raid_general->leader_name, 64);
strn0cpy(raid_general->player_name, in_raid_general->player_name, 64);
raid_general->action = in_raid_general->action;
raid_general->parameter = in_raid_general->parameter;
dest->FastQueuePacket(&outapp);
}
structs::RaidGeneral_Struct* eq = (structs::RaidGeneral_Struct*)outapp->pBuffer;
OUT(action);
OUT(parameter);
OUT_str(leader_name);
OUT_str(player_name);
dest->FastQueuePacket(&outapp);
break;
}
}
safe_delete(inapp);
}
@@ -2785,7 +2809,10 @@ namespace RoF2
else
eq->window = emu->window;
OUT(type);
OUT(invslot);
eq->invslot = ServerToRoF2TypelessSlot(emu->invslot, invtype::typePossessions);
OUT(target_id);
OUT(can_cast);
OUT(can_scribe);
strn0cpy(eq->txtfile, emu->booktext, sizeof(eq->txtfile));
FINISH_ENCODE();
@@ -4411,6 +4438,17 @@ namespace RoF2
FINISH_DIRECT_DECODE();
}
DECODE(OP_BookButton)
{
DECODE_LENGTH_EXACT(structs::BookButton_Struct);
SETUP_DIRECT_DECODE(BookButton_Struct, structs::BookButton_Struct);
emu->invslot = static_cast<int16_t>(RoF2ToServerTypelessSlot(eq->slot, invtype::typePossessions));
IN(target_id);
FINISH_DIRECT_DECODE();
}
DECODE(OP_Buff)
{
DECODE_LENGTH_EXACT(structs::SpellBuffPacket_Struct);
@@ -5077,37 +5115,47 @@ namespace RoF2
{
DECODE_LENGTH_ATLEAST(structs::RaidGeneral_Struct);
// This is a switch on the RaidGeneral action
switch (*(uint32 *)__packet->pBuffer) {
case 35: { // raidMOTD
// we don't have a nice macro for this
structs::RaidMOTD_Struct *__eq_buffer = (structs::RaidMOTD_Struct *)__packet->pBuffer;
__eq_buffer->motd[1023] = '\0';
size_t motd_size = strlen(__eq_buffer->motd) + 1;
__packet->size = sizeof(RaidMOTD_Struct) + motd_size;
__packet->pBuffer = new unsigned char[__packet->size];
RaidMOTD_Struct *emu = (RaidMOTD_Struct *)__packet->pBuffer;
structs::RaidMOTD_Struct *eq = (structs::RaidMOTD_Struct *)__eq_buffer;
strn0cpy(emu->general.player_name, eq->general.player_name, 64);
strn0cpy(emu->motd, eq->motd, motd_size);
IN(general.action);
IN(general.parameter);
FINISH_DIRECT_DECODE();
break;
}
case 36: { // raidPlayerNote unhandled
break;
}
default: {
DECODE_LENGTH_EXACT(structs::RaidGeneral_Struct);
SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct);
strn0cpy(emu->leader_name, eq->leader_name, 64);
strn0cpy(emu->player_name, eq->player_name, 64);
IN(action);
IN(parameter);
FINISH_DIRECT_DECODE();
break;
}
RaidGeneral_Struct* rgs = (RaidGeneral_Struct*)__packet->pBuffer;
switch (rgs->action)
{
case raidSetMotd:
{
SETUP_VAR_DECODE(RaidMOTD_Struct, structs::RaidMOTD_Struct, motd);
IN(general.action);
IN(general.parameter);
IN_str(general.leader_name);
IN_str(general.player_name);
IN_str(motd);
FINISH_VAR_DECODE();
break;
}
case raidSetNote:
{
SETUP_VAR_DECODE(RaidNote_Struct, structs::RaidNote_Struct, note);
IN(general.action);
IN(general.parameter);
IN_str(general.leader_name);
IN_str(general.player_name);
IN_str(note);
FINISH_VAR_DECODE();
break;
}
default:
{
SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct);
IN(action);
IN(parameter);
IN_str(leader_name);
IN_str(player_name);
FINISH_DIRECT_DECODE();
break;
}
}
}
@@ -5117,8 +5165,8 @@ namespace RoF2
SETUP_DIRECT_DECODE(BookRequest_Struct, structs::BookRequest_Struct);
IN(type);
IN(invslot);
IN(subslot);
emu->invslot = static_cast<int16_t>(RoF2ToServerTypelessSlot(eq->invslot, invtype::typePossessions));
IN(target_id);
emu->window = (uint8)eq->window;
strn0cpy(emu->txtfile, eq->txtfile, sizeof(emu->txtfile));
+1
View File
@@ -150,6 +150,7 @@ D(OP_AugmentInfo)
D(OP_AugmentItem)
D(OP_BazaarSearch)
D(OP_BlockedBuffs)
D(OP_BookButton)
D(OP_Buff)
D(OP_BuffRemoveRequest)
D(OP_CastSpell)
+24 -11
View File
@@ -2868,15 +2868,23 @@ struct BookText_Struct {
// This is just a "text file" on the server
// or in our case, the 'name' column in our books table.
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.
/*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;
/*0020*/ uint16 unknown0016;
/*0022*/ char txtfile[8194];
/*0000*/ uint32 window; // where to display the text (0xFFFFFFFF means new window).
/*0004*/ TypelessInventorySlot_Struct invslot; // book ItemIndex (with int16_t alignment padding)
/*0012*/ uint32 type; // 0 = Scroll, 1 = Book, 2 = Item Info. Possibly others
/*0016*/ uint32 target_id; // client's target when using the book
/*0020*/ uint8 can_cast; // show Cast Spell button in book window
/*0021*/ uint8 can_scribe; // show Scribe button in book window
/*0022*/ char txtfile[8194];
/*8216*/
};
// used by Scribe and CastSpell book buttons
struct BookButton_Struct
{
/*0000*/ TypelessInventorySlot_Struct slot; // book ItemIndex (with int16_t alignment padding)
/*0008*/ int32 target_id; // client's target when using the book button
/*0012*/ int32 unused; // always 0 from button packets
/*0016*/
};
/*
@@ -4190,9 +4198,14 @@ struct RaidAddMember_Struct {
/*139*/ uint8 flags[5]; //no idea if these are needed...
};
struct RaidNote_Struct {
/*000*/ RaidGeneral_Struct general;
/*140*/ char note[64];
};
struct RaidMOTD_Struct {
/*000*/ RaidGeneral_Struct general; // leader_name and action only used
/*140*/ char motd[0]; // max size 1024, but reply is variable
/*000*/ RaidGeneral_Struct general;
/*140*/ char motd[1024];
};
struct RaidLeadershipUpdate_Struct {
+6 -1
View File
@@ -4136,9 +4136,14 @@ struct RaidAddMember_Struct {
/*139*/ uint8 flags[5]; //no idea if these are needed...
};
struct RaidNote_Struct {
/*000*/ RaidGeneral_Struct general;
/*140*/ char note[64];
};
struct RaidMOTD_Struct {
/*000*/ RaidGeneral_Struct general; // leader_name and action only used
/*140*/ char motd[0]; // max size 1024, but reply is variable
/*140*/ char motd[1024]; // max size is 1024, but reply is variable
};
struct RaidLeadershipUpdate_Struct {
+151 -89
View File
@@ -34,6 +34,7 @@
#include "../rulesys.h"
#include "../path_manager.h"
#include "../races.h"
#include "../raid.h"
#include <iostream>
#include <sstream>
@@ -1686,88 +1687,124 @@ namespace SoD
ENCODE(OP_RaidJoin)
{
EQApplicationPacket *inapp = *p;
unsigned char * __emu_buffer = inapp->pBuffer;
RaidCreate_Struct *raid_create = (RaidCreate_Struct*)__emu_buffer;
EQApplicationPacket* inapp = *p;
*p = nullptr;
unsigned char* __emu_buffer = inapp->pBuffer;
RaidCreate_Struct* emu = (RaidCreate_Struct*)__emu_buffer;
auto outapp_create = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
structs::RaidGeneral_Struct *general = (structs::RaidGeneral_Struct*)outapp_create->pBuffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
structs::RaidGeneral_Struct* general = (structs::RaidGeneral_Struct*)outapp->pBuffer;
general->action = 8;
general->parameter = 1;
strn0cpy(general->leader_name, raid_create->leader_name, 64);
strn0cpy(general->player_name, raid_create->leader_name, 64);
general->action = raidCreate;
general->parameter = RaidCommandAcceptInvite;
strn0cpy(general->leader_name, emu->leader_name, sizeof(emu->leader_name));
strn0cpy(general->player_name, emu->leader_name, sizeof(emu->leader_name));
dest->FastQueuePacket(&outapp);
dest->FastQueuePacket(&outapp_create);
safe_delete(inapp);
}
ENCODE(OP_RaidUpdate)
{
EQApplicationPacket *inapp = *p;
EQApplicationPacket* inapp = *p;
*p = nullptr;
unsigned char * __emu_buffer = inapp->pBuffer;
RaidGeneral_Struct *raid_gen = (RaidGeneral_Struct*)__emu_buffer;
unsigned char* __emu_buffer = inapp->pBuffer;
RaidGeneral_Struct* raid_gen = (RaidGeneral_Struct*)__emu_buffer;
if (raid_gen->action == 0) // raid add has longer length than other raid updates
switch (raid_gen->action)
{
RaidAddMember_Struct* in_add_member = (RaidAddMember_Struct*)__emu_buffer;
case raidAdd:
{
RaidAddMember_Struct* emu = (RaidAddMember_Struct*)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidAddMember_Struct));
structs::RaidAddMember_Struct *add_member = (structs::RaidAddMember_Struct*)outapp->pBuffer;
structs::RaidAddMember_Struct* eq = (structs::RaidAddMember_Struct*)outapp->pBuffer;
add_member->raidGen.action = in_add_member->raidGen.action;
add_member->raidGen.parameter = in_add_member->raidGen.parameter;
strn0cpy(add_member->raidGen.leader_name, in_add_member->raidGen.leader_name, 64);
strn0cpy(add_member->raidGen.player_name, in_add_member->raidGen.player_name, 64);
add_member->_class = in_add_member->_class;
add_member->level = in_add_member->level;
add_member->isGroupLeader = in_add_member->isGroupLeader;
add_member->flags[0] = in_add_member->flags[0];
add_member->flags[1] = in_add_member->flags[1];
add_member->flags[2] = in_add_member->flags[2];
add_member->flags[3] = in_add_member->flags[3];
add_member->flags[4] = in_add_member->flags[4];
dest->FastQueuePacket(&outapp);
}
else if (raid_gen->action == 35)
{
RaidMOTD_Struct *inmotd = (RaidMOTD_Struct *)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct) +
strlen(inmotd->motd) + 1);
structs::RaidMOTD_Struct *outmotd = (structs::RaidMOTD_Struct *)outapp->pBuffer;
OUT(raidGen.action);
OUT(raidGen.parameter);
OUT_str(raidGen.leader_name);
OUT_str(raidGen.player_name);
OUT(_class);
OUT(level);
OUT(isGroupLeader);
OUT(flags[0]);
OUT(flags[1]);
OUT(flags[2]);
OUT(flags[3]);
OUT(flags[4]);
outmotd->general.action = inmotd->general.action;
strn0cpy(outmotd->general.player_name, inmotd->general.player_name, 64);
strn0cpy(outmotd->motd, inmotd->motd, strlen(inmotd->motd) + 1);
dest->FastQueuePacket(&outapp);
break;
}
else if (raid_gen->action == 14 || raid_gen->action == 30)
case raidSetMotd:
{
RaidLeadershipUpdate_Struct *inlaa = (RaidLeadershipUpdate_Struct *)__emu_buffer;
auto outapp =
new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct));
structs::RaidLeadershipUpdate_Struct *outlaa = (structs::RaidLeadershipUpdate_Struct *)outapp->pBuffer;
RaidMOTD_Struct* emu = (RaidMOTD_Struct*)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct));
structs::RaidMOTD_Struct* eq = (structs::RaidMOTD_Struct*)outapp->pBuffer;
OUT(general.action);
OUT_str(general.player_name);
OUT_str(general.leader_name);
OUT_str(motd);
outlaa->action = inlaa->action;
strn0cpy(outlaa->player_name, inlaa->player_name, 64);
strn0cpy(outlaa->leader_name, inlaa->leader_name, 64);
memcpy(&outlaa->raid, &inlaa->raid, sizeof(RaidLeadershipAA_Struct));
dest->FastQueuePacket(&outapp);
break;
}
else
case raidSetLeaderAbilities:
case raidMakeLeader:
{
RaidGeneral_Struct* in_raid_general = (RaidGeneral_Struct*)__emu_buffer;
RaidLeadershipUpdate_Struct* emu = (RaidLeadershipUpdate_Struct*)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct));
structs::RaidLeadershipUpdate_Struct* eq = (structs::RaidLeadershipUpdate_Struct*)outapp->pBuffer;
OUT(action);
OUT_str(player_name);
OUT_str(leader_name);
memcpy(&eq->raid, &emu->raid, sizeof(RaidLeadershipAA_Struct));
dest->FastQueuePacket(&outapp);
break;
}
case raidSetNote:
{
auto emu = (RaidNote_Struct*)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidNote_Struct));
auto eq = (structs::RaidNote_Struct*)outapp->pBuffer;
OUT(general.action);
OUT_str(general.leader_name);
OUT_str(general.player_name);
OUT_str(note);
dest->FastQueuePacket(&outapp);
break;
}
case raidNoRaid:
{
dest->QueuePacket(inapp);
break;
}
default:
{
RaidGeneral_Struct* emu = (RaidGeneral_Struct*)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
structs::RaidGeneral_Struct *raid_general = (structs::RaidGeneral_Struct*)outapp->pBuffer;
strn0cpy(raid_general->leader_name, in_raid_general->leader_name, 64);
strn0cpy(raid_general->player_name, in_raid_general->player_name, 64);
raid_general->action = in_raid_general->action;
raid_general->parameter = in_raid_general->parameter;
dest->FastQueuePacket(&outapp);
}
structs::RaidGeneral_Struct* eq = (structs::RaidGeneral_Struct*)outapp->pBuffer;
OUT(action);
OUT(parameter);
OUT_str(leader_name);
OUT_str(player_name);
dest->FastQueuePacket(&outapp);
break;
}
}
safe_delete(inapp);
}
@@ -1782,6 +1819,9 @@ namespace SoD
eq->window = emu->window;
OUT(type);
eq->invslot = ServerToSoDSlot(emu->invslot);
OUT(target_id);
OUT(can_cast);
OUT(can_scribe);
strn0cpy(eq->txtfile, emu->booktext, sizeof(eq->txtfile));
FINISH_ENCODE();
@@ -2817,6 +2857,17 @@ namespace SoD
FINISH_DIRECT_DECODE();
}
DECODE(OP_BookButton)
{
DECODE_LENGTH_EXACT(structs::BookButton_Struct);
SETUP_DIRECT_DECODE(BookButton_Struct, structs::BookButton_Struct);
emu->invslot = static_cast<int16_t>(SoDToServerSlot(eq->invslot));
IN(target_id);
FINISH_DIRECT_DECODE();
}
DECODE(OP_Buff)
{
DECODE_LENGTH_EXACT(structs::SpellBuffPacket_Struct);
@@ -3324,37 +3375,47 @@ namespace SoD
{
DECODE_LENGTH_ATLEAST(structs::RaidGeneral_Struct);
// This is a switch on the RaidGeneral action
switch (*(uint32 *)__packet->pBuffer) {
case 35: { // raidMOTD
// we don't have a nice macro for this
structs::RaidMOTD_Struct *__eq_buffer = (structs::RaidMOTD_Struct *)__packet->pBuffer;
__eq_buffer->motd[1023] = '\0';
size_t motd_size = strlen(__eq_buffer->motd) + 1;
__packet->size = sizeof(RaidMOTD_Struct) + motd_size;
__packet->pBuffer = new unsigned char[__packet->size];
RaidMOTD_Struct *emu = (RaidMOTD_Struct *)__packet->pBuffer;
structs::RaidMOTD_Struct *eq = (structs::RaidMOTD_Struct *)__eq_buffer;
strn0cpy(emu->general.player_name, eq->general.player_name, 64);
strn0cpy(emu->motd, eq->motd, motd_size);
IN(general.action);
IN(general.parameter);
FINISH_DIRECT_DECODE();
break;
}
case 36: { // raidPlayerNote unhandled
break;
}
default: {
DECODE_LENGTH_EXACT(structs::RaidGeneral_Struct);
SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct);
strn0cpy(emu->leader_name, eq->leader_name, 64);
strn0cpy(emu->player_name, eq->player_name, 64);
IN(action);
IN(parameter);
FINISH_DIRECT_DECODE();
break;
}
RaidGeneral_Struct* rgs = (RaidGeneral_Struct*)__packet->pBuffer;
switch (rgs->action)
{
case raidSetMotd:
{
SETUP_VAR_DECODE(RaidMOTD_Struct, structs::RaidMOTD_Struct, motd);
IN(general.action);
IN(general.parameter);
IN_str(general.leader_name);
IN_str(general.player_name);
IN_str(motd);
FINISH_VAR_DECODE();
break;
}
case raidSetNote:
{
SETUP_VAR_DECODE(RaidNote_Struct, structs::RaidNote_Struct, note);
IN(general.action);
IN(general.parameter);
IN_str(general.leader_name);
IN_str(general.player_name);
IN_str(note);
FINISH_VAR_DECODE();
break;
}
default:
{
SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct);
IN(action);
IN(parameter);
IN_str(leader_name);
IN_str(player_name);
FINISH_DIRECT_DECODE();
break;
}
}
}
@@ -3364,7 +3425,8 @@ namespace SoD
SETUP_DIRECT_DECODE(BookRequest_Struct, structs::BookRequest_Struct);
IN(type);
emu->invslot = SoDToServerSlot(eq->invslot);
emu->invslot = static_cast<int16_t>(SoDToServerSlot(eq->invslot));
IN(target_id);
emu->window = (uint8)eq->window;
strn0cpy(emu->txtfile, eq->txtfile, sizeof(emu->txtfile));
+1
View File
@@ -103,6 +103,7 @@ D(OP_ApplyPoison)
D(OP_AugmentInfo)
D(OP_AugmentItem)
D(OP_BazaarSearch)
D(OP_BookButton)
D(OP_Buff)
D(OP_CastSpell)
D(OP_ChannelMessage)
+21 -7
View File
@@ -2351,12 +2351,21 @@ struct BookText_Struct {
// This is just a "text file" on the server
// or in our case, the 'name' column in our books table.
struct BookRequest_Struct {
/*0000*/ uint32 window; // where to display the text (0xFFFFFFFF means new window).
/*0004*/ uint32 invslot; // The inventory slot the book is in. Not used, but echoed in the response packet.
/*0008*/ uint32 type; // 0 = Scroll, 1 = Book, 2 = Item Info. Possibly others
/*0012*/ uint32 unknown0012;
/*0016*/ uint16 unknown0016;
/*0018*/ char txtfile[8194];
/*0000*/ uint32 window; // where to display the text (0xFFFFFFFF means new window).
/*0004*/ uint32 invslot; // The inventory slot the book is in
/*0008*/ uint32 type; // 0 = Scroll, 1 = Book, 2 = Item Info. Possibly others
/*0012*/ uint32 target_id;
/*0016*/ uint8 can_cast;
/*0017*/ uint8 can_scribe;
/*0018*/ char txtfile[8194];
};
// used by Scribe and CastSpell book buttons
struct BookButton_Struct
{
/*0000*/ int32 invslot;
/*0004*/ int32 target_id; // client's target when using the book
/*0008*/ int32 unused; // always 0 from button packets
};
/*
@@ -3583,9 +3592,14 @@ struct RaidAddMember_Struct {
/*139*/ uint8 flags[5]; //no idea if these are needed...
};
struct RaidNote_Struct {
/*000*/ RaidGeneral_Struct general;
/*140*/ char note[64];
};
struct RaidMOTD_Struct {
/*000*/ RaidGeneral_Struct general; // leader_name and action only used
/*140*/ char motd[0]; // max size 1024, but reply is variable
/*140*/ char motd[1024]; // max size is 1024, but reply is variable
};
struct RaidLeadershipUpdate_Struct {
+151 -89
View File
@@ -33,6 +33,7 @@
#include "sof_structs.h"
#include "../rulesys.h"
#include "../path_manager.h"
#include "../raid.h"
#include <iostream>
#include <sstream>
@@ -1356,88 +1357,124 @@ namespace SoF
ENCODE(OP_RaidJoin)
{
EQApplicationPacket *inapp = *p;
unsigned char * __emu_buffer = inapp->pBuffer;
RaidCreate_Struct *raid_create = (RaidCreate_Struct*)__emu_buffer;
EQApplicationPacket* inapp = *p;
*p = nullptr;
unsigned char* __emu_buffer = inapp->pBuffer;
RaidCreate_Struct* emu = (RaidCreate_Struct*)__emu_buffer;
auto outapp_create = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
structs::RaidGeneral_Struct *general = (structs::RaidGeneral_Struct*)outapp_create->pBuffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
structs::RaidGeneral_Struct* general = (structs::RaidGeneral_Struct*)outapp->pBuffer;
general->action = 8;
general->parameter = 1;
strn0cpy(general->leader_name, raid_create->leader_name, 64);
strn0cpy(general->player_name, raid_create->leader_name, 64);
general->action = raidCreate;
general->parameter = RaidCommandAcceptInvite;
strn0cpy(general->leader_name, emu->leader_name, sizeof(emu->leader_name));
strn0cpy(general->player_name, emu->leader_name, sizeof(emu->leader_name));
dest->FastQueuePacket(&outapp);
dest->FastQueuePacket(&outapp_create);
safe_delete(inapp);
}
ENCODE(OP_RaidUpdate)
{
EQApplicationPacket *inapp = *p;
EQApplicationPacket* inapp = *p;
*p = nullptr;
unsigned char * __emu_buffer = inapp->pBuffer;
RaidGeneral_Struct *raid_gen = (RaidGeneral_Struct*)__emu_buffer;
unsigned char* __emu_buffer = inapp->pBuffer;
RaidGeneral_Struct* raid_gen = (RaidGeneral_Struct*)__emu_buffer;
if (raid_gen->action == 0) // raid add has longer length than other raid updates
switch (raid_gen->action)
{
RaidAddMember_Struct* in_add_member = (RaidAddMember_Struct*)__emu_buffer;
case raidAdd:
{
RaidAddMember_Struct* emu = (RaidAddMember_Struct*)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidAddMember_Struct));
structs::RaidAddMember_Struct *add_member = (structs::RaidAddMember_Struct*)outapp->pBuffer;
structs::RaidAddMember_Struct* eq = (structs::RaidAddMember_Struct*)outapp->pBuffer;
add_member->raidGen.action = in_add_member->raidGen.action;
add_member->raidGen.parameter = in_add_member->raidGen.parameter;
strn0cpy(add_member->raidGen.leader_name, in_add_member->raidGen.leader_name, 64);
strn0cpy(add_member->raidGen.player_name, in_add_member->raidGen.player_name, 64);
add_member->_class = in_add_member->_class;
add_member->level = in_add_member->level;
add_member->isGroupLeader = in_add_member->isGroupLeader;
add_member->flags[0] = in_add_member->flags[0];
add_member->flags[1] = in_add_member->flags[1];
add_member->flags[2] = in_add_member->flags[2];
add_member->flags[3] = in_add_member->flags[3];
add_member->flags[4] = in_add_member->flags[4];
dest->FastQueuePacket(&outapp);
}
else if (raid_gen->action == 35)
{
RaidMOTD_Struct *inmotd = (RaidMOTD_Struct *)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct) +
strlen(inmotd->motd) + 1);
structs::RaidMOTD_Struct *outmotd = (structs::RaidMOTD_Struct *)outapp->pBuffer;
OUT(raidGen.action);
OUT(raidGen.parameter);
OUT_str(raidGen.leader_name);
OUT_str(raidGen.player_name);
OUT(_class);
OUT(level);
OUT(isGroupLeader);
OUT(flags[0]);
OUT(flags[1]);
OUT(flags[2]);
OUT(flags[3]);
OUT(flags[4]);
outmotd->general.action = inmotd->general.action;
strn0cpy(outmotd->general.player_name, inmotd->general.player_name, 64);
strn0cpy(outmotd->motd, inmotd->motd, strlen(inmotd->motd) + 1);
dest->FastQueuePacket(&outapp);
break;
}
else if (raid_gen->action == 14 || raid_gen->action == 30)
case raidSetMotd:
{
RaidLeadershipUpdate_Struct *inlaa = (RaidLeadershipUpdate_Struct *)__emu_buffer;
auto outapp =
new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct));
structs::RaidLeadershipUpdate_Struct *outlaa = (structs::RaidLeadershipUpdate_Struct *)outapp->pBuffer;
RaidMOTD_Struct* emu = (RaidMOTD_Struct*)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct));
structs::RaidMOTD_Struct* eq = (structs::RaidMOTD_Struct*)outapp->pBuffer;
OUT(general.action);
OUT_str(general.player_name);
OUT_str(general.leader_name);
OUT_str(motd);
outlaa->action = inlaa->action;
strn0cpy(outlaa->player_name, inlaa->player_name, 64);
strn0cpy(outlaa->leader_name, inlaa->leader_name, 64);
memcpy(&outlaa->raid, &inlaa->raid, sizeof(RaidLeadershipAA_Struct));
dest->FastQueuePacket(&outapp);
break;
}
else
case raidSetLeaderAbilities:
case raidMakeLeader:
{
RaidGeneral_Struct* in_raid_general = (RaidGeneral_Struct*)__emu_buffer;
RaidLeadershipUpdate_Struct* emu = (RaidLeadershipUpdate_Struct*)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct));
structs::RaidLeadershipUpdate_Struct* eq = (structs::RaidLeadershipUpdate_Struct*)outapp->pBuffer;
OUT(action);
OUT_str(player_name);
OUT_str(leader_name);
memcpy(&eq->raid, &emu->raid, sizeof(RaidLeadershipAA_Struct));
dest->FastQueuePacket(&outapp);
break;
}
case raidSetNote:
{
auto emu = (RaidNote_Struct*)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidNote_Struct));
auto eq = (structs::RaidNote_Struct*)outapp->pBuffer;
OUT(general.action);
OUT_str(general.leader_name);
OUT_str(general.player_name);
OUT_str(note);
dest->FastQueuePacket(&outapp);
break;
}
case raidNoRaid:
{
dest->QueuePacket(inapp);
break;
}
default:
{
RaidGeneral_Struct* emu = (RaidGeneral_Struct*)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
structs::RaidGeneral_Struct *raid_general = (structs::RaidGeneral_Struct*)outapp->pBuffer;
strn0cpy(raid_general->leader_name, in_raid_general->leader_name, 64);
strn0cpy(raid_general->player_name, in_raid_general->player_name, 64);
raid_general->action = in_raid_general->action;
raid_general->parameter = in_raid_general->parameter;
dest->FastQueuePacket(&outapp);
}
structs::RaidGeneral_Struct* eq = (structs::RaidGeneral_Struct*)outapp->pBuffer;
OUT(action);
OUT(parameter);
OUT_str(leader_name);
OUT_str(player_name);
dest->FastQueuePacket(&outapp);
break;
}
}
safe_delete(inapp);
}
@@ -1452,6 +1489,9 @@ namespace SoF
eq->window = emu->window;
OUT(type);
eq->invslot = ServerToSoFSlot(emu->invslot);
OUT(target_id);
OUT(can_cast);
OUT(can_scribe);
strn0cpy(eq->txtfile, emu->booktext, sizeof(eq->txtfile));
FINISH_ENCODE();
@@ -2261,6 +2301,17 @@ namespace SoF
FINISH_DIRECT_DECODE();
}
DECODE(OP_BookButton)
{
DECODE_LENGTH_EXACT(structs::BookButton_Struct);
SETUP_DIRECT_DECODE(BookButton_Struct, structs::BookButton_Struct);
emu->invslot = static_cast<int16_t>(SoFToServerSlot(eq->invslot));
IN(target_id);
FINISH_DIRECT_DECODE();
}
DECODE(OP_Buff)
{
DECODE_LENGTH_EXACT(structs::SpellBuffPacket_Struct);
@@ -2729,37 +2780,47 @@ namespace SoF
{
DECODE_LENGTH_ATLEAST(structs::RaidGeneral_Struct);
// This is a switch on the RaidGeneral action
switch (*(uint32 *)__packet->pBuffer) {
case 35: { // raidMOTD
// we don't have a nice macro for this
structs::RaidMOTD_Struct *__eq_buffer = (structs::RaidMOTD_Struct *)__packet->pBuffer;
__eq_buffer->motd[1023] = '\0';
size_t motd_size = strlen(__eq_buffer->motd) + 1;
__packet->size = sizeof(RaidMOTD_Struct) + motd_size;
__packet->pBuffer = new unsigned char[__packet->size];
RaidMOTD_Struct *emu = (RaidMOTD_Struct *)__packet->pBuffer;
structs::RaidMOTD_Struct *eq = (structs::RaidMOTD_Struct *)__eq_buffer;
strn0cpy(emu->general.player_name, eq->general.player_name, 64);
strn0cpy(emu->motd, eq->motd, motd_size);
IN(general.action);
IN(general.parameter);
FINISH_DIRECT_DECODE();
break;
}
case 36: { // raidPlayerNote unhandled
break;
}
default: {
DECODE_LENGTH_EXACT(structs::RaidGeneral_Struct);
SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct);
strn0cpy(emu->leader_name, eq->leader_name, 64);
strn0cpy(emu->player_name, eq->player_name, 64);
IN(action);
IN(parameter);
FINISH_DIRECT_DECODE();
break;
}
RaidGeneral_Struct* rgs = (RaidGeneral_Struct*)__packet->pBuffer;
switch (rgs->action)
{
case raidSetMotd:
{
SETUP_VAR_DECODE(RaidMOTD_Struct, structs::RaidMOTD_Struct, motd);
IN(general.action);
IN(general.parameter);
IN_str(general.leader_name);
IN_str(general.player_name);
IN_str(motd);
FINISH_VAR_DECODE();
break;
}
case raidSetNote:
{
SETUP_VAR_DECODE(RaidNote_Struct, structs::RaidNote_Struct, note);
IN(general.action);
IN(general.parameter);
IN_str(general.leader_name);
IN_str(general.player_name);
IN_str(note);
FINISH_VAR_DECODE();
break;
}
default:
{
SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct);
IN(action);
IN(parameter);
IN_str(leader_name);
IN_str(player_name);
FINISH_DIRECT_DECODE();
break;
}
}
}
@@ -2769,7 +2830,8 @@ namespace SoF
SETUP_DIRECT_DECODE(BookRequest_Struct, structs::BookRequest_Struct);
IN(type);
emu->invslot = SoFToServerSlot(eq->invslot);
emu->invslot = static_cast<int16_t>(SoFToServerSlot(eq->invslot));
IN(target_id);
emu->window = (uint8)eq->window;
strn0cpy(emu->txtfile, eq->txtfile, sizeof(emu->txtfile));
+1
View File
@@ -94,6 +94,7 @@ D(OP_AltCurrencySellSelection)
D(OP_ApplyPoison)
D(OP_AugmentInfo)
D(OP_AugmentItem)
D(OP_BookButton)
D(OP_Buff)
D(OP_Bug)
D(OP_CastSpell)
+21 -7
View File
@@ -2321,12 +2321,21 @@ struct BookText_Struct {
// This is just a "text file" on the server
// or in our case, the 'name' column in our books table.
struct BookRequest_Struct {
/*0000*/ uint32 window; // where to display the text (0xFFFFFFFF means new window).
/*0004*/ uint32 invslot; // The inventory slot the book is in. Not used, but echoed in the response packet.
/*0008*/ uint32 type; // 0 = Scroll, 1 = Book, 2 = Item Info. Possibly others
/*0012*/ uint32 unknown0012;
/*0016*/ uint16 unknown0016;
/*0018*/ char txtfile[8194];
/*0000*/ uint32 window; // where to display the text (0xFFFFFFFF means new window).
/*0004*/ uint32 invslot; // The inventory slot the book is in
/*0008*/ uint32 type; // 0 = Scroll, 1 = Book, 2 = Item Info. Possibly others
/*0012*/ uint32 target_id;
/*0016*/ uint8 can_cast;
/*0017*/ uint8 can_scribe;
/*0018*/ char txtfile[8194];
};
// used by Scribe and CastSpell book buttons
struct BookButton_Struct
{
/*0000*/ int32 invslot;
/*0004*/ int32 target_id; // client's target when using the book
/*0008*/ int32 unused; // always 0 from button packets
};
/*
@@ -3508,9 +3517,14 @@ struct RaidAddMember_Struct {
/*139*/ uint8 flags[5]; //no idea if these are needed...
};
struct RaidNote_Struct {
/*000*/ RaidGeneral_Struct general;
/*140*/ char note[64];
};
struct RaidMOTD_Struct {
/*000*/ RaidGeneral_Struct general; // leader_name and action only used
/*140*/ char motd[0]; // max size 1024, but reply is variable
/*140*/ char motd[1024]; // max size is 1024, but reply is variable
};
struct RaidLeadershipUpdate_Struct {
+12
View File
@@ -128,6 +128,15 @@
emu_struct *emu = (emu_struct *) __packet->pBuffer; \
eq_struct *eq = (eq_struct *) __eq_buffer;
#define SETUP_VAR_DECODE(emu_struct, eq_struct, var_field) \
unsigned char *__eq_buffer = __packet->pBuffer; \
eq_struct* in = (eq_struct*)__packet->pBuffer; \
auto size = strlen(in->var_field); \
__packet->size = sizeof(emu_struct) + size + 1; \
__packet->pBuffer = new unsigned char[__packet->size]; \
emu_struct *emu = (emu_struct *) __packet->pBuffer; \
eq_struct *eq = (eq_struct *) __eq_buffer;
#define MEMSET_IN(emu_struct) \
memset(__packet->pBuffer, 0, sizeof(emu_struct));
@@ -146,6 +155,9 @@
delete[] __eq_buffer; \
p->SetOpcode(OP_Unknown);
#define FINISH_VAR_DECODE() \
delete[] __eq_buffer;
//call to finish an encoder using SETUP_DIRECT_DECODE
#define FINISH_DIRECT_DECODE() \
delete[] __eq_buffer;
+171
View File
@@ -33,6 +33,7 @@
#include "../item_instance.h"
#include "titanium_structs.h"
#include "../path_manager.h"
#include "../raid.h"
#include <sstream>
@@ -1245,6 +1246,119 @@ namespace Titanium
FINISH_ENCODE();
}
ENCODE(OP_MarkRaidNPC)
{
ENCODE_LENGTH_EXACT(MarkNPC_Struct);
SETUP_DIRECT_ENCODE(MarkNPC_Struct, MarkNPC_Struct);
EQApplicationPacket* outapp = new EQApplicationPacket(OP_MarkNPC, sizeof(MarkNPC_Struct));
MarkNPC_Struct* mnpcs = (MarkNPC_Struct*)outapp->pBuffer;
mnpcs->TargetID = emu->TargetID;
mnpcs->Number = emu->Number;
dest->QueuePacket(outapp);
safe_delete(outapp);
FINISH_ENCODE();
}
ENCODE(OP_RaidUpdate)
{
EQApplicationPacket* inapp = *p;
*p = nullptr;
unsigned char* __emu_buffer = inapp->pBuffer;
RaidGeneral_Struct* raid_gen = (RaidGeneral_Struct*)__emu_buffer;
switch (raid_gen->action)
{
case raidAdd:
{
RaidAddMember_Struct* emu = (RaidAddMember_Struct*)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidAddMember_Struct));
structs::RaidAddMember_Struct* eq = (structs::RaidAddMember_Struct*)outapp->pBuffer;
OUT(raidGen.action);
OUT(raidGen.parameter);
OUT_str(raidGen.leader_name);
OUT_str(raidGen.player_name);
OUT(_class);
OUT(level);
OUT(isGroupLeader);
dest->FastQueuePacket(&outapp);
break;
}
case raidSetMotd:
{
RaidMOTD_Struct* emu = (RaidMOTD_Struct*)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct));
structs::RaidMOTD_Struct* eq = (structs::RaidMOTD_Struct*)outapp->pBuffer;
OUT(general.action);
OUT_str(general.player_name);
OUT_str(general.leader_name);
OUT_str(motd);
dest->FastQueuePacket(&outapp);
break;
}
case raidSetLeaderAbilities:
case raidMakeLeader:
{
RaidLeadershipUpdate_Struct* emu = (RaidLeadershipUpdate_Struct*)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct));
structs::RaidLeadershipUpdate_Struct* eq = (structs::RaidLeadershipUpdate_Struct*)outapp->pBuffer;
OUT(action);
OUT_str(player_name);
OUT_str(leader_name);
memcpy(&eq->raid, &emu->raid, sizeof(RaidLeadershipAA_Struct));
dest->FastQueuePacket(&outapp);
break;
}
case raidSetNote:
{
auto emu = (RaidNote_Struct*)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidNote_Struct));
auto eq = (structs::RaidNote_Struct*)outapp->pBuffer;
OUT(general.action);
OUT_str(general.leader_name);
OUT_str(general.player_name);
OUT_str(note);
dest->FastQueuePacket(&outapp);
break;
}
case raidNoRaid:
{
dest->QueuePacket(inapp);
break;
}
default:
{
RaidGeneral_Struct* emu = (RaidGeneral_Struct*)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
structs::RaidGeneral_Struct* eq = (structs::RaidGeneral_Struct*)outapp->pBuffer;
OUT(action);
OUT(parameter);
OUT_str(leader_name);
OUT_str(player_name);
dest->FastQueuePacket(&outapp);
break;
}
}
safe_delete(inapp);
}
ENCODE(OP_ReadBook)
{
// no apparent slot translation needed
@@ -2272,6 +2386,63 @@ namespace Titanium
FINISH_DIRECT_DECODE();
}
DECODE(OP_RaidInvite)
{
DECODE_LENGTH_ATLEAST(structs::RaidGeneral_Struct);
RaidGeneral_Struct* rgs = (RaidGeneral_Struct*)__packet->pBuffer;
switch (rgs->action)
{
case raidSetMotd:
{
SETUP_VAR_DECODE(RaidMOTD_Struct, structs::RaidMOTD_Struct, motd);
IN(general.action);
IN(general.parameter);
IN_str(general.leader_name);
IN_str(general.player_name);
auto len = 0;
if (__packet->size < sizeof(structs::RaidMOTD_Struct)) {
len = __packet->size - sizeof(structs::RaidGeneral_Struct);
}
else {
len = sizeof(eq->motd);
}
strn0cpy(emu->motd, eq->motd, len > 1024 ? 1024 : len);
emu->motd[len - 1] = '\0';
FINISH_VAR_DECODE();
break;
}
case raidSetNote:
{
SETUP_VAR_DECODE(RaidNote_Struct, structs::RaidNote_Struct, note);
IN(general.action);
IN(general.parameter);
IN_str(general.leader_name);
IN_str(general.player_name);
IN_str(note);
FINISH_VAR_DECODE();
break;
}
default:
{
SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct);
IN(action);
IN(parameter);
IN_str(leader_name);
IN_str(player_name);
FINISH_DIRECT_DECODE();
break;
}
}
}
DECODE(OP_ReadBook)
{
// no apparent slot translation needed
+3
View File
@@ -61,6 +61,8 @@ E(OP_OnLevelMessage)
E(OP_PetBuffWindow)
E(OP_PlayerProfile)
E(OP_NewSpawn)
E(OP_MarkRaidNPC)
E(OP_RaidUpdate)
E(OP_ReadBook)
E(OP_RespondAA)
E(OP_SendCharInfo)
@@ -106,6 +108,7 @@ D(OP_LoadSpellSet)
D(OP_LootItem)
D(OP_MoveItem)
D(OP_PetCommands)
D(OP_RaidInvite)
D(OP_ReadBook)
D(OP_SetServerFilter)
D(OP_ShopPlayerSell)
+29 -13
View File
@@ -3017,23 +3017,39 @@ struct leadExpUpdateStruct {
/*0028*/ uint32 unknown0028;
};
struct RaidGeneral_Struct {
/*00*/ uint32 action; //=10
/*04*/ char player_name[64]; //should both be the player's name
/*04*/ char leader_name[64];
/*000*/ uint32 action; //=10
/*004*/ char player_name[64]; //should both be the player's name
/*068*/ char leader_name[64];
/*132*/ uint32 parameter;
};
struct RaidAdd_Struct {
/*000*/ uint32 action; //=0
/*004*/ char player_name[64]; //should both be the player's name
/*068*/ char leader_name[64];
/*132*/ uint8 _class;
/*133*/ uint8 level;
/*134*/ uint8 has_group;
/*135*/ uint8 unknown135; //seems to be 0x42 or 0
struct RaidAddMember_Struct {
/*000*/ RaidGeneral_Struct raidGen;
/*136*/ uint8 _class;
/*137*/ uint8 level;
/*138*/ uint8 isGroupLeader;
/*139*/ uint8 unknown139; //seems to be 0x42 or 0
};
struct RaidNote_Struct {
/*000*/ RaidGeneral_Struct general;
/*136*/ char note[64];
};
struct RaidMOTD_Struct {
/*000*/ RaidGeneral_Struct general; // leader_name and action only used
/*136*/ char motd[1024]; // max size is 1024, but reply is variable
};
struct RaidLeadershipUpdate_Struct {
/*000*/ uint32 action;
/*004*/ char player_name[64];
// /*068*/ uint32 Unknown068;
/*072*/ char leader_name[64];
/*136*/ GroupLeadershipAA_Struct group; //unneeded
/*200*/ RaidLeadershipAA_Struct raid;
/*264*/ char Unknown264[128];
};
struct RaidCreate_Struct {
+151 -90
View File
@@ -35,6 +35,7 @@
#include "../path_manager.h"
#include "../classes.h"
#include "../races.h"
#include "../raid.h"
#include <iostream>
#include <sstream>
@@ -1931,88 +1932,124 @@ namespace UF
ENCODE(OP_RaidJoin)
{
EQApplicationPacket *inapp = *p;
unsigned char * __emu_buffer = inapp->pBuffer;
RaidCreate_Struct *raid_create = (RaidCreate_Struct*)__emu_buffer;
EQApplicationPacket* inapp = *p;
*p = nullptr;
unsigned char* __emu_buffer = inapp->pBuffer;
RaidCreate_Struct* emu = (RaidCreate_Struct*)__emu_buffer;
auto outapp_create = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
structs::RaidGeneral_Struct *general = (structs::RaidGeneral_Struct*)outapp_create->pBuffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
structs::RaidGeneral_Struct* general = (structs::RaidGeneral_Struct*)outapp->pBuffer;
general->action = 8;
general->parameter = 1;
strn0cpy(general->leader_name, raid_create->leader_name, 64);
strn0cpy(general->player_name, raid_create->leader_name, 64);
general->action = raidCreate;
general->parameter = RaidCommandAcceptInvite;
strn0cpy(general->leader_name, emu->leader_name, sizeof(emu->leader_name));
strn0cpy(general->player_name, emu->leader_name, sizeof(emu->leader_name));
dest->FastQueuePacket(&outapp);
dest->FastQueuePacket(&outapp_create);
safe_delete(inapp);
}
ENCODE(OP_RaidUpdate)
{
EQApplicationPacket *inapp = *p;
EQApplicationPacket* inapp = *p;
*p = nullptr;
unsigned char * __emu_buffer = inapp->pBuffer;
RaidGeneral_Struct *raid_gen = (RaidGeneral_Struct*)__emu_buffer;
unsigned char* __emu_buffer = inapp->pBuffer;
RaidGeneral_Struct* raid_gen = (RaidGeneral_Struct*)__emu_buffer;
if (raid_gen->action == 0) // raid add has longer length than other raid updates
switch (raid_gen->action)
{
RaidAddMember_Struct* in_add_member = (RaidAddMember_Struct*)__emu_buffer;
case raidAdd:
{
RaidAddMember_Struct* emu = (RaidAddMember_Struct*)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidAddMember_Struct));
structs::RaidAddMember_Struct *add_member = (structs::RaidAddMember_Struct*)outapp->pBuffer;
structs::RaidAddMember_Struct* eq = (structs::RaidAddMember_Struct*)outapp->pBuffer;
add_member->raidGen.action = in_add_member->raidGen.action;
add_member->raidGen.parameter = in_add_member->raidGen.parameter;
strn0cpy(add_member->raidGen.leader_name, in_add_member->raidGen.leader_name, 64);
strn0cpy(add_member->raidGen.player_name, in_add_member->raidGen.player_name, 64);
add_member->_class = in_add_member->_class;
add_member->level = in_add_member->level;
add_member->isGroupLeader = in_add_member->isGroupLeader;
add_member->flags[0] = in_add_member->flags[0];
add_member->flags[1] = in_add_member->flags[1];
add_member->flags[2] = in_add_member->flags[2];
add_member->flags[3] = in_add_member->flags[3];
add_member->flags[4] = in_add_member->flags[4];
dest->FastQueuePacket(&outapp);
}
else if (raid_gen->action == 35)
{
RaidMOTD_Struct *inmotd = (RaidMOTD_Struct *)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct) +
strlen(inmotd->motd) + 1);
structs::RaidMOTD_Struct *outmotd = (structs::RaidMOTD_Struct *)outapp->pBuffer;
OUT(raidGen.action);
OUT(raidGen.parameter);
OUT_str(raidGen.leader_name);
OUT_str(raidGen.player_name);
OUT(_class);
OUT(level);
OUT(isGroupLeader);
OUT(flags[0]);
OUT(flags[1]);
OUT(flags[2]);
OUT(flags[3]);
OUT(flags[4]);
outmotd->general.action = inmotd->general.action;
strn0cpy(outmotd->general.player_name, inmotd->general.player_name, 64);
strn0cpy(outmotd->motd, inmotd->motd, strlen(inmotd->motd) + 1);
dest->FastQueuePacket(&outapp);
break;
}
else if (raid_gen->action == 14 || raid_gen->action == 30)
case raidSetMotd:
{
RaidLeadershipUpdate_Struct *inlaa = (RaidLeadershipUpdate_Struct *)__emu_buffer;
auto outapp =
new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct));
structs::RaidLeadershipUpdate_Struct *outlaa = (structs::RaidLeadershipUpdate_Struct *)outapp->pBuffer;
RaidMOTD_Struct* emu = (RaidMOTD_Struct*)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidMOTD_Struct));
structs::RaidMOTD_Struct* eq = (structs::RaidMOTD_Struct*)outapp->pBuffer;
OUT(general.action);
OUT_str(general.player_name);
OUT_str(general.leader_name);
OUT_str(motd);
outlaa->action = inlaa->action;
strn0cpy(outlaa->player_name, inlaa->player_name, 64);
strn0cpy(outlaa->leader_name, inlaa->leader_name, 64);
memcpy(&outlaa->raid, &inlaa->raid, sizeof(RaidLeadershipAA_Struct));
dest->FastQueuePacket(&outapp);
break;
}
else
case raidSetLeaderAbilities:
case raidMakeLeader:
{
RaidGeneral_Struct* in_raid_general = (RaidGeneral_Struct*)__emu_buffer;
RaidLeadershipUpdate_Struct* emu = (RaidLeadershipUpdate_Struct*)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidLeadershipUpdate_Struct));
structs::RaidLeadershipUpdate_Struct* eq = (structs::RaidLeadershipUpdate_Struct*)outapp->pBuffer;
OUT(action);
OUT_str(player_name);
OUT_str(leader_name);
memcpy(&eq->raid, &emu->raid, sizeof(RaidLeadershipAA_Struct));
dest->FastQueuePacket(&outapp);
break;
}
case raidSetNote:
{
auto emu = (RaidNote_Struct*)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidNote_Struct));
auto eq = (structs::RaidNote_Struct*)outapp->pBuffer;
OUT(general.action);
OUT_str(general.leader_name);
OUT_str(general.player_name);
OUT_str(note);
dest->FastQueuePacket(&outapp);
break;
}
case raidNoRaid:
{
dest->QueuePacket(inapp);
break;
}
default:
{
RaidGeneral_Struct* emu = (RaidGeneral_Struct*)__emu_buffer;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(structs::RaidGeneral_Struct));
structs::RaidGeneral_Struct *raid_general = (structs::RaidGeneral_Struct*)outapp->pBuffer;
strn0cpy(raid_general->leader_name, in_raid_general->leader_name, 64);
strn0cpy(raid_general->player_name, in_raid_general->player_name, 64);
raid_general->action = in_raid_general->action;
raid_general->parameter = in_raid_general->parameter;
dest->FastQueuePacket(&outapp);
}
structs::RaidGeneral_Struct* eq = (structs::RaidGeneral_Struct*)outapp->pBuffer;
OUT(action);
OUT(parameter);
OUT_str(leader_name);
OUT_str(player_name);
dest->FastQueuePacket(&outapp);
break;
}
}
safe_delete(inapp);
}
@@ -2027,6 +2064,9 @@ namespace UF
eq->window = emu->window;
OUT(type);
eq->invslot = ServerToUFSlot(emu->invslot);
OUT(target_id);
OUT(can_cast);
OUT(can_scribe);
strn0cpy(eq->txtfile, emu->booktext, sizeof(eq->txtfile));
FINISH_ENCODE();
@@ -3105,6 +3145,17 @@ namespace UF
FINISH_DIRECT_DECODE();
}
DECODE(OP_BookButton)
{
DECODE_LENGTH_EXACT(structs::BookButton_Struct);
SETUP_DIRECT_DECODE(BookButton_Struct, structs::BookButton_Struct);
emu->invslot = static_cast<int16_t>(UFToServerSlot(eq->invslot));
IN(target_id);
FINISH_DIRECT_DECODE();
}
DECODE(OP_Buff)
{
DECODE_LENGTH_EXACT(structs::SpellBuffPacket_Struct);
@@ -3623,39 +3674,48 @@ namespace UF
{
DECODE_LENGTH_ATLEAST(structs::RaidGeneral_Struct);
// This is a switch on the RaidGeneral action
switch (*(uint32 *)__packet->pBuffer) {
case 35: { // raidMOTD
// we don't have a nice macro for this
structs::RaidMOTD_Struct *__eq_buffer = (structs::RaidMOTD_Struct *)__packet->pBuffer;
__eq_buffer->motd[1023] = '\0';
size_t motd_size = strlen(__eq_buffer->motd) + 1;
__packet->size = sizeof(RaidMOTD_Struct) + motd_size;
__packet->pBuffer = new unsigned char[__packet->size];
RaidMOTD_Struct *emu = (RaidMOTD_Struct *)__packet->pBuffer;
structs::RaidMOTD_Struct *eq = (structs::RaidMOTD_Struct *)__eq_buffer;
strn0cpy(emu->general.player_name, eq->general.player_name, 64);
strn0cpy(emu->motd, eq->motd, motd_size);
IN(general.action);
IN(general.parameter);
FINISH_DIRECT_DECODE();
break;
}
case 36: { // raidPlayerNote unhandled
break;
}
default: {
DECODE_LENGTH_EXACT(structs::RaidGeneral_Struct);
SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct);
strn0cpy(emu->leader_name, eq->leader_name, 64);
strn0cpy(emu->player_name, eq->player_name, 64);
IN(action);
IN(parameter);
FINISH_DIRECT_DECODE();
break;
}
}
RaidGeneral_Struct* rgs = (RaidGeneral_Struct*)__packet->pBuffer;
switch (rgs->action)
{
case raidSetMotd:
{
SETUP_VAR_DECODE(RaidMOTD_Struct, structs::RaidMOTD_Struct, motd);
IN(general.action);
IN(general.parameter);
IN_str(general.leader_name);
IN_str(general.player_name);
IN_str(motd);
FINISH_VAR_DECODE();
break;
}
case raidSetNote:
{
SETUP_VAR_DECODE(RaidNote_Struct, structs::RaidNote_Struct, note);
IN(general.action);
IN(general.parameter);
IN_str(general.leader_name);
IN_str(general.player_name);
IN_str(note);
FINISH_VAR_DECODE();
break;
}
default:
{
SETUP_DIRECT_DECODE(RaidGeneral_Struct, structs::RaidGeneral_Struct);
IN(action);
IN(parameter);
IN_str(leader_name);
IN_str(player_name);
FINISH_DIRECT_DECODE();
break;
}
}
}
DECODE(OP_ReadBook)
@@ -3664,7 +3724,8 @@ namespace UF
SETUP_DIRECT_DECODE(BookRequest_Struct, structs::BookRequest_Struct);
IN(type);
emu->invslot = UFToServerSlot(eq->invslot);
emu->invslot = static_cast<int16_t>(UFToServerSlot(eq->invslot));
IN(target_id);
emu->window = (uint8)eq->window;
strn0cpy(emu->txtfile, eq->txtfile, sizeof(emu->txtfile));
+1
View File
@@ -110,6 +110,7 @@ D(OP_ApplyPoison)
D(OP_AugmentInfo)
D(OP_AugmentItem)
D(OP_BazaarSearch)
D(OP_BookButton)
D(OP_Buff)
D(OP_BuffRemoveRequest)
D(OP_CastSpell)
+22 -8
View File
@@ -2400,12 +2400,21 @@ struct BookText_Struct {
// This is just a "text file" on the server
// or in our case, the 'name' column in our books table.
struct BookRequest_Struct {
/*0000*/ uint32 window; // where to display the text (0xFFFFFFFF means new window).
/*0004*/ uint32 invslot; // The inventory slot the book is in. Not used, but echoed in the response packet.
/*0008*/ uint32 type; // 0 = Scroll, 1 = Book, 2 = Item Info. Possibly others
/*0012*/ uint32 unknown0012;
/*0016*/ uint16 unknown0016;
/*0018*/ char txtfile[8194];
/*0000*/ uint32 window; // where to display the text (0xFFFFFFFF means new window).
/*0004*/ uint32 invslot; // The inventory slot the book is in
/*0008*/ uint32 type; // 0 = Scroll, 1 = Book, 2 = Item Info. Possibly others
/*0012*/ uint32 target_id;
/*0016*/ uint8 can_cast;
/*0017*/ uint8 can_scribe;
/*0018*/ char txtfile[8194];
};
// used by Scribe and CastSpell book buttons
struct BookButton_Struct
{
/*0000*/ int32 invslot;
/*0004*/ int32 target_id; // client's target when using the book
/*0008*/ int32 unused; // always 0 from button packets
};
/*
@@ -3638,9 +3647,14 @@ struct RaidAddMember_Struct {
/*139*/ uint8 flags[5]; //no idea if these are needed...
};
struct RaidNote_Struct {
/*000*/ RaidGeneral_Struct general;
/*140*/ char note[64];
};
struct RaidMOTD_Struct {
/*000*/ RaidGeneral_Struct general; // leader_name and action only used
/*140*/ char motd[0]; // max size 1024, but reply is variable
/*000*/ RaidGeneral_Struct general;
/*140*/ char motd[1024];
};
struct RaidLeadershipUpdate_Struct {
+72
View File
@@ -0,0 +1,72 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemu.org)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef RAID_H
#define RAID_H
enum { //raid packet types:
raidAdd = 0,
raidRemove2 = 1, //parameter=0
raidMemberNameChange = 2,
raidRemove1 = 3, //parameter=0xFFFFFFFF
raidNoLongerLeader = 4,
raidDisband = 5,
raidMembers = 6, //len 395+, details + members list
raidNoAssignLeadership = 7,
raidCreate = 8, //len 72
raidUnknown = 9, // unused?
raidNoRaid = 10, //parameter=0
raidChangeLootType = 11,
raidStringID = 12,
raidChangeGroupLeader = 13, //136 raid leader, new group leader, group_id?
raidSetLeaderAbilities = 14, //472
raidSetLeaderData = 15, // 14,15 SoE names, not sure on difference, 14 packet has 0x100 bytes 15 0x214 in addition to raid general
raidChangeGroup = 16, //?? len 136 old leader, new leader, 0 (preceeded with a remove2)
raidLock = 17, //len 136 leader?, leader, 0
raidUnlock = 18, //len 136 leader?, leader, 0
raidRedStringID = 19,
raidSetLeader = 20, //len 388, contains 'details' struct without members; also used for "invite to raid"
raidMakeLeader = 30,
raidSetMotd = 35,
raidSetNote = 36,
};
enum { //raid command types
RaidCommandInviteIntoExisting = 0, //in use
RaidCommandAcceptInvite = 1, //in use
RaidCommandInvite = 3, //in use
RaidCommandDisband = 5, //in use
RaidCommandMoveGroup = 6, //in use
RaidCommandRemoveGroupLeader = 7,
RaidCommandRaidLock = 8, //in use
RaidCommandRaidUnlock = 9, //in use
RaidCommandLootType = 20, //in use
RaidCommandAddLooter = 21, //in use
RaidCommandRemoveLooter = 22, //in use
RaidCommandMakeLeader = 30,
RaidCommandInviteFail = 31, //already in raid, waiting on invite from other raid, etc
RaidCommandLootType2 = 32, //in use
RaidCommandAddLooter2 = 33, //in use
RaidCommandRemoveLooter2 = 34, //in use
RaidCommandSetMotd = 35,
RaidCommandSetNote = 36,
};
#endif
@@ -0,0 +1,414 @@
/**
* DO NOT MODIFY THIS FILE
*
* This repository was automatically generated and is NOT to be modified directly.
* Any repository modifications are meant to be made to the repository extending the base.
* Any modifications to base repositories are to be made by the generator only
*
* @generator ./utils/scripts/generators/repository-generator.pl
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
*/
#ifndef EQEMU_BASE_BOT_STARTING_ITEMS_REPOSITORY_H
#define EQEMU_BASE_BOT_STARTING_ITEMS_REPOSITORY_H
#include "../../database.h"
#include "../../strings.h"
#include <ctime>
class BaseBotStartingItemsRepository {
public:
struct BotStartingItems {
uint32_t id;
uint32_t races;
uint32_t classes;
uint32_t item_id;
uint8_t item_charges;
int32_t slot_id;
int8_t min_expansion;
int8_t max_expansion;
std::string content_flags;
std::string content_flags_disabled;
};
static std::string PrimaryKey()
{
return std::string("id");
}
static std::vector<std::string> Columns()
{
return {
"id",
"races",
"classes",
"item_id",
"item_charges",
"slot_id",
"min_expansion",
"max_expansion",
"content_flags",
"content_flags_disabled",
};
}
static std::vector<std::string> SelectColumns()
{
return {
"id",
"races",
"classes",
"item_id",
"item_charges",
"slot_id",
"min_expansion",
"max_expansion",
"content_flags",
"content_flags_disabled",
};
}
static std::string ColumnsRaw()
{
return std::string(Strings::Implode(", ", Columns()));
}
static std::string SelectColumnsRaw()
{
return std::string(Strings::Implode(", ", SelectColumns()));
}
static std::string TableName()
{
return std::string("bot_starting_items");
}
static std::string BaseSelect()
{
return fmt::format(
"SELECT {} FROM {}",
SelectColumnsRaw(),
TableName()
);
}
static std::string BaseInsert()
{
return fmt::format(
"INSERT INTO {} ({}) ",
TableName(),
ColumnsRaw()
);
}
static BotStartingItems NewEntity()
{
BotStartingItems e{};
e.id = 0;
e.races = 0;
e.classes = 0;
e.item_id = 0;
e.item_charges = 1;
e.slot_id = -1;
e.min_expansion = -1;
e.max_expansion = -1;
e.content_flags = "";
e.content_flags_disabled = "";
return e;
}
static BotStartingItems GetBotStartingItems(
const std::vector<BotStartingItems> &bot_starting_itemss,
int bot_starting_items_id
)
{
for (auto &bot_starting_items : bot_starting_itemss) {
if (bot_starting_items.id == bot_starting_items_id) {
return bot_starting_items;
}
}
return NewEntity();
}
static BotStartingItems FindOne(
Database& db,
int bot_starting_items_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE {} = {} LIMIT 1",
BaseSelect(),
PrimaryKey(),
bot_starting_items_id
)
);
auto row = results.begin();
if (results.RowCount() == 1) {
BotStartingItems e{};
e.id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.races = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
e.classes = static_cast<uint32_t>(strtoul(row[2], nullptr, 10));
e.item_id = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
e.item_charges = static_cast<uint8_t>(strtoul(row[4], nullptr, 10));
e.slot_id = static_cast<int32_t>(atoi(row[5]));
e.min_expansion = static_cast<int8_t>(atoi(row[6]));
e.max_expansion = static_cast<int8_t>(atoi(row[7]));
e.content_flags = row[8] ? row[8] : "";
e.content_flags_disabled = row[9] ? row[9] : "";
return e;
}
return NewEntity();
}
static int DeleteOne(
Database& db,
int bot_starting_items_id
)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {} = {}",
TableName(),
PrimaryKey(),
bot_starting_items_id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int UpdateOne(
Database& db,
const BotStartingItems &e
)
{
std::vector<std::string> v;
auto columns = Columns();
v.push_back(columns[1] + " = " + std::to_string(e.races));
v.push_back(columns[2] + " = " + std::to_string(e.classes));
v.push_back(columns[3] + " = " + std::to_string(e.item_id));
v.push_back(columns[4] + " = " + std::to_string(e.item_charges));
v.push_back(columns[5] + " = " + std::to_string(e.slot_id));
v.push_back(columns[6] + " = " + std::to_string(e.min_expansion));
v.push_back(columns[7] + " = " + std::to_string(e.max_expansion));
v.push_back(columns[8] + " = '" + Strings::Escape(e.content_flags) + "'");
v.push_back(columns[9] + " = '" + Strings::Escape(e.content_flags_disabled) + "'");
auto results = db.QueryDatabase(
fmt::format(
"UPDATE {} SET {} WHERE {} = {}",
TableName(),
Strings::Implode(", ", v),
PrimaryKey(),
e.id
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static BotStartingItems InsertOne(
Database& db,
BotStartingItems e
)
{
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.races));
v.push_back(std::to_string(e.classes));
v.push_back(std::to_string(e.item_id));
v.push_back(std::to_string(e.item_charges));
v.push_back(std::to_string(e.slot_id));
v.push_back(std::to_string(e.min_expansion));
v.push_back(std::to_string(e.max_expansion));
v.push_back("'" + Strings::Escape(e.content_flags) + "'");
v.push_back("'" + Strings::Escape(e.content_flags_disabled) + "'");
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES ({})",
BaseInsert(),
Strings::Implode(",", v)
)
);
if (results.Success()) {
e.id = results.LastInsertedID();
return e;
}
e = NewEntity();
return e;
}
static int InsertMany(
Database& db,
const std::vector<BotStartingItems> &entries
)
{
std::vector<std::string> insert_chunks;
for (auto &e: entries) {
std::vector<std::string> v;
v.push_back(std::to_string(e.id));
v.push_back(std::to_string(e.races));
v.push_back(std::to_string(e.classes));
v.push_back(std::to_string(e.item_id));
v.push_back(std::to_string(e.item_charges));
v.push_back(std::to_string(e.slot_id));
v.push_back(std::to_string(e.min_expansion));
v.push_back(std::to_string(e.max_expansion));
v.push_back("'" + Strings::Escape(e.content_flags) + "'");
v.push_back("'" + Strings::Escape(e.content_flags_disabled) + "'");
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
}
std::vector<std::string> v;
auto results = db.QueryDatabase(
fmt::format(
"{} VALUES {}",
BaseInsert(),
Strings::Implode(",", insert_chunks)
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static std::vector<BotStartingItems> All(Database& db)
{
std::vector<BotStartingItems> all_entries;
auto results = db.QueryDatabase(
fmt::format(
"{}",
BaseSelect()
)
);
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
BotStartingItems e{};
e.id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.races = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
e.classes = static_cast<uint32_t>(strtoul(row[2], nullptr, 10));
e.item_id = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
e.item_charges = static_cast<uint8_t>(strtoul(row[4], nullptr, 10));
e.slot_id = static_cast<int32_t>(atoi(row[5]));
e.min_expansion = static_cast<int8_t>(atoi(row[6]));
e.max_expansion = static_cast<int8_t>(atoi(row[7]));
e.content_flags = row[8] ? row[8] : "";
e.content_flags_disabled = row[9] ? row[9] : "";
all_entries.push_back(e);
}
return all_entries;
}
static std::vector<BotStartingItems> GetWhere(Database& db, const std::string &where_filter)
{
std::vector<BotStartingItems> all_entries;
auto results = db.QueryDatabase(
fmt::format(
"{} WHERE {}",
BaseSelect(),
where_filter
)
);
all_entries.reserve(results.RowCount());
for (auto row = results.begin(); row != results.end(); ++row) {
BotStartingItems e{};
e.id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
e.races = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
e.classes = static_cast<uint32_t>(strtoul(row[2], nullptr, 10));
e.item_id = static_cast<uint32_t>(strtoul(row[3], nullptr, 10));
e.item_charges = static_cast<uint8_t>(strtoul(row[4], nullptr, 10));
e.slot_id = static_cast<int32_t>(atoi(row[5]));
e.min_expansion = static_cast<int8_t>(atoi(row[6]));
e.max_expansion = static_cast<int8_t>(atoi(row[7]));
e.content_flags = row[8] ? row[8] : "";
e.content_flags_disabled = row[9] ? row[9] : "";
all_entries.push_back(e);
}
return all_entries;
}
static int DeleteWhere(Database& db, const std::string &where_filter)
{
auto results = db.QueryDatabase(
fmt::format(
"DELETE FROM {} WHERE {}",
TableName(),
where_filter
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int Truncate(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"TRUNCATE TABLE {}",
TableName()
)
);
return (results.Success() ? results.RowsAffected() : 0);
}
static int64 GetMaxId(Database& db)
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COALESCE(MAX({}), 0) FROM {}",
PrimaryKey(),
TableName()
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
static int64 Count(Database& db, const std::string &where_filter = "")
{
auto results = db.QueryDatabase(
fmt::format(
"SELECT COUNT(*) FROM {} {}",
TableName(),
(where_filter.empty() ? "" : "WHERE " + where_filter)
)
);
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
}
};
#endif //EQEMU_BASE_BOT_STARTING_ITEMS_REPOSITORY_H
@@ -0,0 +1,50 @@
#ifndef EQEMU_BOT_STARTING_ITEMS_REPOSITORY_H
#define EQEMU_BOT_STARTING_ITEMS_REPOSITORY_H
#include "../database.h"
#include "../strings.h"
#include "base/base_bot_starting_items_repository.h"
class BotStartingItemsRepository: public BaseBotStartingItemsRepository {
public:
/**
* This file was auto generated and can be modified and extended upon
*
* Base repository methods are automatically
* generated in the "base" version of this repository. The base repository
* is immutable and to be left untouched, while methods in this class
* are used as extension methods for more specific persistence-layer
* accessors or mutators.
*
* Base Methods (Subject to be expanded upon in time)
*
* Note: Not all tables are designed appropriately to fit functionality with all base methods
*
* InsertOne
* UpdateOne
* DeleteOne
* FindOne
* GetWhere(std::string where_filter)
* DeleteWhere(std::string where_filter)
* InsertMany
* All
*
* Example custom methods in a repository
*
* BotStartingItemsRepository::GetByZoneAndVersion(int zone_id, int zone_version)
* BotStartingItemsRepository::GetWhereNeverExpires()
* BotStartingItemsRepository::GetWhereXAndY()
* BotStartingItemsRepository::DeleteWhereXAndY()
*
* Most of the above could be covered by base methods, but if you as a developer
* find yourself re-using logic for other parts of the code, its best to just make a
* method that can be re-used easily elsewhere especially if it can use a base repository
* method and encapsulate filters there
*/
// Custom extended repository methods here
};
#endif //EQEMU_BOT_STARTING_ITEMS_REPOSITORY_H
+5
View File
@@ -454,6 +454,8 @@ RULE_INT(Spells, ResurrectionEffectBlock, 2, "0 = allow overwrites/rule disabled
RULE_BOOL(Spells, WaterMatchRequiredForLoS, true, "Enable/Disable the requirement of both the attacker/victim being both in or out of water for spells LoS to pass.")
RULE_INT(Spells, WizardCritMinimumRandomRatio, 20, "The minimum value for the random range which Wizards and Caster DPS Mercs innately have for spell crit ratio. Set to 20 for vanilla values.")
RULE_INT(Spells, WizardCritMaximumRandomRatio, 70, "The maximum value for the random range which Wizards and Caster DPS Mercs innately have for spell crit ratio. Set to 70 for vanilla values.")
RULE_INT(Spells, DefensiveProcPenaltyLevelGap, 6, "Defensive Proc Penalty Level Gap where procs start losing their proc rate at RuleR(Spells, DefensiveProcPenaltyModifier)% per level difference")
RULE_REAL(Spells, DefensiveProcPenaltyLevelGapModifier, 10.0f, "Defensive Proc Penalty Level Gap Modifier where procs start losing their proc rate at defined % after RuleI(Spells, DefensiveProcLevelGap) level difference")
RULE_CATEGORY_END()
RULE_CATEGORY(Combat)
@@ -528,6 +530,8 @@ RULE_BOOL(Combat, BackstabIgnoresElemental, false, "Enable or disable Elemental
RULE_BOOL(Combat, BackstabIgnoresBane, false, "Enable or disable Bane weapon damage affecting backstab damage, false by default.")
RULE_BOOL(Combat, SummonMeleeRange, true, "Enable or disable summoning of a player when already in melee range of the summoner.")
RULE_BOOL(Combat, WaterMatchRequiredForAutoFireLoS, true, "Enable/Disable the requirement of both the attacker/victim being both in or out of water for AutoFire LoS to pass.")
RULE_INT(Combat, ExtraAllowedKickClassesBitmask, 0, "Bitmask for allowing extra classes beyond Warrior, Ranger, Beastlord, and Berserker to kick, No Extra Classes (0) by default")
RULE_INT(Combat, MaxProcs, 4, "Adjustable maximum number of procs per round, the hard cap is MAX_PROCS (11). Requires mob repop or client zone when changed")
RULE_CATEGORY_END()
RULE_CATEGORY(NPC)
@@ -820,6 +824,7 @@ RULE_CATEGORY_END()
RULE_CATEGORY(Expansion)
RULE_INT(Expansion, CurrentExpansion, -1, "The current expansion enabled for the server [-1 = ALL, 0 = Classic, 1 = Kunark etc.]")
RULE_BOOL(Expansion, UseCurrentExpansionAAOnly, false, "When true will only load AA ranks that match CurrentExpansion rule")
RULE_INT(Expansion, AutoGrantAAExpansion, -1, "Expansion to auto grant AAs up to, [-1 = Disabled, 0 = Classic, 1 = Kunark etc.]")
RULE_CATEGORY_END()
RULE_CATEGORY(Instances)
+71 -68
View File
@@ -10,6 +10,7 @@
#include <cereal/types/chrono.hpp>
#include <cereal/types/string.hpp>
#include <cereal/types/vector.hpp>
#include <glm/vec4.hpp>
#define SERVER_TIMEOUT 45000 // how often keepalive gets sent
#define INTERSERVER_TIMER 10000
@@ -1076,7 +1077,7 @@ struct ServerRaidMessage_Struct {
struct ServerRaidMOTD_Struct {
uint32 rid;
char motd[0];
char motd[1024];
};
struct ServerRaidNote_Struct {
@@ -1486,95 +1487,96 @@ struct CZClientMessageString_Struct {
struct CZDialogueWindow_Struct {
uint8 update_type; // 0 - Character, 1 - Group, 2 - Raid, 3 - Guild, 4 - Expedition, 5 - Character Name
int update_identifier; // Character ID, Group ID, Raid ID, Guild ID, or Expedition ID based on update type, 0 for Character Name
char message[4096];
char client_name[64]; // Only used by Character Name Type, else empty
int update_identifier; // Character ID, Group ID, Raid ID, Guild ID, or Expedition ID based on update type, 0 for Character Name
char message[4096];
char client_name[64]; // Only used by Character Name Type, else empty
};
struct CZLDoNUpdate_Struct {
uint8 update_type; // 0 - Character, 1 - Group, 2 - Raid, 3 - Guild, 4 - Expedition, 5 - Character Name
uint8 update_subtype; // 0 - Loss, 1 - Points, 2 - Win
int update_identifier; // Character ID, Group ID, Raid ID, Guild ID, or Expedition ID based on update type, 0 for Character Name
uint8 update_type; // 0 - Character, 1 - Group, 2 - Raid, 3 - Guild, 4 - Expedition, 5 - Character Name
uint8 update_subtype; // 0 - Loss, 1 - Points, 2 - Win
int update_identifier; // Character ID, Group ID, Raid ID, Guild ID, or Expedition ID based on update type, 0 for Character Name
uint32 theme_id;
int points; // Only used in Points Subtype, else 1
char client_name[64]; // Only used by Character Name Type, else empty
int points; // Only used in Points Subtype, else 1
char client_name[64]; // Only used by Character Name Type, else empty
};
struct CZMarquee_Struct {
uint8 update_type; // 0 - Character, 1 - Group, 2 - Raid, 3 - Guild, 4 - Expedition, 5 - Character Name
int update_identifier; // Character ID, Group ID, Raid ID, Guild ID, or Expedition ID based on update type, 0 for Character Name
uint8 update_type; // 0 - Character, 1 - Group, 2 - Raid, 3 - Guild, 4 - Expedition, 5 - Character Name
int update_identifier; // Character ID, Group ID, Raid ID, Guild ID, or Expedition ID based on update type, 0 for Character Name
uint32 type;
uint32 priority;
uint32 fade_in;
uint32 fade_out;
uint32 duration;
char message[512];
char client_name[64]; // Only used by Character Name Type, else empty
char message[512];
char client_name[64]; // Only used by Character Name Type, else empty
};
struct CZMessage_Struct {
uint8 update_type; // 0 - Character, 1 - Group, 2 - Raid, 3 - Guild, 4 - Expedition, 5 - Character Name
int update_identifier; // Group ID, Raid ID, Guild ID, or Expedition ID based on update type, 0 for Character Name
uint8 update_type; // 0 - Character, 1 - Group, 2 - Raid, 3 - Guild, 4 - Expedition, 5 - Character Name
int update_identifier; // Group ID, Raid ID, Guild ID, or Expedition ID based on update type, 0 for Character Name
uint32 type;
char message[512];
char client_name[64]; // Only used by Character Name Type, else empty
char message[512];
char client_name[64]; // Only used by Character Name Type, else empty
};
struct CZMove_Struct {
uint8 update_type; // 0 - Character, 1 - Group, 2 - Raid, 3 - Guild, 4 - Expedition, 5 - Character Name
uint8 update_subtype; // 0 - Move Zone, 1 - Move Zone Instance
int update_identifier; // Character ID, Group ID, Raid ID, Guild ID, or Expedition ID based on update type, 0 for Character Name
uint16 instance_id; // Only used by Move Zone Instance, else 0
char zone_short_name[32]; // Only by with Move Zone, else empty
char client_name[64]; // Only used by Character Name Type, else empty
std::string client_name = std::string(); // Only used by Character Name Type, else empty
glm::vec4 coordinates = glm::vec4(0.f); // XYZ or XYZH, heading is optional, defaults to 0.
uint16 instance_id = 0; // Only used by Move Zone Instance, else 0
uint32 update_identifier = 0; // Character ID, Group ID, Raid ID, Guild ID, or Expedition ID based on update type, 0 for Character Name
uint8 update_type; // 0 - Character, 1 - Group, 2 - Raid, 3 - Guild, 4 - Expedition, 5 - Character Name
uint8 update_subtype; // 0 - Move Zone, 1 - Move Zone Instance
std::string zone_short_name = std::string(); // Only used by Move Zone, else empty
};
struct CZSetEntityVariable_Struct {
uint8 update_type; // 0 - Character, 1 - Group, 2 - Raid, 3 - Guild, 4 - Expedition, 5 - Character Name, 6 - NPC
int update_identifier; // Group ID, Raid ID, Guild ID, Expedition ID, or NPC ID based on update type, 0 for Character Name
char variable_name[256];
char variable_value[256];
char client_name[64]; // Only used by Character Type, else empty
int update_identifier; // Group ID, Raid ID, Guild ID, Expedition ID, or NPC ID based on update type, 0 for Character Name
char variable_name[256];
char variable_value[256];
char client_name[64]; // Only used by Character Type, else empty
};
struct CZSignal_Struct {
uint8 update_type; // 0 - Character, 1 - Group, 2 - Raid, 3 - Guild, 4 - Expedition, 5 - Character Name, 6 - NPC
int update_identifier; // Character ID, Group ID, Raid ID, Guild ID, Expedition ID, or NPC ID based on update type, 0 for Character Name
int signal_id;
char client_name[64]; // Only used by Character Name Type, else empty
int update_identifier; // Character ID, Group ID, Raid ID, Guild ID, Expedition ID, or NPC ID based on update type, 0 for Character Name
int signal_id;
char client_name[64]; // Only used by Character Name Type, else empty
};
struct CZSpell_Struct {
uint8 update_type; // 0 - Character, 1 - Group, 2 - Raid, 3 - Guild, 4 - Expedition, 5 - Character Name
uint8 update_subtype; // 0 - Cast Spell, 1 - Remove Spell
int update_identifier; // Character ID, Group ID, Raid ID, Guild ID, or Expedition ID based on update type, 0 for Character Name
uint8 update_type; // 0 - Character, 1 - Group, 2 - Raid, 3 - Guild, 4 - Expedition, 5 - Character Name
uint8 update_subtype; // 0 - Cast Spell, 1 - Remove Spell
int update_identifier; // Character ID, Group ID, Raid ID, Guild ID, or Expedition ID based on update type, 0 for Character Name
uint32 spell_id;
char client_name[64]; // Only used by Character Name Type, else empty
char client_name[64]; // Only used by Character Name Type, else empty
};
struct CZTaskUpdate_Struct {
uint8 update_type; // 0 - Character, 1 - Group, 2 - Raid, 3 - Guild, 4 - Expedition, 5 - Character Name
uint8 update_subtype; // 0 - Activity Reset, 1 - Activity Update, 2 - Assign Task, 3 - Disable Task, 4 - Enable Task, 5 - Fail Task, 6 - Remove Task
int update_identifier; // Character ID, Group ID, Raid ID, Guild ID, or Expedition ID based on update type, 0 for Character Name
uint8 update_type; // 0 - Character, 1 - Group, 2 - Raid, 3 - Guild, 4 - Expedition, 5 - Character Name
uint8 update_subtype; // 0 - Activity Reset, 1 - Activity Update, 2 - Assign Task, 3 - Disable Task, 4 - Enable Task, 5 - Fail Task, 6 - Remove Task
int update_identifier; // Character ID, Group ID, Raid ID, Guild ID, or Expedition ID based on update type, 0 for Character Name
uint32 task_identifier;
int task_subidentifier; // Activity ID for Activity Reset and Activity Update, NPC Entity ID for Assign Task, else -1
int update_count; // Only used by Activity Update, else 1
bool enforce_level_requirement; // Only used by Assign Task
char client_name[64]; // Only used by Character Name Type, else empty
int task_subidentifier; // Activity ID for Activity Reset and Activity Update, NPC Entity ID for Assign Task, else -1
int update_count; // Only used by Activity Update, else 1
bool enforce_level_requirement; // Only used by Assign Task
char client_name[64]; // Only used by Character Name Type, else empty
};
struct WWDialogueWindow_Struct {
char message[4096];
char message[4096];
uint8 min_status;
uint8 max_status;
};
struct WWLDoNUpdate_Struct {
uint8 update_type; // 0 - Loss, 1 - Points, 2 - Win
uint8 update_type; // 0 - Loss, 1 - Points, 2 - Win
uint32 theme_id;
int points; // Only used in Points Subtype, else 1
uint8 min_status;
uint8 max_status;
int points; // Only used in Points Subtype, else 1
uint8 min_status;
uint8 max_status;
};
struct WWMarquee_Struct {
@@ -1583,56 +1585,57 @@ struct WWMarquee_Struct {
uint32 fade_in;
uint32 fade_out;
uint32 duration;
char message[512];
uint8 min_status;
uint8 max_status;
char message[512];
uint8 min_status;
uint8 max_status;
};
struct WWMessage_Struct {
uint32 type;
char message[512];
uint8 min_status;
uint8 max_status;
char message[512];
uint8 min_status;
uint8 max_status;
};
struct WWMove_Struct {
uint8 update_type; // 0 - Move Zone, 1 - Move Zone Instance
char zone_short_name[32]; // Used with Move Zone
uint8 update_type; // 0 - Move Zone, 1 - Move Zone Instance
char zone_short_name[32]; // Used with Move Zone
uint16 instance_id; // Used with Move Zone Instance
uint8 min_status;
uint8 max_status;
uint8 min_status;
uint8 max_status;
};
struct WWSetEntityVariable_Struct {
uint8 update_type; // 0 - Character, 1 - NPC
char variable_name[256];
char variable_value[256];
char variable_name[256];
char variable_value[256];
uint8 min_status;
uint8 max_status;
};
struct WWSignal_Struct {
uint8 update_type; // 0 - Character, 1 - NPC
int signal_id;
int signal_id;
uint8 min_status;
uint8 max_status;
};
struct WWSpell_Struct {
uint8 update_type; // 0 - Cast Spell, 1 - Remove Spell
uint8 update_type; // 0 - Cast Spell, 1 - Remove Spell
uint32 spell_id;
uint8 min_status;
uint8 max_status;
uint8 min_status;
uint8 max_status;
};
struct WWTaskUpdate_Struct {
uint8 update_type; // 0 - Activity Reset, 1 - Activity Update, 2 - Assign Task, 3 - Disable Task, 4 - Enable Task, 5 - Fail Task, 6 - Remove Task
uint8 update_type; // 0 - Activity Reset, 1 - Activity Update, 2 - Assign Task, 3 - Disable Task, 4 - Enable Task, 5 - Fail Task, 6 - Remove Task
uint32 task_identifier;
int task_subidentifier; // Activity ID for Activity Reset and Activity Update, NPC Entity ID for Assign Task, else -1
int update_count; // Update Count for Activity Update, else 1
bool enforce_level_requirement; // Only used by Assign Task, else false
uint8 min_status;
uint8 max_status;
int task_subidentifier; // Activity ID for Activity Reset and Activity Update, NPC Entity ID for Assign Task, else -1
int update_count; // Update Count for Activity Update, else 1
bool enforce_level_requirement; // Only used by Assign Task, else false
uint8 min_status;
uint8 max_status;
};
struct ReloadWorld_Struct {
+3 -3
View File
@@ -25,7 +25,7 @@
// Build variables
// these get injected during the build pipeline
#define CURRENT_VERSION "22.25.0-dev" // always append -dev to the current version for custom-builds
#define CURRENT_VERSION "22.29.1-dev" // always append -dev to the current version for custom-builds
#define LOGIN_VERSION "0.8.0"
#define COMPILE_DATE __DATE__
#define COMPILE_TIME __TIME__
@@ -42,9 +42,9 @@
* Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
*/
#define CURRENT_BINARY_DATABASE_VERSION 9235
#define CURRENT_BINARY_DATABASE_VERSION 9239
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9039
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9040
#endif
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "eqemu-server",
"version": "22.25.0",
"version": "22.29.1",
"repository": {
"type": "git",
"url": "https://github.com/EQEmu/Server.git"
+5
View File
@@ -156,6 +156,11 @@ bool UCSDatabase::VerifyMailKey(const std::string& characterName, int IPAddress,
return false;
}
if (results.RowCount() == 0) {
LogInfo("No mailkeys found for [{}].", characterName.c_str());
return false;
}
auto row = results.begin();
// The key is the client's IP address (expressed as 8 hex digits) and an 8 hex digit random string generated
+1
View File
@@ -370,6 +370,7 @@ OP_AggroMeterTargetInfo=0x16bc
OP_AggroMeterUpdate=0x1781
OP_UnderWorld=0x2eb3 # clients sends up when they detect an underworld issue, might be useful for cheat detection
OP_KickPlayers=0x6770
OP_BookButton=0x6146
# Expeditions
OP_DzQuit=0xb2e3
+1
View File
@@ -360,6 +360,7 @@ OP_Marquee=0x7dc9
OP_Fling=0x2b88
OP_CancelSneakHide=0x7705
OP_UnderWorld=0x51ae # clients sends up when they detect an underworld issue, might be useful for cheat detection
OP_BookButton=0x4348
# Expedition
OP_DzQuit=0x054e
+1
View File
@@ -341,6 +341,7 @@ OP_Marquee=0x2f75
OP_Untargetable=0x3e36
OP_CancelSneakHide=0x5335
OP_UnderWorld=0x7580 # clients sends up when they detect an underworld issue, might be useful for cheat detection
OP_BookButton=0x4eee
#expedition
OP_DzQuit=0x20d6
+2
View File
@@ -423,6 +423,8 @@ OP_CancelInvite=0x0000
OP_RaidJoin=0x1f21 # ShowEQ 10/27/05
OP_RaidInvite=0x5891 # ShowEQ 10/27/05
OP_RaidUpdate=0x1f21 # EQEmu 06/29/05
OP_RaidDelegateAbility=0x56eb
OP_RaidClearNPCMarks=0x1794
OP_InspectBuffs=0x4FB6
+3
View File
@@ -371,6 +371,7 @@ OP_Marquee=0x3675
OP_Fling=0x51b1
OP_CancelSneakHide=0x7686
OP_UnderWorld=0x2d9d # clients sends up when they detect an underworld issue, might be useful for cheat detection
OP_BookButton=0x018e
OP_DzQuit=0x1539
OP_DzListTimers=0x21e9
@@ -533,6 +534,8 @@ OP_LFGResponse=0x0000 #
OP_RaidInvite=0x60b5 # C
OP_RaidUpdate=0x4d8b # C
OP_RaidJoin=0x0000 #
OP_RaidDelegateAbility=0x0297
OP_RaidClearNPCMarks=0x2af4
# Button-push commands
OP_Taunt=0x30e2 # C
+2 -2
View File
@@ -1,6 +1,6 @@
#!/bin/bash
set -x
set -ex
sudo chown eqemu:eqemu /drone/src/ * -R
sudo chown eqemu:eqemu /home/eqemu/.ccache/ * -R
@@ -9,7 +9,7 @@ git submodule init && git submodule update
perl utils/scripts/build/tag-version.pl
mkdir -p build && cd build && cmake -DEQEMU_BUILD_TESTS=ON -DEQEMU_BUILD_STATIC=ON -DEQEMU_BUILD_LOGIN=ON -DEQEMU_BUILD_LUA=ON -DCMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING="-Os" -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -G 'Unix Makefiles' .. && make -j$((`nproc`-4))
mkdir -p build && cd build && cmake -DEQEMU_BUILD_TESTS=ON -DEQEMU_BUILD_STATIC=ON -DEQEMU_BUILD_LOGIN=ON -DEQEMU_BUILD_LUA=ON -DEQEMU_BUILD_PERL=ON -DCMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING="-Os" -DCMAKE_CXX_COMPILER_LAUNCHER=ccache -G 'Unix Makefiles' .. && make -j$((`nproc`-4))
curl https://raw.githubusercontent.com/Akkadius/eqemu-install-v2/master/eqemu_config.json --output eqemu_config.json
./bin/tests
+2 -2
View File
@@ -10,7 +10,7 @@ require (
require (
github.com/golang/protobuf v1.3.2 // indirect
github.com/google/go-querystring v1.1.0 // indirect
golang.org/x/crypto v0.1.0 // indirect
golang.org/x/net v0.7.0 // indirect
golang.org/x/crypto v0.14.0 // indirect
golang.org/x/net v0.17.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
)
+4 -4
View File
@@ -10,12 +10,12 @@ github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU=
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+240 -220
View File
@@ -1,4 +1,4 @@
#! /usr/bin/perl
#!/usr/bin/perl
########################################################################
#::: 13th floor import script
@@ -9,247 +9,267 @@
use DBI;
use DBD::mysql;
my $database_name = "";
my $db_host = "";
my $db_port = "";
my $db_name = "";
my $db_user = "";
my $db_pass = "";
my $total_items = 0;
my $read_items_file = "items.txt"; #default
my $dbh = LoadMysql();
read_eqemu_config_json();
my $dbh = DBI->connect("DBI:mysql:database=$db_name;host=$db_host;port=$db_port", $db_user, $db_pass) or die "Cannot connect to MySql.";
read_items_file_from_13th_floor_text();
update_items_table();
sub LoadMysql{
#::: Config Variables
my $confile = "eqemu_config.xml";
open(F, "<$confile") or die "Unable to open config: $confile\n";
my $indb = 0;
while(<F>) {
s/\r//g;
if(/<database>/i) { $indb = 1; }
next unless($indb == 1);
if(/<\/database>/i) { $indb = 0; last; }
if(/<host>(.*)<\/host>/i) { $host = $1; }
elsif(/<username>(.*)<\/username>/i) { $user = $1; }
elsif(/<password>(.*)<\/password>/i) { $pass = $1; }
elsif(/<db>(.*)<\/db>/i) { $db = $1; }
}
$database_name = $db;
#::: DATA SOURCE NAME
$dsn = "dbi:mysql:$db:localhost:3306";
#::: PERL DBI CONNECT
$connect = DBI->connect($dsn, $user, $pass);
return $connect;
print "\n\nImport complete!\n\n";
sub read_eqemu_config_json {
use JSON;
my $json = new JSON();
my $config;
my $config_file = "eqemu_config.json";
my $content;
open(my $fh, '<', $config_file) or die "cannot open file $config_file"; {
local $/;
$content = <$fh>;
}
close($fh);
$config = $json->decode($content);
$db_host = $config->{"server"}{"database"}{"host"};
$db_port = $config->{"server"}{"database"}{"port"};
$db_name = $config->{"server"}{"database"}{"db"};
$db_user = $config->{"server"}{"database"}{"username"};
$db_pass = $config->{"server"}{"database"}{"password"};
}
sub read_items_file_from_13th_floor_text {
#::: Read from file and place into array
open(F, "<" . $read_items_file) or die "Unable to open itemfile: " . $read_items_file . "\n";
my @item_file_lines = <F>;
close(F);
#::: Read from file and place into array
open(F, "<" . $read_items_file) or die "Unable to open itemfile: " . $read_items_file . "\n";
my @item_file_lines = <F>;
close(F);
#::: Chomp this array...
my @newitem_file_lines;
chomp($item_file_lines[0]);
@fields = split("(?<!\\\\)\\|", $item_file_lines[0]);
my $sth = $dbh->prepare("SHOW TABLES LIKE 'items_floor'");
$sth->execute();
my $has_items_floor = $sth->fetchrow_array();
#::: If we have items_floor
if ($has_items_floor eq '') {
$dbh->do("CREATE TABLE `items_floor` (`" . join("` VARCHAR(64) NOT NULL DEFAULT '', `", @fields). "` VARCHAR(64) NOT NULL DEFAULT '', UNIQUE INDEX `ID` (`id`)) COLLATE='latin1_swedish_ci' ENGINE=MyISAM");
$dbh->do("ALTER TABLE `items_floor` CHANGE `id` `id` INT(11) NOT NULL DEFAULT '0'");
printf "Database items_floor created\n";
}
#::: Create REPLACE INTO header and define worker variables...
$master_insert = "REPLACE INTO `items_floor` (" . join(",", @fields) . ") VALUES ";
$query_insert_ph = ""; #::: Used for building placeholder values in query Ex: (?, ?, ?)
@field_values = (); #::: Used for stuffing mysql field values
$query_count = 0; #::: Used for chunking query updates
$print_cycle = 0; #::: Counter for console updates
$start_time = time(); #::: Start time for import
$total_items_file = scalar(grep $_, @item_file_lines) - 1; #::: Total items in text file
#::: Chomp this array...
my @newitem_file_lines;
chomp($item_file_lines[0]);
@fields = split("(?<!\\\\)\\|", $item_file_lines[0]);
#::: Iterate through each item in items.txt
for (1 .. $#item_file_lines) {
@f = split("(?<!\\\\)\\|", $item_file_lines[$_]);
my $sth = $dbh->prepare("SHOW TABLES LIKE 'items_floor'");
$sth->execute();
my $has_items_floor = $sth->fetchrow_array();
#::: Build our individual prepared statement (?, ?) values in the insert_ph
#::: ?, ? placeholders will be resolved via @field_values in the execute
$query_insert_ph .= " (";
foreach (@f) {
push (@field_values, trim($_));
$query_insert_ph .= "?, ";
}
$query_insert_ph = substr($query_insert_ph, 0, -2);
$query_insert_ph .= "), ";
#::: If we don't have items_floor table
if ($has_items_floor eq '') {
$dbh->do("CREATE TABLE `items_floor` (`" . join("` VARCHAR(64) NOT NULL DEFAULT '', `", @fields). "` VARCHAR(64) NOT NULL DEFAULT '', UNIQUE INDEX `ID` (`id`)) COLLATE='latin1_swedish_ci' ENGINE=MyISAM");
$dbh->do("ALTER TABLE `items_floor` CHANGE `id` `id` INT(11) NOT NULL DEFAULT '0'");
printf "Database items_floor created\n";
}
#::: Let's chunk our updates so we can break up the amount of individual queries
if($query_count > 500){
$query_insert_ph = substr($query_insert_ph, 0, -2);
$dbh->prepare($master_insert . " " . $query_insert_ph)->execute(@field_values);
$query_count = 0;
$query_insert_ph = "";
@field_values = ();
}
#::: Print updates to console
if($print_cycle > 25){
print "Processing (" . $read_items_file . ") :: (Items: " . $total_items . "/" . $total_items_file . ") \r";
$print_cycle = 0;
}
#::: Create REPLACE INTO header and define worker variables...
$master_insert = "REPLACE INTO `items_floor` (" . join(",", @fields) . ") VALUES ";
$query_insert_ph = ""; #::: Used for building placeholder values in query Ex: (?, ?, ?)
@field_values = (); #::: Used for stuffing mysql field values
$query_count = 0; #::: Used for chunking query updates
$print_cycle = 0; #::: Counter for console updates
$start_time = time(); #::: Start time for import
$total_items_file = scalar(grep $_, @item_file_lines) - 1; #::: Total items in text file
#::: Counters
$total_items++;
$query_count++;
$print_cycle++;
}
#::: One last processing print
print "Processing (" . $read_items_file . ") :: (Items: " . $total_items . "/" . $total_items_file . ") \r";
printf "\n" . $total_items . " items added to database... Took " . (time() - $start_time) . " second(s)... \n";
print "Flipping slots 21 and 22...";
$rows_affected = $dbh->prepare("
UPDATE `items_floor`
SET `slots` = (`slots` ^ 6291456)
WHERE (`slots` & 6291456)
IN (2097152, 4194304)")->execute();
print " Rows affected (" . $rows_affected . ")\n";
#::: Iterate through each item in items.txt
for (1 .. $#item_file_lines) {
@f = split("(?<!\\\\)\\|", $item_file_lines[$_]);
#::: Build our individual prepared statement (?, ?) values in the insert_ph
#::: ?, ? placeholders will be resolved via @field_values in the execute
$query_insert_ph .= " (";
foreach (@f) {
push (@field_values, trim($_));
$query_insert_ph .= "?, ";
}
$query_insert_ph = substr($query_insert_ph, 0, -2);
$query_insert_ph .= "), ";
#::: Let's chunk our updates so we can break up the amount of individual queries
if($query_count > 500){
$query_insert_ph = substr($query_insert_ph, 0, -2);
$dbh->prepare($master_insert . " " . $query_insert_ph)->execute(@field_values);
$query_count = 0;
$query_insert_ph = "";
@field_values = ();
}
#::: Print updates to console
if($print_cycle > 25){
print "Processing (" . $read_items_file . ") :: (Items: " . $total_items . "/" . $total_items_file . ") \r";
$print_cycle = 0;
}
#::: Counters
$total_items++;
$query_count++;
$print_cycle++;
}
#::: One last processing print
print "Processing (" . $read_items_file . ") :: (Items: " . $total_items . "/" . $total_items_file . ") \r";
printf "\n" . $total_items . " items imported... Took " . (time() - $start_time) . " second(s)... \n";
#::: Process slots 21, 22
print "Flipping slots 21 and 22...";
$rows_affected = $dbh->prepare("
UPDATE `items_floor`
SET `slots` = (`slots` ^ 6291456)
WHERE (`slots` & 6291456)
IN (2097152, 4194304)")->execute();
print " :: Rows affected (" . $rows_affected . ")\n";
#::: Update idfile entries
print "Updating idfile entries...";
$rows_affected = $dbh->prepare("
UPDATE `items_floor`
SET `idfile` = CONCAT('IT', `idfile`)")->execute();
print " :: Rows affected(" . $rows_affected . ")\n";
}
sub update_items_table {
#::: Keep Items table sane
$query_handle = $dbh->prepare("
ALTER TABLE `items`
MODIFY COLUMN `UNK132` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL;
");
$query_handle->execute();
my @matching_table;
my @missing_items_table;
my @missing_items_floor_table;
#::: Get columns from `items`
my $sth = $dbh->prepare("SHOW COLUMNS FROM `items`;");
$sth->execute();
my @items_table;
while (my @row = $sth->fetchrow_array()) {
push(@items_table, $row[0]);
}
#::: Get columns from `items_floor`
$sth2 = $dbh->prepare("SHOW COLUMNS FROM `items_floor`");
$sth2->execute();
my @items_floor_table;
while (my @row = $sth2->fetchrow_array()) {
push(@items_floor_table, $row[0]);
}
#::: Go through the original items table columns and line them up with what columns match on 13th floor
#::: This is so we can use the matching columns to update and insert item data into `items` table
foreach $value (@items_table) {
if ( grep( /^$value$/i, @items_floor_table ) ) {
push(@matching_table, $value);
} else {
#::: What values are we missing from EMU items table..
push(@missing_items_table, $value);
}
}
#::: What values are we missing from.. 13thFloor
foreach $value (@items_floor_table) {
if ( grep( /^$value$/i, @items_table ) ) {
#DO NOTHING...
} else {
push(@missing_items_floor_table, $value);
}
}
print "Updating items table...\n";
#::: Go through the matched columns and build our query strings...
my $items_field_list = ""; #::: Build the field list for the INSERT (field1, field2)
my $items_floor_field_list = ""; #::: What fields we will select from items_floor table to insert into items (matched columns)
my $update_fields = ""; #::: To update an existing item entry if it exists...
my @matching_table;
my @missing_items_table;
my @missing_items_floor_table;
foreach $match (@matching_table) {
$match = lc($match);
$update_fields .= "`" . $match . "` = fi.`" . $match . "`, ";
$items_field_list .= "`" . $match . "`, ";
$items_floor_field_list .= "fi.`" . $match . "`, ";
}
#::: Trim ', ' off the ends
$update_fields = substr($update_fields, 0, -2);
$items_field_list = substr($items_field_list, 0, -2);
$items_floor_field_list = substr($items_floor_field_list, 0, -2);
#::: Mixed up fields...
$items_floor_field_list =~ s/booktype/booklang/g; #our booktype is mixed with theirs...
$update_fields =~ s/`booktype` = fi.`booktype`/`booktype` = fi.`booklang`/g;
print "Comparing table structure...\n";
#::: Get columns from `items`
my $sth = $dbh->prepare("SHOW COLUMNS FROM `items`;");
$sth->execute();
my @items_table;
while (my @row = $sth->fetchrow_array()) {
push(@items_table, $row[0]);
}
#::: FIELDS THAT DO NOT MATCH GO HERE
my @items_add = (
"casttime_", "endur", "range", "attuneable", "evolvinglevel", "herosforgemodel", "scrolltype",
"scriptfileid", "powersourcecapacity", "augslot1unk2", "augslot2unk2", "augslot3unk2", "augslot4unk2",
"augslot5unk2", "augslot6unk2", "recskill", "book"
);
my @items_floor_add = (
"foodduration", "endurance", "therange", "attunable", "evolvl", "heroforge1", "scrolleffecttype",
"rightclickscriptid", "powersourcecap", "augslot1unk", "augslot2unk", "augslot3unk", "augslot4unk",
"augslot5unk", "augslot6unk", "reqskill", "booktype"
);
#::: Match the mis-matched fields...
my $spot = 0;
foreach $value (@items_add) {
$items_field_list .= ", `" . $value . "`";
$update_fields .= ", `" . $value . "` = fi.`" . $items_floor_add[$spot] . "`";
$spot++;
@missing_items_table = grep {$_ ne $value} @missing_items_table;
}
foreach $value (@items_floor_add) {
$items_floor_field_list .= ", fi.`" . $value . "`";
@missing_items_floor_table = grep {$_ ne $value} @missing_items_floor_table;
}
my $update_query = "
INSERT INTO items (" . $items_field_list . ")
SELECT " . $items_floor_field_list . "
FROM items_floor fi
ON DUPLICATE KEY UPDATE " . $update_fields;
#::: Print missing fields to file
my $write_file = "missing_item_fields.txt";
open(F, ">$write_file") or die "Unable to open questfile: $write_file\n";
print F "$update_query \n\n";
print F "EQEMU items Table missing fields\n";
foreach $value (@missing_items_table) {
print F "$value\n";
}
print F "\n\n13thFloor items Table missing fields\n";
foreach $value (@missing_items_floor_table) {
print F "$value\n";
}
close(F);
#::: Number of rows affected by query
$rows = $dbh->do($update_query);
#::: Update stackables
$dbh->do("UPDATE items i SET i.stackable = 1 WHERE i.stacksize > 1");
print "Added all new items to Items table (" . $rows . ")!\n";
#::: Get columns from `items_floor`
$sth2 = $dbh->prepare("SHOW COLUMNS FROM `items_floor`");
$sth2->execute();
my @items_floor_table;
while (my @row = $sth2->fetchrow_array()) {
push(@items_floor_table, $row[0]);
}
#::: Go through the original items table columns and line them up with what columns match on 13th floor
#::: This is so we can use the matching columns to update and insert item data into `items` table
foreach $value (@items_table) {
if ( grep( /^$value$/i, @items_floor_table ) ) {
push(@matching_table, $value);
} else {
#::: What values are we missing from EMU items table..
push(@missing_items_table, $value);
}
}
#::: What values are we missing from.. 13thFloor
foreach $value (@items_floor_table) {
if ( grep( /^$value$/i, @items_table ) ) {
#DO NOTHING...
} else {
push(@missing_items_floor_table, $value);
}
}
#::: Go through the matched columns and build our query strings...
my $items_field_list = ""; #::: Build the field list for the INSERT (field1, field2)
my $items_floor_field_list = ""; #::: What fields we will select from items_floor table to insert into items (matched columns)
my $update_fields = ""; #::: To update an existing item entry if it exists...
foreach $match (@matching_table) {
$match = lc($match);
$update_fields .= "`" . $match . "` = fi.`" . $match . "`, ";
$items_field_list .= "`" . $match . "`, ";
$items_floor_field_list .= "fi.`" . $match . "`, ";
}
#::: Trim ', ' off the ends
$update_fields = substr($update_fields, 0, -2);
$items_field_list = substr($items_field_list, 0, -2);
$items_floor_field_list = substr($items_floor_field_list, 0, -2);
#::: Mixed up fields...
$items_floor_field_list =~ s/booktype/booklang/g; #our booktype is mixed with theirs...
$update_fields =~ s/`booktype` = fi.`booktype`/`booktype` = fi.`booklang`/g;
#::: FIELDS THAT DO NOT MATCH GO HERE
my @items_add = (
"casttime_", "endur", "range", "attuneable", "evolvinglevel", "herosforgemodel", "scrolltype",
"scriptfileid", "powersourcecapacity", "augslot1unk2", "augslot2unk2", "augslot3unk2", "augslot4unk2",
"augslot5unk2", "augslot6unk2", "recskill", "book", "procunk1"
);
my @items_floor_add = (
"foodduration", "endurance", "therange", "attunable", "evolvl", "heroforge1", "scrolleffecttype",
"rightclickscriptid", "powersourcecap", "augslot1unk", "augslot2unk", "augslot3unk", "augslot4unk",
"augslot5unk", "augslot6unk", "reqskill", "booktype", "prockunk1"
);
#::: Match the mis-matched fields...
print "Matching fields...\n";
my $spot = 0;
foreach $value (@items_add) {
$items_field_list .= ", `" . $value . "`";
$update_fields .= ", `" . $value . "` = fi.`" . $items_floor_add[$spot] . "`";
$spot++;
@missing_items_table = grep {$_ ne $value} @missing_items_table;
}
foreach $value (@items_floor_add) {
$items_floor_field_list .= ", fi.`" . $value . "`";
@missing_items_floor_table = grep {$_ ne $value} @missing_items_floor_table;
}
my $update_query = "
INSERT INTO items (" . $items_field_list . ")
SELECT " . $items_floor_field_list . "
FROM items_floor fi
ON DUPLICATE KEY UPDATE " . $update_fields;
#::: Print missing fields to file
print "Writing query and discrepencies to file...\n";
my $write_file = "missing_item_fields.txt";
open(F, ">$write_file") or die "Unable to open file: $write_file\n";
print F "$update_query \n\n";
print F "EQEMU items table extra fields:\n";
foreach $value (@missing_items_table) {
print F "$value\n";
}
print F "\n\n13thFloor items table extra fields:\n";
foreach $value (@missing_items_floor_table) {
print F "$value\n";
}
close(F);
#::: Number of rows affected by query
$rows = $dbh->do($update_query);
print "Added or updated " . $rows . " entries.\n";
#::: Update stackables
print "Updating stackable field...\n";
$dbh->do("UPDATE items i SET i.stackable = 1 WHERE i.stacksize > 1");
#::: Update legacy research tome bagtypes
print "Updating legacy research tomes...\n";
$dbh->do("UPDATE items i SET i.bagtype = 24 WHERE i.id IN (17655, 17903)"); #RESEARCHWIZ
$dbh->do("UPDATE items i SET i.bagtype = 25 WHERE i.id IN (17502, 17653)"); #RESEARCHMAG
$dbh->do("UPDATE items i SET i.bagtype = 26 WHERE i.id IN (17501, 17654)"); #RESEARCHNEC
$dbh->do("UPDATE items i SET i.bagtype = 27 WHERE i.id IN (17500, 17652)"); #RESEARCHENC
}
sub trim($) {
my $string = shift;
$string =~ s/^\s+//;
$string =~ s/\s+$//;
return $string;
}
my $string = shift;
$string =~ s/^\s+//;
$string =~ s/\s+$//;
return $string;
}
+12 -7
View File
@@ -1226,15 +1226,20 @@ void ConsoleCrossZoneMove(
}
auto pack = new ServerPacket(ServerOP_CZMove, sizeof(CZMove_Struct));
auto* CZM = (CZMove_Struct*) pack->pBuffer;
auto m = (CZMove_Struct*) pack->pBuffer;
CZM->update_type = update_type;
CZM->update_subtype = !instance_id ? CZMoveUpdateSubtype_MoveZone : CZMoveUpdateSubtype_MoveZoneInstance;
CZM->update_identifier = update_identifier;
CZM->instance_id = instance_id;
if (!name.empty()) {
m->client_name = name;
}
strn0cpy(CZM->zone_short_name, zone_short_name.c_str(), sizeof(CZM->zone_short_name));
strn0cpy(CZM->client_name, name.c_str(), sizeof(CZM->client_name));
m->instance_id = instance_id;
m->update_identifier = update_identifier;
m->update_type = update_type;
m->update_subtype = !instance_id ? CZMoveUpdateSubtype_MoveZone : CZMoveUpdateSubtype_MoveZoneInstance;
if (!zone_short_name.empty()) {
m->zone_short_name = zone_short_name;
}
zoneserver_list.SendPacket(pack);
safe_delete(pack);
+172 -33
View File
@@ -1111,7 +1111,7 @@ void Client::PurchaseAlternateAdvancementRank(int rank_id) {
return;
}
FinishAlternateAdvancementPurchase(rank, false);
FinishAlternateAdvancementPurchase(rank, false, true);
}
bool Client::GrantAlternateAdvancementAbility(int aa_id, int points, bool ignore_cost) {
@@ -1134,13 +1134,13 @@ bool Client::GrantAlternateAdvancementAbility(int aa_id, int points, bool ignore
}
ret = true;
FinishAlternateAdvancementPurchase(rank, ignore_cost);
FinishAlternateAdvancementPurchase(rank, ignore_cost, true);
}
return ret;
}
void Client::FinishAlternateAdvancementPurchase(AA::Rank *rank, bool ignore_cost) {
void Client::FinishAlternateAdvancementPurchase(AA::Rank *rank, bool ignore_cost, bool send_message_and_save) {
auto rank_id = rank->base_ability->first_rank_id;
if (rank->base_ability->charges) {
@@ -1156,7 +1156,7 @@ void Client::FinishAlternateAdvancementPurchase(AA::Rank *rank, bool ignore_cost
SetAA(rank_id, rank->current_value, 0);
//if not max then send next aa
if (rank->next) {
if (rank->next && send_message_and_save) {
SendAlternateAdvancementRank(rank->base_ability->id, rank->next->current_value);
}
}
@@ -1164,10 +1164,12 @@ void Client::FinishAlternateAdvancementPurchase(AA::Rank *rank, bool ignore_cost
auto cost = !ignore_cost ? rank->cost : 0;
m_pp.aapoints -= static_cast<uint32>(cost);
SaveAA();
SendAlternateAdvancementPoints();
SendAlternateAdvancementStats();
if (send_message_and_save) {
SaveAA();
SendAlternateAdvancementPoints();
SendAlternateAdvancementStats();
}
if (player_event_logs.IsEventEnabled(PlayerEvent::AA_PURCHASE)) {
auto e = PlayerEvent::AAPurchasedEvent{
@@ -1181,14 +1183,16 @@ void Client::FinishAlternateAdvancementPurchase(AA::Rank *rank, bool ignore_cost
}
if (rank->prev) {
MessageString(
Chat::Yellow,
AA_IMPROVE,
std::to_string(rank->title_sid).c_str(),
std::to_string(rank->prev->current_value).c_str(),
std::to_string(cost).c_str(),
cost == 1 ? std::to_string(AA_POINT).c_str() : std::to_string(AA_POINTS).c_str()
);
if (send_message_and_save) {
MessageString(
Chat::Yellow,
AA_IMPROVE,
std::to_string(rank->title_sid).c_str(),
std::to_string(rank->prev->current_value).c_str(),
std::to_string(cost).c_str(),
cost == 1 ? std::to_string(AA_POINT).c_str() : std::to_string(AA_POINTS).c_str()
);
}
/* QS: Player_Log_AA_Purchases */
if (RuleB(QueryServ, PlayerLogAAPurchases)) {
@@ -1203,13 +1207,15 @@ void Client::FinishAlternateAdvancementPurchase(AA::Rank *rank, bool ignore_cost
QServ->PlayerLogEvent(Player_Log_AA_Purchases, CharacterID(), event_desc);
}
} else {
MessageString(
Chat::Yellow,
AA_GAIN_ABILITY,
std::to_string(rank->title_sid).c_str(),
std::to_string(cost).c_str(),
cost == 1 ? std::to_string(AA_POINT).c_str() : std::to_string(AA_POINTS).c_str()
);
if (send_message_and_save) {
MessageString(
Chat::Yellow,
AA_GAIN_ABILITY,
std::to_string(rank->title_sid).c_str(),
std::to_string(cost).c_str(),
cost == 1 ? std::to_string(AA_POINT).c_str() : std::to_string(AA_POINTS).c_str()
);
}
/* QS: Player_Log_AA_Purchases */
if (RuleB(QueryServ, PlayerLogAAPurchases)) {
@@ -1570,6 +1576,10 @@ bool Mob::SetAA(uint32 rank_id, uint32 new_value, uint32 charges) {
bool Mob::CanUseAlternateAdvancementRank(AA::Rank *rank) {
if (!rank) {
return false;
}
AA::Ability *ability = rank->base_ability;
if(!ability)
@@ -1594,6 +1604,15 @@ bool Mob::CanUseAlternateAdvancementRank(AA::Rank *rank) {
}
}
int expansion = RuleI(Expansion, CurrentExpansion);
bool use_expansion_aa = RuleB(Expansion, UseCurrentExpansionAAOnly);
if (use_expansion_aa && expansion >= 0) {
if (rank->expansion > expansion) {
return false;
}
}
if (IsClient()) {
if (rank->expansion && !(CastToClient()->GetPP().expansions & (1 << (rank->expansion - 1)))) {
return false;
@@ -1645,6 +1664,10 @@ bool Mob::CanPurchaseAlternateAdvancementRank(AA::Rank *rank, bool check_price,
return false;
}
if (IsClient() && CastToClient()->HasAlreadyPurchasedRank(rank)) {
return false;
}
//You can't purchase grant only AAs they can only be assigned
if(check_grant && ability->grant_only) {
return false;
@@ -1764,7 +1787,7 @@ bool ZoneDatabase::LoadAlternateAdvancementAbilities(std::unordered_map<int, std
{
abilities.clear();
std::string query = "SELECT id, name, category, classes, races, deities, drakkin_heritage, status, type, charges, "
"grant_only, reset_on_death, first_rank_id FROM aa_ability WHERE enabled = 1";
"grant_only, reset_on_death, auto_grant_enabled, first_rank_id FROM aa_ability WHERE enabled = 1";
auto results = QueryDatabase(query);
if(results.Success()) {
for(auto row = results.begin(); row != results.end(); ++row) {
@@ -1782,7 +1805,8 @@ bool ZoneDatabase::LoadAlternateAdvancementAbilities(std::unordered_map<int, std
ability->charges = Strings::ToInt(row[9]);
ability->grant_only = Strings::ToBool(row[10]);
ability->reset_on_death = Strings::ToBool(row[11]);
ability->first_rank_id = Strings::ToInt(row[12]);
ability->auto_grant_enabled = Strings::ToBool(row[12]);
ability->first_rank_id = Strings::ToInt(row[13]);
ability->first = nullptr;
abilities[ability->id] = std::unique_ptr<AA::Ability>(ability);
@@ -1793,17 +1817,11 @@ bool ZoneDatabase::LoadAlternateAdvancementAbilities(std::unordered_map<int, std
}
LogInfo("Loaded [{}] Alternate Advancement Abilities", Strings::Commify((int)abilities.size()));
int expansion = RuleI(Expansion, CurrentExpansion);
bool use_expansion_aa = RuleB(Expansion, UseCurrentExpansionAAOnly);
ranks.clear();
if (use_expansion_aa && expansion >= 0) {
query = fmt::format("SELECT id, upper_hotkey_sid, lower_hotkey_sid, title_sid, desc_sid, cost, level_req, spell, spell_type, recast_time, "
"next_id, expansion FROM aa_ranks WHERE expansion <= {}", expansion);
} else {
query = "SELECT id, upper_hotkey_sid, lower_hotkey_sid, title_sid, desc_sid, cost, level_req, spell, spell_type, recast_time, "
query = "SELECT id, upper_hotkey_sid, lower_hotkey_sid, title_sid, desc_sid, cost, level_req, spell, spell_type, recast_time, "
"next_id, expansion FROM aa_ranks";
}
results = QueryDatabase(query);
if(results.Success()) {
for(auto row = results.begin(); row != results.end(); ++row) {
@@ -2068,3 +2086,124 @@ void Client::TogglePurchaseAlternativeAdvancementRank(int rank_id){
CalcBonuses();
}
void Client::AutoGrantAAPoints() {
int auto_grant_expansion = RuleI(Expansion, AutoGrantAAExpansion);
if (auto_grant_expansion == -1) {
return;
}
//iterate through every AA
for (auto& iter : zone->aa_abilities) {
auto ability = iter.second.get();
if (ability->grant_only) {
continue;
}
if (ability->charges > 0) {
continue;
}
if (!ability->auto_grant_enabled) {
continue;
}
auto level = GetLevel();
auto p = 1;
auto rank = ability->first;
while (rank != nullptr) {
if (CanUseAlternateAdvancementRank(rank)) {
if (rank->expansion <= auto_grant_expansion && rank->level_req <= level && !HasAlreadyPurchasedRank(rank)) {
FinishAlternateAdvancementPurchase(rank, true, false);
if (rank->prev) {
MessageString(
Chat::Yellow,
AA_IMPROVE,
std::to_string(rank->title_sid).c_str(),
std::to_string(rank->prev->current_value).c_str(),
"0",
std::to_string(AA_POINTS).c_str()
);
}
else {
MessageString(
Chat::Yellow,
AA_GAIN_ABILITY,
std::to_string(rank->title_sid).c_str(),
"0",
std::to_string(AA_POINTS).c_str()
);
}
}
}
else {
break;
}
p++;
rank = rank->next;
}
}
SendClearAA();
SendAlternateAdvancementTable();
SendAlternateAdvancementPoints();
SendAlternateAdvancementStats();
}
void Client::GrantAllAAPoints(uint8 unlock_level)
{
//iterate through every AA
for (auto& aa : zone->aa_abilities) {
AA::Ability* ability = aa.second.get();
if (ability->charges > 0) {
continue;
}
const uint8 level = unlock_level ? unlock_level : GetLevel();
AA::Rank* rank = ability->first;
while (rank) {
if (!CanUseAlternateAdvancementRank(rank)) {
break;
}
if (rank->level_req <= level && !HasAlreadyPurchasedRank(rank)) {
FinishAlternateAdvancementPurchase(rank, true, false);
}
rank = rank->next;
}
}
SaveAA();
SendClearAA();
SendAlternateAdvancementTable();
SendAlternateAdvancementPoints();
SendAlternateAdvancementStats();
}
bool Client::HasAlreadyPurchasedRank(AA::Rank* rank) {
const auto& aa = aa_ranks.find(rank->base_ability->id);
if (aa == aa_ranks.end()) {
return false;
}
const auto& ability_rank = zone->GetAlternateAdvancementAbilityAndRank(aa->first, aa->second.first);
AA::Ability* ability = ability_rank.first;
AA::Rank* current = ability_rank.second;
while (current) {
if (current == rank) {
return true;
}
current = current->prev;
}
return false;
}
+1
View File
@@ -50,6 +50,7 @@ public:
int status;
bool grant_only;
bool reset_on_death;
bool auto_grant_enabled;
int type;
int charges;
int first_rank_id;
+13 -1
View File
@@ -1073,10 +1073,13 @@ bool Mob::CombatRange(Mob* other, float fixed_size_mod, bool aeRampage, ExtraAtt
if (aeRampage) {
float aeramp_size = RuleR(Combat, AERampageMaxDistance);
LogCombatDetail("AERampage: Default - aeramp_size = [{}] ", aeramp_size);
if (opts) {
if (opts->range_percent > 0) {
aeramp_size = opts->range_percent;
LogCombatDetail("AE Rampage: range_percent = [{}] -- aeramp_size [{}]", opts->range_percent, aeramp_size);
}
}
@@ -1087,8 +1090,17 @@ bool Mob::CombatRange(Mob* other, float fixed_size_mod, bool aeRampage, ExtraAtt
}
float ramp_range = size_mod * aeramp_size;
LogCombatDetail("AE Rampage: ramp_range = [{}] -- (size_mod [{}] * aeramp_size [{}])", ramp_range, size_mod, aeramp_size);
LogCombatDetail("AE Rampage: _DistNoRoot [{}] <= ramp_range [{}]", _DistNoRoot, ramp_range);
return _DistNoRoot <= ramp_range;
if (_DistNoRoot <= ramp_range) {
LogCombatDetail("AE Rampage: Combat Distance returned [true]");
return true;
} else {
LogCombatDetail("AE Rampage: Combat Distance returned [false]");
return false;
}
}
if (_DistNoRoot <= size_mod) {
+38 -28
View File
@@ -1741,7 +1741,8 @@ bool Client::Death(Mob* killerMob, int64 damage, uint16 spell, EQ::skills::Skill
static_cast<int>(attack_skill)
);
if (parse->EventPlayer(EVENT_DEATH, this, export_string, 0) != 0) {
std::vector<std::any> args = { CastToMob() };
if (parse->EventPlayer(EVENT_DEATH, this, export_string, 0, &args) != 0) {
if (GetHP() < 0) {
SetHP(0);
}
@@ -2388,7 +2389,8 @@ bool NPC::Death(Mob* killer_mob, int64 damage, uint16 spell, EQ::skills::SkillTy
static_cast<int>(attack_skill)
);
if (parse->EventNPC(EVENT_DEATH, this, oos, export_string, 0) != 0) {
std::vector<std::any> args = { CastToMob() };
if (parse->EventNPC(EVENT_DEATH, this, oos, export_string, 0, &args) != 0) {
if (GetHP() < 0) {
SetHP(0);
}
@@ -2405,7 +2407,9 @@ bool NPC::Death(Mob* killer_mob, int64 damage, uint16 spell, EQ::skills::SkillTy
spell,
static_cast<int>(attack_skill)
);
if (parse->EventBot(EVENT_DEATH, CastToBot(), oos, export_string, 0) != 0) {
std::vector<std::any> args = { CastToMob() };
if (parse->EventBot(EVENT_DEATH, CastToBot(), oos, export_string, 0, &args) != 0) {
if (GetHP() < 0) {
SetHP(0);
}
@@ -3624,7 +3628,7 @@ int64 Mob::ReduceAllDamage(int64 damage)
bool Mob::HasProcs() const
{
for (int i = 0; i < MAX_PROCS; i++) {
for (int i = 0; i < m_max_procs; i++) {
if (IsValidSpell(PermaProcs[i].spellID) || IsValidSpell(SpellProcs[i].spellID)) {
return true;
}
@@ -3642,7 +3646,7 @@ bool Mob::HasProcs() const
bool Mob::HasDefensiveProcs() const
{
for (int i = 0; i < MAX_PROCS; i++) {
for (int i = 0; i < m_max_procs; i++) {
if (IsValidSpell(DefensiveProcs[i].spellID)) {
return true;
}
@@ -3678,7 +3682,7 @@ bool Mob::HasSkillProcSuccess() const
bool Mob::HasRangedProcs() const
{
for (int i = 0; i < MAX_PROCS; i++){
for (int i = 0; i < m_max_procs; i++){
if (IsValidSpell(RangedProcs[i].spellID)) {
return true;
}
@@ -4226,7 +4230,7 @@ void Mob::CommonDamage(Mob* attacker, int64 &damage, const uint16 spell_id, cons
//this was done to simplify the code here (since we can only effectively skip one mob on queue)
eqFilterType filter;
Mob* skip = attacker;
if (attacker && attacker->GetOwnerID()) {
if (attacker && attacker->GetOwner()) {
//attacker is a pet, let pet owners see their pet's damage
Mob* owner = attacker->GetOwner();
if (owner && owner->IsClient()) {
@@ -4539,8 +4543,8 @@ float Mob::GetDefensiveProcChances(float &ProcBonus, float &ProcChance, uint16 h
}
// argument 'weapon' not used
void Mob::TryDefensiveProc(Mob *on, uint16 hand) {
void Mob::TryDefensiveProc(Mob *on, uint16 hand)
{
if (!on) {
SetTarget(nullptr);
LogError("A null Mob object was passed to Mob::TryDefensiveProc for evaluation!");
@@ -4552,31 +4556,34 @@ void Mob::TryDefensiveProc(Mob *on, uint16 hand) {
}
if (!on->HasDied() && on->GetHP() > 0) {
float ProcChance, ProcBonus;
on->GetDefensiveProcChances(ProcBonus, ProcChance, hand, this);
float proc_chance, proc_bonus;
on->GetDefensiveProcChances(proc_bonus, proc_chance, hand, this);
if (hand == EQ::invslot::slotSecondary) {
ProcChance /= 2;
proc_chance /= 2;
}
int level_penalty = 0;
int level_diff = GetLevel() - on->GetLevel();
if (level_diff > 6) {//10% penalty per level if > 6 levels over target.
level_penalty = (level_diff - 6) * 10;
int level_penalty = 0;
int level_diff = GetLevel() - on->GetLevel();
int penalty_level_gap = RuleI(Spells, DefensiveProcPenaltyLevelGap);
if (
penalty_level_gap >= 0 &&
level_diff > penalty_level_gap
) {//10% penalty per level if > penalty_level_gap levels over target.
level_penalty = (level_diff - penalty_level_gap) * RuleR(Spells, DefensiveProcPenaltyLevelGapModifier);
}
ProcChance -= ProcChance*level_penalty / 100;
proc_chance -= proc_chance * level_penalty / 100;
if (ProcChance < 0) {
if (proc_chance < 0) {
return;
}
//Spell Procs and Quest added procs
for (int i = 0; i < MAX_PROCS; i++) {
for (int i = 0; i < m_max_procs; i++) {
if (IsValidSpell(DefensiveProcs[i].spellID)) {
if (!IsProcLimitTimerActive(DefensiveProcs[i].base_spellID, DefensiveProcs[i].proc_reuse_time, ProcType::DEFENSIVE_PROC)) {
float chance = ProcChance * (static_cast<float>(DefensiveProcs[i].chance) / 100.0f);
float chance = proc_chance * (static_cast<float>(DefensiveProcs[i].chance) / 100.0f);
if (zone->random.Roll(chance)) {
ExecWeaponProc(nullptr, DefensiveProcs[i].spellID, on);
CheckNumHitsRemaining(NumHit::DefensiveSpellProcs, 0, DefensiveProcs[i].base_spellID);
@@ -4589,14 +4596,14 @@ void Mob::TryDefensiveProc(Mob *on, uint16 hand) {
//AA Procs
if (IsOfClientBot()) {
for (int i = 0; i < MAX_AA_PROCS; i += 4) {
int32 aa_rank_id = aabonuses.DefensiveProc[i + +SBIndex::COMBAT_PROC_ORIGIN_ID];
int32 aa_spell_id = aabonuses.DefensiveProc[i + SBIndex::COMBAT_PROC_SPELL_ID];
int32 aa_proc_chance = 100 + aabonuses.DefensiveProc[i + SBIndex::COMBAT_PROC_RATE_MOD];
int32 aa_rank_id = aabonuses.DefensiveProc[i + +SBIndex::COMBAT_PROC_ORIGIN_ID];
int32 aa_spell_id = aabonuses.DefensiveProc[i + SBIndex::COMBAT_PROC_SPELL_ID];
int32 aa_proc_chance = 100 + aabonuses.DefensiveProc[i + SBIndex::COMBAT_PROC_RATE_MOD];
uint32 aa_proc_reuse_timer = aabonuses.DefensiveProc[i + SBIndex::COMBAT_PROC_REUSE_TIMER];
if (aa_rank_id) {
if (!IsProcLimitTimerActive(-aa_rank_id, aa_proc_reuse_timer, ProcType::DEFENSIVE_PROC)) {
float chance = ProcChance * (static_cast<float>(aa_proc_chance) / 100.0f);
float chance = proc_chance * (static_cast<float>(aa_proc_chance) / 100.0f);
if (zone->random.Roll(chance) && IsValidSpell(aa_spell_id)) {
ExecWeaponProc(nullptr, aa_spell_id, on);
SetProcLimitTimer(-aa_rank_id, aa_proc_reuse_timer, ProcType::DEFENSIVE_PROC);
@@ -4776,7 +4783,7 @@ void Mob::TrySpellProc(const EQ::ItemInstance *inst, const EQ::ItemData *weapon,
int16 poison_slot=-1;
for (uint32 i = 0; i < MAX_PROCS; i++) {
for (uint32 i = 0; i < m_max_procs; i++) {
if (IsPet() && hand != EQ::invslot::slotPrimary) //Pets can only proc spell procs from their primay hand (ie; beastlord pets)
continue; // If pets ever can proc from off hand, this will need to change
@@ -5205,8 +5212,11 @@ bool Mob::TryFinishingBlow(Mob *defender, int64 &damage)
FB_Level = itembonuses.FinishingBlowLvl[SBIndex::FINISHING_EFFECT_LEVEL_MAX];
// modern AA description says rank 1 (500) is 50% chance
int ProcChance =
aabonuses.FinishingBlow[SBIndex::FINISHING_EFFECT_PROC_CHANCE] + spellbonuses.FinishingBlow[SBIndex::FINISHING_EFFECT_PROC_CHANCE] + spellbonuses.FinishingBlow[SBIndex::FINISHING_EFFECT_PROC_CHANCE];
int ProcChance = (
aabonuses.FinishingBlow[SBIndex::FINISHING_EFFECT_PROC_CHANCE] +
itembonuses.FinishingBlow[SBIndex::FINISHING_EFFECT_PROC_CHANCE] +
spellbonuses.FinishingBlow[SBIndex::FINISHING_EFFECT_PROC_CHANCE]
);
if (FB_Level && FB_Dmg && (defender->GetLevel() <= FB_Level) &&
(ProcChance >= zone->random.Int(1, 1000))) {
+67 -20
View File
@@ -22,8 +22,11 @@
#include "doors.h"
#include "quest_parser_collection.h"
#include "lua_parser.h"
#include "../common/repositories/bot_inventories_repository.h"
#include "../common/repositories/bot_spell_settings_repository.h"
#include "../common/repositories/bot_starting_items_repository.h"
#include "../common/data_verification.h"
#include "../common/repositories/criteria/content_filter_criteria.h"
// This constructor is used during the bot create command
Bot::Bot(NPCType *npcTypeData, Client* botOwner) : NPC(npcTypeData, nullptr, glm::vec4(), Ground, false), rest_timer(1), ping_timer(1) {
@@ -465,6 +468,14 @@ Bot::~Bot() {
}
entity_list.RemoveBot(GetID());
if (GetGroup()) {
GetGroup()->MemberZoned(this);
}
if (GetRaid()) {
GetRaid()->MemberZoned(CastToClient());
}
}
void Bot::SetBotID(uint32 botID) {
@@ -643,7 +654,7 @@ NPCType *Bot::FillNPCTypeStruct(
n->current_hp = hp;
n->max_hp = hp;
n->size = size;
n->runspeed = 0.7f;
n->runspeed = 1.25f;
n->gender = gender;
n->race = botRace;
n->class_ = botClass;
@@ -2219,10 +2230,10 @@ void Bot::AI_Process()
// OK TO IDLE
// Ok to idle
if (TryIdleChecks(fm_distance)) {
if (TryNonCombatMovementChecks(bot_owner, follow_mob, Goal)) {
return;
}
if (TryNonCombatMovementChecks(bot_owner, follow_mob, Goal)) {
if (TryIdleChecks(fm_distance)) {
return;
}
if (TryBardMovementCasts()) {
@@ -2255,23 +2266,11 @@ bool Bot::TryNonCombatMovementChecks(Client* bot_owner, const Mob* follow_mob, g
if ((!bot_owner->GetBotPulling() || PULLING_BOT) && (destination_distance > GetFollowDistance())) {
if (!IsRooted()) {
if (rest_timer.Enabled()) {
rest_timer.Disable();
}
bool running = true;
if (destination_distance < GetFollowDistance() + BOT_FOLLOW_DISTANCE_WALK) {
running = false;
}
if (running) {
RunTo(Goal.x, Goal.y, Goal.z);
}
else {
WalkTo(Goal.x, Goal.y, Goal.z);
}
RunTo(Goal.x, Goal.y, Goal.z);
return true;
}
@@ -3337,7 +3336,8 @@ bool Bot::Spawn(Client* botCharacterOwner) {
if (auto raid = entity_list.GetRaidByBotName(GetName())) {
// Safety Check to confirm we have a valid raid
if (!raid->IsRaidMember(GetBotOwner()->GetName())) {
auto owner = GetBotOwner();
if (owner && !raid->IsRaidMember(owner->GetCleanName())) {
Bot::RemoveBotFromRaid(this);
} else {
SetRaidGrouped(true);
@@ -3347,7 +3347,8 @@ bool Bot::Spawn(Client* botCharacterOwner) {
}
else if (auto group = entity_list.GetGroupByMobName(GetName())) {
// Safety Check to confirm we have a valid group
if (!group->IsGroupMember(GetBotOwner()->GetName())) {
auto owner = GetBotOwner();
if (owner && !group->IsGroupMember(owner->GetCleanName())) {
Bot::RemoveBotFromGroup(this, group);
} else {
SetGrouped(true);
@@ -8568,6 +8569,7 @@ std::vector<Mob*> Bot::GetApplySpellList(
void Bot::ApplySpell(
int spell_id,
int duration,
int level,
ApplySpellType apply_type,
bool allow_pets,
bool is_raid_group_only
@@ -8575,13 +8577,14 @@ void Bot::ApplySpell(
const auto& l = GetApplySpellList(apply_type, allow_pets, is_raid_group_only);
for (const auto& m : l) {
m->ApplySpellBuff(spell_id, duration);
m->ApplySpellBuff(spell_id, duration, level);
}
}
void Bot::SetSpellDuration(
int spell_id,
int duration,
int level,
ApplySpellType apply_type,
bool allow_pets,
bool is_raid_group_only
@@ -8589,7 +8592,7 @@ void Bot::SetSpellDuration(
const auto& l = GetApplySpellList(apply_type, allow_pets, is_raid_group_only);
for (const auto& m : l) {
m->SetBuffDuration(spell_id, duration);
m->SetBuffDuration(spell_id, duration, level);
}
}
@@ -8729,4 +8732,48 @@ bool Bot::CheckSpawnConditions(Client* c) {
return true;
}
void Bot::AddBotStartingItems(uint16 race_id, uint8 class_id)
{
if (!IsPlayerRace(race_id) || !IsPlayerClass(class_id)) {
return;
}
const uint16 race_bitmask = GetPlayerRaceBit(race_id);
const uint16 class_bitmask = GetPlayerClassBit(class_id);
const auto& l = BotStartingItemsRepository::GetWhere(
content_db,
fmt::format(
"(races & {} OR races = 0) AND "
"(classes & {} OR classes = 0) {}",
race_bitmask,
class_bitmask,
ContentFilterCriteria::apply()
)
);
if (l.empty()) {
return;
}
std::vector<BotInventoriesRepository::BotInventories> v;
for (const auto& e : l) {
if (
CanClassEquipItem(e.item_id) &&
(CanRaceEquipItem(e.item_id) || RuleB(Bots, AllowBotEquipAnyRaceGear))
) {
auto i = BotInventoriesRepository::NewEntity();
i.bot_id = GetBotID();
i.slot_id = e.slot_id;
i.item_id = e.item_id;
i.inst_charges = e.item_charges;
v.emplace_back(i);
}
}
BotInventoriesRepository::InsertMany(content_db, v);
}
uint8 Bot::spell_casting_chances[SPELL_TYPE_COUNT][PLAYER_CLASS_COUNT][EQ::constants::STANCE_TYPE_COUNT][cntHSND] = { 0 };
+4 -3
View File
@@ -39,7 +39,6 @@
constexpr uint32 BOT_FOLLOW_DISTANCE_DEFAULT = 184; // as DSq value (~13.565 units)
constexpr uint32 BOT_FOLLOW_DISTANCE_DEFAULT_MAX = 2500; // as DSq value (50 units)
constexpr uint32 BOT_FOLLOW_DISTANCE_WALK = 1000; // as DSq value (~31.623 units)
constexpr uint32 BOT_KEEP_ALIVE_INTERVAL = 5000; // 5 seconds
@@ -461,6 +460,8 @@ public:
uint8 gender
);
void AddBotStartingItems(uint16 race_id, uint8 class_id);
// Static Bot Group Methods
static bool AddBotToGroup(Bot* bot, Group* group);
static bool RemoveBotFromGroup(Bot* bot, Group* group);
@@ -584,7 +585,7 @@ public:
// "Quest API" Methods
bool HasBotSpellEntry(uint16 spellid);
void ApplySpell(int spell_id, int duration = 0, ApplySpellType apply_type = ApplySpellType::Solo, bool allow_pets = false, bool is_raid_group_only = true);
void ApplySpell(int spell_id, int duration = 0, int level = -1, ApplySpellType apply_type = ApplySpellType::Solo, bool allow_pets = false, bool is_raid_group_only = true);
void BreakInvis();
void Escape();
void Fling(float value, float target_x, float target_y, float target_z, bool ignore_los = false, bool clip_through_walls = false, bool calculate_speed = false);
@@ -593,7 +594,7 @@ public:
int32 GetAugmentIDAt(int16 slot_id, uint8 augslot);
int32 GetRawItemAC();
void SendSpellAnim(uint16 targetid, uint16 spell_id);
void SetSpellDuration(int spell_id, int duration = 0, ApplySpellType apply_type = ApplySpellType::Solo, bool allow_pets = false, bool is_raid_group_only = true);
void SetSpellDuration(int spell_id, int duration = 0, int level = -1, ApplySpellType apply_type = ApplySpellType::Solo, bool allow_pets = false, bool is_raid_group_only = true);
// "SET" Class Methods
void SetBotSpellID(uint32 newSpellID);
+2
View File
@@ -9041,6 +9041,8 @@ uint32 helper_bot_create(Client *bot_owner, std::string bot_name, uint8 bot_clas
parse->EventPlayer(EVENT_BOT_CREATE, bot_owner, export_string, 0);
}
my_bot->AddBotStartingItems(bot_race, bot_class);
safe_delete(my_bot);
return bot_id;
+11 -20
View File
@@ -2211,25 +2211,13 @@ void Client::ReadBook(BookRequest_Struct *book) {
if (ClientVersion() >= EQ::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 EQ::ItemInstance *inst = nullptr;
if (read_from_slot <= EQ::invbag::GENERAL_BAGS_END)
{
inst = m_inv[read_from_slot];
}
if (book->invslot <= EQ::invbag::GENERAL_BAGS_END)
{
inst = m_inv[book->invslot];
}
if(inst)
out->type = inst->GetItem()->Book;
@@ -2240,6 +2228,9 @@ void Client::ReadBook(BookRequest_Struct *book) {
out->type = book->type;
}
out->invslot = book->invslot;
out->target_id = book->target_id;
out->can_cast = 0; // todo: implement
out->can_scribe = 0; // todo: implement
memcpy(out->booktext, booktxt2.c_str(), length);
@@ -11090,8 +11081,6 @@ void Client::SetTrackingID(uint32 entity_id)
}
TrackingID = entity_id;
MessageString(Chat::Skills, TRACKING_BEGIN, m->GetCleanName());
}
int Client::GetRecipeMadeCount(uint32 recipe_id)
@@ -11290,6 +11279,7 @@ std::vector<Mob*> Client::GetApplySpellList(
void Client::ApplySpell(
int spell_id,
int duration,
int level,
ApplySpellType apply_type,
bool allow_pets,
bool is_raid_group_only,
@@ -11298,13 +11288,14 @@ void Client::ApplySpell(
const auto& l = GetApplySpellList(apply_type, allow_pets, is_raid_group_only, allow_bots);
for (const auto& m : l) {
m->ApplySpellBuff(spell_id, duration);
m->ApplySpellBuff(spell_id, duration, level);
}
}
void Client::SetSpellDuration(
int spell_id,
int duration,
int level,
ApplySpellType apply_type,
bool allow_pets,
bool is_raid_group_only,
@@ -11313,7 +11304,7 @@ void Client::SetSpellDuration(
const auto& l = GetApplySpellList(apply_type, allow_pets, is_raid_group_only, allow_bots);
for (const auto& m : l) {
m->SetBuffDuration(spell_id, duration);
m->SetBuffDuration(spell_id, duration, level);
}
}
+6 -1
View File
@@ -905,6 +905,9 @@ public:
int GetAAPoints() { return m_pp.aapoints; }
int GetSpentAA() { return m_pp.aapoints_spent; }
uint32 GetRequiredAAExperience();
void AutoGrantAAPoints();
void GrantAllAAPoints(uint8 unlock_level = 0);
bool HasAlreadyPurchasedRank(AA::Rank* rank);
bool SendGMCommand(std::string message, bool ignore_status = false);
@@ -920,6 +923,7 @@ public:
void ApplySpell(
int spell_id,
int duration = 0,
int level = -1,
ApplySpellType apply_type = ApplySpellType::Solo,
bool allow_pets = false,
bool is_raid_group_only = true,
@@ -929,6 +933,7 @@ public:
void SetSpellDuration(
int spell_id,
int duration = 0,
int level = -1,
ApplySpellType apply_type = ApplySpellType::Solo,
bool allow_pets = false,
bool is_raid_group_only = true,
@@ -1662,7 +1667,7 @@ protected:
bool client_data_loaded;
void FinishAlternateAdvancementPurchase(AA::Rank *rank, bool ignore_cost);
void FinishAlternateAdvancementPurchase(AA::Rank *rank, bool ignore_cost, bool send_message_and_save);
Mob* bind_sight_target;
+30 -3
View File
@@ -18,6 +18,8 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#include "../common/global_define.h"
#include "../common/eqemu_logsys.h"
#include "../common/opcodemgr.h"
#include "../common/raid.h"
#include <iomanip>
#include <iostream>
#include <math.h>
@@ -145,6 +147,7 @@ void MapOpcodes()
ConnectedOpcodes[OP_Bind_Wound] = &Client::Handle_OP_Bind_Wound;
ConnectedOpcodes[OP_BlockedBuffs] = &Client::Handle_OP_BlockedBuffs;
ConnectedOpcodes[OP_BoardBoat] = &Client::Handle_OP_BoardBoat;
ConnectedOpcodes[OP_BookButton] = &Client::Handle_OP_BookButton;
ConnectedOpcodes[OP_Buff] = &Client::Handle_OP_Buff;
ConnectedOpcodes[OP_BuffRemoveRequest] = &Client::Handle_OP_BuffRemoveRequest;
ConnectedOpcodes[OP_Bug] = &Client::Handle_OP_Bug;
@@ -918,6 +921,8 @@ void Client::CompleteConnect()
RecordStats();
AutoGrantAAPoints();
// enforce some rules..
if (!CanEnterZone()) {
LogInfo("Kicking character [{}] from zone, not allowed here (missing requirements)", GetCleanName());
@@ -4128,6 +4133,28 @@ void Client::Handle_OP_BoardBoat(const EQApplicationPacket *app)
return;
}
void Client::Handle_OP_BookButton(const EQApplicationPacket* app)
{
if (app->size != sizeof(BookButton_Struct))
{
LogError("Size mismatch in OP_BookButton. expected [{}] got [{}]", sizeof(BookButton_Struct), app->size);
DumpPacket(app);
return;
}
BookButton_Struct* book = reinterpret_cast<BookButton_Struct*>(app->pBuffer);
const EQ::ItemInstance* const inst = GetInv().GetItem(book->invslot);
if (inst && inst->GetItem()->Book)
{
// todo: if scribe book learn recipes and delete book from inventory
// todo: if cast book use its spell on target and delete book from inventory (unless reusable?)
}
EQApplicationPacket outapp(OP_FinishWindow, 0);
QueuePacket(&outapp);
}
void Client::Handle_OP_Buff(const EQApplicationPacket *app)
{
/*
@@ -12553,8 +12580,8 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket* app)
if (!raid) {
break;
}
raid->SaveRaidNote(raid_command_packet->leader_name, raid_command_packet->note);
RaidNote_Struct* note = (RaidNote_Struct*)app->pBuffer;
raid->SaveRaidNote(raid_command_packet->leader_name, note->note);
raid->SendRaidNotesToWorld();
break;
}
@@ -14398,7 +14425,7 @@ void Client::Handle_OP_Split(const EQApplicationPacket *app)
if (raid)
raid->SplitMoney(raid->GetGroup(this), split->copper, split->silver, split->gold, split->platinum);
else if (group)
group->SplitMoney(split->copper, split->silver, split->gold, split->platinum);
group->SplitMoney(split->copper, split->silver, split->gold, split->platinum, this);
return;
+1
View File
@@ -56,6 +56,7 @@
void Handle_OP_Bind_Wound(const EQApplicationPacket *app);
void Handle_OP_BlockedBuffs(const EQApplicationPacket *app);
void Handle_OP_BoardBoat(const EQApplicationPacket *app);
void Handle_OP_BookButton(const EQApplicationPacket *app);
void Handle_OP_Buff(const EQApplicationPacket *app);
void Handle_OP_BuffRemoveRequest(const EQApplicationPacket *app);
void Handle_OP_Bug(const EQApplicationPacket *app);
+14 -12
View File
@@ -137,6 +137,7 @@ int command_init(void)
command_add("givemoney", "[Platinum] [Gold] [Silver] [Copper] - Gives specified amount of money to you or your player target", AccountStatus::GMMgmt, command_givemoney) ||
command_add("gmzone", "[Zone ID|Zone Short Name] [Version] [Instance Identifier] - Zones to a private GM instance (Version defaults to 0 and Instance Identifier defaults to 'gmzone' if not used)", AccountStatus::GMAdmin, command_gmzone) ||
command_add("goto", "[playername] or [x y z] [h] - Teleport to the provided coordinates or to your target", AccountStatus::Steward, command_goto) ||
command_add("grantaa", "[level] - Grants a player all available AA points up the specified level, all AAs are granted if no level is specified.", AccountStatus::GMMgmt, command_grantaa) ||
command_add("grid", "[add/delete] [grid_num] [wandertype] [pausetype] - Create/delete a wandering grid", AccountStatus::GMAreas, command_grid) ||
command_add("guild", "Guild manipulation commands. Use argument help for more info.", AccountStatus::Steward, command_guild) ||
command_add("help", "[Search Criteria] - List available commands and their description, specify partial command as argument to search", AccountStatus::Player, command_help) ||
@@ -436,13 +437,13 @@ int command_realdispatch(Client *c, std::string message, bool ignore_status)
{
Seperator sep(message.c_str(), ' ', 10, 100, true); // "three word argument" should be considered 1 arg
std::string cstr(sep.arg[0] + 1);
std::string command(sep.arg[0] + 1);
if (commandlist.count(cstr) != 1) {
if (commandlist.count(command) != 1) {
return -2;
}
auto cur = commandlist[cstr];
const CommandRecord* current_command = commandlist[command];
bool is_subcommand = false;
bool can_use_subcommand = false;
@@ -450,11 +451,11 @@ int command_realdispatch(Client *c, std::string message, bool ignore_status)
const auto arguments = sep.argnum;
if (arguments >= 2) {
if (arguments) {
const std::string& sub_command = sep.arg[1];
for (const auto &e : command_subsettings) {
if (e.sub_command == sub_command) {
if (e.parent_command == command && e.sub_command == sub_command) {
can_use_subcommand = c->Admin() >= static_cast<int16>(e.access_level);
is_subcommand = true;
found_subcommand_setting = true;
@@ -464,7 +465,7 @@ int command_realdispatch(Client *c, std::string message, bool ignore_status)
if (!found_subcommand_setting) {
for (const auto &e: command_subsettings) {
if (e.sub_command == sub_command) {
if (e.parent_command == command && e.sub_command == sub_command) {
can_use_subcommand = c->Admin() >= static_cast<int16>(e.access_level);
is_subcommand = true;
break;
@@ -474,7 +475,7 @@ int command_realdispatch(Client *c, std::string message, bool ignore_status)
}
if (!ignore_status) {
if (!is_subcommand && c->Admin() < cur->admin) {
if (!is_subcommand && c->Admin() < current_command->admin) {
c->Message(Chat::White, "Your status is not high enough to use this command.");
return -1;
}
@@ -496,7 +497,7 @@ int command_realdispatch(Client *c, std::string message, bool ignore_status)
QServ->PlayerLogEvent(Player_Log_Issued_Commands, c->CharacterID(), event_desc);
}
if (cur->admin >= COMMANDS_LOGGING_MIN_STATUS) {
if (current_command->admin >= COMMANDS_LOGGING_MIN_STATUS) {
LogCommands(
"[{}] ([{}]) used command: [{}] (target=[{}])",
c->GetName(),
@@ -506,8 +507,8 @@ int command_realdispatch(Client *c, std::string message, bool ignore_status)
);
}
if (!cur->function) {
LogError("Command [{}] has a null function", cstr);
if (!current_command->function) {
LogError("Command [{}] has a null function", command);
return -1;
}
@@ -524,7 +525,7 @@ int command_realdispatch(Client *c, std::string message, bool ignore_status)
RecordPlayerEventLogWithClient(c, PlayerEvent::GM_COMMAND, e);
}
cur->function(c, &sep); // Dispatch C++ Command
current_command->function(c, &sep); // Dispatch C++ Command
return 0;
}
@@ -664,7 +665,7 @@ void command_hotfix(Client *c, const Seperator *sep)
hotfix_command = fmt::format("\"{}\" -hotfix={}", shared_memory_path, hotfix_name);
}
else {
hotfix_command = fmt::format("\"{}\"", shared_memory_path, hotfix_name);
hotfix_command = fmt::format("\"{}\"", shared_memory_path);
}
LogInfo("Running hotfix command [{}]", hotfix_command);
@@ -826,6 +827,7 @@ void command_bot(Client *c, const Seperator *sep)
#include "gm_commands/givemoney.cpp"
#include "gm_commands/gmzone.cpp"
#include "gm_commands/goto.cpp"
#include "gm_commands/grantaa.cpp"
#include "gm_commands/grid.cpp"
#include "gm_commands/guild.cpp"
#include "gm_commands/hp.cpp"
+1
View File
@@ -87,6 +87,7 @@ void command_giveitem(Client *c, const Seperator *sep);
void command_givemoney(Client *c, const Seperator *sep);
void command_gmzone(Client *c, const Seperator *sep);
void command_goto(Client *c, const Seperator *sep);
void command_grantaa(Client* c, const Seperator* sep);
void command_grid(Client *c, const Seperator *sep);
void command_guild(Client *c, const Seperator *sep);
void command_help(Client *c, const Seperator *sep);
+2
View File
@@ -207,6 +207,8 @@ enum {
MODIFY_AVOID_DAMAGE = 51, //Modify by percent the NPCs chance to riposte, block, parry or dodge individually, or for all skills
IMMUNE_FADING_MEMORIES = 52,
IMMUNE_OPEN = 53,
IMMUNE_ASSASSINATE = 54,
IMMUNE_HEADSHOT = 55,
MAX_SPECIAL_ATTACK
};
+104 -17
View File
@@ -1560,6 +1560,7 @@ void PerlembParser::ExportEventVariables(
if (extra_pointers && extra_pointers->size() == 1) {
ExportVar(package_name.c_str(), "target", "Mob", std::any_cast<Mob*>(extra_pointers->at(0)));
}
break;
}
@@ -1606,9 +1607,11 @@ void PerlembParser::ExportEventVariables(
case EVENT_CLICK_DOOR: {
ExportVar(package_name.c_str(), "doorid", data);
ExportVar(package_name.c_str(), "version", zone->GetInstanceVersion());
if (extra_pointers && extra_pointers->size() == 1) {
ExportVar(package_name.c_str(), "door", "Doors", std::any_cast<Doors*>(extra_pointers->at(0)));
}
break;
}
@@ -1649,6 +1652,16 @@ void PerlembParser::ExportEventVariables(
ExportVar(package_name.c_str(), "spell_id", sep.arg[0]);
ExportVar(package_name.c_str(), "caster_id", sep.arg[1]);
ExportVar(package_name.c_str(), "caster_level", sep.arg[2]);
ExportVar(package_name.c_str(), "target_id", sep.arg[3]);
if (extra_pointers && extra_pointers->size() == 1) {
ExportVar(package_name.c_str(), "target", "Mob", std::any_cast<Mob*>(extra_pointers->at(0)));
}
if (IsValidSpell(Strings::ToUnsignedInt(sep.arg[0]))) {
ExportVar(package_name.c_str(), "spell", "Spell", (void*)&spells[Strings::ToUnsignedInt(sep.arg[0])]);
}
break;
}
@@ -1683,9 +1696,11 @@ void PerlembParser::ExportEventVariables(
case EVENT_PLAYER_PICKUP: {
ExportVar(package_name.c_str(), "picked_up_id", data);
ExportVar(package_name.c_str(), "picked_up_entity_id", extradata);
if (extra_pointers && extra_pointers->size() == 1) {
ExportVar(package_name.c_str(), "item", "QuestItem", std::any_cast<EQ::ItemInstance*>(extra_pointers->at(0)));
}
break;
}
@@ -1731,12 +1746,18 @@ void PerlembParser::ExportEventVariables(
ExportVar(package_name.c_str(), "itemname", item_inst->GetItem()->Name);
ExportVar(package_name.c_str(), "slotid", extradata);
ExportVar(package_name.c_str(), "spell_id", item_inst->GetItem()->Click.Effect);
if (IsValidSpell(item_inst->GetItem()->Click.Effect)) {
ExportVar(package_name.c_str(), "spell", "Spell", (void*)&spells[item_inst->GetItem()->Click.Effect]);
}
break;
}
case EVENT_ITEM_CLICK_CAST_CLIENT:
case EVENT_ITEM_CLICK_CLIENT: {
ExportVar(package_name.c_str(), "slot_id", data);
if (extra_pointers && extra_pointers->size() == 1) {
auto* item = std::any_cast<EQ::ItemInstance*>(extra_pointers->at(0));
if (item) {
@@ -1744,8 +1765,13 @@ void PerlembParser::ExportEventVariables(
ExportVar(package_name.c_str(), "item_name", item->GetItem()->Name);
ExportVar(package_name.c_str(), "spell_id", item->GetItem()->Click.Effect);
ExportVar(package_name.c_str(), "item", "QuestItem", item);
if (IsValidSpell(item->GetItem()->Click.Effect)) {
ExportVar(package_name.c_str(), "spell", "Spell", (void*)&spells[item->GetItem()->Click.Effect]);
}
}
}
break;
}
@@ -1776,6 +1802,11 @@ void PerlembParser::ExportEventVariables(
ExportVar(package_name.c_str(), "tics_remaining", sep.arg[1]);
ExportVar(package_name.c_str(), "caster_level", sep.arg[2]);
ExportVar(package_name.c_str(), "buff_slot", sep.arg[3]);
if (IsValidSpell(objid)) {
ExportVar(package_name.c_str(), "spell", "Spell", (void*)&spells[objid]);
}
break;
}
@@ -1789,34 +1820,42 @@ void PerlembParser::ExportEventVariables(
case EVENT_FORAGE_SUCCESS: {
ExportVar(package_name.c_str(), "foraged_item", extradata);
if (extra_pointers && extra_pointers->size() == 1) {
ExportVar(package_name.c_str(), "item", "QuestItem", std::any_cast<EQ::ItemInstance*>(extra_pointers->at(0)));
}
break;
}
case EVENT_FISH_SUCCESS: {
ExportVar(package_name.c_str(), "fished_item", extradata);
if (extra_pointers && extra_pointers->size() == 1) {
ExportVar(package_name.c_str(), "item", "QuestItem", std::any_cast<EQ::ItemInstance*>(extra_pointers->at(0)));
}
break;
}
case EVENT_CLICK_OBJECT: {
ExportVar(package_name.c_str(), "objectid", data);
ExportVar(package_name.c_str(), "clicker_id", extradata);
if (extra_pointers && extra_pointers->size() == 1) {
ExportVar(package_name.c_str(), "object", "Object", std::any_cast<Object*>(extra_pointers->at(0)));
}
break;
}
case EVENT_DISCOVER_ITEM: {
ExportVar(package_name.c_str(), "itemid", extradata);
if (extra_pointers && extra_pointers->size() == 1) {
ExportVar(package_name.c_str(), "item", "QuestItem", std::any_cast<EQ::ItemInstance*>(extra_pointers->at(0)));
}
break;
}
@@ -1836,27 +1875,20 @@ void PerlembParser::ExportEventVariables(
break;
}
case EVENT_DEATH_ZONE:
case EVENT_DEATH:
case EVENT_DEATH_COMPLETE: {
case EVENT_DEATH: {
Seperator sep(data);
ExportVar(package_name.c_str(), "killer_id", sep.arg[0]);
ExportVar(package_name.c_str(), "killer_damage", sep.arg[1]);
ExportVar(package_name.c_str(), "killer_spell", sep.arg[2]);
ExportVar(package_name.c_str(), "killer_skill", sep.arg[3]);
if (extra_pointers && extra_pointers->size() >= 1)
{
Corpse* corpse = std::any_cast<Corpse*>(extra_pointers->at(0));
if (corpse)
{
ExportVar(package_name.c_str(), "killed_corpse_id", corpse->GetID());
}
if (IsValidSpell(Strings::ToUnsignedInt(sep.arg[2]))) {
ExportVar(package_name.c_str(), "spell", "Spell", (void*)&spells[Strings::ToUnsignedInt(sep.arg[2])]);
}
if (extra_pointers && extra_pointers->size() >= 2)
{
NPC* killed = std::any_cast<NPC*>(extra_pointers->at(1));
if (killed)
{
if (extra_pointers && extra_pointers->size() == 1) {
Mob* killed = std::any_cast<Mob*>(extra_pointers->at(0));
if (killed) {
ExportVar(package_name.c_str(), "killed_entity_id", killed->GetID());
ExportVar(package_name.c_str(), "killed_bot_id", killed->IsBot() ? killed->CastToBot()->GetBotID() : 0);
ExportVar(package_name.c_str(), "killed_npc_id", killed->IsNPC() ? killed->GetNPCTypeID() : 0);
@@ -1866,6 +1898,42 @@ void PerlembParser::ExportEventVariables(
ExportVar(package_name.c_str(), "killed_h", killed->GetHeading());
}
}
break;
}
case EVENT_DEATH_ZONE:
case EVENT_DEATH_COMPLETE: {
Seperator sep(data);
ExportVar(package_name.c_str(), "killer_id", sep.arg[0]);
ExportVar(package_name.c_str(), "killer_damage", sep.arg[1]);
ExportVar(package_name.c_str(), "killer_spell", sep.arg[2]);
ExportVar(package_name.c_str(), "killer_skill", sep.arg[3]);
if (IsValidSpell(Strings::ToUnsignedInt(sep.arg[2]))) {
ExportVar(package_name.c_str(), "spell", "Spell", (void*)&spells[Strings::ToUnsignedInt(sep.arg[2])]);
}
if (extra_pointers && extra_pointers->size() >= 1) {
Corpse* corpse = std::any_cast<Corpse*>(extra_pointers->at(0));
if (corpse) {
ExportVar(package_name.c_str(), "killed_corpse_id", corpse->GetID());
}
}
if (extra_pointers && extra_pointers->size() >= 2) {
NPC* killed = std::any_cast<NPC*>(extra_pointers->at(1));
if (killed) {
ExportVar(package_name.c_str(), "killed_entity_id", killed->GetID());
ExportVar(package_name.c_str(), "killed_bot_id", killed->IsBot() ? killed->CastToBot()->GetBotID() : 0);
ExportVar(package_name.c_str(), "killed_npc_id", killed->IsNPC() ? killed->GetNPCTypeID() : 0);
ExportVar(package_name.c_str(), "killed_x", killed->GetX());
ExportVar(package_name.c_str(), "killed_y", killed->GetY());
ExportVar(package_name.c_str(), "killed_z", killed->GetZ());
ExportVar(package_name.c_str(), "killed_h", killed->GetHeading());
}
}
break;
}
@@ -1888,6 +1956,7 @@ void PerlembParser::ExportEventVariables(
ExportVar(package_name.c_str(), "slot_id", extradata);
ExportVar(package_name.c_str(), "item", "QuestItem", item_instance);
}
break;
}
@@ -1915,8 +1984,7 @@ void PerlembParser::ExportEventVariables(
std::string tradeskill_id = "-1";
if (strcmp(sep.arg[0], "check_zone") == 0) {
zone_id = sep.arg[1];
}
else if (strcmp(sep.arg[0], "check_tradeskill") == 0) {
} else if (strcmp(sep.arg[0], "check_tradeskill") == 0) {
tradeskill_id = sep.arg[1];
}
@@ -1945,17 +2013,21 @@ void PerlembParser::ExportEventVariables(
case EVENT_CONSIDER: {
ExportVar(package_name.c_str(), "entity_id", Strings::ToInt(data));
if (extra_pointers && extra_pointers->size() == 1) {
ExportVar(package_name.c_str(), "target", "Mob", std::any_cast<Mob*>(extra_pointers->at(0)));
}
break;
}
case EVENT_CONSIDER_CORPSE: {
ExportVar(package_name.c_str(), "corpse_entity_id", Strings::ToInt(data));
if (extra_pointers && extra_pointers->size() == 1) {
ExportVar(package_name.c_str(), "corpse", "Corpse", std::any_cast<Corpse*>(extra_pointers->at(0)));
}
break;
}
@@ -1970,9 +2042,11 @@ void PerlembParser::ExportEventVariables(
ExportVar(package_name.c_str(), "item_id", extradata);
ExportVar(package_name.c_str(), "item_quantity", sep.arg[0]);
ExportVar(package_name.c_str(), "slot_id", sep.arg[1]);
if (extra_pointers && extra_pointers->size() == 1) {
ExportVar(package_name.c_str(), "item", "QuestItem", std::any_cast<EQ::ItemInstance*>(extra_pointers->at(0)));
}
break;
}
@@ -1982,9 +2056,11 @@ void PerlembParser::ExportEventVariables(
ExportVar(package_name.c_str(), "item_id", extradata);
ExportVar(package_name.c_str(), "item_quantity", sep.arg[0]);
ExportVar(package_name.c_str(), "slot_id", sep.arg[1]);
if (extra_pointers && extra_pointers->size() == 1) {
ExportVar(package_name.c_str(), "item", "QuestItem", std::any_cast<EQ::ItemInstance*>(extra_pointers->at(0)));
}
break;
}
@@ -2090,9 +2166,11 @@ void PerlembParser::ExportEventVariables(
case EVENT_INSPECT: {
ExportVar(package_name.c_str(), "target_id", extradata);
if (extra_pointers && extra_pointers->size() == 1) {
ExportVar(package_name.c_str(), "target", "Mob", std::any_cast<Mob*>(extra_pointers->at(0)));
}
break;
}
@@ -2117,6 +2195,7 @@ void PerlembParser::ExportEventVariables(
ExportVar(package_name.c_str(), "area_id", *std::any_cast<int*>(extra_pointers->at(0)));
ExportVar(package_name.c_str(), "area_type", *std::any_cast<int*>(extra_pointers->at(1)));
}
break;
}
@@ -2156,6 +2235,11 @@ void PerlembParser::ExportEventVariables(
ExportVar(package_name.c_str(), "buff_slot", sep.arg[6]);
ExportVar(package_name.c_str(), "is_buff_tic", sep.arg[7]);
ExportVar(package_name.c_str(), "special_attack", sep.arg[8]);
if (IsValidSpell(Strings::ToUnsignedInt(sep.arg[2]))) {
ExportVar(package_name.c_str(), "spell", "Spell", (void*)&spells[Strings::ToUnsignedInt(sep.arg[2])]);
}
break;
}
@@ -2167,6 +2251,7 @@ void PerlembParser::ExportEventVariables(
ExportVar(package_name.c_str(), "quantity", inst->IsStackable() ? inst->GetCharges() : 1);
ExportVar(package_name.c_str(), "item", "QuestItem", inst);
}
break;
}
@@ -2177,9 +2262,11 @@ void PerlembParser::ExportEventVariables(
Seperator sep(data);
ExportVar(package_name.c_str(), "slot_id", sep.arg[0]);
ExportVar(package_name.c_str(), "spell_id", sep.arg[1]);
if (IsValidSpell(Strings::ToUnsignedInt(sep.arg[1]))) {
ExportVar(package_name.c_str(), "spell", "Spell", (void*)&spells[Strings::ToUnsignedInt(sep.arg[1])]);
}
break;
}
+483 -49
View File
@@ -3481,78 +3481,488 @@ void Perl__crosszonemessageplayerbyname(const char* client_name, uint32 type, co
quest_manager.CrossZoneMessage(CZUpdateType_ClientName, update_identifier, type, message, client_name);
}
void Perl__crosszonemoveplayerbycharid(int character_id, const char* zone_short_name)
void Perl__crosszonemoveplayerbycharid(uint32 character_id, std::string zone_short_name)
{
uint16 instance_id = 0;
quest_manager.CrossZoneMove(CZUpdateType_Character, CZMoveUpdateSubtype_MoveZone, character_id, zone_short_name, instance_id);
quest_manager.CrossZoneMove(
CZMove_Struct{
.update_identifier = character_id,
.update_type = CZUpdateType_Character,
.update_subtype = CZMoveUpdateSubtype_MoveZone,
.zone_short_name = zone_short_name,
}
);
}
void Perl__crosszonemoveplayerbygroupid(int group_id, const char* zone_short_name)
void Perl__crosszonemoveplayerbycharid(uint32 character_id, std::string zone_short_name, float x, float y, float z)
{
uint16 instance_id = 0;
quest_manager.CrossZoneMove(CZUpdateType_Group, CZMoveUpdateSubtype_MoveZone, group_id, zone_short_name, instance_id);
quest_manager.CrossZoneMove(
CZMove_Struct{
.coordinates = glm::vec4(x, y, z, 0.0f),
.update_identifier = character_id,
.update_type = CZUpdateType_Character,
.update_subtype = CZMoveUpdateSubtype_MoveZone,
.zone_short_name = zone_short_name,
}
);
}
void Perl__crosszonemoveplayerbyraidid(int raid_id, const char* zone_short_name)
void Perl__crosszonemoveplayerbycharid(
uint32 character_id,
std::string zone_short_name,
float x,
float y,
float z,
float heading
)
{
uint16 instance_id = 0;
quest_manager.CrossZoneMove(CZUpdateType_Raid, CZMoveUpdateSubtype_MoveZone, raid_id, zone_short_name, instance_id);
quest_manager.CrossZoneMove(
CZMove_Struct{
.coordinates = glm::vec4(x, y, z, heading),
.update_identifier = character_id,
.update_type = CZUpdateType_Character,
.update_subtype = CZMoveUpdateSubtype_MoveZone,
.zone_short_name = zone_short_name,
}
);
}
void Perl__crosszonemoveplayerbyguildid(int guild_id, const char* zone_short_name)
void Perl__crosszonemoveplayerbygroupid(uint32 group_id, std::string zone_short_name)
{
uint16 instance_id = 0;
quest_manager.CrossZoneMove(CZUpdateType_Guild, CZMoveUpdateSubtype_MoveZone, guild_id, zone_short_name, instance_id);
quest_manager.CrossZoneMove(
CZMove_Struct{
.update_identifier = group_id,
.update_type = CZUpdateType_Group,
.update_subtype = CZMoveUpdateSubtype_MoveZone,
.zone_short_name = zone_short_name,
}
);
}
void Perl__crosszonemoveplayerbyexpeditionid(uint32 expedition_id, const char* zone_short_name)
void Perl__crosszonemoveplayerbygroupid(uint32 group_id, std::string zone_short_name, float x, float y, float z)
{
uint16 instance_id = 0;
quest_manager.CrossZoneMove(CZUpdateType_Expedition, CZMoveUpdateSubtype_MoveZone, expedition_id, zone_short_name, instance_id);
quest_manager.CrossZoneMove(
CZMove_Struct{
.coordinates = glm::vec4(x, y, z, 0.0f),
.update_identifier = group_id,
.update_type = CZUpdateType_Group,
.update_subtype = CZMoveUpdateSubtype_MoveZone,
.zone_short_name = zone_short_name,
}
);
}
void Perl__crosszonemoveplayerbyname(const char* client_name, const char* zone_short_name)
void Perl__crosszonemoveplayerbygroupid(
uint32 group_id,
std::string zone_short_name,
float x,
float y,
float z,
float heading
)
{
int update_identifier = 0;
uint16 instance_id = 0;
quest_manager.CrossZoneMove(CZUpdateType_ClientName, CZMoveUpdateSubtype_MoveZone, update_identifier, zone_short_name, instance_id, client_name);
quest_manager.CrossZoneMove(
CZMove_Struct{
.coordinates = glm::vec4(x, y, z, heading),
.update_identifier = group_id,
.update_type = CZUpdateType_Group,
.update_subtype = CZMoveUpdateSubtype_MoveZone,
.zone_short_name = zone_short_name,
}
);
}
void Perl__crosszonemoveinstancebycharid(int character_id, uint16 instance_id)
void Perl__crosszonemoveplayerbyraidid(uint32 raid_id, std::string zone_short_name)
{
const char* zone_short_name = "";
quest_manager.CrossZoneMove(CZUpdateType_Character, CZMoveUpdateSubtype_MoveZoneInstance, character_id, zone_short_name, instance_id);
quest_manager.CrossZoneMove(
CZMove_Struct{
.update_identifier = raid_id,
.update_type = CZUpdateType_Raid,
.update_subtype = CZMoveUpdateSubtype_MoveZone,
.zone_short_name = zone_short_name,
}
);
}
void Perl__crosszonemoveinstancebygroupid(int group_id, uint16 instance_id)
void Perl__crosszonemoveplayerbyraidid(uint32 raid_id, std::string zone_short_name, float x, float y, float z)
{
const char* zone_short_name = "";
quest_manager.CrossZoneMove(CZUpdateType_Group, CZMoveUpdateSubtype_MoveZoneInstance, group_id, zone_short_name, instance_id);
quest_manager.CrossZoneMove(
CZMove_Struct{
.coordinates = glm::vec4(x, y, z, 0.0f),
.update_identifier = raid_id,
.update_type = CZUpdateType_Raid,
.update_subtype = CZMoveUpdateSubtype_MoveZone,
.zone_short_name = zone_short_name,
}
);
}
void Perl__crosszonemoveinstancebyraidid(int raid_id, uint16 instance_id)
void Perl__crosszonemoveplayerbyraidid(uint32 raid_id, std::string zone_short_name, float x, float y, float z, float heading)
{
const char* zone_short_name = "";
quest_manager.CrossZoneMove(CZUpdateType_Raid, CZMoveUpdateSubtype_MoveZoneInstance, raid_id, zone_short_name, instance_id);
quest_manager.CrossZoneMove(
CZMove_Struct{
.coordinates = glm::vec4(x, y, z, heading),
.update_identifier = raid_id,
.update_type = CZUpdateType_Raid,
.update_subtype = CZMoveUpdateSubtype_MoveZone,
.zone_short_name = zone_short_name,
}
);
}
void Perl__crosszonemoveinstancebyguildid(int guild_id, uint16 instance_id)
void Perl__crosszonemoveplayerbyguildid(uint32 guild_id, std::string zone_short_name)
{
const char* zone_short_name = "";
quest_manager.CrossZoneMove(CZUpdateType_Guild, CZMoveUpdateSubtype_MoveZoneInstance, guild_id, zone_short_name, instance_id);
quest_manager.CrossZoneMove(
CZMove_Struct{
.update_identifier = guild_id,
.update_type = CZUpdateType_Guild,
.update_subtype = CZMoveUpdateSubtype_MoveZone,
.zone_short_name = zone_short_name,
}
);
}
void Perl__crosszonemoveplayerbyguildid(uint32 guild_id, std::string zone_short_name, float x, float y, float z)
{
quest_manager.CrossZoneMove(
CZMove_Struct{
.coordinates = glm::vec4(x, y, z, 0.0f),
.update_identifier = guild_id,
.update_type = CZUpdateType_Guild,
.update_subtype = CZMoveUpdateSubtype_MoveZone,
.zone_short_name = zone_short_name,
}
);
}
void Perl__crosszonemoveplayerbyguildid(
uint32 guild_id,
std::string zone_short_name,
float x,
float y,
float z,
float heading
)
{
quest_manager.CrossZoneMove(
CZMove_Struct{
.coordinates = glm::vec4(x, y, z, heading),
.update_identifier = guild_id,
.update_type = CZUpdateType_Guild,
.update_subtype = CZMoveUpdateSubtype_MoveZone,
.zone_short_name = zone_short_name,
}
);
}
void Perl__crosszonemoveplayerbyexpeditionid(uint32 expedition_id, std::string zone_short_name)
{
quest_manager.CrossZoneMove(
CZMove_Struct{
.update_identifier = expedition_id,
.update_type = CZUpdateType_Expedition,
.update_subtype = CZMoveUpdateSubtype_MoveZone,
.zone_short_name = zone_short_name,
}
);
}
void Perl__crosszonemoveplayerbyexpeditionid(uint32 expedition_id, std::string zone_short_name, float x, float y, float z)
{
quest_manager.CrossZoneMove(
CZMove_Struct{
.coordinates = glm::vec4(x, y, z, 0.0f),
.update_identifier = expedition_id,
.update_type = CZUpdateType_Expedition,
.update_subtype = CZMoveUpdateSubtype_MoveZone,
.zone_short_name = zone_short_name,
}
);
}
void Perl__crosszonemoveplayerbyexpeditionid(
uint32 expedition_id,
std::string zone_short_name,
float x,
float y,
float z,
float heading
)
{
quest_manager.CrossZoneMove(
CZMove_Struct{
.coordinates = glm::vec4(x, y, z, heading),
.update_identifier = expedition_id,
.update_type = CZUpdateType_Expedition,
.update_subtype = CZMoveUpdateSubtype_MoveZone,
.zone_short_name = zone_short_name,
}
);
}
void Perl__crosszonemoveplayerbyname(std::string client_name, std::string zone_short_name)
{
quest_manager.CrossZoneMove(
CZMove_Struct{
.client_name = client_name,
.update_type = CZUpdateType_ClientName,
.update_subtype = CZMoveUpdateSubtype_MoveZone,
.zone_short_name = zone_short_name,
}
);
}
void Perl__crosszonemoveplayerbyname(std::string client_name, std::string zone_short_name, float x, float y, float z)
{
quest_manager.CrossZoneMove(
CZMove_Struct{
.client_name = client_name,
.coordinates = glm::vec4(x, y, z, 0.0f),
.update_type = CZUpdateType_ClientName,
.update_subtype = CZMoveUpdateSubtype_MoveZone,
.zone_short_name = zone_short_name,
}
);
}
void Perl__crosszonemoveplayerbyname(std::string client_name, std::string zone_short_name, float x, float y, float z, float heading)
{
quest_manager.CrossZoneMove(
CZMove_Struct{
.client_name = client_name,
.coordinates = glm::vec4(x, y, z, heading),
.update_type = CZUpdateType_ClientName,
.update_subtype = CZMoveUpdateSubtype_MoveZone,
.zone_short_name = zone_short_name,
}
);
}
void Perl__crosszonemoveinstancebycharid(uint32 character_id, uint16 instance_id)
{
quest_manager.CrossZoneMove(
CZMove_Struct{
.instance_id = instance_id,
.update_identifier = character_id,
.update_type = CZUpdateType_Character,
.update_subtype = CZMoveUpdateSubtype_MoveZoneInstance,
}
);
}
void Perl__crosszonemoveinstancebycharid(uint32 character_id, uint16 instance_id, float x, float y, float z)
{
quest_manager.CrossZoneMove(
CZMove_Struct{
.coordinates = glm::vec4(x, y, z, 0.0f),
.instance_id = instance_id,
.update_identifier = character_id,
.update_type = CZUpdateType_Character,
.update_subtype = CZMoveUpdateSubtype_MoveZoneInstance,
}
);
}
void Perl__crosszonemoveinstancebycharid(uint32 character_id, uint16 instance_id, float x, float y, float z, float heading)
{
quest_manager.CrossZoneMove(
CZMove_Struct{
.coordinates = glm::vec4(x, y, z, heading),
.instance_id = instance_id,
.update_identifier = character_id,
.update_type = CZUpdateType_Character,
.update_subtype = CZMoveUpdateSubtype_MoveZoneInstance,
}
);
}
void Perl__crosszonemoveinstancebygroupid(uint32 group_id, uint16 instance_id)
{
quest_manager.CrossZoneMove(
CZMove_Struct{
.instance_id = instance_id,
.update_identifier = group_id,
.update_type = CZUpdateType_Group,
.update_subtype = CZMoveUpdateSubtype_MoveZoneInstance,
}
);
}
void Perl__crosszonemoveinstancebygroupid(uint32 group_id, uint16 instance_id, float x, float y, float z)
{
quest_manager.CrossZoneMove(
CZMove_Struct{
.coordinates = glm::vec4(x, y, z, 0.0f),
.instance_id = instance_id,
.update_identifier = group_id,
.update_type = CZUpdateType_Group,
.update_subtype = CZMoveUpdateSubtype_MoveZoneInstance,
}
);
}
void Perl__crosszonemoveinstancebygroupid(uint32 group_id, uint16 instance_id, float x, float y, float z, float heading)
{
quest_manager.CrossZoneMove(
CZMove_Struct{
.coordinates = glm::vec4(x, y, z, heading),
.instance_id = instance_id,
.update_identifier = group_id,
.update_type = CZUpdateType_Group,
.update_subtype = CZMoveUpdateSubtype_MoveZoneInstance,
}
);
}
void Perl__crosszonemoveinstancebyraidid(uint32 raid_id, uint16 instance_id)
{
quest_manager.CrossZoneMove(
CZMove_Struct{
.instance_id = instance_id,
.update_identifier = raid_id,
.update_type = CZUpdateType_Raid,
.update_subtype = CZMoveUpdateSubtype_MoveZoneInstance,
}
);
}
void Perl__crosszonemoveinstancebyraidid(uint32 raid_id, uint16 instance_id, float x, float y, float z)
{
quest_manager.CrossZoneMove(
CZMove_Struct{
.coordinates = glm::vec4(x, y, z, 0.0f),
.instance_id = instance_id,
.update_identifier = raid_id,
.update_type = CZUpdateType_Raid,
.update_subtype = CZMoveUpdateSubtype_MoveZoneInstance,
}
);
}
void Perl__crosszonemoveinstancebyraidid(uint32 raid_id, uint16 instance_id, float x, float y, float z, float heading)
{
quest_manager.CrossZoneMove(
CZMove_Struct{
.coordinates = glm::vec4(x, y, z, heading),
.instance_id = instance_id,
.update_identifier = raid_id,
.update_type = CZUpdateType_Raid,
.update_subtype = CZMoveUpdateSubtype_MoveZoneInstance,
}
);
}
void Perl__crosszonemoveinstancebyguildid(uint32 guild_id, uint16 instance_id)
{
quest_manager.CrossZoneMove(
CZMove_Struct{
.instance_id = instance_id,
.update_identifier = guild_id,
.update_type = CZUpdateType_Guild,
.update_subtype = CZMoveUpdateSubtype_MoveZoneInstance,
}
);
}
void Perl__crosszonemoveinstancebyguildid(uint32 guild_id, uint16 instance_id, float x, float y, float z)
{
quest_manager.CrossZoneMove(
CZMove_Struct{
.coordinates = glm::vec4(x, y, z, 0.0f),
.instance_id = instance_id,
.update_identifier = guild_id,
.update_type = CZUpdateType_Guild,
.update_subtype = CZMoveUpdateSubtype_MoveZoneInstance,
}
);
}
void Perl__crosszonemoveinstancebyguildid(uint32 guild_id, uint16 instance_id, float x, float y, float z, float heading)
{
quest_manager.CrossZoneMove(
CZMove_Struct{
.coordinates = glm::vec4(x, y, z, heading),
.instance_id = instance_id,
.update_identifier = guild_id,
.update_type = CZUpdateType_Guild,
.update_subtype = CZMoveUpdateSubtype_MoveZoneInstance,
}
);
}
void Perl__crosszonemoveinstancebyexpeditionid(uint32 expedition_id, uint16 instance_id)
{
const char* zone_short_name = "";
quest_manager.CrossZoneMove(CZUpdateType_Expedition, CZMoveUpdateSubtype_MoveZoneInstance, expedition_id, zone_short_name, instance_id);
quest_manager.CrossZoneMove(
CZMove_Struct{
.instance_id = instance_id,
.update_identifier = expedition_id,
.update_type = CZUpdateType_Expedition,
.update_subtype = CZMoveUpdateSubtype_MoveZoneInstance,
}
);
}
void Perl__crosszonemoveinstancebyclientname(const char* client_name, uint16 instance_id)
void Perl__crosszonemoveinstancebyexpeditionid(uint32 expedition_id, uint16 instance_id, float x, float y, float z)
{
int update_identifier = 0;
const char* zone_short_name = "";
quest_manager.CrossZoneMove(CZUpdateType_ClientName, CZMoveUpdateSubtype_MoveZoneInstance, update_identifier, zone_short_name, instance_id, client_name);
quest_manager.CrossZoneMove(
CZMove_Struct{
.coordinates = glm::vec4(x, y, z, 0.0f),
.instance_id = instance_id,
.update_identifier = expedition_id,
.update_type = CZUpdateType_Expedition,
.update_subtype = CZMoveUpdateSubtype_MoveZoneInstance,
}
);
}
void Perl__crosszonemoveinstancebyexpeditionid(uint32 expedition_id, uint16 instance_id, float x, float y, float z, float heading)
{
quest_manager.CrossZoneMove(
CZMove_Struct{
.coordinates = glm::vec4(x, y, z, heading),
.instance_id = instance_id,
.update_identifier = expedition_id,
.update_type = CZUpdateType_Expedition,
.update_subtype = CZMoveUpdateSubtype_MoveZoneInstance,
}
);
}
void Perl__crosszonemoveinstancebyclientname(std::string client_name, uint16 instance_id)
{
quest_manager.CrossZoneMove(
CZMove_Struct{
.client_name = client_name,
.instance_id = instance_id,
.update_type = CZUpdateType_ClientName,
.update_subtype = CZMoveUpdateSubtype_MoveZoneInstance,
}
);
}
void Perl__crosszonemoveinstancebyclientname(std::string client_name, uint16 instance_id, float x, float y, float z)
{
quest_manager.CrossZoneMove(
CZMove_Struct{
.client_name = client_name,
.coordinates = glm::vec4(x, y, z, 0.0f),
.instance_id = instance_id,
.update_type = CZUpdateType_ClientName,
.update_subtype = CZMoveUpdateSubtype_MoveZoneInstance,
}
);
}
void Perl__crosszonemoveinstancebyclientname(std::string client_name, uint16 instance_id, float x, float y, float z, float heading)
{
quest_manager.CrossZoneMove(
CZMove_Struct{
.client_name = client_name,
.coordinates = glm::vec4(x, y, z, heading),
.instance_id = instance_id,
.update_type = CZUpdateType_ClientName,
.update_subtype = CZMoveUpdateSubtype_MoveZoneInstance,
}
);
}
void Perl__crosszoneremoveldonlossbycharid(int character_id, uint32 theme_id)
@@ -5762,18 +6172,42 @@ void perl_register_quest()
package.add("crosszonemessageplayerbyguildid", &Perl__crosszonemessageplayerbyguildid);
package.add("crosszonemessageplayerbyexpeditionid", &Perl__crosszonemessageplayerbyexpeditionid);
package.add("crosszonemessageplayerbyname", &Perl__crosszonemessageplayerbyname);
package.add("crosszonemoveplayerbycharid", &Perl__crosszonemoveplayerbycharid);
package.add("crosszonemoveplayerbygroupid", &Perl__crosszonemoveplayerbygroupid);
package.add("crosszonemoveplayerbyraidid", &Perl__crosszonemoveplayerbyraidid);
package.add("crosszonemoveplayerbyguildid", &Perl__crosszonemoveplayerbyguildid);
package.add("crosszonemoveplayerbyexpeditionid", &Perl__crosszonemoveplayerbyexpeditionid);
package.add("crosszonemoveplayerbyname", &Perl__crosszonemoveplayerbyname);
package.add("crosszonemoveinstancebycharid", &Perl__crosszonemoveinstancebycharid);
package.add("crosszonemoveinstancebygroupid", &Perl__crosszonemoveinstancebygroupid);
package.add("crosszonemoveinstancebyraidid", &Perl__crosszonemoveinstancebyraidid);
package.add("crosszonemoveinstancebyguildid", &Perl__crosszonemoveinstancebyguildid);
package.add("crosszonemoveinstancebyexpeditionid", &Perl__crosszonemoveinstancebyexpeditionid);
package.add("crosszonemoveinstancebyclientname", &Perl__crosszonemoveinstancebyclientname);
package.add("crosszonemoveplayerbycharid", (void(*)(uint32, std::string))&Perl__crosszonemoveplayerbycharid);
package.add("crosszonemoveplayerbycharid", (void(*)(uint32, std::string, float, float, float))&Perl__crosszonemoveplayerbycharid);
package.add("crosszonemoveplayerbycharid", (void(*)(uint32, std::string, float, float, float, float))&Perl__crosszonemoveplayerbycharid);
package.add("crosszonemoveplayerbygroupid", (void(*)(uint32, std::string))&Perl__crosszonemoveplayerbygroupid);
package.add("crosszonemoveplayerbygroupid", (void(*)(uint32, std::string, float, float, float))&Perl__crosszonemoveplayerbygroupid);
package.add("crosszonemoveplayerbygroupid", (void(*)(uint32, std::string, float, float, float, float))&Perl__crosszonemoveplayerbygroupid);
package.add("crosszonemoveplayerbyraidid", (void(*)(uint32, std::string))&Perl__crosszonemoveplayerbyraidid);
package.add("crosszonemoveplayerbyraidid", (void(*)(uint32, std::string, float, float, float))&Perl__crosszonemoveplayerbyraidid);
package.add("crosszonemoveplayerbyraidid", (void(*)(uint32, std::string, float, float, float, float))&Perl__crosszonemoveplayerbyraidid);
package.add("crosszonemoveplayerbyguildid", (void(*)(uint32, std::string))&Perl__crosszonemoveplayerbyguildid);
package.add("crosszonemoveplayerbyguildid", (void(*)(uint32, std::string, float, float, float))&Perl__crosszonemoveplayerbyguildid);
package.add("crosszonemoveplayerbyguildid", (void(*)(uint32, std::string, float, float, float, float))&Perl__crosszonemoveplayerbyguildid);
package.add("crosszonemoveplayerbyexpeditionid", (void(*)(uint32, std::string))&Perl__crosszonemoveplayerbyexpeditionid);
package.add("crosszonemoveplayerbyexpeditionid", (void(*)(uint32, std::string, float, float, float))&Perl__crosszonemoveplayerbyexpeditionid);
package.add("crosszonemoveplayerbyexpeditionid", (void(*)(uint32, std::string, float, float, float, float))&Perl__crosszonemoveplayerbyexpeditionid);
package.add("crosszonemoveplayerbyname", (void(*)(std::string, std::string))&Perl__crosszonemoveplayerbyname);
package.add("crosszonemoveplayerbyname", (void(*)(std::string, std::string, float, float, float))&Perl__crosszonemoveplayerbyname);
package.add("crosszonemoveplayerbyname", (void(*)(std::string, std::string, float, float, float, float))&Perl__crosszonemoveplayerbyname);
package.add("crosszonemoveinstancebycharid", (void(*)(uint32, uint16))&Perl__crosszonemoveinstancebycharid);
package.add("crosszonemoveinstancebycharid", (void(*)(uint32, uint16, float, float, float))&Perl__crosszonemoveinstancebycharid);
package.add("crosszonemoveinstancebycharid", (void(*)(uint32, uint16, float, float, float, float))&Perl__crosszonemoveinstancebycharid);
package.add("crosszonemoveinstancebygroupid", (void(*)(uint32, uint16))&Perl__crosszonemoveinstancebygroupid);
package.add("crosszonemoveinstancebygroupid", (void(*)(uint32, uint16, float, float, float))&Perl__crosszonemoveinstancebygroupid);
package.add("crosszonemoveinstancebygroupid", (void(*)(uint32, uint16, float, float, float, float))&Perl__crosszonemoveinstancebygroupid);
package.add("crosszonemoveinstancebyraidid", (void(*)(uint32, uint16))&Perl__crosszonemoveinstancebyraidid);
package.add("crosszonemoveinstancebyraidid", (void(*)(uint32, uint16, float, float, float))&Perl__crosszonemoveinstancebyraidid);
package.add("crosszonemoveinstancebyraidid", (void(*)(uint32, uint16, float, float, float, float))&Perl__crosszonemoveinstancebyraidid);
package.add("crosszonemoveinstancebyguildid", (void(*)(uint32, uint16))&Perl__crosszonemoveinstancebyguildid);
package.add("crosszonemoveinstancebyguildid", (void(*)(uint32, uint16, float, float, float))&Perl__crosszonemoveinstancebyguildid);
package.add("crosszonemoveinstancebyguildid", (void(*)(uint32, uint16, float, float, float, float))&Perl__crosszonemoveinstancebyguildid);
package.add("crosszonemoveinstancebyexpeditionid", (void(*)(uint32, uint16))&Perl__crosszonemoveinstancebyexpeditionid);
package.add("crosszonemoveinstancebyexpeditionid", (void(*)(uint32, uint16, float, float, float))&Perl__crosszonemoveinstancebyexpeditionid);
package.add("crosszonemoveinstancebyexpeditionid", (void(*)(uint32, uint16, float, float, float, float))&Perl__crosszonemoveinstancebyexpeditionid);
package.add("crosszonemoveinstancebyclientname", (void(*)(std::string, uint16))&Perl__crosszonemoveinstancebyclientname);
package.add("crosszonemoveinstancebyclientname", (void(*)(std::string, uint16, float, float, float))&Perl__crosszonemoveinstancebyclientname);
package.add("crosszonemoveinstancebyclientname", (void(*)(std::string, uint16, float, float, float, float))&Perl__crosszonemoveinstancebyclientname);
package.add("crosszoneremoveldonlossbycharid", &Perl__crosszoneremoveldonlossbycharid);
package.add("crosszoneremoveldonlossbygroupid", &Perl__crosszoneremoveldonlossbygroupid);
package.add("crosszoneremoveldonlossbyraidid", &Perl__crosszoneremoveldonlossbyraidid);
+4
View File
@@ -5652,6 +5652,10 @@ void EntityList::SendAlternateAdvancementStats() {
for (auto &c : client_list) {
c.second->Message(Chat::White, "Reloading AA");
c.second->ReloadExpansionProfileSetting();
if (!database.LoadAlternateAdvancement(c.second)) {
c.second->Message(Chat::Red, "Error loading alternate advancement character data");
}
c.second->SendClearPlayerAA();
c.second->SendAlternateAdvancementTable();
c.second->SendAlternateAdvancementStats();
+2
View File
@@ -938,6 +938,8 @@ void Client::SetLevel(uint8 set_level, bool command)
m_pp.exp = GetEXPForLevel(set_level);
Message(Chat::Yellow, fmt::format("Welcome to level {}!", set_level).c_str());
lu->exp = 0;
AutoGrantAAPoints();
} else {
const auto temporary_xp = (
static_cast<float>(m_pp.exp - GetEXPForLevel(GetLevel())) /
+36 -47
View File
@@ -7,58 +7,47 @@ void command_castspell(Client *c, const Seperator *sep)
return;
}
Mob *target = c;
if (c->GetTarget()) {
target = c->GetTarget();
}
if (!sep->IsNumber(1)) {
const auto arguments = sep->argnum;
if (!arguments || !sep->IsNumber(1)) {
c->Message(
Chat::White,
"Usage: #castspell [Spell ID] [Instant (0 = False, 1 = True, Default is 1 if Unused)]"
);
return;
}
else {
uint16 spell_id = Strings::ToUnsignedInt(sep->arg[1]);
if (IsCastRestrictedSpell(spell_id) && c->Admin() < commandCastSpecials) {
c->Message(Chat::Red, "Unable to cast spell.");
}
else if (spell_id >= SPDAT_RECORDS) {
c->Message(Chat::White, "Invalid Spell ID.");
}
else {
bool instant_cast = (c->Admin() >= commandInstacast ? true : false);
if (instant_cast && sep->IsNumber(2)) {
instant_cast = Strings::ToInt(sep->arg[2]) ? true : false;
c->Message(Chat::White, fmt::format("{}", Strings::ToInt(sep->arg[2])).c_str());
}
if (c->Admin() >= commandInstacast && instant_cast) {
c->SpellFinished(
spell_id,
target,
EQ::spells::CastingSlot::Item,
0,
-1,
spells[spell_id].resist_difficulty
);
}
else {
c->CastSpell(spell_id, target->GetID(), EQ::spells::CastingSlot::Item, spells[spell_id].cast_time);
}
c->Message(
Chat::White,
fmt::format(
"Cast {} ({}) on {}{}.",
GetSpellName(spell_id),
spell_id,
c->GetTargetDescription(target),
instant_cast ? " instantly" : ""
).c_str()
);
}
Mob* t = c;
if (c->GetTarget()) {
t = c->GetTarget();
}
const uint16 spell_id = Strings::ToUnsignedInt(sep->arg[1]);
if (IsCastRestrictedSpell(spell_id) && c->Admin() < commandCastSpecials) {
c->Message(Chat::White, "Unable to cast spell.");
return;
} else if (spell_id >= SPDAT_RECORDS) {
c->Message(Chat::White, "Invalid Spell ID.");
return;
}
const bool instant_cast = sep->IsNumber(2) ? Strings::ToBool(sep->arg[2]) : true;
const uint16 target_id = t->GetID();
if (instant_cast) {
c->SpellFinished(spell_id, t);
} else {
c->CastSpell(spell_id, t->GetID(), EQ::spells::CastingSlot::Item, spells[spell_id].cast_time);
}
c->Message(
Chat::White,
fmt::format(
"Cast {} ({}) on {}{}.",
GetSpellName(spell_id),
spell_id,
c->GetTargetDescription(t, TargetDescriptionType::LCSelf, target_id),
instant_cast ? " instantly" : ""
).c_str()
);
}
+3 -1
View File
@@ -72,7 +72,9 @@ void command_find(Client *c, const Seperator *sep)
// skip the first arg
for (auto i = 1; i <= arguments; i++) {
args.emplace_back(sep->arg[i]);
if (sep->arg[i]) {
args.emplace_back(sep->arg[i]);
}
}
// build the rewrite string
+30
View File
@@ -0,0 +1,30 @@
#include "../client.h"
void command_grantaa(Client *c, const Seperator *sep)
{
if (!c->GetTarget() || !c->GetTarget()->IsClient()) {
c->Message(Chat::White, "You must target a player to use this command.");
return;
}
const uint8 unlock_level = sep->IsNumber(1) ? static_cast<uint8>(Strings::ToUnsignedInt(sep->arg[1])) : 0;
auto t = c->GetTarget()->CastToClient();
t->GrantAllAAPoints(unlock_level);
c->Message(
Chat::White,
fmt::format(
"Successfully granted all Alternate Advancements for {}{}.",
c->GetTargetDescription(t),
(
unlock_level ?
fmt::format(
" up to level {}",
unlock_level
) :
""
)
).c_str()
);
}
+8 -3
View File
@@ -46,7 +46,12 @@ void command_movechar(Client *c, const Seperator *sep)
}
auto zone_id = ZoneID(zone_short_name);
std::string zone_long_name = ZoneLongName(zone_id);
auto z = GetZone(zone_id);
if (!z) {
c->Message(Chat::Red, "Invalid zone.");
return;
}
bool is_special_zone = (
zone_short_name.find("cshome") != std::string::npos ||
@@ -59,7 +64,7 @@ void command_movechar(Client *c, const Seperator *sep)
Chat::White,
fmt::format(
"{} ({}) is a special zone and you cannot move someone there.",
zone_long_name,
z->long_name,
zone_short_name
).c_str()
);
@@ -91,7 +96,7 @@ void command_movechar(Client *c, const Seperator *sep)
fmt::format(
"Character Move {} | Zone: {} ({}) ID: {}",
moved_string,
zone_long_name,
z->long_name,
zone_short_name,
zone_id
).c_str()
+26 -17
View File
@@ -339,24 +339,33 @@ void command_npcedit(Client *c, const Seperator *sep)
}
} else if (!strcasecmp(sep->arg[1], "faction")) {
if (sep->IsNumber(2)) {
auto faction_id = Strings::ToInt(sep->arg[2]);
auto faction_name = content_db.GetFactionName(faction_id);
n.npc_faction_id = faction_id;
d = fmt::format(
"{} is now using Faction {}.",
npc_id_string,
(
!faction_name.empty() ?
fmt::format(
"{} ({})",
faction_name,
faction_id
) :
Strings::Commify(sep->arg[2])
)
);
auto npc_faction_id = Strings::ToInt(sep->arg[2]);
const NPCFactionList* cf = content_db.GetNPCFactionEntry(npc_faction_id);
if (cf) {
auto faction_id = cf->primaryfaction;
auto faction_name = content_db.GetFactionName(faction_id);
n.npc_faction_id = npc_faction_id;
d = fmt::format(
"{} is now using Faction {}.",
npc_id_string,
(
!faction_name.empty() ?
fmt::format(
"{} ({})",
faction_name,
faction_id
) :
Strings::Commify(sep->arg[2])
)
);
}
else {
c->Message(Chat::White, "Need to provide a valid, existing, npc_faction_id");
return;
}
} else {
c->Message(Chat::White, "Usage: #npcedit faction [Faction ID] - Sets an NPC's Faction ID");
c->Message(Chat::White, "Usage: #npcedit faction [npc_faction_id] - Sets an NPC's npc Faction ID (not primary faction) but lookup into table.");
return;
}
} else if (!strcasecmp(sep->arg[1], "adventure_template_id")) {
+3 -1
View File
@@ -136,7 +136,9 @@ void command_set(Client *c, const Seperator *sep)
// skip the first arg
for (auto i = 1; i <= arguments; i++) {
args.emplace_back(sep->arg[i]);
if (sep->arg[i]) {
args.emplace_back(sep->arg[i]);
}
}
// build the rewrite string
+3 -1
View File
@@ -115,7 +115,9 @@ void command_show(Client *c, const Seperator *sep)
// skip the first arg
for (auto i = 1; i <= arguments; i++) {
args.emplace_back(sep->arg[i]);
if (sep->arg[i]) {
args.emplace_back(sep->arg[i]);
}
}
// build the rewrite string
+7 -7
View File
@@ -46,7 +46,7 @@ void ShowGroupInfo(Client *c, const Seperator *sep)
);
const std::string yes = DialogueWindow::ColorMessage("forest_green", "Y");
const std::string no = DialogueWindow::ColorMessage("red1", "N");
const std::string no = DialogueWindow::ColorMessage("red_1", "N");
for (int group_member = 0; group_member < MAX_GROUP_MEMBERS; group_member++) {
if (g->membername[group_member][0] == '\0') {
@@ -60,8 +60,8 @@ void ShowGroupInfo(Client *c, const Seperator *sep)
popup_table += DialogueWindow::TableRow(
fmt::format(
"{}{}{}{}{}{}",
group_member,
(
DialogueWindow::TableCell(std::to_string(group_member)),
DialogueWindow::TableCell(
strcmp(g->membername[group_member], c->GetCleanName()) ?
g->membername[group_member] :
fmt::format(
@@ -69,10 +69,10 @@ void ShowGroupInfo(Client *c, const Seperator *sep)
g->membername[group_member]
)
),
g->members[group_member] ? yes : no,
is_assist ? yes : no,
is_puller ? yes : no,
is_tank ? yes : no
DialogueWindow::TableCell(g->members[group_member] ? yes : no),
DialogueWindow::TableCell(is_assist ? yes : no),
DialogueWindow::TableCell(is_puller ? yes : no),
DialogueWindow::TableCell(is_tank ? yes : no)
)
);
}
+2 -2
View File
@@ -24,7 +24,7 @@ void ShowZoneData(Client *c, const Seperator *sep)
fmt::format(
"{} {} {}",
DialogueWindow::ColorMessage(
"red1",
"red_1",
std::to_string(zone->newzone_data.fog_red[fog_index])
),
DialogueWindow::ColorMessage(
@@ -206,7 +206,7 @@ void ShowZoneData(Client *c, const Seperator *sep)
DialogueWindow::TableCell(
zone->newzone_data.suspend_buffs ?
DialogueWindow::ColorMessage("forest_green", "Y") :
DialogueWindow::ColorMessage("red1", "N")
DialogueWindow::ColorMessage("red_1", "N")
)
);
+17 -12
View File
@@ -15,7 +15,7 @@ void command_summon(Client *c, const Seperator *sep)
return;
}
Mob* target;
Mob* t = c;
if (arguments == 1) {
std::string character_name = sep->arg[1];
@@ -33,7 +33,7 @@ void command_summon(Client *c, const Seperator *sep)
auto search_client = entity_list.GetClientByName(character_name.c_str());
if (search_client) {
target = search_client->CastToMob();
t = search_client->CastToMob();
} else {
if (!worldserver.Connected()) {
c->Message(Chat::White, "World server is currently disconnected.");
@@ -56,19 +56,24 @@ void command_summon(Client *c, const Seperator *sep)
return;
}
} else if (c->GetTarget()) {
target = c->GetTarget();
t = c->GetTarget();
}
if (c == target) {
if (c == t) {
c->Message(Chat::White, "You cannot summon yourself.");
return;
}
if (!t) {
c->Message(Chat::White, "You must have a target to summon.");
return;
}
c->Message(
Chat::White,
fmt::format(
"Summoning {} to {:.2f}, {:.2f}, {:.2f} in {} ({}).",
c->GetTargetDescription(target),
c->GetTargetDescription(t),
c->GetX(),
c->GetY(),
c->GetZ(),
@@ -77,8 +82,8 @@ void command_summon(Client *c, const Seperator *sep)
).c_str()
);
if (target->IsClient()) {
target->CastToClient()->MovePC(
if (t->IsClient()) {
t->CastToClient()->MovePC(
zone->GetZoneID(),
zone->GetInstanceID(),
c->GetX(),
@@ -91,10 +96,10 @@ void command_summon(Client *c, const Seperator *sep)
return;
}
target->GMMove(c->GetPosition());
t->GMMove(c->GetPosition());
if (target->IsNPC()) {
target->CastToNPC()->SaveGuardSpot(glm::vec4(0.0f));
if (t->IsNPC()) {
t->CastToNPC()->SaveGuardSpot(glm::vec4(0.0f));
}
}
+70 -63
View File
@@ -9,7 +9,7 @@
but WITHOUT ANY WARRANTY except by those people which sell it, which
are required to give you total support for your newly bought product;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
@@ -113,89 +113,91 @@ Group::~Group()
}
//Split money used in OP_Split (/split and /autosplit).
void Group::SplitMoney(uint32 copper, uint32 silver, uint32 gold, uint32 platinum, Client *splitter) {
//avoid unneeded work
if (
!copper &&
!silver &&
!gold &&
!platinum
) {
void Group::SplitMoney(uint32 copper, uint32 silver, uint32 gold, uint32 platinum, Client *splitter)
{
// Return early if no money to split.
if (!copper && !silver && !gold && !platinum) {
return;
}
uint8 member_count = 0;
// splitter can not be nullptr
if (!splitter) {
return;
}
// find number of clients in group and check if splitter is in group
uint8 member_count = 0;
bool splitter_in_group = false;
for (uint32 i = 0; i < MAX_GROUP_MEMBERS; i++) {
// Don't split with Mercs or Bots
if (members[i] && members[i]->IsClient()) {
member_count++;
if (members[i]->CastToClient() == splitter) {
splitter_in_group = true;
}
}
}
// Return if no group members found.
if (!member_count) {
return;
}
uint32 modifier;
if (member_count > 1) {
modifier = platinum % member_count;
if (modifier) {
platinum -= modifier;
gold += 10 * modifier;
}
modifier = gold % member_count;
if (modifier) {
gold -= modifier;
silver += 10 * modifier;
}
modifier = silver % member_count;
if (modifier) {
silver -= modifier;
copper += 10 * modifier;
}
// Splitter must be in group
if (!splitter_in_group) {
return;
}
auto copper_split = copper / member_count;
auto silver_split = silver / member_count;
auto gold_split = gold / member_count;
auto platinum_split = platinum / member_count;
// Calculate split and remainder for each coin type
uint32 copper_split = copper / member_count;
uint32 copper_remainder = copper % member_count;
uint32 silver_split = silver / member_count;
uint32 silver_remainder = silver % member_count;
uint32 gold_split = gold / member_count;
uint32 gold_remainder = gold % member_count;
uint32 platinum_split = platinum / member_count;
uint32 platinum_remainder = platinum % member_count;
for (uint32 i = 0; i < MAX_GROUP_MEMBERS; i++) {
if (members[i] && members[i]->IsClient()) { // If Group Member is Client
members[i]->CastToClient()->AddMoneyToPP(
copper_split,
silver_split,
gold_split,
platinum_split,
true
);
// Loop through the group members to split the coins.
for (const auto &m: members) {
if (m && m->IsClient()) {
Client *member_client = m->CastToClient();
if (player_event_logs.IsEventEnabled(PlayerEvent::SPLIT_MONEY)) {
auto e = PlayerEvent::SplitMoneyEvent{
.copper = copper_split,
.silver = silver_split,
.gold = gold_split,
.platinum = platinum_split,
.player_money_balance = members[i]->CastToClient()->GetCarriedMoney(),
};
uint32 receive_copper = copper_split;
uint32 receive_silver = silver_split;
uint32 receive_gold = gold_split;
uint32 receive_platinum = platinum_split;
RecordPlayerEventLogWithClient(members[i]->CastToClient(), PlayerEvent::SPLIT_MONEY, e);
// splitter gets the remainders of coin
if (member_client == splitter) {
receive_copper += copper_remainder;
receive_silver += silver_remainder;
receive_gold += gold_remainder;
receive_platinum += platinum_remainder;
}
members[i]->CastToClient()->MessageString(
// Add the coins to the player's purse.
member_client->AddMoneyToPP(receive_copper, receive_silver, receive_gold, receive_platinum, true);
// If logging of player money transactions is enabled, record the transaction.
if (player_event_logs.IsEventEnabled(PlayerEvent::SPLIT_MONEY)) {
auto e = PlayerEvent::SplitMoneyEvent{
.copper = receive_copper,
.silver = receive_silver,
.gold = receive_gold,
.platinum = receive_platinum,
.player_money_balance = member_client->GetCarriedMoney(),
};
RecordPlayerEventLogWithClient(member_client, PlayerEvent::SPLIT_MONEY, e);
}
// Notify the player of their received coins.
member_client->MessageString(
Chat::MoneySplit,
YOU_RECEIVE_AS_SPLIT,
Strings::Money(
platinum_split,
gold_split,
silver_split,
copper_split
).c_str()
Strings::Money(receive_platinum, receive_gold, receive_silver, receive_copper).c_str()
);
}
}
@@ -553,8 +555,13 @@ void Group::MemberZoned(Mob* removemob) {
//should NOT clear the name, it is used for world communication.
for (auto & m : members) {
if (m && (m == removemob || (m->IsBot() && m->CastToBot()->GetBotOwner() == removemob))) {
m = nullptr;
if (m) {
if (m->IsBot() && m->CastToBot()->GetBotOwner() && m->CastToBot()->GetBotOwner() == removemob) {
m = nullptr;
}
else if (m == removemob) {
m = nullptr;
}
}
}
+70 -32
View File
@@ -155,44 +155,58 @@ void Lua_Bot::ApplySpell(int spell_id, int duration) {
self->ApplySpell(spell_id, duration);
}
void Lua_Bot::ApplySpell(int spell_id, int duration, bool allow_pets) {
void Lua_Bot::ApplySpell(int spell_id, int duration, int level) {
Lua_Safe_Call_Void();
self->ApplySpell(spell_id, duration, ApplySpellType::Solo, allow_pets);
self->ApplySpell(spell_id, duration, level, ApplySpellType::Solo);
}
void Lua_Bot::ApplySpell(int spell_id, int duration, int level, bool allow_pets) {
Lua_Safe_Call_Void();
self->ApplySpell(spell_id, duration, level, ApplySpellType::Solo, allow_pets);
}
void Lua_Bot::ApplySpellGroup(int spell_id) {
Lua_Safe_Call_Void();
self->ApplySpell(spell_id, 0, ApplySpellType::Group);
self->ApplySpell(spell_id, 0, -1, ApplySpellType::Group);
}
void Lua_Bot::ApplySpellGroup(int spell_id, int duration) {
Lua_Safe_Call_Void();
self->ApplySpell(spell_id, duration, ApplySpellType::Group);
self->ApplySpell(spell_id, duration, -1, ApplySpellType::Group);
}
void Lua_Bot::ApplySpellGroup(int spell_id, int duration, int level) {
Lua_Safe_Call_Void();
self->ApplySpell(spell_id, duration, level, ApplySpellType::Group);
}
void Lua_Bot::ApplySpellGroup(int spell_id, int duration, bool allow_pets) {
void Lua_Bot::ApplySpellGroup(int spell_id, int duration, int level, bool allow_pets) {
Lua_Safe_Call_Void();
self->ApplySpell(spell_id, duration, ApplySpellType::Group, allow_pets);
self->ApplySpell(spell_id, duration, level, ApplySpellType::Group, allow_pets);
}
void Lua_Bot::ApplySpellRaid(int spell_id) {
Lua_Safe_Call_Void();
self->ApplySpell(spell_id, 0, ApplySpellType::Raid);
self->ApplySpell(spell_id, 0, -1, ApplySpellType::Raid);
}
void Lua_Bot::ApplySpellRaid(int spell_id, int duration) {
Lua_Safe_Call_Void();
self->ApplySpell(spell_id, duration, ApplySpellType::Raid, true, true);
self->ApplySpell(spell_id, duration, -1, ApplySpellType::Raid, true, true);
}
void Lua_Bot::ApplySpellRaid(int spell_id, int duration, bool allow_pets) {
void Lua_Bot::ApplySpellRaid(int spell_id, int duration, int level) {
Lua_Safe_Call_Void();
self->ApplySpell(spell_id, duration, ApplySpellType::Raid, allow_pets, true);
self->ApplySpell(spell_id, duration, level, ApplySpellType::Raid, true, true);
}
void Lua_Bot::ApplySpellRaid(int spell_id, int duration, bool allow_pets, bool is_raid_group_only) {
void Lua_Bot::ApplySpellRaid(int spell_id, int duration, int level, bool allow_pets) {
Lua_Safe_Call_Void();
self->ApplySpell(spell_id, duration, ApplySpellType::Raid, allow_pets, is_raid_group_only);
self->ApplySpell(spell_id, duration, level, ApplySpellType::Raid, allow_pets, true);
}
void Lua_Bot::ApplySpellRaid(int spell_id, int duration, int level, bool allow_pets, bool is_raid_group_only) {
Lua_Safe_Call_Void();
self->ApplySpell(spell_id, duration, level, ApplySpellType::Raid, allow_pets, is_raid_group_only);
}
void Lua_Bot::SetSpellDuration(int spell_id) {
@@ -205,44 +219,59 @@ void Lua_Bot::SetSpellDuration(int spell_id, int duration) {
self->SetSpellDuration(spell_id, duration);
}
void Lua_Bot::SetSpellDuration(int spell_id, int duration, bool allow_pets) {
void Lua_Bot::SetSpellDuration(int spell_id, int duration, int level) {
Lua_Safe_Call_Void();
self->SetSpellDuration(spell_id, duration, ApplySpellType::Solo, allow_pets);
self->SetSpellDuration(spell_id, duration, level);
}
void Lua_Bot::SetSpellDuration(int spell_id, int duration, int level, bool allow_pets) {
Lua_Safe_Call_Void();
self->SetSpellDuration(spell_id, duration, level, ApplySpellType::Solo, allow_pets);
}
void Lua_Bot::SetSpellDurationGroup(int spell_id) {
Lua_Safe_Call_Void();
self->SetSpellDuration(spell_id, 0, ApplySpellType::Group);
self->SetSpellDuration(spell_id, 0, -1, ApplySpellType::Group);
}
void Lua_Bot::SetSpellDurationGroup(int spell_id, int duration) {
Lua_Safe_Call_Void();
self->SetSpellDuration(spell_id, duration, ApplySpellType::Group);
self->SetSpellDuration(spell_id, duration, -1, ApplySpellType::Group);
}
void Lua_Bot::SetSpellDurationGroup(int spell_id, int duration, bool allow_pets) {
void Lua_Bot::SetSpellDurationGroup(int spell_id, int duration, int level) {
Lua_Safe_Call_Void();
self->SetSpellDuration(spell_id, duration, ApplySpellType::Group, allow_pets);
self->SetSpellDuration(spell_id, duration, level, ApplySpellType::Group);
}
void Lua_Bot::SetSpellDurationGroup(int spell_id, int duration, int level, bool allow_pets) {
Lua_Safe_Call_Void();
self->SetSpellDuration(spell_id, duration, level, ApplySpellType::Group, allow_pets);
}
void Lua_Bot::SetSpellDurationRaid(int spell_id) {
Lua_Safe_Call_Void();
self->SetSpellDuration(spell_id, 0, ApplySpellType::Raid);
self->SetSpellDuration(spell_id, 0, -1, ApplySpellType::Raid);
}
void Lua_Bot::SetSpellDurationRaid(int spell_id, int duration) {
Lua_Safe_Call_Void();
self->SetSpellDuration(spell_id, duration, ApplySpellType::Raid);
self->SetSpellDuration(spell_id, duration, -1, ApplySpellType::Raid);
}
void Lua_Bot::SetSpellDurationRaid(int spell_id, int duration, bool allow_pets) {
void Lua_Bot::SetSpellDurationRaid(int spell_id, int duration, int level) {
Lua_Safe_Call_Void();
self->SetSpellDuration(spell_id, duration, ApplySpellType::Raid, allow_pets);
self->SetSpellDuration(spell_id, duration, level, ApplySpellType::Raid);
}
void Lua_Bot::SetSpellDurationRaid(int spell_id, int duration, bool allow_pets, bool is_raid_group_only) {
void Lua_Bot::SetSpellDurationRaid(int spell_id, int duration, int level, bool allow_pets) {
Lua_Safe_Call_Void();
self->SetSpellDuration(spell_id, duration, ApplySpellType::Raid, allow_pets, is_raid_group_only);
self->SetSpellDuration(spell_id, duration, level, ApplySpellType::Raid, allow_pets);
}
void Lua_Bot::SetSpellDurationRaid(int spell_id, int duration, int level, bool allow_pets, bool is_raid_group_only) {
Lua_Safe_Call_Void();
self->SetSpellDuration(spell_id, duration, level, ApplySpellType::Raid, allow_pets, is_raid_group_only);
}
int Lua_Bot::CountAugmentEquippedByID(uint32 item_id) {
@@ -555,14 +584,20 @@ luabind::scope lua_register_bot() {
.def("AddItem", (void(Lua_Bot::*)(luabind::adl::object))&Lua_Bot::AddItem)
.def("ApplySpell", (void(Lua_Bot::*)(int))&Lua_Bot::ApplySpell)
.def("ApplySpell", (void(Lua_Bot::*)(int,int))&Lua_Bot::ApplySpell)
.def("ApplySpell", (void(Lua_Bot::*)(int,int,bool))&Lua_Bot::ApplySpell)
.def("ApplySpell", (void(Lua_Bot::*)(int,int,int))&Lua_Bot::ApplySpell)
.def("ApplySpell", (void(Lua_Bot::*)(int,int,int,bool))&Lua_Bot::ApplySpell)
.def("ApplySpell", (void(Lua_Bot::*)(int,int,int,bool))&Lua_Bot::ApplySpell)
.def("ApplySpellGroup", (void(Lua_Bot::*)(int))&Lua_Bot::ApplySpellGroup)
.def("ApplySpellGroup", (void(Lua_Bot::*)(int,int))&Lua_Bot::ApplySpellGroup)
.def("ApplySpellGroup", (void(Lua_Bot::*)(int,int,bool))&Lua_Bot::ApplySpellGroup)
.def("ApplySpellGroup", (void(Lua_Bot::*)(int,int,int))&Lua_Bot::ApplySpellGroup)
.def("ApplySpellGroup", (void(Lua_Bot::*)(int,int,int,bool))&Lua_Bot::ApplySpellGroup)
.def("ApplySpellGroup", (void(Lua_Bot::*)(int,int,int,bool))&Lua_Bot::ApplySpellGroup)
.def("ApplySpellRaid", (void(Lua_Bot::*)(int))&Lua_Bot::ApplySpellRaid)
.def("ApplySpellRaid", (void(Lua_Bot::*)(int,int))&Lua_Bot::ApplySpellRaid)
.def("ApplySpellRaid", (void(Lua_Bot::*)(int,int,bool))&Lua_Bot::ApplySpellRaid)
.def("ApplySpellRaid", (void(Lua_Bot::*)(int,int,bool,bool))&Lua_Bot::ApplySpellRaid)
.def("ApplySpellRaid", (void(Lua_Bot::*)(int,int,int))&Lua_Bot::ApplySpellRaid)
.def("ApplySpellRaid", (void(Lua_Bot::*)(int,int,int,bool))&Lua_Bot::ApplySpellRaid)
.def("ApplySpellRaid", (void(Lua_Bot::*)(int,int,int,bool,bool))&Lua_Bot::ApplySpellRaid)
.def("ApplySpellRaid", (void(Lua_Bot::*)(int,int,int,bool,bool))&Lua_Bot::ApplySpellRaid)
.def("Camp", (void(Lua_Bot::*)(void))&Lua_Bot::Camp)
.def("Camp", (void(Lua_Bot::*)(bool))&Lua_Bot::Camp)
.def("CountBotItem", (uint32(Lua_Bot::*)(uint32))&Lua_Bot::CountBotItem)
@@ -622,14 +657,17 @@ luabind::scope lua_register_bot() {
.def("SetExpansionBitmask", (void(Lua_Bot::*)(int,bool))&Lua_Bot::SetExpansionBitmask)
.def("SetSpellDuration", (void(Lua_Bot::*)(int))&Lua_Bot::SetSpellDuration)
.def("SetSpellDuration", (void(Lua_Bot::*)(int,int))&Lua_Bot::SetSpellDuration)
.def("SetSpellDuration", (void(Lua_Bot::*)(int,int,bool))&Lua_Bot::SetSpellDuration)
.def("SetSpellDuration", (void(Lua_Bot::*)(int,int,int))&Lua_Bot::SetSpellDuration)
.def("SetSpellDuration", (void(Lua_Bot::*)(int,int,int,bool))&Lua_Bot::SetSpellDuration)
.def("SetSpellDurationGroup", (void(Lua_Bot::*)(int))&Lua_Bot::SetSpellDurationGroup)
.def("SetSpellDurationGroup", (void(Lua_Bot::*)(int,int))&Lua_Bot::SetSpellDurationGroup)
.def("SetSpellDurationGroup", (void(Lua_Bot::*)(int,int,bool))&Lua_Bot::SetSpellDurationGroup)
.def("SetSpellDurationGroup", (void(Lua_Bot::*)(int,int,int))&Lua_Bot::SetSpellDurationGroup)
.def("SetSpellDurationGroup", (void(Lua_Bot::*)(int,int,int,bool))&Lua_Bot::SetSpellDurationGroup)
.def("SetSpellDurationRaid", (void(Lua_Bot::*)(int))&Lua_Bot::SetSpellDurationRaid)
.def("SetSpellDurationRaid", (void(Lua_Bot::*)(int,int))&Lua_Bot::SetSpellDurationRaid)
.def("SetSpellDurationRaid", (void(Lua_Bot::*)(int,int,bool))&Lua_Bot::SetSpellDurationRaid)
.def("SetSpellDurationRaid", (void(Lua_Bot::*)(int,int,bool,bool))&Lua_Bot::SetSpellDurationRaid)
.def("SetSpellDurationRaid", (void(Lua_Bot::*)(int,int,int))&Lua_Bot::SetSpellDurationRaid)
.def("SetSpellDurationRaid", (void(Lua_Bot::*)(int,int,int,bool))&Lua_Bot::SetSpellDurationRaid)
.def("SetSpellDurationRaid", (void(Lua_Bot::*)(int,int,int,bool,bool))&Lua_Bot::SetSpellDurationRaid)
.def("SendPayload", (void(Lua_Bot::*)(int))&Lua_Bot::SendPayload)
.def("SendPayload", (void(Lua_Bot::*)(int,std::string))&Lua_Bot::SendPayload)
.def("Signal", (void(Lua_Bot::*)(int))&Lua_Bot::Signal)
+14 -8
View File
@@ -77,29 +77,35 @@ public:
void ApplySpell(int spell_id);
void ApplySpell(int spell_id, int duration);
void ApplySpell(int spell_id, int duration, bool allow_pets);
void ApplySpell(int spell_id, int duration, int level);
void ApplySpell(int spell_id, int duration, int level, bool allow_pets);
void ApplySpellGroup(int spell_id);
void ApplySpellGroup(int spell_id, int duration);
void ApplySpellGroup(int spell_id, int duration, bool allow_pets);
void ApplySpellGroup(int spell_id, int duration, int level);
void ApplySpellGroup(int spell_id, int duration, int level, bool allow_pets);
void ApplySpellRaid(int spell_id);
void ApplySpellRaid(int spell_id, int duration);
void ApplySpellRaid(int spell_id, int duration, bool allow_pets);
void ApplySpellRaid(int spell_id, int duration, bool allow_pets, bool is_raid_group_only);
void ApplySpellRaid(int spell_id, int duration, int level);
void ApplySpellRaid(int spell_id, int duration, int level, bool allow_pets);
void ApplySpellRaid(int spell_id, int duration, int level, bool allow_pets, bool is_raid_group_only);
void SetSpellDuration(int spell_id);
void SetSpellDuration(int spell_id, int duration);
void SetSpellDuration(int spell_id, int duration, bool allow_pets);
void SetSpellDuration(int spell_id, int duration, int level);
void SetSpellDuration(int spell_id, int duration, int level, bool allow_pets);
void SetSpellDurationGroup(int spell_id);
void SetSpellDurationGroup(int spell_id, int duration);
void SetSpellDurationGroup(int spell_id, int duration, bool allow_pets);
void SetSpellDurationGroup(int spell_id, int duration, int level);
void SetSpellDurationGroup(int spell_id, int duration, int level, bool allow_pets);
void SetSpellDurationRaid(int spell_id);
void SetSpellDurationRaid(int spell_id, int duration);
void SetSpellDurationRaid(int spell_id, int duration, bool allow_pets);
void SetSpellDurationRaid(int spell_id, int duration, bool allow_pets, bool is_raid_group_only);
void SetSpellDurationRaid(int spell_id, int duration, int level);
void SetSpellDurationRaid(int spell_id, int duration, int level, bool allow_pets);
void SetSpellDurationRaid(int spell_id, int duration, int level, bool allow_pets, bool is_raid_group_only);
int CountAugmentEquippedByID(uint32 item_id);
int CountItemEquippedByID(uint32 item_id);
+100 -50
View File
@@ -2716,59 +2716,74 @@ void Lua_Client::ApplySpell(int spell_id, int duration) {
self->ApplySpell(spell_id, duration);
}
void Lua_Client::ApplySpell(int spell_id, int duration, bool allow_pets) {
void Lua_Client::ApplySpell(int spell_id, int duration, int level) {
Lua_Safe_Call_Void();
self->ApplySpell(spell_id, duration, ApplySpellType::Solo, allow_pets);
self->ApplySpell(spell_id, duration, level);
}
void Lua_Client::ApplySpell(int spell_id, int duration, bool allow_pets, bool allow_bots) {
void Lua_Client::ApplySpell(int spell_id, int duration, int level, bool allow_pets) {
Lua_Safe_Call_Void();
self->ApplySpell(spell_id, duration, ApplySpellType::Solo, allow_pets, true, allow_bots);
self->ApplySpell(spell_id, duration, level, ApplySpellType::Solo, allow_pets);
}
void Lua_Client::ApplySpell(int spell_id, int duration, int level, bool allow_pets, bool allow_bots) {
Lua_Safe_Call_Void();
self->ApplySpell(spell_id, duration, level, ApplySpellType::Solo, allow_pets, true, allow_bots);
}
void Lua_Client::ApplySpellGroup(int spell_id) {
Lua_Safe_Call_Void();
self->ApplySpell(spell_id, 0, ApplySpellType::Group);
self->ApplySpell(spell_id, 0, -1, ApplySpellType::Group);
}
void Lua_Client::ApplySpellGroup(int spell_id, int duration) {
Lua_Safe_Call_Void();
self->ApplySpell(spell_id, duration, ApplySpellType::Group);
self->ApplySpell(spell_id, duration, -1, ApplySpellType::Group);
}
void Lua_Client::ApplySpellGroup(int spell_id, int duration, bool allow_pets) {
void Lua_Client::ApplySpellGroup(int spell_id, int duration, int level) {
Lua_Safe_Call_Void();
self->ApplySpell(spell_id, duration, ApplySpellType::Group, allow_pets);
self->ApplySpell(spell_id, duration, level, ApplySpellType::Group);
}
void Lua_Client::ApplySpellGroup(int spell_id, int duration, bool allow_pets, bool allow_bots) {
void Lua_Client::ApplySpellGroup(int spell_id, int duration, int level, bool allow_pets) {
Lua_Safe_Call_Void();
self->ApplySpell(spell_id, duration, ApplySpellType::Group, allow_pets, true, allow_bots);
self->ApplySpell(spell_id, duration, level, ApplySpellType::Group, allow_pets);
}
void Lua_Client::ApplySpellGroup(int spell_id, int duration, int level, bool allow_pets, bool allow_bots) {
Lua_Safe_Call_Void();
self->ApplySpell(spell_id, duration, level, ApplySpellType::Group, allow_pets, true, allow_bots);
}
void Lua_Client::ApplySpellRaid(int spell_id) {
Lua_Safe_Call_Void();
self->ApplySpell(spell_id, 0, ApplySpellType::Raid);
self->ApplySpell(spell_id, 0, -1, ApplySpellType::Raid);
}
void Lua_Client::ApplySpellRaid(int spell_id, int duration) {
Lua_Safe_Call_Void();
self->ApplySpell(spell_id, duration, ApplySpellType::Raid);
self->ApplySpell(spell_id, duration, -1, ApplySpellType::Raid);
}
void Lua_Client::ApplySpellRaid(int spell_id, int duration, bool allow_pets) {
void Lua_Client::ApplySpellRaid(int spell_id, int duration, int level) {
Lua_Safe_Call_Void();
self->ApplySpell(spell_id, duration, ApplySpellType::Raid, allow_pets);
self->ApplySpell(spell_id, duration, level, ApplySpellType::Raid);
}
void Lua_Client::ApplySpellRaid(int spell_id, int duration, bool allow_pets, bool is_raid_group_only) {
void Lua_Client::ApplySpellRaid(int spell_id, int duration, int level, bool allow_pets) {
Lua_Safe_Call_Void();
self->ApplySpell(spell_id, duration, ApplySpellType::Raid, allow_pets, is_raid_group_only);
self->ApplySpell(spell_id, duration, level, ApplySpellType::Raid, allow_pets);
}
void Lua_Client::ApplySpellRaid(int spell_id, int duration, bool allow_pets, bool is_raid_group_only, bool allow_bots) {
void Lua_Client::ApplySpellRaid(int spell_id, int duration, int level, bool allow_pets, bool is_raid_group_only) {
Lua_Safe_Call_Void();
self->ApplySpell(spell_id, duration, ApplySpellType::Raid, allow_pets, is_raid_group_only, allow_bots);
self->ApplySpell(spell_id, duration, level, ApplySpellType::Raid, allow_pets, is_raid_group_only);
}
void Lua_Client::ApplySpellRaid(int spell_id, int duration, int level, bool allow_pets, bool is_raid_group_only, bool allow_bots) {
Lua_Safe_Call_Void();
self->ApplySpell(spell_id, duration, level, ApplySpellType::Raid, allow_pets, is_raid_group_only, allow_bots);
}
void Lua_Client::SetSpellDuration(int spell_id) {
@@ -2781,59 +2796,74 @@ void Lua_Client::SetSpellDuration(int spell_id, int duration) {
self->SetSpellDuration(spell_id, duration);
}
void Lua_Client::SetSpellDuration(int spell_id, int duration, bool allow_pets) {
void Lua_Client::SetSpellDuration(int spell_id, int duration, int level) {
Lua_Safe_Call_Void();
self->SetSpellDuration(spell_id, duration, ApplySpellType::Solo, allow_pets);
self->SetSpellDuration(spell_id, duration, level);
}
void Lua_Client::SetSpellDuration(int spell_id, int duration, bool allow_pets, bool allow_bots) {
void Lua_Client::SetSpellDuration(int spell_id, int duration, int level, bool allow_pets) {
Lua_Safe_Call_Void();
self->SetSpellDuration(spell_id, duration, ApplySpellType::Solo, allow_pets, true, allow_bots);
self->SetSpellDuration(spell_id, duration, level, ApplySpellType::Solo, allow_pets);
}
void Lua_Client::SetSpellDuration(int spell_id, int duration, int level, bool allow_pets, bool allow_bots) {
Lua_Safe_Call_Void();
self->SetSpellDuration(spell_id, duration, level, ApplySpellType::Solo, allow_pets, true, allow_bots);
}
void Lua_Client::SetSpellDurationGroup(int spell_id) {
Lua_Safe_Call_Void();
self->SetSpellDuration(spell_id, 0, ApplySpellType::Group);
self->SetSpellDuration(spell_id, 0, -1, ApplySpellType::Group);
}
void Lua_Client::SetSpellDurationGroup(int spell_id, int duration) {
Lua_Safe_Call_Void();
self->SetSpellDuration(spell_id, duration, ApplySpellType::Group);
self->SetSpellDuration(spell_id, duration, -1, ApplySpellType::Group);
}
void Lua_Client::SetSpellDurationGroup(int spell_id, int duration, bool allow_pets) {
void Lua_Client::SetSpellDurationGroup(int spell_id, int duration, int level) {
Lua_Safe_Call_Void();
self->SetSpellDuration(spell_id, duration, ApplySpellType::Group, allow_pets);
self->SetSpellDuration(spell_id, duration, level, ApplySpellType::Group);
}
void Lua_Client::SetSpellDurationGroup(int spell_id, int duration, bool allow_pets, bool allow_bots) {
void Lua_Client::SetSpellDurationGroup(int spell_id, int duration, int level, bool allow_pets) {
Lua_Safe_Call_Void();
self->SetSpellDuration(spell_id, duration, ApplySpellType::Group, allow_pets, true, allow_bots);
self->SetSpellDuration(spell_id, duration, level, ApplySpellType::Group, allow_pets);
}
void Lua_Client::SetSpellDurationGroup(int spell_id, int duration, int level, bool allow_pets, bool allow_bots) {
Lua_Safe_Call_Void();
self->SetSpellDuration(spell_id, duration, level, ApplySpellType::Group, allow_pets, true, allow_bots);
}
void Lua_Client::SetSpellDurationRaid(int spell_id) {
Lua_Safe_Call_Void();
self->SetSpellDuration(spell_id, 0, ApplySpellType::Raid);
self->SetSpellDuration(spell_id, 0, -1, ApplySpellType::Raid);
}
void Lua_Client::SetSpellDurationRaid(int spell_id, int duration) {
Lua_Safe_Call_Void();
self->SetSpellDuration(spell_id, duration, ApplySpellType::Raid);
self->SetSpellDuration(spell_id, duration, -1, ApplySpellType::Raid);
}
void Lua_Client::SetSpellDurationRaid(int spell_id, int duration, bool allow_pets) {
void Lua_Client::SetSpellDurationRaid(int spell_id, int duration, int level) {
Lua_Safe_Call_Void();
self->SetSpellDuration(spell_id, duration, ApplySpellType::Raid, allow_pets);
self->SetSpellDuration(spell_id, duration, level, ApplySpellType::Raid);
}
void Lua_Client::SetSpellDurationRaid(int spell_id, int duration, bool allow_pets, bool is_raid_group_only) {
void Lua_Client::SetSpellDurationRaid(int spell_id, int duration, int level, bool allow_pets) {
Lua_Safe_Call_Void();
self->SetSpellDuration(spell_id, duration, ApplySpellType::Raid, allow_pets, is_raid_group_only);
self->SetSpellDuration(spell_id, duration, level, ApplySpellType::Raid, allow_pets);
}
void Lua_Client::SetSpellDurationRaid(int spell_id, int duration, bool allow_pets, bool is_raid_group_only, bool allow_bots) {
void Lua_Client::SetSpellDurationRaid(int spell_id, int duration, int level, bool allow_pets, bool is_raid_group_only) {
Lua_Safe_Call_Void();
self->SetSpellDuration(spell_id, duration, ApplySpellType::Group, allow_pets, is_raid_group_only, allow_bots);
self->SetSpellDuration(spell_id, duration, level, ApplySpellType::Raid, allow_pets, is_raid_group_only);
}
void Lua_Client::SetSpellDurationRaid(int spell_id, int duration, int level, bool allow_pets, bool is_raid_group_only, bool allow_bots) {
Lua_Safe_Call_Void();
self->SetSpellDuration(spell_id, duration, level, ApplySpellType::Group, allow_pets, is_raid_group_only, allow_bots);
}
void Lua_Client::UpdateAdmin() {
@@ -3134,6 +3164,18 @@ void Lua_Client::SetBucket(std::string bucket_name, std::string bucket_value, st
self->SetBucket(bucket_name, bucket_value, expiration);
}
void Lua_Client::GrantAllAAPoints()
{
Lua_Safe_Call_Void();
self->GrantAllAAPoints();
}
void Lua_Client::GrantAllAAPoints(uint8 unlock_level)
{
Lua_Safe_Call_Void();
self->GrantAllAAPoints(unlock_level);
}
luabind::scope lua_register_client() {
return luabind::class_<Lua_Client, Lua_Mob>("Client")
.def(luabind::constructor<>())
@@ -3164,17 +3206,20 @@ luabind::scope lua_register_client() {
.def("Admin", (int16(Lua_Client::*)(void))&Lua_Client::Admin)
.def("ApplySpell", (void(Lua_Client::*)(int))&Lua_Client::ApplySpell)
.def("ApplySpell", (void(Lua_Client::*)(int,int))&Lua_Client::ApplySpell)
.def("ApplySpell", (void(Lua_Client::*)(int,int,bool))&Lua_Client::ApplySpell)
.def("ApplySpell", (void(Lua_Client::*)(int,int,bool,bool))&Lua_Client::ApplySpell)
.def("ApplySpell", (void(Lua_Client::*)(int,int,int))&Lua_Client::ApplySpell)
.def("ApplySpell", (void(Lua_Client::*)(int,int,int,bool))&Lua_Client::ApplySpell)
.def("ApplySpell", (void(Lua_Client::*)(int,int,int,bool,bool))&Lua_Client::ApplySpell)
.def("ApplySpellGroup", (void(Lua_Client::*)(int))&Lua_Client::ApplySpellGroup)
.def("ApplySpellGroup", (void(Lua_Client::*)(int,int))&Lua_Client::ApplySpellGroup)
.def("ApplySpellGroup", (void(Lua_Client::*)(int,int,bool))&Lua_Client::ApplySpellGroup)
.def("ApplySpellGroup", (void(Lua_Client::*)(int,int,bool,bool))&Lua_Client::ApplySpellGroup)
.def("ApplySpellGroup", (void(Lua_Client::*)(int,int,int))&Lua_Client::ApplySpellGroup)
.def("ApplySpellGroup", (void(Lua_Client::*)(int,int,int,bool))&Lua_Client::ApplySpellGroup)
.def("ApplySpellGroup", (void(Lua_Client::*)(int,int,int,bool,bool))&Lua_Client::ApplySpellGroup)
.def("ApplySpellRaid", (void(Lua_Client::*)(int))&Lua_Client::ApplySpellRaid)
.def("ApplySpellRaid", (void(Lua_Client::*)(int,int))&Lua_Client::ApplySpellRaid)
.def("ApplySpellRaid", (void(Lua_Client::*)(int,int,bool))&Lua_Client::ApplySpellRaid)
.def("ApplySpellRaid", (void(Lua_Client::*)(int,int,bool,bool))&Lua_Client::ApplySpellRaid)
.def("ApplySpellRaid", (void(Lua_Client::*)(int,int,bool,bool,bool))&Lua_Client::ApplySpellRaid)
.def("ApplySpellRaid", (void(Lua_Client::*)(int,int,int))&Lua_Client::ApplySpellRaid)
.def("ApplySpellRaid", (void(Lua_Client::*)(int,int,int,bool))&Lua_Client::ApplySpellRaid)
.def("ApplySpellRaid", (void(Lua_Client::*)(int,int,int,bool,bool))&Lua_Client::ApplySpellRaid)
.def("ApplySpellRaid", (void(Lua_Client::*)(int,int,int,bool,bool,bool))&Lua_Client::ApplySpellRaid)
.def("AssignTask", (void(Lua_Client::*)(int))&Lua_Client::AssignTask)
.def("AssignTask", (void(Lua_Client::*)(int,int))&Lua_Client::AssignTask)
.def("AssignTask", (void(Lua_Client::*)(int,int,bool))&Lua_Client::AssignTask)
@@ -3381,6 +3426,8 @@ luabind::scope lua_register_client() {
.def("GetPEQZoneFlags", (luabind::object(Lua_Client::*)(lua_State*))&Lua_Client::GetPEQZoneFlags)
.def("GetZoneFlags", (luabind::object(Lua_Client::*)(lua_State*))&Lua_Client::GetZoneFlags)
.def("GoFish", (void(Lua_Client::*)(void))&Lua_Client::GoFish)
.def("GrantAllAAPoints", (void(Lua_Client::*)(void))&Lua_Client::GrantAllAAPoints)
.def("GrantAllAAPoints", (void(Lua_Client::*)(uint8))&Lua_Client::GrantAllAAPoints)
.def("GrantAlternateAdvancementAbility", (bool(Lua_Client::*)(int, int))&Lua_Client::GrantAlternateAdvancementAbility)
.def("GrantAlternateAdvancementAbility", (bool(Lua_Client::*)(int, int, bool))&Lua_Client::GrantAlternateAdvancementAbility)
.def("GuildID", (uint32(Lua_Client::*)(void))&Lua_Client::GuildID)
@@ -3595,17 +3642,20 @@ luabind::scope lua_register_client() {
.def("SetSkillPoints", (void(Lua_Client::*)(int))&Lua_Client::SetSkillPoints)
.def("SetSpellDuration", (void(Lua_Client::*)(int))&Lua_Client::SetSpellDuration)
.def("SetSpellDuration", (void(Lua_Client::*)(int,int))&Lua_Client::SetSpellDuration)
.def("SetSpellDuration", (void(Lua_Client::*)(int,int,bool))&Lua_Client::SetSpellDuration)
.def("SetSpellDuration", (void(Lua_Client::*)(int,int,bool,bool))&Lua_Client::SetSpellDuration)
.def("SetSpellDuration", (void(Lua_Client::*)(int,int,int))&Lua_Client::SetSpellDuration)
.def("SetSpellDuration", (void(Lua_Client::*)(int,int,int,bool))&Lua_Client::SetSpellDuration)
.def("SetSpellDuration", (void(Lua_Client::*)(int,int,int,bool,bool))&Lua_Client::SetSpellDuration)
.def("SetSpellDurationGroup", (void(Lua_Client::*)(int))&Lua_Client::SetSpellDurationGroup)
.def("SetSpellDurationGroup", (void(Lua_Client::*)(int,int))&Lua_Client::SetSpellDurationGroup)
.def("SetSpellDurationGroup", (void(Lua_Client::*)(int,int,bool))&Lua_Client::SetSpellDurationGroup)
.def("SetSpellDurationGroup", (void(Lua_Client::*)(int,int,bool,bool))&Lua_Client::SetSpellDurationGroup)
.def("SetSpellDurationGroup", (void(Lua_Client::*)(int,int,int))&Lua_Client::SetSpellDurationGroup)
.def("SetSpellDurationGroup", (void(Lua_Client::*)(int,int,int,bool))&Lua_Client::SetSpellDurationGroup)
.def("SetSpellDurationGroup", (void(Lua_Client::*)(int,int,int,bool,bool))&Lua_Client::SetSpellDurationGroup)
.def("SetSpellDurationRaid", (void(Lua_Client::*)(int))&Lua_Client::SetSpellDurationRaid)
.def("SetSpellDurationRaid", (void(Lua_Client::*)(int,int))&Lua_Client::SetSpellDurationRaid)
.def("SetSpellDurationRaid", (void(Lua_Client::*)(int,int,bool))&Lua_Client::SetSpellDurationRaid)
.def("SetSpellDurationRaid", (void(Lua_Client::*)(int,int,bool,bool))&Lua_Client::SetSpellDurationRaid)
.def("SetSpellDurationRaid", (void(Lua_Client::*)(int,int,bool,bool,bool))&Lua_Client::SetSpellDurationRaid)
.def("SetSpellDurationRaid", (void(Lua_Client::*)(int,int,int))&Lua_Client::SetSpellDurationRaid)
.def("SetSpellDurationRaid", (void(Lua_Client::*)(int,int,int,bool))&Lua_Client::SetSpellDurationRaid)
.def("SetSpellDurationRaid", (void(Lua_Client::*)(int,int,int,bool,bool))&Lua_Client::SetSpellDurationRaid)
.def("SetSpellDurationRaid", (void(Lua_Client::*)(int,int,int,bool,bool,bool))&Lua_Client::SetSpellDurationRaid)
.def("SetStartZone", (void(Lua_Client::*)(int))&Lua_Client::SetStartZone)
.def("SetStartZone", (void(Lua_Client::*)(int,float))&Lua_Client::SetStartZone)
.def("SetStartZone", (void(Lua_Client::*)(int,float,float))&Lua_Client::SetStartZone)
+22 -14
View File
@@ -480,38 +480,46 @@ public:
std::string GetBucketRemaining(std::string bucket_name);
void SetBucket(std::string bucket_name, std::string bucket_value);
void SetBucket(std::string bucket_name, std::string bucket_value, std::string expiration);
void GrantAllAAPoints();
void GrantAllAAPoints(uint8 unlock_level);
void ApplySpell(int spell_id);
void ApplySpell(int spell_id, int duration);
void ApplySpell(int spell_id, int duration, bool allow_pets);
void ApplySpell(int spell_id, int duration, bool allow_pets, bool allow_bots);
void ApplySpell(int spell_id, int duration, int level);
void ApplySpell(int spell_id, int duration, int level, bool allow_pets);
void ApplySpell(int spell_id, int duration, int level, bool allow_pets, bool allow_bots);
void ApplySpellGroup(int spell_id);
void ApplySpellGroup(int spell_id, int duration);
void ApplySpellGroup(int spell_id, int duration, bool allow_pets);
void ApplySpellGroup(int spell_id, int duration, bool allow_pets, bool allow_bots);
void ApplySpellGroup(int spell_id, int duration, int level);
void ApplySpellGroup(int spell_id, int duration, int level, bool allow_pets);
void ApplySpellGroup(int spell_id, int duration, int level, bool allow_pets, bool allow_bots);
void ApplySpellRaid(int spell_id);
void ApplySpellRaid(int spell_id, int duration);
void ApplySpellRaid(int spell_id, int duration, bool allow_pets);
void ApplySpellRaid(int spell_id, int duration, bool allow_pets, bool is_raid_group_only);
void ApplySpellRaid(int spell_id, int duration, bool allow_pets, bool is_raid_group_only, bool allow_bots);
void ApplySpellRaid(int spell_id, int duration, int level);
void ApplySpellRaid(int spell_id, int duration, int level, bool allow_pets);
void ApplySpellRaid(int spell_id, int duration, int level, bool allow_pets, bool is_raid_group_only);
void ApplySpellRaid(int spell_id, int duration, int level, bool allow_pets, bool is_raid_group_only, bool allow_bots);
void SetSpellDuration(int spell_id);
void SetSpellDuration(int spell_id, int duration);
void SetSpellDuration(int spell_id, int duration, bool allow_pets);
void SetSpellDuration(int spell_id, int duration, bool allow_pets, bool allow_bots);
void SetSpellDuration(int spell_id, int duration, int level);
void SetSpellDuration(int spell_id, int duration, int level, bool allow_pets);
void SetSpellDuration(int spell_id, int duration, int level, bool allow_pets, bool allow_bots);
void SetSpellDurationGroup(int spell_id);
void SetSpellDurationGroup(int spell_id, int duration);
void SetSpellDurationGroup(int spell_id, int duration, bool allow_pets);
void SetSpellDurationGroup(int spell_id, int duration, bool allow_pets, bool allow_bots);
void SetSpellDurationGroup(int spell_id, int duration, int level);
void SetSpellDurationGroup(int spell_id, int duration, int level, bool allow_pets);
void SetSpellDurationGroup(int spell_id, int duration, int level, bool allow_pets, bool allow_bots);
void SetSpellDurationRaid(int spell_id);
void SetSpellDurationRaid(int spell_id, int duration);
void SetSpellDurationRaid(int spell_id, int duration, bool allow_pets);
void SetSpellDurationRaid(int spell_id, int duration, bool allow_pets, bool is_raid_group_only);
void SetSpellDurationRaid(int spell_id, int duration, bool allow_pets, bool is_raid_group_only, bool allow_bots);
void SetSpellDurationRaid(int spell_id, int duration, int level);
void SetSpellDurationRaid(int spell_id, int duration, int level, bool allow_pets);
void SetSpellDurationRaid(int spell_id, int duration, int level, bool allow_pets, bool is_raid_group_only);
void SetSpellDurationRaid(int spell_id, int duration, int level, bool allow_pets, bool is_raid_group_only, bool allow_bots);
int GetEnvironmentDamageModifier();
+431 -73
View File
@@ -2539,90 +2539,424 @@ void lua_cross_zone_message_player_by_name(uint32 type, const char* client_name,
quest_manager.CrossZoneMessage(update_type, update_identifier, type, message, client_name);
}
void lua_cross_zone_move_player_by_char_id(int character_id, const char* zone_short_name) {
uint8 update_type = CZUpdateType_Character;
uint8 update_subtype = CZMoveUpdateSubtype_MoveZone;
uint16 instance_id = 0;
quest_manager.CrossZoneMove(update_type, update_subtype, character_id, zone_short_name, instance_id);
void lua_cross_zone_move_player_by_char_id(uint32 character_id, std::string zone_short_name) {
quest_manager.CrossZoneMove(
CZMove_Struct{
.update_identifier = character_id,
.update_type = CZUpdateType_Character,
.update_subtype = CZMoveUpdateSubtype_MoveZone,
.zone_short_name = zone_short_name,
}
);
}
void lua_cross_zone_move_player_by_group_id(int group_id, const char* zone_short_name) {
uint8 update_type = CZUpdateType_Group;
uint8 update_subtype = CZMoveUpdateSubtype_MoveZone;
uint16 instance_id = 0;
quest_manager.CrossZoneMove(update_type, update_subtype, group_id, zone_short_name, instance_id);
void lua_cross_zone_move_player_by_char_id(uint32 character_id, std::string zone_short_name, float x, float y, float z) {
quest_manager.CrossZoneMove(
CZMove_Struct{
.coordinates = glm::vec4(x, y, z, 0.0f),
.update_identifier = character_id,
.update_type = CZUpdateType_Character,
.update_subtype = CZMoveUpdateSubtype_MoveZone,
.zone_short_name = zone_short_name,
}
);
}
void lua_cross_zone_move_player_by_raid_id(int raid_id, const char* zone_short_name) {
uint8 update_type = CZUpdateType_Raid;
uint8 update_subtype = CZMoveUpdateSubtype_MoveZone;
uint16 instance_id = 0;
quest_manager.CrossZoneMove(update_type, update_subtype, raid_id, zone_short_name, instance_id);
void lua_cross_zone_move_player_by_char_id(uint32 character_id, std::string zone_short_name, float x, float y, float z, float heading) {
quest_manager.CrossZoneMove(
CZMove_Struct{
.coordinates = glm::vec4(x, y, z, heading),
.update_identifier = character_id,
.update_type = CZUpdateType_Character,
.update_subtype = CZMoveUpdateSubtype_MoveZone,
.zone_short_name = zone_short_name,
}
);
}
void lua_cross_zone_move_player_by_guild_id(int guild_id, const char* zone_short_name) {
uint8 update_type = CZUpdateType_Guild;
uint8 update_subtype = CZMoveUpdateSubtype_MoveZone;
uint16 instance_id = 0;
quest_manager.CrossZoneMove(update_type, update_subtype, guild_id, zone_short_name, instance_id);
void lua_cross_zone_move_player_by_group_id(uint32 group_id, std::string zone_short_name) {
quest_manager.CrossZoneMove(
CZMove_Struct{
.update_identifier = group_id,
.update_type = CZUpdateType_Group,
.update_subtype = CZMoveUpdateSubtype_MoveZone,
.zone_short_name = zone_short_name,
}
);
}
void lua_cross_zone_move_player_by_expedition_id(int expedition_id, const char* zone_short_name) {
uint8 update_type = CZUpdateType_Expedition;
uint8 update_subtype = CZMoveUpdateSubtype_MoveZone;
uint16 instance_id = 0;
quest_manager.CrossZoneMove(update_type, update_subtype, expedition_id, zone_short_name, instance_id);
void lua_cross_zone_move_player_by_group_id(uint32 group_id, std::string zone_short_name, float x, float y, float z) {
quest_manager.CrossZoneMove(
CZMove_Struct{
.coordinates = glm::vec4(x, y, z, 0.0f),
.update_identifier = group_id,
.update_type = CZUpdateType_Group,
.update_subtype = CZMoveUpdateSubtype_MoveZone,
.zone_short_name = zone_short_name,
}
);
}
void lua_cross_zone_move_player_by_client_name(const char* client_name, const char* zone_short_name) {
uint8 update_type = CZUpdateType_Character;
uint8 update_subtype = CZMoveUpdateSubtype_MoveZone;
int update_identifier = 0;
uint16 instance_id = 0;
quest_manager.CrossZoneMove(update_type, update_subtype, update_identifier, zone_short_name, instance_id, client_name);
void lua_cross_zone_move_player_by_group_id(uint32 group_id, std::string zone_short_name, float x, float y, float z, float heading) {
quest_manager.CrossZoneMove(
CZMove_Struct{
.coordinates = glm::vec4(x, y, z, heading),
.update_identifier = group_id,
.update_type = CZUpdateType_Group,
.update_subtype = CZMoveUpdateSubtype_MoveZone,
.zone_short_name = zone_short_name,
}
);
}
void lua_cross_zone_move_instance_by_char_id(int character_id, uint16 instance_id) {
uint8 update_type = CZUpdateType_Character;
uint8 update_subtype = CZMoveUpdateSubtype_MoveZoneInstance;
const char* zone_short_name = "";
quest_manager.CrossZoneMove(update_type, update_subtype, character_id, zone_short_name, instance_id);
void lua_cross_zone_move_player_by_raid_id(uint32 raid_id, std::string zone_short_name) {
quest_manager.CrossZoneMove(
CZMove_Struct{
.update_identifier = raid_id,
.update_type = CZUpdateType_Raid,
.update_subtype = CZMoveUpdateSubtype_MoveZone,
.zone_short_name = zone_short_name,
}
);
}
void lua_cross_zone_move_instance_by_group_id(int group_id, uint16 instance_id) {
uint8 update_type = CZUpdateType_Group;
uint8 update_subtype = CZMoveUpdateSubtype_MoveZoneInstance;
const char* zone_short_name = "";
quest_manager.CrossZoneMove(update_type, update_subtype, group_id, zone_short_name, instance_id);
void lua_cross_zone_move_player_by_raid_id(uint32 raid_id, std::string zone_short_name, float x, float y, float z) {
quest_manager.CrossZoneMove(
CZMove_Struct{
.coordinates = glm::vec4(x, y, z, 0.0f),
.update_identifier = raid_id,
.update_type = CZUpdateType_Raid,
.update_subtype = CZMoveUpdateSubtype_MoveZone,
.zone_short_name = zone_short_name,
}
);
}
void lua_cross_zone_move_instance_by_raid_id(int raid_id, uint16 instance_id) {
uint8 update_type = CZUpdateType_Raid;
uint8 update_subtype = CZMoveUpdateSubtype_MoveZoneInstance;
const char* zone_short_name = "";
quest_manager.CrossZoneMove(update_type, update_subtype, raid_id, zone_short_name, instance_id);
void lua_cross_zone_move_player_by_raid_id(uint32 raid_id, std::string zone_short_name, float x, float y, float z, float heading) {
quest_manager.CrossZoneMove(
CZMove_Struct{
.coordinates = glm::vec4(x, y, z, heading),
.update_identifier = raid_id,
.update_type = CZUpdateType_Raid,
.update_subtype = CZMoveUpdateSubtype_MoveZone,
.zone_short_name = zone_short_name,
}
);
}
void lua_cross_zone_move_instance_by_guild_id(int guild_id, uint16 instance_id) {
uint8 update_type = CZUpdateType_Guild;
uint8 update_subtype = CZMoveUpdateSubtype_MoveZoneInstance;
const char* zone_short_name = "";
quest_manager.CrossZoneMove(update_type, update_subtype, guild_id, zone_short_name, instance_id);
void lua_cross_zone_move_player_by_guild_id(uint32 guild_id, std::string zone_short_name) {
quest_manager.CrossZoneMove(
CZMove_Struct{
.update_identifier = guild_id,
.update_type = CZUpdateType_Guild,
.update_subtype = CZMoveUpdateSubtype_MoveZone,
.zone_short_name = zone_short_name,
}
);
}
void lua_cross_zone_move_player_by_guild_id(uint32 guild_id, std::string zone_short_name, float x, float y, float z) {
quest_manager.CrossZoneMove(
CZMove_Struct{
.coordinates = glm::vec4(x, y, z, 0.0f),
.update_identifier = guild_id,
.update_type = CZUpdateType_Guild,
.update_subtype = CZMoveUpdateSubtype_MoveZone,
.zone_short_name = zone_short_name,
}
);
}
void lua_cross_zone_move_player_by_guild_id(uint32 guild_id, std::string zone_short_name, float x, float y, float z, float heading) {
quest_manager.CrossZoneMove(
CZMove_Struct{
.coordinates = glm::vec4(x, y, z, heading),
.update_identifier = guild_id,
.update_type = CZUpdateType_Guild,
.update_subtype = CZMoveUpdateSubtype_MoveZone,
.zone_short_name = zone_short_name,
}
);
}
void lua_cross_zone_move_player_by_expedition_id(uint32 expedition_id, std::string zone_short_name) {
quest_manager.CrossZoneMove(
CZMove_Struct{
.update_identifier = expedition_id,
.update_type = CZUpdateType_Expedition,
.update_subtype = CZMoveUpdateSubtype_MoveZone,
.zone_short_name = zone_short_name,
}
);
}
void lua_cross_zone_move_player_by_expedition_id(uint32 expedition_id, std::string zone_short_name, float x, float y, float z) {
quest_manager.CrossZoneMove(
CZMove_Struct{
.coordinates = glm::vec4(x, y, z, 0.0f),
.update_identifier = expedition_id,
.update_type = CZUpdateType_Expedition,
.update_subtype = CZMoveUpdateSubtype_MoveZone,
.zone_short_name = zone_short_name,
}
);
}
void lua_cross_zone_move_player_by_expedition_id(uint32 expedition_id, std::string zone_short_name, float x, float y, float z, float heading) {
quest_manager.CrossZoneMove(
CZMove_Struct{
.coordinates = glm::vec4(x, y, z, heading),
.update_identifier = expedition_id,
.update_type = CZUpdateType_Expedition,
.update_subtype = CZMoveUpdateSubtype_MoveZone,
.zone_short_name = zone_short_name,
}
);
}
void lua_cross_zone_move_player_by_client_name(std::string client_name, std::string zone_short_name) {
quest_manager.CrossZoneMove(
CZMove_Struct{
.client_name = client_name,
.update_type = CZUpdateType_ClientName,
.update_subtype = CZMoveUpdateSubtype_MoveZone,
.zone_short_name = zone_short_name,
}
);
}
void lua_cross_zone_move_player_by_client_name(std::string client_name, std::string zone_short_name, float x, float y, float z) {
quest_manager.CrossZoneMove(
CZMove_Struct{
.client_name = client_name,
.coordinates = glm::vec4(x, y, z, 0.0f),
.update_type = CZUpdateType_ClientName,
.update_subtype = CZMoveUpdateSubtype_MoveZone,
.zone_short_name = zone_short_name,
}
);
}
void lua_cross_zone_move_player_by_client_name(std::string client_name, std::string zone_short_name, float x, float y, float z, float heading) {
quest_manager.CrossZoneMove(
CZMove_Struct{
.client_name = client_name,
.coordinates = glm::vec4(x, y, z, heading),
.update_type = CZUpdateType_ClientName,
.update_subtype = CZMoveUpdateSubtype_MoveZone,
.zone_short_name = zone_short_name,
}
);
}
void lua_cross_zone_move_instance_by_char_id(uint32 character_id, uint16 instance_id) {
quest_manager.CrossZoneMove(
CZMove_Struct{
.instance_id = instance_id,
.update_identifier = character_id,
.update_type = CZUpdateType_Character,
.update_subtype = CZMoveUpdateSubtype_MoveZoneInstance,
}
);
}
void lua_cross_zone_move_instance_by_char_id(uint32 character_id, uint16 instance_id, float x, float y, float z) {
quest_manager.CrossZoneMove(
CZMove_Struct{
.coordinates = glm::vec4(x, y, z, 0.0f),
.instance_id = instance_id,
.update_identifier = character_id,
.update_type = CZUpdateType_Character,
.update_subtype = CZMoveUpdateSubtype_MoveZoneInstance,
}
);
}
void lua_cross_zone_move_instance_by_char_id(uint32 character_id, uint16 instance_id, float x, float y, float z, float heading) {
quest_manager.CrossZoneMove(
CZMove_Struct{
.coordinates = glm::vec4(x, y, z, heading),
.instance_id = instance_id,
.update_identifier = character_id,
.update_type = CZUpdateType_Character,
.update_subtype = CZMoveUpdateSubtype_MoveZoneInstance,
}
);
}
void lua_cross_zone_move_instance_by_group_id(uint32 group_id, uint16 instance_id) {
quest_manager.CrossZoneMove(
CZMove_Struct{
.instance_id = instance_id,
.update_identifier = group_id,
.update_type = CZUpdateType_Group,
.update_subtype = CZMoveUpdateSubtype_MoveZoneInstance,
}
);
}
void lua_cross_zone_move_instance_by_group_id(uint32 group_id, uint16 instance_id, float x, float y, float z) {
quest_manager.CrossZoneMove(
CZMove_Struct{
.coordinates = glm::vec4(x, y, z, 0.0f),
.instance_id = instance_id,
.update_identifier = group_id,
.update_type = CZUpdateType_Group,
.update_subtype = CZMoveUpdateSubtype_MoveZoneInstance,
}
);
}
void lua_cross_zone_move_instance_by_group_id(uint32 group_id, uint16 instance_id, float x, float y, float z, float heading) {
quest_manager.CrossZoneMove(
CZMove_Struct{
.coordinates = glm::vec4(x, y, z, heading),
.instance_id = instance_id,
.update_identifier = group_id,
.update_type = CZUpdateType_Group,
.update_subtype = CZMoveUpdateSubtype_MoveZoneInstance,
}
);
}
void lua_cross_zone_move_instance_by_raid_id(uint32 raid_id, uint16 instance_id) {
quest_manager.CrossZoneMove(
CZMove_Struct{
.instance_id = instance_id,
.update_identifier = raid_id,
.update_type = CZUpdateType_Raid,
.update_subtype = CZMoveUpdateSubtype_MoveZoneInstance,
}
);
}
void lua_cross_zone_move_instance_by_raid_id(uint32 raid_id, uint16 instance_id, float x, float y, float z) {
quest_manager.CrossZoneMove(
CZMove_Struct{
.coordinates = glm::vec4(x, y, z, 0.0f),
.instance_id = instance_id,
.update_identifier = raid_id,
.update_type = CZUpdateType_Raid,
.update_subtype = CZMoveUpdateSubtype_MoveZoneInstance,
}
);
}
void lua_cross_zone_move_instance_by_raid_id(uint32 raid_id, uint16 instance_id, float x, float y, float z, float heading) {
quest_manager.CrossZoneMove(
CZMove_Struct{
.coordinates = glm::vec4(x, y, z, heading),
.instance_id = instance_id,
.update_identifier = raid_id,
.update_type = CZUpdateType_Raid,
.update_subtype = CZMoveUpdateSubtype_MoveZoneInstance,
}
);
}
void lua_cross_zone_move_instance_by_guild_id(uint32 guild_id, uint16 instance_id) {
quest_manager.CrossZoneMove(
CZMove_Struct{
.instance_id = instance_id,
.update_identifier = guild_id,
.update_type = CZUpdateType_Guild,
.update_subtype = CZMoveUpdateSubtype_MoveZoneInstance,
}
);
}
void lua_cross_zone_move_instance_by_guild_id(uint32 guild_id, uint16 instance_id, float x, float y, float z) {
quest_manager.CrossZoneMove(
CZMove_Struct{
.coordinates = glm::vec4(x, y, z, 0.0f),
.instance_id = instance_id,
.update_identifier = guild_id,
.update_type = CZUpdateType_Guild,
.update_subtype = CZMoveUpdateSubtype_MoveZoneInstance,
}
);
}
void lua_cross_zone_move_instance_by_guild_id(uint32 guild_id, uint16 instance_id, float x, float y, float z, float heading) {
quest_manager.CrossZoneMove(
CZMove_Struct{
.coordinates = glm::vec4(x, y, z, heading),
.instance_id = instance_id,
.update_identifier = guild_id,
.update_type = CZUpdateType_Guild,
.update_subtype = CZMoveUpdateSubtype_MoveZoneInstance,
}
);
}
void lua_cross_zone_move_instance_by_expedition_id(uint32 expedition_id, uint16 instance_id) {
uint8 update_type = CZUpdateType_Expedition;
uint8 update_subtype = CZMoveUpdateSubtype_MoveZoneInstance;
const char* zone_short_name = "";
quest_manager.CrossZoneMove(update_type, update_subtype, expedition_id, zone_short_name, instance_id);
quest_manager.CrossZoneMove(
CZMove_Struct{
.instance_id = instance_id,
.update_identifier = expedition_id,
.update_type = CZUpdateType_Expedition,
.update_subtype = CZMoveUpdateSubtype_MoveZoneInstance,
}
);
}
void lua_cross_zone_move_instance_by_client_name(const char* client_name, uint16 instance_id) {
uint8 update_type = CZUpdateType_ClientName;
uint8 update_subtype = CZMoveUpdateSubtype_MoveZoneInstance;
int update_identifier = 0;
const char* zone_short_name = "";
quest_manager.CrossZoneMove(update_type, update_subtype, update_identifier, zone_short_name, instance_id, client_name);
void lua_cross_zone_move_instance_by_expedition_id(uint32 expedition_id, uint16 instance_id, float x, float y, float z) {
quest_manager.CrossZoneMove(
CZMove_Struct{
.coordinates = glm::vec4(x, y, z, 0.0f),
.instance_id = instance_id,
.update_identifier = expedition_id,
.update_type = CZUpdateType_Expedition,
.update_subtype = CZMoveUpdateSubtype_MoveZoneInstance,
}
);
}
void lua_cross_zone_move_instance_by_expedition_id(uint32 expedition_id, uint16 instance_id, float x, float y, float z, float heading) {
quest_manager.CrossZoneMove(
CZMove_Struct{
.coordinates = glm::vec4(x, y, z, heading),
.instance_id = instance_id,
.update_identifier = expedition_id,
.update_type = CZUpdateType_Expedition,
.update_subtype = CZMoveUpdateSubtype_MoveZoneInstance,
}
);
}
void lua_cross_zone_move_instance_by_client_name(std::string client_name, uint16 instance_id) {
quest_manager.CrossZoneMove(
CZMove_Struct{
.client_name = client_name,
.instance_id = instance_id,
.update_type = CZUpdateType_ClientName,
.update_subtype = CZMoveUpdateSubtype_MoveZoneInstance,
}
);
}
void lua_cross_zone_move_instance_by_client_name(std::string client_name, uint16 instance_id, float x, float y, float z) {
quest_manager.CrossZoneMove(
CZMove_Struct{
.client_name = client_name,
.coordinates = glm::vec4(x, y, z, 0.0f),
.instance_id = instance_id,
.update_type = CZUpdateType_ClientName,
.update_subtype = CZMoveUpdateSubtype_MoveZoneInstance,
}
);
}
void lua_cross_zone_move_instance_by_client_name(std::string client_name, uint16 instance_id, float x, float y, float z, float heading) {
quest_manager.CrossZoneMove(
CZMove_Struct{
.client_name = client_name,
.coordinates = glm::vec4(x, y, z, heading),
.instance_id = instance_id,
.update_type = CZUpdateType_ClientName,
.update_subtype = CZMoveUpdateSubtype_MoveZoneInstance,
}
);
}
void lua_cross_zone_remove_ldon_loss_by_char_id(int character_id, uint32 theme_id) {
@@ -5890,18 +6224,42 @@ luabind::scope lua_register_general() {
luabind::def("cross_zone_message_player_by_guild_id", &lua_cross_zone_message_player_by_guild_id),
luabind::def("cross_zone_message_player_by_expedition_id", &lua_cross_zone_message_player_by_expedition_id),
luabind::def("cross_zone_message_player_by_name", &lua_cross_zone_message_player_by_name),
luabind::def("cross_zone_move_player_by_char_id", &lua_cross_zone_move_player_by_char_id),
luabind::def("cross_zone_move_player_by_group_id", &lua_cross_zone_move_player_by_group_id),
luabind::def("cross_zone_move_player_by_raid_id", &lua_cross_zone_move_player_by_raid_id),
luabind::def("cross_zone_move_player_by_guild_id", &lua_cross_zone_move_player_by_guild_id),
luabind::def("cross_zone_move_player_by_expedition_id", &lua_cross_zone_move_player_by_expedition_id),
luabind::def("cross_zone_move_player_by_client_name", &lua_cross_zone_move_player_by_client_name),
luabind::def("cross_zone_move_instance_by_char_id", &lua_cross_zone_move_instance_by_char_id),
luabind::def("cross_zone_move_instance_by_group_id", &lua_cross_zone_move_instance_by_group_id),
luabind::def("cross_zone_move_instance_by_raid_id", &lua_cross_zone_move_instance_by_raid_id),
luabind::def("cross_zone_move_instance_by_guild_id", &lua_cross_zone_move_instance_by_guild_id),
luabind::def("cross_zone_move_instance_by_expedition_id", &lua_cross_zone_move_instance_by_expedition_id),
luabind::def("cross_zone_move_instance_by_client_name", &lua_cross_zone_move_instance_by_client_name),
luabind::def("cross_zone_move_player_by_char_id", (void(*)(uint32,std::string))&lua_cross_zone_move_player_by_char_id),
luabind::def("cross_zone_move_player_by_char_id", (void(*)(uint32,std::string,float,float,float))&lua_cross_zone_move_player_by_char_id),
luabind::def("cross_zone_move_player_by_char_id", (void(*)(uint32,std::string,float,float,float,float))&lua_cross_zone_move_player_by_char_id),
luabind::def("cross_zone_move_player_by_group_id", (void(*)(uint32,std::string))&lua_cross_zone_move_player_by_group_id),
luabind::def("cross_zone_move_player_by_group_id", (void(*)(uint32,std::string,float,float,float))&lua_cross_zone_move_player_by_group_id),
luabind::def("cross_zone_move_player_by_group_id", (void(*)(uint32,std::string,float,float,float,float))&lua_cross_zone_move_player_by_group_id),
luabind::def("cross_zone_move_player_by_raid_id", (void(*)(uint32,std::string))&lua_cross_zone_move_player_by_raid_id),
luabind::def("cross_zone_move_player_by_raid_id", (void(*)(uint32,std::string,float,float,float))&lua_cross_zone_move_player_by_raid_id),
luabind::def("cross_zone_move_player_by_raid_id", (void(*)(uint32,std::string,float,float,float,float))&lua_cross_zone_move_player_by_raid_id),
luabind::def("cross_zone_move_player_by_guild_id", (void(*)(uint32,std::string))&lua_cross_zone_move_player_by_guild_id),
luabind::def("cross_zone_move_player_by_guild_id", (void(*)(uint32,std::string,float,float,float))&lua_cross_zone_move_player_by_guild_id),
luabind::def("cross_zone_move_player_by_guild_id", (void(*)(uint32,std::string,float,float,float,float))&lua_cross_zone_move_player_by_guild_id),
luabind::def("cross_zone_move_player_by_expedition_id", (void(*)(uint32,std::string))&lua_cross_zone_move_player_by_expedition_id),
luabind::def("cross_zone_move_player_by_expedition_id", (void(*)(uint32,std::string,float,float,float))&lua_cross_zone_move_player_by_expedition_id),
luabind::def("cross_zone_move_player_by_expedition_id", (void(*)(uint32,std::string,float,float,float,float))&lua_cross_zone_move_player_by_expedition_id),
luabind::def("cross_zone_move_player_by_client_name", (void(*)(std::string,std::string))&lua_cross_zone_move_player_by_client_name),
luabind::def("cross_zone_move_player_by_client_name", (void(*)(std::string,std::string,float,float,float))&lua_cross_zone_move_player_by_client_name),
luabind::def("cross_zone_move_player_by_client_name", (void(*)(std::string,std::string,float,float,float,float))&lua_cross_zone_move_player_by_client_name),
luabind::def("cross_zone_move_instance_by_char_id", (void(*)(uint32,uint16))&lua_cross_zone_move_instance_by_char_id),
luabind::def("cross_zone_move_instance_by_char_id", (void(*)(uint32,uint16,float,float,float))&lua_cross_zone_move_instance_by_char_id),
luabind::def("cross_zone_move_instance_by_char_id", (void(*)(uint32,uint16,float,float,float,float))&lua_cross_zone_move_instance_by_char_id),
luabind::def("cross_zone_move_instance_by_group_id", (void(*)(uint32,uint16))&lua_cross_zone_move_instance_by_group_id),
luabind::def("cross_zone_move_instance_by_group_id", (void(*)(uint32,uint16,float,float,float))&lua_cross_zone_move_instance_by_group_id),
luabind::def("cross_zone_move_instance_by_group_id", (void(*)(uint32,uint16,float,float,float,float))&lua_cross_zone_move_instance_by_group_id),
luabind::def("cross_zone_move_instance_by_raid_id", (void(*)(uint32,uint16))&lua_cross_zone_move_instance_by_raid_id),
luabind::def("cross_zone_move_instance_by_raid_id", (void(*)(uint32,uint16,float,float,float))&lua_cross_zone_move_instance_by_raid_id),
luabind::def("cross_zone_move_instance_by_raid_id", (void(*)(uint32,uint16,float,float,float,float))&lua_cross_zone_move_instance_by_raid_id),
luabind::def("cross_zone_move_instance_by_guild_id", (void(*)(uint32,uint16))&lua_cross_zone_move_instance_by_guild_id),
luabind::def("cross_zone_move_instance_by_guild_id", (void(*)(uint32,uint16,float,float,float))&lua_cross_zone_move_instance_by_guild_id),
luabind::def("cross_zone_move_instance_by_guild_id", (void(*)(uint32,uint16,float,float,float,float))&lua_cross_zone_move_instance_by_guild_id),
luabind::def("cross_zone_move_instance_by_expedition_id", (void(*)(uint32,uint16))&lua_cross_zone_move_instance_by_expedition_id),
luabind::def("cross_zone_move_instance_by_expedition_id", (void(*)(uint32,uint16,float,float,float))&lua_cross_zone_move_instance_by_expedition_id),
luabind::def("cross_zone_move_instance_by_expedition_id", (void(*)(uint32,uint16,float,float,float,float))&lua_cross_zone_move_instance_by_expedition_id),
luabind::def("cross_zone_move_instance_by_client_name", (void(*)(std::string,uint16))&lua_cross_zone_move_instance_by_client_name),
luabind::def("cross_zone_move_instance_by_client_name", (void(*)(std::string,uint16,float,float,float))&lua_cross_zone_move_instance_by_client_name),
luabind::def("cross_zone_move_instance_by_client_name", (void(*)(std::string,uint16,float,float,float,float))&lua_cross_zone_move_instance_by_client_name),
luabind::def("cross_zone_remove_ldon_loss_by_char_id", &lua_cross_zone_remove_ldon_loss_by_char_id),
luabind::def("cross_zone_remove_ldon_loss_by_group_id", &lua_cross_zone_remove_ldon_loss_by_group_id),
luabind::def("cross_zone_remove_ldon_loss_by_raid_id", &lua_cross_zone_remove_ldon_loss_by_raid_id),
+32 -6
View File
@@ -315,11 +315,16 @@ void Lua_Mob::SetInvisible(int state) {
self->SetInvisible(state);
}
bool Lua_Mob::FindBuff(int spell_id) {
bool Lua_Mob::FindBuff(uint16 spell_id) {
Lua_Safe_Call_Bool();
return self->FindBuff(spell_id);
}
bool Lua_Mob::FindBuff(uint16 spell_id, uint16 caster_id) {
Lua_Safe_Call_Bool();
return self->FindBuff(spell_id, caster_id);
}
uint16 Lua_Mob::FindBuffBySlot(int slot) {
Lua_Safe_Call_Int();
return self->FindBuffBySlot(slot);
@@ -873,7 +878,13 @@ bool Lua_Mob::CastSpell(int spell_id, int target_id) {
bool Lua_Mob::CastSpell(int spell_id, int target_id, int slot) {
Lua_Safe_Call_Bool();
return self->CastSpell(spell_id, target_id, static_cast<EQ::spells::CastingSlot>(slot));
int cast_slot = 0;
if (slot >= 0 || slot <= 23 || slot == 255) {
cast_slot = slot;
}
return self->CastSpell(spell_id, target_id, static_cast<EQ::spells::CastingSlot>(cast_slot));
}
bool Lua_Mob::CastSpell(int spell_id, int target_id, int slot, int cast_time) {
@@ -2532,6 +2543,11 @@ void Lua_Mob::ApplySpellBuff(int spell_id, int duration) {
self->ApplySpellBuff(spell_id, duration);
}
void Lua_Mob::ApplySpellBuff(int spell_id, int duration, int level) {
Lua_Safe_Call_Void();
self->ApplySpellBuff(spell_id, level);
}
int Lua_Mob::GetBuffStatValueBySlot(uint8 slot, const char* identifier) {
Lua_Safe_Call_Int();
return self->GetBuffStatValueBySlot(slot, identifier);
@@ -2552,6 +2568,11 @@ void Lua_Mob::SetBuffDuration(int spell_id, int duration) {
self->SetBuffDuration(spell_id, duration);
}
void Lua_Mob::SetBuffDuration(int spell_id, int duration, int level) {
Lua_Safe_Call_Void();
self->SetBuffDuration(spell_id, duration, level);
}
Lua_Mob Lua_Mob::GetUltimateOwner() {
Lua_Safe_Call_Class(Lua_Mob);
return Lua_Mob(self->GetUltimateOwner());
@@ -3166,7 +3187,8 @@ luabind::scope lua_register_mob() {
.def("AddToHateList", (void(Lua_Mob::*)(Lua_Mob,int64,int64,bool,bool))&Lua_Mob::AddToHateList)
.def("AddToHateList", (void(Lua_Mob::*)(Lua_Mob,int64,int64,bool,bool,bool))&Lua_Mob::AddToHateList)
.def("ApplySpellBuff", (void(Lua_Mob::*)(int))&Lua_Mob::ApplySpellBuff)
.def("ApplySpellBuff", (void(Lua_Mob::*)(int, int))&Lua_Mob::ApplySpellBuff)
.def("ApplySpellBuff", (void(Lua_Mob::*)(int,int))&Lua_Mob::ApplySpellBuff)
.def("ApplySpellBuff", (void(Lua_Mob::*)(int,int,int))&Lua_Mob::ApplySpellBuff)
.def("Attack", (bool(Lua_Mob::*)(Lua_Mob))&Lua_Mob::Attack)
.def("Attack", (bool(Lua_Mob::*)(Lua_Mob,int))&Lua_Mob::Attack)
.def("Attack", (bool(Lua_Mob::*)(Lua_Mob,int,bool))&Lua_Mob::Attack)
@@ -3313,7 +3335,8 @@ luabind::scope lua_register_mob() {
.def("Emote", &Lua_Mob::Emote)
.def("EntityVariableExists", &Lua_Mob::EntityVariableExists)
.def("FaceTarget", (void(Lua_Mob::*)(Lua_Mob))&Lua_Mob::FaceTarget)
.def("FindBuff", &Lua_Mob::FindBuff)
.def("FindBuff", (bool(Lua_Mob::*)(uint16))&Lua_Mob::FindBuff)
.def("FindBuff", (bool(Lua_Mob::*)(uint16,uint16))&Lua_Mob::FindBuff)
.def("FindBuffBySlot", (uint16(Lua_Mob::*)(int))&Lua_Mob::FindBuffBySlot)
.def("FindGroundZ", (double(Lua_Mob::*)(double,double))&Lua_Mob::FindGroundZ)
.def("FindGroundZ", (double(Lua_Mob::*)(double,double,double))&Lua_Mob::FindGroundZ)
@@ -3613,7 +3636,8 @@ luabind::scope lua_register_mob() {
.def("SetBucket", (void(Lua_Mob::*)(std::string,std::string))&Lua_Mob::SetBucket)
.def("SetBucket", (void(Lua_Mob::*)(std::string,std::string,std::string))&Lua_Mob::SetBucket)
.def("SetBuffDuration", (void(Lua_Mob::*)(int))&Lua_Mob::SetBuffDuration)
.def("SetBuffDuration", (void(Lua_Mob::*)(int, int))&Lua_Mob::SetBuffDuration)
.def("SetBuffDuration", (void(Lua_Mob::*)(int,int))&Lua_Mob::SetBuffDuration)
.def("SetBuffDuration", (void(Lua_Mob::*)(int,int,int))&Lua_Mob::SetBuffDuration)
.def("SetCurrentWP", &Lua_Mob::SetCurrentWP)
.def("SetDestructibleObject", (void(Lua_Mob::*)(bool))&Lua_Mob::SetDestructibleObject)
.def("SetDisableMelee", (void(Lua_Mob::*)(bool))&Lua_Mob::SetDisableMelee)
@@ -3733,7 +3757,9 @@ luabind::scope lua_register_special_abilities() {
luabind::value("immune_aggro_client", static_cast<int>(IMMUNE_AGGRO_CLIENT)),
luabind::value("immune_aggro_npc", static_cast<int>(IMMUNE_AGGRO_NPC)),
luabind::value("modify_avoid_damage", static_cast<int>(MODIFY_AVOID_DAMAGE)),
luabind::value("immune_open", static_cast<int>(IMMUNE_OPEN))
luabind::value("immune_open", static_cast<int>(IMMUNE_OPEN)),
luabind::value("immune_assassinate", static_cast<int>(IMMUNE_ASSASSINATE)),
luabind::value("immune_headshot", static_cast<int>(IMMUNE_HEADSHOT))
)];
}
+4 -1
View File
@@ -90,7 +90,8 @@ public:
uint8 GetInvisibleUndeadLevel();
void SetSeeInvisibleLevel(uint8 invisible_level);
void SetSeeInvisibleUndeadLevel(uint8 invisible_level);
bool FindBuff(int spell_id);
bool FindBuff(uint16 spell_id);
bool FindBuff(uint16 spell_id, uint16 caster_id);
uint16 FindBuffBySlot(int slot);
uint32 BuffCount();
uint32 BuffCount(bool is_beneficial);
@@ -481,10 +482,12 @@ public:
bool CanRaceEquipItem(uint32 item_id);
void ApplySpellBuff(int spell_id);
void ApplySpellBuff(int spell_id, int duration);
void ApplySpellBuff(int spell_id, int duration, int level);
int GetBuffStatValueBySlot(uint8 slot, const char* identifier);
int GetBuffStatValueBySpell(int spell_id, const char* identifier);
void SetBuffDuration(int spell_id);
void SetBuffDuration(int spell_id, int duration);
void SetBuffDuration(int spell_id, int duration, int level);
void CloneAppearance(Lua_Mob other);
void CloneAppearance(Lua_Mob other, bool clone_name);
void DamageArea(int64 damage);
+30
View File
@@ -354,6 +354,16 @@ void handle_npc_cast(
lua_pushinteger(L, Strings::ToUnsignedInt(sep.arg[2]));
lua_setfield(L, -2, "caster_level");
lua_pushinteger(L, Strings::ToUnsignedInt(sep.arg[3]));
lua_setfield(L, -2, "target_id");
if (extra_pointers && extra_pointers->size() == 1) {
Lua_Mob l_mob(std::any_cast<Mob*>(extra_pointers->at(0)));
luabind::adl::object l_mob_o = luabind::adl::object(L, l_mob);
l_mob_o.push(L);
lua_setfield(L, -2, "target");
}
}
void handle_npc_area(
@@ -715,6 +725,16 @@ void handle_player_cast(
lua_pushinteger(L, Strings::ToUnsignedInt(sep.arg[2]));
lua_setfield(L, -2, "caster_level");
lua_pushinteger(L, Strings::ToUnsignedInt(sep.arg[3]));
lua_setfield(L, -2, "target_id");
if (extra_pointers && extra_pointers->size() == 1) {
Lua_Mob l_mob(std::any_cast<Mob*>(extra_pointers->at(0)));
luabind::adl::object l_mob_o = luabind::adl::object(L, l_mob);
l_mob_o.push(L);
lua_setfield(L, -2, "target");
}
}
void handle_player_task_fail(
@@ -1955,6 +1975,16 @@ void handle_bot_cast(
lua_pushinteger(L, Strings::ToUnsignedInt(sep.arg[2]));
lua_setfield(L, -2, "caster_level");
lua_pushinteger(L, Strings::ToUnsignedInt(sep.arg[3]));
lua_setfield(L, -2, "target_id");
if (extra_pointers && extra_pointers->size() == 1) {
Lua_Mob l_mob(std::any_cast<Mob*>(extra_pointers->at(0)));
luabind::adl::object l_mob_o = luabind::adl::object(L, l_mob);
l_mob_o.push(L);
lua_setfield(L, -2, "target");
}
}
void handle_bot_combat(
+46 -42
View File
@@ -288,8 +288,11 @@ Mob::Mob(
feigned = false;
int max_procs = MAX_PROCS;
m_max_procs = std::min(RuleI(Combat, MaxProcs), max_procs);
// clear the proc arrays
for (int j = 0; j < MAX_PROCS; j++) {
for (int j = 0; j < m_max_procs; j++) {
PermaProcs[j].spellID = SPELL_UNKNOWN;
PermaProcs[j].chance = 0;
PermaProcs[j].base_spellID = SPELL_UNKNOWN;
@@ -511,6 +514,7 @@ Mob::Mob(
SetCanOpenDoors(true);
is_boat = IsBoat();
}
Mob::~Mob()
@@ -593,42 +597,49 @@ void Mob::CalcSeeInvisibleLevel()
see_invis = std::max({ spellbonuses.SeeInvis, itembonuses.SeeInvis, aabonuses.SeeInvis, innate_see_invis });
}
void Mob::CalcInvisibleLevel()
{
bool is_invisible = invisible;
bool Mob::HasAnInvisibilityEffect() {
return invisible || hidden || improved_hidden || invisible_animals || invisible_undead;
}
invisible = std::max({ spellbonuses.invisibility, nobuff_invisible });
invisible_undead = spellbonuses.invisibility_verse_undead;
invisible_animals = spellbonuses.invisibility_verse_animal;
if (!is_invisible && invisible) {
SetInvisible(Invisibility::Invisible, true);
return;
}
if (is_invisible && !invisible) {
SetInvisible(invisible, true);
return;
void Mob::BreakCharmPetIfConditionsMet() {
auto pet = GetPet();
if (pet && pet->GetPetType() == petCharmed && HasAnInvisibilityEffect()) {
if (RuleB(Pets, LivelikeBreakCharmOnInvis) || IsInvisible(pet)) {
pet->BuffFadeByEffect(SE_Charm);
}
LogRules(
"Pets:LivelikeBreakCharmOnInvis for [{}] invisible [{}] hidden [{}] improved_hidden (shroud of stealth) [{}] invisible_animals [{}] invisible_undead [{}]",
GetCleanName(),
invisible,
hidden,
improved_hidden,
invisible_animals,
invisible_undead
);
}
}
void Mob::SetInvisible(uint8 state, bool set_on_bonus_calc)
void Mob::CalcInvisibleLevel()
{
/*
If you set an NPC to invisible you will only be able to see it on
your client if your see invisible level is greater than equal to the invisible level.
Note, the clients spell file must match the servers see invisible level on the spell.
*/
bool was_invisible = invisible;
invisible = std::max({spellbonuses.invisibility, nobuff_invisible});
invisible_undead = spellbonuses.invisibility_verse_undead;
invisible_animals = spellbonuses.invisibility_verse_animal;
if (was_invisible != invisible) {
SetInvisible(invisible, true);
return;
}
BreakCharmPetIfConditionsMet();
}
void Mob::SetInvisible(uint8 state, bool set_on_bonus_calc) {
if (state == Invisibility::Visible) {
SendAppearancePacket(AT_Invis, Invisibility::Visible);
ZeroInvisibleVars(InvisType::T_INVISIBLE);
}
else {
/*
if your setting invisible from a script, or escape/fading memories effect then
we use the internal invis variable which allows invisible without a buff on mob.
*/
} else {
if (!set_on_bonus_calc) {
nobuff_invisible = state;
CalcInvisibleLevel();
@@ -636,14 +647,7 @@ void Mob::SetInvisible(uint8 state, bool set_on_bonus_calc)
SendAppearancePacket(AT_Invis, invisible);
}
// Invis and hide breaks charms
auto pet = GetPet();
if (pet && pet->GetPetType() == petCharmed && (invisible || hidden || improved_hidden || invisible_animals || invisible_undead)) {
if (RuleB(Pets, LivelikeBreakCharmOnInvis) || IsInvisible(pet)) {
pet->BuffFadeByEffect(SE_Charm);
}
LogRules("Pets:LivelikeBreakCharmOnInvis for [{}] | Invis [{}] - Hidden [{}] - Shroud of Stealth [{}] - IVA [{}] - IVU [{}]", GetCleanName(), invisible, hidden, improved_hidden, invisible_animals, invisible_undead);
}
BreakCharmPetIfConditionsMet();
}
void Mob::ZeroInvisibleVars(uint8 invisible_type)
@@ -3460,10 +3464,10 @@ void Mob::ShowBuffs(Client* c) {
);
for (auto i = 0; i < GetMaxTotalSlots(); i++) {
const auto spell_id = buffs[i].spellid;
const auto buff_duration_formula = spells[spell_id].buff_duration_formula;
const auto spell_id = buffs[i].spellid;
if (IsValidSpell(spell_id)) {
const auto is_permanent = (
const auto buff_duration_formula = spells[spell_id].buff_duration_formula;
const auto is_permanent = (
buff_duration_formula == DF_Aura ||
buff_duration_formula == DF_Permanent
);
@@ -5068,7 +5072,7 @@ const char *Mob::GetCleanName()
return clean_name;
}
std::string Mob::GetTargetDescription(Mob* target, uint8 description_type)
std::string Mob::GetTargetDescription(Mob* target, uint8 description_type, uint16 entity_id_override)
{
std::string self_return = "yourself";
@@ -5114,12 +5118,12 @@ std::string Mob::GetTargetDescription(Mob* target, uint8 description_type)
auto d = fmt::format(
"{}",
(
this == target ?
target && this == target ?
self_return :
fmt::format(
"{} ({})",
target->GetCleanName(),
target->GetID()
entity_id_override ? entity_id_override : target->GetID()
)
)
);
+11 -6
View File
@@ -41,7 +41,7 @@
char* strn0cpy(char* dest, const char* source, uint32 size);
#define MAX_SPECIAL_ATTACK_PARAMS 8
#define MAX_SPECIAL_ATTACK_PARAMS 9
class Client;
class EQApplicationPacket;
@@ -269,6 +269,8 @@ public:
return;
}
bool HasAnInvisibilityEffect();
void BreakCharmPetIfConditionsMet();
//Invisible
bool IsInvisible(Mob* other = 0) const;
void SetInvisible(uint8 state, bool set_on_bonus_calc = false);
@@ -464,7 +466,7 @@ public:
void DamageShield(Mob* other, bool spell_ds = false);
int32 RuneAbsorb(int64 damage, uint16 type);
std::vector<uint16> GetBuffSpellIDs();
bool FindBuff(uint16 spell_id);
bool FindBuff(uint16 spell_id, uint16 caster_id = 0);
uint16 FindBuffBySlot(int slot);
uint32 BuffCount(bool is_beneficial = true, bool is_detrimental = true);
bool FindType(uint16 type, bool bOffensive = false, uint16 threshold = 100);
@@ -497,8 +499,8 @@ public:
void ListAppearanceEffects(Client* c);
void ClearAppearenceEffects();
void SendSavedAppearenceEffects(Client *receiver);
void SetBuffDuration(int spell_id, int duration = 0);
void ApplySpellBuff(int spell_id, int duration = 0);
void SetBuffDuration(int spell_id, int duration = 0, int level_override = -1);
void ApplySpellBuff(int spell_id, int duration = 0, int level_override = -1);
int GetBuffStatValueBySpell(int32 spell_id, const char* stat_identifier);
int GetBuffStatValueBySlot(uint8 slot, const char* stat_identifier);
@@ -586,7 +588,7 @@ public:
virtual void SetName(const char *new_name = nullptr) { new_name ? strn0cpy(name, new_name, 64) :
strn0cpy(name, GetName(), 64); return; };
inline Mob* GetTarget() const { return target; }
std::string GetTargetDescription(Mob* target, uint8 description_type = TargetDescriptionType::LCSelf);
std::string GetTargetDescription(Mob* target, uint8 description_type = TargetDescriptionType::LCSelf, uint16 entity_id_override = 0);
virtual void SetTarget(Mob* mob);
inline bool HasTargetReflection() const { return (target && target != this && target->target == this); }
virtual inline float GetHPRatio() const { return max_hp == 0 ? 0 : ((float) current_hp / max_hp * 100); }
@@ -1457,6 +1459,9 @@ protected:
Timer m_z_clip_check_timer;
// dynamically set via memory on constructor
int8 m_max_procs = 0;
virtual bool AI_EngagedCastCheck() { return(false); }
virtual bool AI_PursueCastCheck() { return(false); }
virtual bool AI_IdleCastCheck() { return(false); }
@@ -1598,7 +1603,7 @@ protected:
int16 GetSympatheticSpellProcRate(uint16 spell_id);
uint16 GetSympatheticSpellProcID(uint16 spell_id);
enum {MAX_PROCS = 4};
enum {MAX_PROCS = 10};
tProc PermaProcs[MAX_PROCS];
tProc SpellProcs[MAX_PROCS];
tProc DefensiveProcs[MAX_PROCS];
+100 -16
View File
@@ -65,24 +65,59 @@ void Perl_Bot_ApplySpell(Bot* self, int spell_id, int duration)
self->ApplySpell(spell_id, duration);
}
void Perl_Bot_ApplySpell(Bot* self, int spell_id, int duration, bool allow_pets)
void Perl_Bot_ApplySpell(Bot* self, int spell_id, int duration, int level)
{
self->ApplySpell(spell_id, duration, ApplySpellType::Solo, allow_pets);
self->ApplySpell(spell_id, duration, level, ApplySpellType::Solo);
}
void Perl_Bot_ApplySpell(Bot* self, int spell_id, int duration, int level, bool allow_pets)
{
self->ApplySpell(spell_id, duration, level, ApplySpellType::Solo, allow_pets);
}
void Perl_Bot_ApplySpellGroup(Bot* self, int spell_id)
{
self->ApplySpell(spell_id, 0, ApplySpellType::Group);
self->ApplySpell(spell_id, 0, -1, ApplySpellType::Group);
}
void Perl_Bot_ApplySpellGroup(Bot* self, int spell_id, int duration)
{
self->ApplySpell(spell_id, duration, ApplySpellType::Group);
self->ApplySpell(spell_id, duration, -1, ApplySpellType::Group);
}
void Perl_Bot_ApplySpellGroup(Bot* self, int spell_id, int duration, bool allow_pets)
void Perl_Bot_ApplySpellGroup(Bot* self, int spell_id, int duration, int level)
{
self->ApplySpell(spell_id, duration, ApplySpellType::Group, allow_pets);
self->ApplySpell(spell_id, duration, level, ApplySpellType::Group);
}
void Perl_Bot_ApplySpellGroup(Bot* self, int spell_id, int duration, int level, bool allow_pets)
{
self->ApplySpell(spell_id, duration, level, ApplySpellType::Group, allow_pets);
}
void Perl_Bot_ApplySpellRaid(Bot* self, int spell_id)
{
self->ApplySpell(spell_id, 0, -1, ApplySpellType::Raid);
}
void Perl_Bot_ApplySpellRaid(Bot* self, int spell_id, int duration)
{
self->ApplySpell(spell_id, duration, -1, ApplySpellType::Raid);
}
void Perl_Bot_ApplySpellRaid(Bot* self, int spell_id, int duration, int level)
{
self->ApplySpell(spell_id, duration, level, ApplySpellType::Raid);
}
void Perl_Bot_ApplySpellRaid(Bot* self, int spell_id, int duration, int level, bool allow_pets)
{
self->ApplySpell(spell_id, duration, level, ApplySpellType::Raid, allow_pets);
}
void Perl_Bot_ApplySpellRaid(Bot* self, int spell_id, int duration, int level, bool allow_pets, bool is_raid_group_only)
{
self->ApplySpell(spell_id, duration, level, ApplySpellType::Raid, allow_pets, is_raid_group_only);
}
uint32 Perl_Bot_CountBotItem(Bot* self, uint32 item_id)
@@ -315,24 +350,59 @@ void Perl_Bot_SetSpellDuration(Bot* self, int spell_id, int duration)
self->SetSpellDuration(spell_id, duration);
}
void Perl_Bot_SetSpellDuration(Bot* self, int spell_id, int duration, bool allow_pets)
void Perl_Bot_SetSpellDuration(Bot* self, int spell_id, int duration, int level)
{
self->SetSpellDuration(spell_id, duration, ApplySpellType::Solo, allow_pets);
self->SetSpellDuration(spell_id, duration);
}
void Perl_Bot_SetSpellDuration(Bot* self, int spell_id, int duration, int level, bool allow_pets)
{
self->SetSpellDuration(spell_id, duration, level, ApplySpellType::Solo, allow_pets);
}
void Perl_Bot_SetSpellDurationGroup(Bot* self, int spell_id)
{
self->SetSpellDuration(spell_id, 0, ApplySpellType::Group);
self->SetSpellDuration(spell_id, 0, -1, ApplySpellType::Group);
}
void Perl_Bot_SetSpellDurationGroup(Bot* self, int spell_id, int duration)
{
self->SetSpellDuration(spell_id, duration, ApplySpellType::Group);
self->SetSpellDuration(spell_id, duration, -1, ApplySpellType::Group);
}
void Perl_Bot_SetSpellDurationGroup(Bot* self, int spell_id, int duration, bool allow_pets)
void Perl_Bot_SetSpellDurationGroup(Bot* self, int spell_id, int duration, int level)
{
self->SetSpellDuration(spell_id, duration, ApplySpellType::Group, allow_pets);
self->SetSpellDuration(spell_id, duration, level, ApplySpellType::Group);
}
void Perl_Bot_SetSpellDurationGroup(Bot* self, int spell_id, int duration, int level, bool allow_pets)
{
self->SetSpellDuration(spell_id, duration, level, ApplySpellType::Group, allow_pets);
}
void Perl_Bot_SetSpellDurationRaid(Bot* self, int spell_id)
{
self->SetSpellDuration(spell_id, 0, -1, ApplySpellType::Raid);
}
void Perl_Bot_SetSpellDurationRaid(Bot* self, int spell_id, int duration)
{
self->SetSpellDuration(spell_id, duration, -1, ApplySpellType::Raid);
}
void Perl_Bot_SetSpellDurationRaid(Bot* self, int spell_id, int duration, int level)
{
self->SetSpellDuration(spell_id, duration, level, ApplySpellType::Raid);
}
void Perl_Bot_SetSpellDurationRaid(Bot* self, int spell_id, int duration, int level, bool allow_pets)
{
self->SetSpellDuration(spell_id, duration, level, ApplySpellType::Raid, allow_pets);
}
void Perl_Bot_SetSpellDurationRaid(Bot* self, int spell_id, int duration, int level, bool allow_pets, bool is_raid_group_only)
{
self->SetSpellDuration(spell_id, duration, level, ApplySpellType::Raid, allow_pets, is_raid_group_only);
}
bool Perl_Bot_ReloadBotDataBuckets(Bot* self)
@@ -473,10 +543,17 @@ void perl_register_bot()
package.add("AddItem", &Perl_Bot_AddItem);
package.add("ApplySpell", (void(*)(Bot*, int))&Perl_Bot_ApplySpell);
package.add("ApplySpell", (void(*)(Bot*, int, int))&Perl_Bot_ApplySpell);
package.add("ApplySpell", (void(*)(Bot*, int, int, bool))&Perl_Bot_ApplySpell);
package.add("ApplySpell", (void(*)(Bot*, int, int, int))&Perl_Bot_ApplySpell);
package.add("ApplySpell", (void(*)(Bot*, int, int, int, bool))&Perl_Bot_ApplySpell);
package.add("ApplySpellGroup", (void(*)(Bot*, int))&Perl_Bot_ApplySpellGroup);
package.add("ApplySpellGroup", (void(*)(Bot*, int, int))&Perl_Bot_ApplySpellGroup);
package.add("ApplySpellGroup", (void(*)(Bot*, int, int, bool))&Perl_Bot_ApplySpellGroup);
package.add("ApplySpellGroup", (void(*)(Bot*, int, int, int))&Perl_Bot_ApplySpellGroup);
package.add("ApplySpellGroup", (void(*)(Bot*, int, int, int, bool))&Perl_Bot_ApplySpellGroup);
package.add("ApplySpellRaid", (void(*)(Bot*, int))&Perl_Bot_ApplySpellRaid);
package.add("ApplySpellRaid", (void(*)(Bot*, int, int))&Perl_Bot_ApplySpellRaid);
package.add("ApplySpellRaid", (void(*)(Bot*, int, int, int))&Perl_Bot_ApplySpellRaid);
package.add("ApplySpellRaid", (void(*)(Bot*, int, int, int, bool))&Perl_Bot_ApplySpellRaid);
package.add("ApplySpellRaid", (void(*)(Bot*, int, int, int, bool, bool))&Perl_Bot_ApplySpellRaid);
package.add("Camp", (void(*)(Bot*))&Perl_Bot_Camp);
package.add("Camp", (void(*)(Bot*, bool))&Perl_Bot_Camp);
package.add("CountAugmentEquippedByID", &Perl_Bot_CountAugmentEquippedByID);
@@ -533,10 +610,17 @@ void perl_register_bot()
package.add("SetExpansionBitmask", (void(*)(Bot*, int, bool))&Perl_Bot_SetExpansionBitmask);
package.add("SetSpellDuration", (void(*)(Bot*, int))&Perl_Bot_SetSpellDuration);
package.add("SetSpellDuration", (void(*)(Bot*, int, int))&Perl_Bot_SetSpellDuration);
package.add("SetSpellDuration", (void(*)(Bot*, int, int, bool))&Perl_Bot_SetSpellDuration);
package.add("SetSpellDuration", (void(*)(Bot*, int, int, int))&Perl_Bot_SetSpellDuration);
package.add("SetSpellDuration", (void(*)(Bot*, int, int, int, bool))&Perl_Bot_SetSpellDuration);
package.add("SetSpellDurationGroup", (void(*)(Bot*, int))&Perl_Bot_SetSpellDurationGroup);
package.add("SetSpellDurationGroup", (void(*)(Bot*, int, int))&Perl_Bot_SetSpellDurationGroup);
package.add("SetSpellDurationGroup", (void(*)(Bot*, int, int, bool))&Perl_Bot_SetSpellDurationGroup);
package.add("SetSpellDurationGroup", (void(*)(Bot*, int, int, int))&Perl_Bot_SetSpellDurationGroup);
package.add("SetSpellDurationGroup", (void(*)(Bot*, int, int, int, bool))&Perl_Bot_SetSpellDurationGroup);
package.add("SetSpellDurationRaid", (void(*)(Bot*, int))&Perl_Bot_SetSpellDurationRaid);
package.add("SetSpellDurationRaid", (void(*)(Bot*, int, int))&Perl_Bot_SetSpellDurationRaid);
package.add("SetSpellDurationRaid", (void(*)(Bot*, int, int, int))&Perl_Bot_SetSpellDurationRaid);
package.add("SetSpellDurationRaid", (void(*)(Bot*, int, int, int, bool))&Perl_Bot_SetSpellDurationRaid);
package.add("SetSpellDurationRaid", (void(*)(Bot*, int, int, int, bool, bool))&Perl_Bot_SetSpellDurationRaid);
package.add("Signal", &Perl_Bot_Signal);
package.add("Sit", &Perl_Bot_Sit);
package.add("Stand", &Perl_Bot_Stand);
+99 -50
View File
@@ -2616,59 +2616,74 @@ void Perl_Client_ApplySpell(Client* self, int spell_id, int duration)
self->ApplySpell(spell_id, duration);
}
void Perl_Client_ApplySpell(Client* self, int spell_id, int duration, bool allow_pets)
void Perl_Client_ApplySpell(Client* self, int spell_id, int duration, int level)
{
self->ApplySpell(spell_id, duration, ApplySpellType::Solo, allow_pets);
self->ApplySpell(spell_id, duration, level);
}
void Perl_Client_ApplySpell(Client* self, int spell_id, int duration, bool allow_pets, bool allow_bots)
void Perl_Client_ApplySpell(Client* self, int spell_id, int duration, int level, bool allow_pets)
{
self->ApplySpell(spell_id, duration, ApplySpellType::Solo, allow_pets, true, allow_bots);
self->ApplySpell(spell_id, duration, level, ApplySpellType::Solo, allow_pets);
}
void Perl_Client_ApplySpell(Client* self, int spell_id, int duration, int level, bool allow_pets, bool allow_bots)
{
self->ApplySpell(spell_id, duration, level, ApplySpellType::Solo, allow_pets, true, allow_bots);
}
void Perl_Client_ApplySpellGroup(Client* self, int spell_id)
{
self->ApplySpell(spell_id, 0, ApplySpellType::Group);
self->ApplySpell(spell_id, 0, -1, ApplySpellType::Group);
}
void Perl_Client_ApplySpellGroup(Client* self, int spell_id, int duration)
{
self->ApplySpell(spell_id, duration, ApplySpellType::Group);
self->ApplySpell(spell_id, duration, -1, ApplySpellType::Group);
}
void Perl_Client_ApplySpellGroup(Client* self, int spell_id, int duration, bool allow_pets)
void Perl_Client_ApplySpellGroup(Client* self, int spell_id, int duration, int level)
{
self->ApplySpell(spell_id, duration, ApplySpellType::Group, allow_pets);
self->ApplySpell(spell_id, duration, level, ApplySpellType::Group);
}
void Perl_Client_ApplySpellGroup(Client* self, int spell_id, int duration, bool allow_pets, bool allow_bots)
void Perl_Client_ApplySpellGroup(Client* self, int spell_id, int duration, int level, bool allow_pets)
{
self->ApplySpell(spell_id, duration, ApplySpellType::Group, allow_pets, true, allow_bots);
self->ApplySpell(spell_id, duration, level, ApplySpellType::Group, allow_pets);
}
void Perl_Client_ApplySpellGroup(Client* self, int spell_id, int duration, int level, bool allow_pets, bool allow_bots)
{
self->ApplySpell(spell_id, duration, level, ApplySpellType::Group, allow_pets, true, allow_bots);
}
void Perl_Client_ApplySpellRaid(Client* self, int spell_id)
{
self->ApplySpell(spell_id, 0, ApplySpellType::Raid);
self->ApplySpell(spell_id, 0, -1, ApplySpellType::Raid);
}
void Perl_Client_ApplySpellRaid(Client* self, int spell_id, int duration)
{
self->ApplySpell(spell_id, duration, ApplySpellType::Raid);
self->ApplySpell(spell_id, duration, -1, ApplySpellType::Raid);
}
void Perl_Client_ApplySpellRaid(Client* self, int spell_id, int duration, bool allow_pets)
void Perl_Client_ApplySpellRaid(Client* self, int spell_id, int duration, int level)
{
self->ApplySpell(spell_id, duration, ApplySpellType::Raid, allow_pets);
self->ApplySpell(spell_id, duration, level, ApplySpellType::Raid);
}
void Perl_Client_ApplySpellRaid(Client* self, int spell_id, int duration, bool allow_pets, bool is_raid_group_only)
void Perl_Client_ApplySpellRaid(Client* self, int spell_id, int duration, int level, bool allow_pets)
{
self->ApplySpell(spell_id, duration, ApplySpellType::Raid, allow_pets, is_raid_group_only);
self->ApplySpell(spell_id, duration, level, ApplySpellType::Raid, allow_pets);
}
void Perl_Client_ApplySpellRaid(Client* self, int spell_id, int duration, bool allow_pets, bool is_raid_group_only, bool allow_bots)
void Perl_Client_ApplySpellRaid(Client* self, int spell_id, int duration, int level, bool allow_pets, bool is_raid_group_only)
{
self->ApplySpell(spell_id, duration, ApplySpellType::Raid, allow_pets, is_raid_group_only, allow_bots);
self->ApplySpell(spell_id, duration, level, ApplySpellType::Raid, allow_pets, is_raid_group_only);
}
void Perl_Client_ApplySpellRaid(Client* self, int spell_id, int duration, int level, bool allow_pets, bool is_raid_group_only, bool allow_bots)
{
self->ApplySpell(spell_id, duration, level, ApplySpellType::Raid, allow_pets, is_raid_group_only, allow_bots);
}
void Perl_Client_SetSpellDuration(Client* self, int spell_id)
@@ -2681,59 +2696,74 @@ void Perl_Client_SetSpellDuration(Client* self, int spell_id, int duration)
self->SetSpellDuration(spell_id, duration);
}
void Perl_Client_SetSpellDuration(Client* self, int spell_id, int duration, bool allow_pets)
void Perl_Client_SetSpellDuration(Client* self, int spell_id, int duration, int level)
{
self->SetSpellDuration(spell_id, duration, ApplySpellType::Solo, allow_pets);
self->SetSpellDuration(spell_id, duration, level);
}
void Perl_Client_SetSpellDuration(Client* self, int spell_id, int duration, bool allow_pets, bool allow_bots)
void Perl_Client_SetSpellDuration(Client* self, int spell_id, int duration, int level, bool allow_pets)
{
self->SetSpellDuration(spell_id, duration, ApplySpellType::Solo, allow_pets, true, allow_bots);
self->SetSpellDuration(spell_id, duration, level, ApplySpellType::Solo, allow_pets);
}
void Perl_Client_SetSpellDuration(Client* self, int spell_id, int duration, int level, bool allow_pets, bool allow_bots)
{
self->SetSpellDuration(spell_id, duration, level, ApplySpellType::Solo, allow_pets, true, allow_bots);
}
void Perl_Client_SetSpellDurationGroup(Client* self, int spell_id)
{
self->SetSpellDuration(spell_id, 0, ApplySpellType::Group);
self->SetSpellDuration(spell_id, 0, -1, ApplySpellType::Group);
}
void Perl_Client_SetSpellDurationGroup(Client* self, int spell_id, int duration)
{
self->SetSpellDuration(spell_id, duration, ApplySpellType::Group);
self->SetSpellDuration(spell_id, duration, -1, ApplySpellType::Group);
}
void Perl_Client_SetSpellDurationGroup(Client* self, int spell_id, int duration, bool allow_pets)
void Perl_Client_SetSpellDurationGroup(Client* self, int spell_id, int duration, int level)
{
self->SetSpellDuration(spell_id, duration, ApplySpellType::Group, allow_pets);
self->SetSpellDuration(spell_id, duration, level, ApplySpellType::Group);
}
void Perl_Client_SetSpellDurationGroup(Client* self, int spell_id, int duration, bool allow_pets, bool allow_bots)
void Perl_Client_SetSpellDurationGroup(Client* self, int spell_id, int duration, int level, bool allow_pets)
{
self->SetSpellDuration(spell_id, duration, ApplySpellType::Group, allow_pets, true, allow_bots);
self->SetSpellDuration(spell_id, duration, level, ApplySpellType::Group, allow_pets);
}
void Perl_Client_SetSpellDurationGroup(Client* self, int spell_id, int duration, int level, bool allow_pets, bool allow_bots)
{
self->SetSpellDuration(spell_id, duration, level, ApplySpellType::Group, allow_pets, true, allow_bots);
}
void Perl_Client_SetSpellDurationRaid(Client* self, int spell_id)
{
self->ApplySpell(spell_id, 0, ApplySpellType::Raid);
self->ApplySpell(spell_id, 0, -1, ApplySpellType::Raid);
}
void Perl_Client_SetSpellDurationRaid(Client* self, int spell_id, int duration)
{
self->ApplySpell(spell_id, duration, ApplySpellType::Raid);
self->ApplySpell(spell_id, duration, -1, ApplySpellType::Raid);
}
void Perl_Client_SetSpellDurationRaid(Client* self, int spell_id, int duration, bool allow_pets)
void Perl_Client_SetSpellDurationRaid(Client* self, int spell_id, int duration, int level)
{
self->SetSpellDuration(spell_id, duration, ApplySpellType::Raid, allow_pets);
self->ApplySpell(spell_id, duration, level, ApplySpellType::Raid);
}
void Perl_Client_SetSpellDurationRaid(Client* self, int spell_id, int duration, bool allow_pets, bool is_raid_group_only)
void Perl_Client_SetSpellDurationRaid(Client* self, int spell_id, int duration, int level, bool allow_pets)
{
self->SetSpellDuration(spell_id, duration, ApplySpellType::Raid, allow_pets, is_raid_group_only);
self->SetSpellDuration(spell_id, duration, level, ApplySpellType::Raid, allow_pets);
}
void Perl_Client_SetSpellDurationRaid(Client* self, int spell_id, int duration, bool allow_pets, bool is_raid_group_only, bool allow_bots)
void Perl_Client_SetSpellDurationRaid(Client* self, int spell_id, int duration, int level, bool allow_pets, bool is_raid_group_only)
{
self->SetSpellDuration(spell_id, duration, ApplySpellType::Raid, allow_pets, is_raid_group_only, allow_bots);
self->SetSpellDuration(spell_id, duration, level, ApplySpellType::Raid, allow_pets, is_raid_group_only);
}
void Perl_Client_SetSpellDurationRaid(Client* self, int spell_id, int duration, int level, bool allow_pets, bool is_raid_group_only, bool allow_bots)
{
self->SetSpellDuration(spell_id, duration, level, ApplySpellType::Raid, allow_pets, is_raid_group_only, allow_bots);
}
perl::array Perl_Client_GetPEQZoneFlags(Client* self)
@@ -2952,6 +2982,16 @@ void Perl_Client_SetLDoNPoints(Client* self, uint32 theme_id, uint32 points)
self->SetLDoNPoints(theme_id, points);
}
void Perl_Client_GrantAllAAPoints(Client* self)
{
self->GrantAllAAPoints();
}
void Perl_Client_GrantAllAAPoints(Client* self, uint8 unlock_level)
{
self->GrantAllAAPoints(unlock_level);
}
void perl_register_client()
{
perl::interpreter perl(PERL_GET_THX);
@@ -2985,17 +3025,20 @@ void perl_register_client()
package.add("Admin", &Perl_Client_Admin);
package.add("ApplySpell", (void(*)(Client*, int))&Perl_Client_ApplySpell);
package.add("ApplySpell", (void(*)(Client*, int, int))&Perl_Client_ApplySpell);
package.add("ApplySpell", (void(*)(Client*, int, int, bool))&Perl_Client_ApplySpell);
package.add("ApplySpell", (void(*)(Client*, int, int, bool, bool))&Perl_Client_ApplySpell);
package.add("ApplySpell", (void(*)(Client*, int, int, int))&Perl_Client_ApplySpell);
package.add("ApplySpell", (void(*)(Client*, int, int, int, bool))&Perl_Client_ApplySpell);
package.add("ApplySpell", (void(*)(Client*, int, int, int, bool, bool))&Perl_Client_ApplySpell);
package.add("ApplySpellGroup", (void(*)(Client*, int))&Perl_Client_ApplySpellGroup);
package.add("ApplySpellGroup", (void(*)(Client*, int, int))&Perl_Client_ApplySpellGroup);
package.add("ApplySpellGroup", (void(*)(Client*, int, int, bool))&Perl_Client_ApplySpellGroup);
package.add("ApplySpellGroup", (void(*)(Client*, int, int, bool, bool))&Perl_Client_ApplySpellGroup);
package.add("ApplySpellGroup", (void(*)(Client*, int, int, int))&Perl_Client_ApplySpellGroup);
package.add("ApplySpellGroup", (void(*)(Client*, int, int, int, bool))&Perl_Client_ApplySpellGroup);
package.add("ApplySpellGroup", (void(*)(Client*, int, int, int, bool, bool))&Perl_Client_ApplySpellGroup);
package.add("ApplySpellRaid", (void(*)(Client*, int))&Perl_Client_ApplySpellRaid);
package.add("ApplySpellRaid", (void(*)(Client*, int, int))&Perl_Client_ApplySpellRaid);
package.add("ApplySpellRaid", (void(*)(Client*, int, int, bool))&Perl_Client_ApplySpellRaid);
package.add("ApplySpellRaid", (void(*)(Client*, int, int, bool, bool))&Perl_Client_ApplySpellRaid);
package.add("ApplySpellRaid", (void(*)(Client*, int, int, bool, bool, bool))&Perl_Client_ApplySpellRaid);
package.add("ApplySpellRaid", (void(*)(Client*, int, int, int))&Perl_Client_ApplySpellRaid);
package.add("ApplySpellRaid", (void(*)(Client*, int, int, int, bool))&Perl_Client_ApplySpellRaid);
package.add("ApplySpellRaid", (void(*)(Client*, int, int, int, bool, bool))&Perl_Client_ApplySpellRaid);
package.add("ApplySpellRaid", (void(*)(Client*, int, int, int, bool, bool, bool))&Perl_Client_ApplySpellRaid);
package.add("AssignTask", (void(*)(Client*, int))&Perl_Client_AssignTask);
package.add("AssignTask", (void(*)(Client*, int, int))&Perl_Client_AssignTask);
package.add("AssignTask", (void(*)(Client*, int, int, bool))&Perl_Client_AssignTask);
@@ -3199,6 +3242,8 @@ void perl_register_client()
package.add("GetPEQZoneFlags", &Perl_Client_GetPEQZoneFlags);
package.add("GetZoneFlags", &Perl_Client_GetZoneFlags);
package.add("GoFish", &Perl_Client_GoFish);
package.add("GrantAllAAPoints", (void(*)(Client*))&Perl_Client_GrantAllAAPoints);
package.add("GrantAllAAPoints", (void(*)(Client*, uint8))&Perl_Client_GrantAllAAPoints);
package.add("GrantAlternateAdvancementAbility", (bool(*)(Client*, int, int))&Perl_Client_GrantAlternateAdvancementAbility);
package.add("GrantAlternateAdvancementAbility", (bool(*)(Client*, int, int, bool))&Perl_Client_GrantAlternateAdvancementAbility);
package.add("GuildID", &Perl_Client_GuildID);
@@ -3410,17 +3455,21 @@ void perl_register_client()
package.add("SetSkillPoints", &Perl_Client_SetSkillPoints);
package.add("SetSpellDuration", (void(*)(Client*, int))&Perl_Client_SetSpellDuration);
package.add("SetSpellDuration", (void(*)(Client*, int, int))&Perl_Client_SetSpellDuration);
package.add("SetSpellDuration", (void(*)(Client*, int, int, bool))&Perl_Client_SetSpellDuration);
package.add("SetSpellDuration", (void(*)(Client*, int, int, bool, bool))&Perl_Client_SetSpellDuration);
package.add("SetSpellDuration", (void(*)(Client*, int, int, int))&Perl_Client_SetSpellDuration);
package.add("SetSpellDuration", (void(*)(Client*, int, int, int, bool))&Perl_Client_SetSpellDuration);
package.add("SetSpellDuration", (void(*)(Client*, int, int, int, bool, bool))&Perl_Client_SetSpellDuration);
package.add("SetSpellDurationGroup", (void(*)(Client*, int))&Perl_Client_SetSpellDurationGroup);
package.add("SetSpellDurationGroup", (void(*)(Client*, int, int))&Perl_Client_SetSpellDurationGroup);
package.add("SetSpellDurationGroup", (void(*)(Client*, int, int, bool))&Perl_Client_SetSpellDurationGroup);
package.add("SetSpellDurationGroup", (void(*)(Client*, int, int, bool, bool))&Perl_Client_SetSpellDurationGroup);
package.add("SetSpellDurationGroup", (void(*)(Client*, int, int, int))&Perl_Client_SetSpellDurationGroup);
package.add("SetSpellDurationGroup", (void(*)(Client*, int, int, int, bool))&Perl_Client_SetSpellDurationGroup);
package.add("SetSpellDurationGroup", (void(*)(Client*, int, int, int, bool, bool))&Perl_Client_SetSpellDurationGroup);
package.add("SetSpellDurationRaid", (void(*)(Client*, int))&Perl_Client_SetSpellDurationRaid);
package.add("SetSpellDurationRaid", (void(*)(Client*, int, int))&Perl_Client_SetSpellDurationRaid);
package.add("SetSpellDurationRaid", (void(*)(Client*, int, int, bool))&Perl_Client_SetSpellDurationRaid);
package.add("SetSpellDurationRaid", (void(*)(Client*, int, int, bool, bool))&Perl_Client_SetSpellDurationRaid);
package.add("SetSpellDurationRaid", (void(*)(Client*, int, int, bool, bool, bool))&Perl_Client_SetSpellDurationRaid);
package.add("SetSpellDurationRaid", (void(*)(Client*, int, int, int))&Perl_Client_SetSpellDurationRaid);
package.add("SetSpellDurationRaid", (void(*)(Client*, int, int, int, bool))&Perl_Client_SetSpellDurationRaid);
package.add("SetSpellDurationRaid", (void(*)(Client*, int, int, int, bool, bool))&Perl_Client_SetSpellDurationRaid);
package.add("SetSpellDurationRaid", (void(*)(Client*, int, int, int, bool, bool, bool))&Perl_Client_SetSpellDurationRaid);
package.add("SetSpellDurationRaid", (void(*)(Client*, int, int, int, bool, bool, bool))&Perl_Client_SetSpellDurationRaid);
package.add("SetStartZone", (void(*)(Client*, uint32))&Perl_Client_SetStartZone);
package.add("SetStartZone", (void(*)(Client*, uint32, float, float, float))&Perl_Client_SetStartZone);
package.add("SetStartZone", (void(*)(Client*, uint32, float, float, float, float))&Perl_Client_SetStartZone);
+30 -133
View File
@@ -362,6 +362,11 @@ bool Perl_Mob_FindBuff(Mob* self, uint16 spell_id) // @categories Spells and Dis
return self->FindBuff(spell_id);
}
bool Perl_Mob_FindBuff(Mob* self, uint16 spell_id, uint16 caster_id) // @categories Spells and Disciplines, Script Utility
{
return self->FindBuff(spell_id, caster_id);
}
int Perl_Mob_FindBuffBySlot(Mob* self, int slot) // @categories Spells and Disciplines, Script Utility
{
return self->FindBuffBySlot(slot);
@@ -1897,13 +1902,7 @@ void Perl_Mob_SendIllusion(Mob *self, uint16 race_id, uint8 gender_id, uint8 tex
);
}
void Perl_Mob_SendIllusion(
Mob *self,
uint16 race_id,
uint8 gender_id,
uint8 texture,
uint8 helmet_texture
) // @categories Script Utility
void Perl_Mob_SendIllusion(Mob *self, uint16 race_id, uint8 gender_id, uint8 texture, uint8 helmet_texture) // @categories Script Utility
{
self->SendIllusionPacket(
AppearanceStruct{
@@ -1915,14 +1914,7 @@ void Perl_Mob_SendIllusion(
);
}
void Perl_Mob_SendIllusion(
Mob *self,
uint16 race_id,
uint8 gender_id,
uint8 texture,
uint8 helmet_texture,
uint8 face
) // @categories Script Utility
void Perl_Mob_SendIllusion(Mob *self, uint16 race_id, uint8 gender_id, uint8 texture, uint8 helmet_texture, uint8 face) // @categories Script Utility
{
self->SendIllusionPacket(
AppearanceStruct{
@@ -1935,15 +1927,7 @@ void Perl_Mob_SendIllusion(
);
}
void Perl_Mob_SendIllusion(
Mob *self,
uint16 race_id,
uint8 gender_id,
uint8 texture,
uint8 helmet_texture,
uint8 face,
uint8 hair
) // @categories Script Utility
void Perl_Mob_SendIllusion(Mob *self, uint16 race_id, uint8 gender_id, uint8 texture, uint8 helmet_texture, uint8 face, uint8 hair) // @categories Script Utility
{
self->SendIllusionPacket(
AppearanceStruct{
@@ -1957,16 +1941,7 @@ void Perl_Mob_SendIllusion(
);
}
void Perl_Mob_SendIllusion(
Mob *self,
uint16 race_id,
uint8 gender_id,
uint8 texture,
uint8 helmet_texture,
uint8 face,
uint8 hair,
uint8 hair_color
) // @categories Script Utility
void Perl_Mob_SendIllusion(Mob *self, uint16 race_id, uint8 gender_id, uint8 texture, uint8 helmet_texture, uint8 face, uint8 hair, uint8 hair_color) // @categories Script Utility
{
self->SendIllusionPacket(
AppearanceStruct{
@@ -1981,17 +1956,7 @@ void Perl_Mob_SendIllusion(
);
}
void Perl_Mob_SendIllusion(
Mob *self,
uint16 race_id,
uint8 gender_id,
uint8 texture,
uint8 helmet_texture,
uint8 face,
uint8 hair,
uint8 hair_color,
uint8 beard
) // @categories Script Utility
void Perl_Mob_SendIllusion(Mob *self, uint16 race_id, uint8 gender_id, uint8 texture, uint8 helmet_texture, uint8 face, uint8 hair, uint8 hair_color, uint8 beard) // @categories Script Utility
{
self->SendIllusionPacket(
AppearanceStruct{
@@ -2007,18 +1972,7 @@ void Perl_Mob_SendIllusion(
);
}
void Perl_Mob_SendIllusion(
Mob *self,
uint16 race_id,
uint8 gender_id,
uint8 texture,
uint8 helmet_texture,
uint8 face,
uint8 hair,
uint8 hair_color,
uint8 beard,
uint8 beard_color
) // @categories Script Utility
void Perl_Mob_SendIllusion(Mob *self, uint16 race_id, uint8 gender_id, uint8 texture, uint8 helmet_texture, uint8 face, uint8 hair, uint8 hair_color, uint8 beard, uint8 beard_color) // @categories Script Utility
{
self->SendIllusionPacket(
AppearanceStruct{
@@ -2035,19 +1989,7 @@ void Perl_Mob_SendIllusion(
);
}
void Perl_Mob_SendIllusion(
Mob *self,
uint16 race_id,
uint8 gender_id,
uint8 texture,
uint8 helmet_texture,
uint8 face,
uint8 hair,
uint8 hair_color,
uint8 beard,
uint8 beard_color,
uint32 drakkin_heritage
) // @categories Script Utility
void Perl_Mob_SendIllusion(Mob *self, uint16 race_id, uint8 gender_id, uint8 texture, uint8 helmet_texture, uint8 face, uint8 hair, uint8 hair_color, uint8 beard, uint8 beard_color, uint32 drakkin_heritage) // @categories Script Utility
{
self->SendIllusionPacket(
AppearanceStruct{
@@ -2065,20 +2007,7 @@ void Perl_Mob_SendIllusion(
);
}
void Perl_Mob_SendIllusion(
Mob *self,
uint16 race_id,
uint8 gender_id,
uint8 texture,
uint8 helmet_texture,
uint8 face,
uint8 hair,
uint8 hair_color,
uint8 beard,
uint8 beard_color,
uint32 drakkin_heritage,
uint32 drakkin_tattoo
) // @categories Script Utility
void Perl_Mob_SendIllusion(Mob *self, uint16 race_id, uint8 gender_id, uint8 texture, uint8 helmet_texture, uint8 face, uint8 hair, uint8 hair_color, uint8 beard, uint8 beard_color, uint32 drakkin_heritage, uint32 drakkin_tattoo) // @categories Script Utility
{
self->SendIllusionPacket(
AppearanceStruct{
@@ -2097,21 +2026,7 @@ void Perl_Mob_SendIllusion(
);
}
void Perl_Mob_SendIllusion(
Mob *self,
uint16 race_id,
uint8 gender_id,
uint8 texture,
uint8 helmet_texture,
uint8 face,
uint8 hair,
uint8 hair_color,
uint8 beard,
uint8 beard_color,
uint32 drakkin_heritage,
uint32 drakkin_tattoo,
uint32 drakkin_details
) // @categories Script Utility
void Perl_Mob_SendIllusion(Mob *self, uint16 race_id, uint8 gender_id, uint8 texture, uint8 helmet_texture, uint8 face, uint8 hair, uint8 hair_color, uint8 beard, uint8 beard_color, uint32 drakkin_heritage, uint32 drakkin_tattoo, uint32 drakkin_details) // @categories Script Utility
{
self->SendIllusionPacket(
AppearanceStruct{
@@ -2131,22 +2046,7 @@ void Perl_Mob_SendIllusion(
);
}
void Perl_Mob_SendIllusion(
Mob *self,
uint16 race_id,
uint8 gender_id,
uint8 texture,
uint8 helmet_texture,
uint8 face,
uint8 hair,
uint8 hair_color,
uint8 beard,
uint8 beard_color,
uint32 drakkin_heritage,
uint32 drakkin_tattoo,
uint32 drakkin_details,
float size
) // @categories Script Utility
void Perl_Mob_SendIllusion(Mob *self, uint16 race_id, uint8 gender_id, uint8 texture, uint8 helmet_texture, uint8 face, uint8 hair, uint8 hair_color, uint8 beard, uint8 beard_color, uint32 drakkin_heritage, uint32 drakkin_tattoo, uint32 drakkin_details, float size) // @categories Script Utility
{
self->SendIllusionPacket(
AppearanceStruct{
@@ -2167,23 +2067,7 @@ void Perl_Mob_SendIllusion(
);
}
void Perl_Mob_SendIllusion(
Mob *self,
uint16 race_id,
uint8 gender_id,
uint8 texture,
uint8 helmet_texture,
uint8 face,
uint8 hair,
uint8 hair_color,
uint8 beard,
uint8 beard_color,
uint32 drakkin_heritage,
uint32 drakkin_tattoo,
uint32 drakkin_details,
float size,
Client *target
) // @categories Script Utility
void Perl_Mob_SendIllusion(Mob *self, uint16 race_id, uint8 gender_id, uint8 texture, uint8 helmet_texture, uint8 face, uint8 hair, uint8 hair_color, uint8 beard, uint8 beard_color, uint32 drakkin_heritage, uint32 drakkin_tattoo, uint32 drakkin_details, float size, Client *target) // @categories Script Utility
{
self->SendIllusionPacket(
AppearanceStruct{
@@ -2880,6 +2764,11 @@ void Perl_Mob_SetBuffDuration(Mob* self, int spell_id, int duration) // @categor
self->SetBuffDuration(spell_id, duration);
}
void Perl_Mob_SetBuffDuration(Mob* self, int spell_id, int duration, int level) // @categories Script Utility, Spells and Disciplines
{
self->SetBuffDuration(spell_id, duration, level);
}
void Perl_Mob_ApplySpellBuff(Mob* self, int spell_id) // @categories Script Utility, Spells and Disciplines
{
self->ApplySpellBuff(spell_id);
@@ -2890,6 +2779,11 @@ void Perl_Mob_ApplySpellBuff(Mob* self, int spell_id, int duration) // @categori
self->ApplySpellBuff(spell_id, duration);
}
void Perl_Mob_ApplySpellBuff(Mob* self, int spell_id, int duration, int level) // @categories Script Utility, Spells and Disciplines
{
self->ApplySpellBuff(spell_id, duration, level);
}
int Perl_Mob_GetSkillDmgAmt(Mob* self, int skill_id)
{
return self->GetSkillDmgAmt(skill_id);
@@ -3436,6 +3330,7 @@ void perl_register_mob()
package.add("AddToHateList", (void(*)(Mob*, Mob*, int64_t, int64_t, bool, bool, bool))&Perl_Mob_AddToHateList);
package.add("ApplySpellBuff", (void(*)(Mob*, int))&Perl_Mob_ApplySpellBuff);
package.add("ApplySpellBuff", (void(*)(Mob*, int, int))&Perl_Mob_ApplySpellBuff);
package.add("ApplySpellBuff", (void(*)(Mob*, int, int, int))&Perl_Mob_ApplySpellBuff);
package.add("Attack", (bool(*)(Mob*, Mob*))&Perl_Mob_Attack);
package.add("Attack", (bool(*)(Mob*, Mob*, int))&Perl_Mob_Attack);
package.add("Attack", (bool(*)(Mob*, Mob*, int, bool))&Perl_Mob_Attack);
@@ -3559,7 +3454,8 @@ void perl_register_mob()
package.add("EntityVariableExists", &Perl_Mob_EntityVariableExists);
package.add("FaceTarget", (void(*)(Mob*))&Perl_Mob_FaceTarget);
package.add("FaceTarget", (void(*)(Mob*, Mob*))&Perl_Mob_FaceTarget);
package.add("FindBuff", &Perl_Mob_FindBuff);
package.add("FindBuff", (bool(*)(Mob*, uint16))&Perl_Mob_FindBuff);
package.add("FindBuff", (bool(*)(Mob*, uint16, uint16))&Perl_Mob_FindBuff);
package.add("FindBuffBySlot", &Perl_Mob_FindBuffBySlot);
package.add("FindGroundZ", (float(*)(Mob*, float, float))&Perl_Mob_FindGroundZ);
package.add("FindGroundZ", (float(*)(Mob*, float, float, float))&Perl_Mob_FindGroundZ);
@@ -3927,6 +3823,7 @@ void perl_register_mob()
package.add("SetBucket", (void(*)(Mob*, std::string, std::string, std::string))&Perl_Mob_SetBucket);
package.add("SetBuffDuration", (void(*)(Mob*, int))&Perl_Mob_SetBuffDuration);
package.add("SetBuffDuration", (void(*)(Mob*, int, int))&Perl_Mob_SetBuffDuration);
package.add("SetBuffDuration", (void(*)(Mob*, int, int, int))&Perl_Mob_SetBuffDuration);
package.add("SetCurrentWP", &Perl_Mob_SetCurrentWP);
package.add("SetDeltas", &Perl_Mob_SetDeltas);
package.add("SetDisableMelee", &Perl_Mob_SetDisableMelee);
+20 -8
View File
@@ -2650,6 +2650,8 @@ bool QuestManager::createBot(const char *name, const char *lastname, uint8 level
).c_str()
);
} else {
new_bot->AddBotStartingItems(race, botclass);
initiator->Message(
Chat::White,
fmt::format(
@@ -3980,15 +3982,25 @@ void QuestManager::CrossZoneMessage(uint8 update_type, int update_identifier, ui
safe_delete(pack);
}
void QuestManager::CrossZoneMove(uint8 update_type, uint8 update_subtype, int update_identifier, const char* zone_short_name, uint16 instance_id, const char* client_name) {
void QuestManager::CrossZoneMove(const CZMove_Struct& m)
{
auto pack = new ServerPacket(ServerOP_CZMove, sizeof(CZMove_Struct));
CZMove_Struct* CZM = (CZMove_Struct*)pack->pBuffer;
CZM->update_type = update_type;
CZM->update_subtype = update_subtype;
CZM->update_identifier = update_identifier;
strn0cpy(CZM->zone_short_name, zone_short_name, 32);
CZM->instance_id = instance_id;
strn0cpy(CZM->client_name, client_name, 64);
auto s = (CZMove_Struct*) pack->pBuffer;
if (!m.client_name.empty()) {
s->client_name = m.client_name;
}
s->coordinates = m.coordinates;
s->instance_id = m.instance_id;
s->update_type = m.update_type;
s->update_subtype = m.update_subtype;
s->update_identifier = m.update_identifier;
if (!m.zone_short_name.empty()) {
s->zone_short_name = m.zone_short_name;
}
worldserver.SendPacket(pack);
safe_delete(pack);
}
+1 -1
View File
@@ -312,7 +312,7 @@ public:
void CrossZoneLDoNUpdate(uint8 update_type, uint8 update_subtype, int update_identifier, uint32 theme_id, int points = 1, const char* client_name = "");
void CrossZoneMarquee(uint8 update_type, int update_identifier, uint32 type, uint32 priority, uint32 fade_in, uint32 fade_out, uint32 duration, const char* message, const char* client_name = "");
void CrossZoneMessage(uint8 update_type, int update_identifier, uint32 type, const char* message, const char* client_name = "");
void CrossZoneMove(uint8 update_type, uint8 update_subtype, int update_identifier, const char* zone_short_name, uint16 instance_id, const char* client_name = "");
void CrossZoneMove(const CZMove_Struct& m);
void CrossZoneSetEntityVariable(uint8 update_type, int update_identifier, const char* variable_name, const char* variable_value, const char* client_name = "");
void CrossZoneSignal(uint8 update_type, int update_identifier, int signal_id, const char* client_name = "");
void CrossZoneSpell(uint8 update_type, uint8 update_subtype, int update_identifier, uint32 spell_id, const char* client_name = "");
+51 -46
View File
@@ -20,6 +20,8 @@
#include "../common/events/player_event_logs.h"
#include "../common/repositories/raid_details_repository.h"
#include "../common/repositories/raid_members_repository.h"
#include "../common/raid.h"
#include "client.h"
#include "entity.h"
@@ -1547,21 +1549,22 @@ void Raid::SendRaidGroupRemove(const char *who, uint32 gid)
void Raid::SendRaidMOTD(Client *c)
{
if (!c || motd.empty()) {
if (!c || motd.empty() || c->IsBot()) {
return;
}
if (entity_list.GetBotByBotName(c->GetName())) {
return;
}
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(RaidMOTD_Struct));
auto data = (RaidMOTD_Struct*)outapp->pBuffer;
size_t size = motd.size() + 1;
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(RaidMOTD_Struct) + size);
auto rmotd = (RaidMOTD_Struct *)outapp->pBuffer;
rmotd->general.action = raidSetMotd;
strn0cpy(rmotd->general.player_name, c->GetName(), 64);
strn0cpy(rmotd->motd, motd.c_str(), size);
c->FastQueuePacket(&outapp);
data->general.action = raidSetMotd;
data->general.parameter = 0;
data->general.unknown1 = 0;
strn0cpy(data->general.leader_name, c->GetName(), sizeof(c->GetName()));
strn0cpy(data->general.player_name, GetLeaderName().c_str(), 64);
strn0cpy(data->motd, motd.c_str(), sizeof(data->motd));
c->QueuePacket(outapp);
safe_delete(outapp);
}
void Raid::SendRaidMOTD()
@@ -1587,11 +1590,10 @@ void Raid::SendRaidMOTDToWorld()
return;
}
size_t size = motd.size() + 1;
auto pack = new ServerPacket(ServerOP_RaidMOTD, sizeof(ServerRaidMOTD_Struct) + size);
auto pack = new ServerPacket(ServerOP_RaidMOTD, sizeof(ServerRaidMOTD_Struct));
auto smotd = (ServerRaidMOTD_Struct *)pack->pBuffer;
smotd->rid = GetID();
strn0cpy(smotd->motd, motd.c_str(), size);
strn0cpy(smotd->motd, motd.c_str(), sizeof(smotd->motd));
worldserver.SendPacket(pack);
safe_delete(pack);
}
@@ -1705,33 +1707,31 @@ bool Raid::LearnMembers()
{
memset(members, 0, (sizeof(RaidMember) * MAX_RAID_MEMBERS));
const auto query = fmt::format(
"SELECT name, groupid, _class, level, "
"isgroupleader, israidleader, islooter, is_marker, is_assister, bot_id, note "
"FROM raid_members WHERE raidid = {} ORDER BY groupid",
GetID()
auto raid_members = RaidMembersRepository::GetWhere(
content_db,
fmt::format(
"raidid = {}",
GetID()
)
);
auto results = database.QueryDatabase(query);
if (!results.Success()) {
return false;
}
if (!results.RowCount()) {
if (raid_members.empty()) {
disbandCheck = true;
return false;
}
int i = 0;
for (auto row: results) {
if (!row[0]) {
for (const auto &e: raid_members) {
if (e.name.empty()) {
continue;
}
members[i].member = nullptr;
strn0cpy(members[i].member_name, row[0], sizeof(members[i].member_name));
strn0cpy(members[i].note, row[10], sizeof(members[i].note));
uint32 group_id = Strings::ToUnsignedInt(row[1]);
strn0cpy(members[i].member_name, e.name.c_str(), sizeof(members[i].member_name));
uint32 group_id = e.groupid;
if (!e.note.empty()) {
members[i].note = e.note;
}
if (group_id >= MAX_RAID_GROUPS) {
members[i].group_number = RAID_GROUPLESS;
@@ -1740,14 +1740,14 @@ bool Raid::LearnMembers()
members[i].group_number = group_id;
}
members[i]._class = Strings::ToUnsignedInt(row[2]);
members[i].level = Strings::ToUnsignedInt(row[3]);
members[i].is_group_leader = Strings::ToBool(row[4]);
members[i].is_raid_leader = Strings::ToBool(row[5]);
members[i].is_looter = Strings::ToBool(row[6]);
members[i].main_marker = Strings::ToUnsignedInt(row[7]);
members[i].main_assister = Strings::ToUnsignedInt(row[8]);
members[i].is_bot = Strings::ToBool(row[9]) > 0;
members[i]._class = e._class;
members[i].level = e.level;
members[i].is_group_leader = e.isgroupleader;
members[i].is_raid_leader = e.israidleader;
members[i].is_looter = e.islooter;
members[i].main_marker = e.is_marker;
members[i].main_assister = e.is_assister;
members[i].is_bot = e.bot_id > 0;
++i;
}
return true;
@@ -2275,7 +2275,7 @@ std::vector<RaidMember> Raid::GetMembersWithNotes()
{
std::vector<RaidMember> raid_members;
for (const auto& m : members) {
if (strlen(m.note) != 0) {
if (!m.note.empty()) {
raid_members.emplace_back(m);
}
}
@@ -2288,12 +2288,17 @@ void Raid::SendRaidNotes()
VerifyRaid();
for (const auto& c : GetMembersWithNotes()) {
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(RaidGeneral_Struct));
auto note = (RaidGeneral_Struct*)outapp->pBuffer;
note->action = raidSetNote;
strn0cpy(note->leader_name, c.member_name, 64);
strn0cpy(note->player_name, GetLeaderName().c_str(), 64);
strn0cpy(note->note, c.note, 64);
auto outapp = new EQApplicationPacket(OP_RaidUpdate, sizeof(RaidNote_Struct));
auto data = (RaidNote_Struct*)outapp->pBuffer;
data->general.action = raidSetNote;
data->general.parameter = 0;
data->general.unknown1 = 0;
strn0cpy(data->general.leader_name, c.member_name, sizeof(c.member_name));
strn0cpy(data->general.player_name, GetLeaderName().c_str(), GetLeaderName().length());
strn0cpy(data->note, c.note.c_str(), sizeof(data->note));
QueuePacket(outapp);
safe_delete(outapp);
}
@@ -2552,7 +2557,7 @@ void Raid::UpdateXTargetType(XTargetType Type, Mob *m, const char *name)
}
if (name) {
strncpy(rm.member->XTargets[i].Name, name, 64);
strn0cpy(rm.member->XTargets[i].Name, name, 64);
}
rm.member->SendXTargetPacket(i, m);
+1 -50
View File
@@ -27,55 +27,6 @@ class Client;
class EQApplicationPacket;
class Mob;
enum { //raid packet types:
raidAdd = 0,
raidRemove2 = 1, //parameter=0
raidMemberNameChange = 2,
raidRemove1 = 3, //parameter=0xFFFFFFFF
raidNoLongerLeader = 4,
raidDisband = 5,
raidMembers = 6, //len 395+, details + members list
raidNoAssignLeadership = 7,
raidCreate = 8, //len 72
raidUnknown = 9, // unused?
raidNoRaid = 10, //parameter=0
raidChangeLootType = 11,
raidStringID = 12,
raidChangeGroupLeader = 13, //136 raid leader, new group leader, group_id?
raidSetLeaderAbilities = 14, //472
raidSetLeaderData = 15, // 14,15 SoE names, not sure on difference, 14 packet has 0x100 bytes 15 0x214 in addition to raid general
raidChangeGroup = 16, //?? len 136 old leader, new leader, 0 (preceeded with a remove2)
raidLock = 17, //len 136 leader?, leader, 0
raidUnlock = 18, //len 136 leader?, leader, 0
raidRedStringID = 19,
raidSetLeader = 20, //len 388, contains 'details' struct without members; also used for "invite to raid"
raidMakeLeader = 30,
raidSetMotd = 35,
raidSetNote = 36,
};
enum { //raid command types
RaidCommandInviteIntoExisting = 0, //in use
RaidCommandAcceptInvite = 1, //in use
RaidCommandInvite = 3, //in use
RaidCommandDisband = 5, //in use
RaidCommandMoveGroup = 6, //in use
RaidCommandRemoveGroupLeader = 7,
RaidCommandRaidLock = 8, //in use
RaidCommandRaidUnlock = 9, //in use
RaidCommandLootType = 20, //in use
RaidCommandAddLooter = 21, //in use
RaidCommandRemoveLooter = 22, //in use
RaidCommandMakeLeader = 30,
RaidCommandInviteFail = 31, //already in raid, waiting on invite from other raid, etc
RaidCommandLootType2 = 32, //in use
RaidCommandAddLooter2 = 33, //in use
RaidCommandRemoveLooter2 = 34, //in use
RaidCommandSetMotd = 35,
RaidCommandSetNote = 36,
};
enum {
FindNextMarkerSlot = 1,
FindNextAssisterSlot = 2,
@@ -129,7 +80,7 @@ struct RaidMember{
uint32 group_number;
uint8 _class;
uint8 level;
char note[64];
std::string note;
bool is_group_leader;
bool is_raid_leader;
bool is_looter;
+182 -109
View File
@@ -281,41 +281,54 @@ void Mob::DoSpecialAttackDamage(Mob *who, EQ::skills::SkillType skill, int32 bas
// We should probably refactor this to take the struct not the packet
void Client::OPCombatAbility(const CombatAbility_Struct *ca_atk)
{
if (!GetTarget())
if (!GetTarget()) {
return;
}
// make sure were actually able to use such an attack. (Bards can throw while casting. ~Kayen confirmed on live 1/22)
if ((spellend_timer.Enabled() && GetClass() != BARD)|| IsFeared() || IsStunned() || IsMezzed() || DivineAura() || dead)
if (
(spellend_timer.Enabled() && GetClass() != BARD) ||
IsFeared() ||
IsStunned() ||
IsMezzed() ||
DivineAura() ||
dead
) {
return;
}
pTimerType timer = pTimerCombatAbility;
// RoF2+ Tiger Claw is unlinked from other monk skills, if they ever do that for other classes there will need
// to be more checks here
if (ClientVersion() >= EQ::versions::ClientVersion::RoF2 && ca_atk->m_skill == EQ::skills::SkillTigerClaw)
if (ClientVersion() >= EQ::versions::ClientVersion::RoF2 && ca_atk->m_skill == EQ::skills::SkillTigerClaw) {
timer = pTimerCombatAbility2;
}
bool CanBypassSkillCheck = false;
bool bypass_skill_check = false;
if (ca_atk->m_skill == EQ::skills::SkillBash) { // SLAM - Bash without a shield equipped
switch (GetRace())
{
case OGRE:
case TROLL:
case BARBARIAN:
CanBypassSkillCheck = true;
default:
break;
switch (GetRace()) {
case OGRE:
case TROLL:
case BARBARIAN:
bypass_skill_check = true;
default:
break;
}
}
/* Check to see if actually have skill */
if (!MaxSkill(static_cast<EQ::skills::SkillType>(ca_atk->m_skill)) && !CanBypassSkillCheck)
// Check to see if actually have skill
if (!MaxSkill(static_cast<EQ::skills::SkillType>(ca_atk->m_skill)) && !bypass_skill_check) {
return;
}
if (GetTarget()->GetID() != ca_atk->m_target)
return; // invalid packet.
if (!IsAttackAllowed(GetTarget()))
if (GetTarget()->GetID() != ca_atk->m_target) { // invalid packet.
return;
}
if (!IsAttackAllowed(GetTarget())) {
return;
}
// These two are not subject to the combat ability timer, as they
// allready do their checking in conjunction with the attack timer
@@ -324,146 +337,194 @@ void Client::OPCombatAbility(const CombatAbility_Struct *ca_atk)
if (ca_atk->m_skill == EQ::skills::SkillThrowing) {
SetAttackTimer();
ThrowingAttack(GetTarget());
if (CheckDoubleRangedAttack())
if (CheckDoubleRangedAttack()) {
ThrowingAttack(GetTarget(), true);
}
return;
}
// ranged attack (archery)
if (ca_atk->m_skill == EQ::skills::SkillArchery) {
SetAttackTimer();
RangedAttack(GetTarget());
if (CheckDoubleRangedAttack())
if (CheckDoubleRangedAttack()) {
RangedAttack(GetTarget(), true);
}
return;
}
// could we return here? Im not sure is m_atk 11 is used for real specials
}
// check range for all these abilities, they are all close combat stuff
if (!CombatRange(GetTarget()))
if (!CombatRange(GetTarget())) {
return;
}
if (!p_timers.Expired(&database, timer, false)) {
Message(Chat::Red, "Ability recovery time not yet met.");
return;
}
int ReuseTime = 0;
int ClientHaste = GetHaste();
int HasteMod = 0;
int reuse_time = 0;
int haste = GetHaste();
int haste_modifier = 0;
if (ClientHaste >= 0)
HasteMod = (10000 / (100 + ClientHaste)); //+100% haste = 2x as many attacks
else
HasteMod = (100 - ClientHaste); //-100% haste = 1/2 as many attacks
if (haste >= 0) {
haste_modifier = (10000 / (100 + haste)); //+100% haste = 2x as many attacks
} else {
haste_modifier = (100 - haste); //-100% haste = 1/2 as many attacks
}
int64 dmg = 0;
int64 damage = 0;
int16 skill_reduction = GetSkillReuseTime(ca_atk->m_skill);
int32 skill_reduction = GetSkillReuseTime(ca_atk->m_skill);
// not sure what the '100' indicates..if ->m_atk is not used as 'slot' reference, then change SlotRange above back to '11'
if (ca_atk->m_atk == 100 &&
ca_atk->m_skill == EQ::skills::SkillBash) { // SLAM - Bash without a shield equipped
// not sure what the '100' indicates, if ->m_atk is not used as 'slot' reference, then change SlotRange above back to '11'
if (
ca_atk->m_atk == 100 &&
ca_atk->m_skill == EQ::skills::SkillBash
) { // SLAM - Bash without a shield equipped
if (GetTarget() != this) {
CheckIncreaseSkill(EQ::skills::SkillBash, GetTarget(), 10);
DoAnim(animTailRake, 0, false);
int32 ht = 0;
if (GetWeaponDamage(GetTarget(), GetInv().GetItem(EQ::invslot::slotSecondary)) <= 0 &&
GetWeaponDamage(GetTarget(), GetInv().GetItem(EQ::invslot::slotShoulders)) <= 0)
dmg = -5;
else
ht = dmg = GetBaseSkillDamage(EQ::skills::SkillBash, GetTarget());
int hate_override = 0;
ReuseTime = BashReuseTime - 1 - skill_reduction;
ReuseTime = (ReuseTime * HasteMod) / 100;
DoSpecialAttackDamage(GetTarget(), EQ::skills::SkillBash, dmg, 0, ht, ReuseTime);
if (ReuseTime > 0)
p_timers.Start(timer, ReuseTime);
if (
GetWeaponDamage(GetTarget(), GetInv().GetItem(EQ::invslot::slotSecondary)) <= 0 &&
GetWeaponDamage(GetTarget(), GetInv().GetItem(EQ::invslot::slotShoulders)) <= 0
) {
damage = -5;
} else {
hate_override = damage = GetBaseSkillDamage(EQ::skills::SkillBash, GetTarget());
}
reuse_time = BashReuseTime - 1 - skill_reduction;
reuse_time = (reuse_time * haste_modifier) / 100;
DoSpecialAttackDamage(GetTarget(), EQ::skills::SkillBash, damage, 0, hate_override, reuse_time);
if (reuse_time) {
p_timers.Start(timer, reuse_time);
}
}
return;
}
if (ca_atk->m_atk == 100 && ca_atk->m_skill == EQ::skills::SkillFrenzy) {
int attack_rounds = 1;
int max_dmg = GetBaseSkillDamage(EQ::skills::SkillFrenzy, GetTarget());
CheckIncreaseSkill(EQ::skills::SkillFrenzy, GetTarget(), 10);
int AtkRounds = 1;
int32 max_dmg = GetBaseSkillDamage(EQ::skills::SkillFrenzy, GetTarget());
DoAnim(anim1HWeapon, 0, false);
if (GetClass() == BERSERKER) {
int chance = GetLevel() * 2 + GetSkill(EQ::skills::SkillFrenzy);
if (zone->random.Roll0(450) < chance)
AtkRounds++;
if (zone->random.Roll0(450) < chance)
AtkRounds++;
if (zone->random.Roll0(450) < chance) {
attack_rounds++;
}
if (zone->random.Roll0(450) < chance) {
attack_rounds++;
}
}
ReuseTime = FrenzyReuseTime - 1 - skill_reduction;
ReuseTime = (ReuseTime * HasteMod) / 100;
reuse_time = FrenzyReuseTime - 1 - skill_reduction;
reuse_time = (reuse_time * haste_modifier) / 100;
auto primary_in_use = GetInv().GetItem(EQ::invslot::slotPrimary);
const EQ::ItemInstance* primary_in_use = GetInv().GetItem(EQ::invslot::slotPrimary);
if (primary_in_use && GetWeaponDamage(GetTarget(), primary_in_use) <= 0) {
max_dmg = DMG_INVULNERABLE;
}
while (AtkRounds > 0) {
if (GetTarget())
DoSpecialAttackDamage(GetTarget(), EQ::skills::SkillFrenzy, max_dmg, 0, max_dmg, ReuseTime);
AtkRounds--;
while (attack_rounds > 0) {
if (GetTarget()) {
DoSpecialAttackDamage(GetTarget(), EQ::skills::SkillFrenzy, max_dmg, 0, max_dmg, reuse_time);
}
attack_rounds--;
}
if (reuse_time) {
p_timers.Start(timer, reuse_time);
}
if (ReuseTime > 0)
p_timers.Start(timer, ReuseTime);
return;
}
switch (GetClass()) {
case BERSERKER:
case WARRIOR:
case RANGER:
case BEASTLORD:
if (ca_atk->m_atk != 100 || ca_atk->m_skill != EQ::skills::SkillKick)
break;
const uint8 class_id = GetClass();
// Warrior, Ranger, Monk, Beastlord, and Berserker can kick always
const uint32 allowed_kick_classes = RuleI(Combat, ExtraAllowedKickClassesBitmask);
const bool can_use_kick = (
class_id == WARRIOR ||
class_id == RANGER ||
class_id == MONK ||
class_id == BEASTLORD ||
class_id == BERSERKER ||
allowed_kick_classes & GetPlayerClassBit(class_id)
);
bool found_skill = false;
if (
ca_atk->m_atk == 100 &&
ca_atk->m_skill == EQ::skills::SkillKick &&
can_use_kick
) {
if (GetTarget() != this) {
CheckIncreaseSkill(EQ::skills::SkillKick, GetTarget(), 10);
DoAnim(animKick, 0, false);
int32 ht = 0;
if (GetWeaponDamage(GetTarget(), GetInv().GetItem(EQ::invslot::slotFeet)) <= 0)
dmg = -5;
else
ht = dmg = GetBaseSkillDamage(EQ::skills::SkillKick, GetTarget());
int hate_override = 0;
if (GetWeaponDamage(GetTarget(), GetInv().GetItem(EQ::invslot::slotFeet)) <= 0) {
damage = -5;
} else {
hate_override = damage = GetBaseSkillDamage(EQ::skills::SkillKick, GetTarget());
}
ReuseTime = KickReuseTime - 1 - skill_reduction;
DoSpecialAttackDamage(GetTarget(), EQ::skills::SkillKick, dmg, 0, ht, ReuseTime);
reuse_time = KickReuseTime - 1 - skill_reduction;
DoSpecialAttackDamage(GetTarget(), EQ::skills::SkillKick, damage, 0, hate_override, reuse_time);
found_skill = true;
}
break;
case MONK: {
ReuseTime = MonkSpecialAttack(GetTarget(), ca_atk->m_skill) - 1 - skill_reduction;
}
if (class_id == MONK) {
reuse_time = MonkSpecialAttack(GetTarget(), ca_atk->m_skill) - 1 - skill_reduction;
// Live AA - Technique of Master Wu
int wuchance = itembonuses.DoubleSpecialAttack + spellbonuses.DoubleSpecialAttack + aabonuses.DoubleSpecialAttack;
int wu_chance = (
itembonuses.DoubleSpecialAttack +
spellbonuses.DoubleSpecialAttack +
aabonuses.DoubleSpecialAttack
);
if (wuchance) {
const int MonkSPA[5] = {
if (wu_chance) {
const int monk_special_attacks[5] = {
EQ::skills::SkillFlyingKick,
EQ::skills::SkillDragonPunch,
EQ::skills::SkillEagleStrike,
EQ::skills::SkillTigerClaw,
EQ::skills::SkillRoundKick
};
int extra = 0;
// always 1/4 of the double attack chance, 25% at rank 5 (100/4)
while (wuchance > 0) {
if (zone->random.Roll(wuchance)) {
while (wu_chance > 0) {
if (zone->random.Roll(wu_chance)) {
++extra;
}
else {
} else {
break;
}
wuchance /= 4;
wu_chance /= 4;
}
if (extra) {
SendColoredText(
400,
@@ -474,37 +535,47 @@ void Client::OPCombatAbility(const CombatAbility_Struct *ca_atk)
)
);
}
auto classic = RuleB(Combat, ClassicMasterWu);
const bool is_classic_master_wu = RuleB(Combat, ClassicMasterWu);
while (extra) {
MonkSpecialAttack(GetTarget(), (classic ? MonkSPA[zone->random.Int(0, 4)] : ca_atk->m_skill));
MonkSpecialAttack(
GetTarget(),
(is_classic_master_wu ? monk_special_attacks[zone->random.Int(0, 4)] : ca_atk->m_skill)
);
--extra;
}
}
if (ReuseTime < 100) {
if (reuse_time < 100) {
// hackish... but we return a huge reuse time if this is an
// invalid skill, otherwise, we can safely assume it is a
// valid monk skill and just cast it to a SkillType
CheckIncreaseSkill((EQ::skills::SkillType)ca_atk->m_skill, GetTarget(), 10);
CheckIncreaseSkill((EQ::skills::SkillType) ca_atk->m_skill, GetTarget(), 10);
}
break;
}
case ROGUE: {
if (ca_atk->m_atk != 100 || ca_atk->m_skill != EQ::skills::SkillBackstab)
break;
ReuseTime = BackstabReuseTime-1 - skill_reduction;
TryBackstab(GetTarget(), ReuseTime);
break;
}
default:
//they have no abilities... wtf? make em wait a bit
ReuseTime = 9 - skill_reduction;
break;
found_skill = true;
}
ReuseTime = (ReuseTime * HasteMod) / 100;
if (ReuseTime > 0) {
p_timers.Start(timer, ReuseTime);
if (
ca_atk->m_atk == 100 &&
ca_atk->m_skill == EQ::skills::SkillBackstab &&
class_id == ROGUE
) {
reuse_time = BackstabReuseTime - 1 - skill_reduction;
TryBackstab(GetTarget(), reuse_time);
found_skill = true;
}
if (!found_skill) {
reuse_time = 9 - skill_reduction;
}
reuse_time = (reuse_time * haste_modifier) / 100;
reuse_time = EQ::Clamp(reuse_time, 0, reuse_time);
if (reuse_time) {
p_timers.Start(timer, reuse_time);
}
}
@@ -2230,7 +2301,8 @@ int Mob::TryHeadShot(Mob *defender, EQ::skills::SkillType skillInUse)
!defender->IsClient() &&
skillInUse == EQ::skills::SkillArchery &&
GetTarget() == defender &&
(defender->GetBodyType() == BT_Humanoid || !RuleB(Combat, HeadshotOnlyHumanoids))
(defender->GetBodyType() == BT_Humanoid || !RuleB(Combat, HeadshotOnlyHumanoids)) &&
!defender->GetSpecialAbility(IMMUNE_HEADSHOT)
) {
uint32 HeadShot_Dmg = aabonuses.HeadShot[SBIndex::FINISHING_EFFECT_DMG] + spellbonuses.HeadShot[SBIndex::FINISHING_EFFECT_DMG] + itembonuses.HeadShot[SBIndex::FINISHING_EFFECT_DMG];
uint8 HeadShot_Level = 0; // Get Highest Headshot Level
@@ -2266,7 +2338,8 @@ int Mob::TryAssassinate(Mob *defender, EQ::skills::SkillType skillInUse)
!defender->IsClient() &&
GetLevel() >= 60 &&
(skillInUse == EQ::skills::SkillBackstab || skillInUse == EQ::skills::SkillThrowing) &&
(defender->GetBodyType() == BT_Humanoid || !RuleB(Combat, AssassinateOnlyHumanoids))
(defender->GetBodyType() == BT_Humanoid || !RuleB(Combat, AssassinateOnlyHumanoids)) &&
!defender->GetSpecialAbility(IMMUNE_ASSASSINATE)
) {
int chance = GetDEX();
if (skillInUse == EQ::skills::SkillBackstab) {
+8 -10
View File
@@ -2266,7 +2266,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
if((spell_id != 6882) && (spell_id != 6884)) // Chaotic Jester/Steadfast Servant
{
char pet_name[64];
snprintf(pet_name, sizeof(pet_name), "%s`s pet", caster->GetCleanName());
snprintf(pet_name, sizeof(pet_name), "%s`s_pet", caster->GetCleanName());
caster->TemporaryPets(spell_id, this, pet_name);
}
else
@@ -2443,7 +2443,7 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove
{
if(caster && caster->IsClient()) {
char pet_name[64];
snprintf(pet_name, sizeof(pet_name), "%s`s doppelganger", caster->GetCleanName());
snprintf(pet_name, sizeof(pet_name), "%s`s_doppelganger", caster->GetCleanName());
int pet_count = spells[spell_id].base_value[i];
int pet_duration = spells[spell_id].max_value[i];
caster->CastToClient()->Doppelganger(spell_id, this, pet_name, pet_count, pet_duration);
@@ -10378,7 +10378,7 @@ bool Mob::HasPersistDeathIllusion(int32 spell_id) {
return false;
}
void Mob::SetBuffDuration(int spell_id, int duration) {
void Mob::SetBuffDuration(int spell_id, int duration, int level) {
/*
Will refresh the buff with specified spell_id to the specified duration
@@ -10402,22 +10402,20 @@ void Mob::SetBuffDuration(int spell_id, int duration) {
int buff_count = GetMaxTotalSlots();
for (int slot = 0; slot < buff_count; slot++) {
if (!adjust_all_buffs) {
if (IsValidSpell(buffs[slot].spellid) && buffs[slot].spellid == spell_id) {
SpellOnTarget(buffs[slot].spellid, this, 0, false, 0, false, -1, duration, true);
SpellOnTarget(buffs[slot].spellid, this, 0, false, 0, false, level, duration, true);
return;
}
}
else {
} else {
if (IsValidSpell(buffs[slot].spellid)) {
SpellOnTarget(buffs[slot].spellid, this, 0, false, 0, false, -1, duration, true);
SpellOnTarget(buffs[slot].spellid, this, 0, false, 0, false, level, duration, true);
}
}
}
}
void Mob::ApplySpellBuff(int spell_id, int duration)
void Mob::ApplySpellBuff(int spell_id, int duration, int level)
{
/*
Used for quest command to apply a new buff with custom duration.
@@ -10435,7 +10433,7 @@ void Mob::ApplySpellBuff(int spell_id, int duration)
duration = PERMANENT_BUFF_DURATION;
}
SpellOnTarget(spell_id, this, 0, false, 0, false, -1, duration);
SpellOnTarget(spell_id, this, 0, false, 0, false, level, duration);
}
int Mob::GetBuffStatValueBySpell(int32 spell_id, const char* stat_identifier)
+90 -41
View File
@@ -238,13 +238,16 @@ bool Mob::CastSpell(uint16 spell_id, uint16 target_id, CastingSlot slot,
if (IsClient()) {
if (parse->PlayerHasQuestSub(EVENT_CAST_BEGIN)) {
Mob* spell_target = entity_list.GetMobID(target_id);
std::vector<std::any> args = { spell_target };
const auto& export_string = fmt::format(
"{} {} {}",
"{} {} {} {}",
spell_id,
GetID(),
GetCasterLevel(spell_id)
GetCasterLevel(spell_id),
target_id
);
if (parse->EventPlayer(EVENT_CAST_BEGIN, CastToClient(), export_string, 0) != 0) {
if (parse->EventPlayer(EVENT_CAST_BEGIN, CastToClient(), export_string, 0, &args) != 0) {
if (IsDiscipline(spell_id)) {
CastToClient()->SendDisciplineTimer(spells[spell_id].timer_id, 0);
}
@@ -256,23 +259,29 @@ bool Mob::CastSpell(uint16 spell_id, uint16 target_id, CastingSlot slot,
}
} else if (IsNPC()) {
if (parse->HasQuestSub(GetNPCTypeID(), EVENT_CAST_BEGIN)) {
Mob* spell_target = entity_list.GetMobID(target_id);
std::vector<std::any> args = { spell_target };
const auto& export_string = fmt::format(
"{} {} {}",
"{} {} {} {}",
spell_id,
GetID(),
GetCasterLevel(spell_id)
GetCasterLevel(spell_id),
target_id
);
parse->EventNPC(EVENT_CAST_BEGIN, CastToNPC(), nullptr, export_string, 0);
parse->EventNPC(EVENT_CAST_BEGIN, CastToNPC(), nullptr, export_string, 0, &args);
}
} else if (IsBot()) {
if (parse->BotHasQuestSub(EVENT_CAST_BEGIN)) {
Mob* spell_target = entity_list.GetMobID(target_id);
std::vector<std::any> args = { spell_target };
const auto& export_string = fmt::format(
"{} {} {}",
"{} {} {} {}",
spell_id,
GetID(),
GetCasterLevel(spell_id)
GetCasterLevel(spell_id),
target_id
);
parse->EventBot(EVENT_CAST_BEGIN, CastToBot(), nullptr, export_string, 0);
parse->EventBot(EVENT_CAST_BEGIN, CastToBot(), nullptr, export_string, 0, &args);
}
}
@@ -1648,24 +1657,41 @@ void Mob::CastedSpellFinished(uint16 spell_id, uint32 target_id, CastingSlot slo
// at this point the spell has successfully been cast
//
const auto& export_string = fmt::format(
"{} {} {}",
spell_id,
GetID(),
GetCasterLevel(spell_id)
);
if (IsClient()) {
if (parse->PlayerHasQuestSub(EVENT_CAST)) {
parse->EventPlayer(EVENT_CAST, CastToClient(), export_string, 0);
std::vector<std::any> args = { spell_target };
const auto& export_string = fmt::format(
"{} {} {} {}",
spell_id,
GetID(),
GetCasterLevel(spell_id),
target_id
);
parse->EventPlayer(EVENT_CAST, CastToClient(), export_string, 0, &args);
}
} else if (IsNPC()) {
if (parse->HasQuestSub(GetNPCTypeID(), EVENT_CAST)) {
parse->EventNPC(EVENT_CAST, CastToNPC(), nullptr, export_string, 0);
std::vector<std::any> args = { spell_target };
const auto& export_string = fmt::format(
"{} {} {} {}",
spell_id,
GetID(),
GetCasterLevel(spell_id),
target_id
);
parse->EventNPC(EVENT_CAST, CastToNPC(), nullptr, export_string, 0, &args);
}
} else if (IsBot()) {
if (parse->BotHasQuestSub(EVENT_CAST)) {
parse->EventBot(EVENT_CAST, CastToBot(), nullptr, export_string, 0);
std::vector<std::any> args = { spell_target };
const auto& export_string = fmt::format(
"{} {} {} {}",
spell_id,
GetID(),
GetCasterLevel(spell_id),
target_id
);
parse->EventBot(EVENT_CAST, CastToBot(), nullptr, export_string, 0, &args);
}
}
@@ -2736,12 +2762,18 @@ bool Mob::ApplyBardPulse(int32 spell_id, Mob *spell_target, CastingSlot slot) {
Live does not spam client with do not take hold messages. Checking here avoids that from happening. Only try to reapply if charm fades.
*/
if (spell_target->IsCharmed() && spells[spell_id].mana == 0 && spell_target->GetOwner() == this && IsEffectInSpell(spell_id, SE_Charm)) {
if (IsClient()) {
CastToClient()->CheckSongSkillIncrease(spell_id);
}
return true;
}
/*
If divine aura applied while pulsing, it is not interrupted but does not reapply until DA fades.
*/
if (DivineAura() && !IsCastNotStandingSpell(spell_id)) {
if (IsClient()) {
CastToClient()->CheckSongSkillIncrease(spell_id);
}
return true;
}
/*
@@ -2755,6 +2787,9 @@ bool Mob::ApplyBardPulse(int32 spell_id, Mob *spell_target, CastingSlot slot) {
return false;
}
if (IsClient()) {
CastToClient()->CheckSongSkillIncrease(spell_id);
}
return true;
}
@@ -3655,10 +3690,14 @@ bool Mob::SpellOnTarget(
}
// select target
uint16 target_id = 0;
if (IsEffectInSpell(spell_id, SE_BindSight)) {
action->target = GetID();
target_id = GetID();
} else {
action->target = spelltar->GetID();
target_id = spelltar->GetID();
}
action->spell_level = action->level = caster_level; // caster level, for animation only
@@ -3691,33 +3730,39 @@ bool Mob::SpellOnTarget(
if (spelltar->IsNPC()) {
if (parse->HasQuestSub(spelltar->GetNPCTypeID(), EVENT_CAST_ON)) {
std::vector<std::any> args = { spelltar };
const auto& export_string = fmt::format(
"{} {} {}",
"{} {} {} {}",
spell_id,
GetID(),
caster_level
caster_level,
target_id
);
parse->EventNPC(EVENT_CAST_ON, spelltar->CastToNPC(), this, export_string, 0);
parse->EventNPC(EVENT_CAST_ON, spelltar->CastToNPC(), this, export_string, 0, &args);
}
} else if (spelltar->IsClient()) {
if (parse->PlayerHasQuestSub(EVENT_CAST_ON)) {
std::vector<std::any> args = { spelltar };
const auto& export_string = fmt::format(
"{} {} {}",
"{} {} {} {}",
spell_id,
GetID(),
caster_level
caster_level,
target_id
);
parse->EventPlayer(EVENT_CAST_ON, spelltar->CastToClient(), export_string, 0);
parse->EventPlayer(EVENT_CAST_ON, spelltar->CastToClient(), export_string, 0, &args);
}
} else if (spelltar->IsBot()) {
if (parse->BotHasQuestSub(EVENT_CAST_ON)) {
std::vector<std::any> args = { spelltar };
const auto& export_string = fmt::format(
"{} {} {}",
"{} {} {} {}",
spell_id,
GetID(),
caster_level
caster_level,
target_id
);
parse->EventBot(EVENT_CAST_ON, spelltar->CastToBot(), this, export_string, 0);
parse->EventBot(EVENT_CAST_ON, spelltar->CastToBot(), this, export_string, 0, &args);
}
}
@@ -4402,14 +4447,18 @@ std::vector<uint16> Mob::GetBuffSpellIDs()
return l;
}
bool Mob::FindBuff(uint16 spell_id)
bool Mob::FindBuff(uint16 spell_id, uint16 caster_id)
{
uint32 buff_count = GetMaxTotalSlots();
const int buff_count = GetMaxTotalSlots();
for (int buff_slot = 0; buff_slot < buff_count; buff_slot++) {
auto current_spell_id = buffs[buff_slot].spellid;
const uint16 current_spell_id = buffs[buff_slot].spellid;
if (
IsValidSpell(current_spell_id) &&
current_spell_id == spell_id
current_spell_id == spell_id &&
(
!caster_id ||
buffs[buff_slot].casterid == caster_id
)
) {
return true;
}
@@ -5968,7 +6017,7 @@ bool Mob::IsCombatProc(uint16 spell_id) {
/*
Procs that originate from casted spells are still limited by SPA 311 (~Kayen confirmed on live 2/4/22)
*/
for (int i = 0; i < MAX_PROCS; i++) {
for (int i = 0; i < m_max_procs; i++) {
if (PermaProcs[i].spellID == spell_id ||
SpellProcs[i].spellID == spell_id ||
RangedProcs[i].spellID == spell_id ||
@@ -5995,7 +6044,7 @@ bool Mob::AddProcToWeapon(uint16 spell_id, bool bPerma, uint16 iChance, uint16 b
int i;
if (bPerma) {
for (i = 0; i < MAX_PROCS; i++) {
for (i = 0; i < m_max_procs; i++) {
if (!IsValidSpell(PermaProcs[i].spellID)) {
PermaProcs[i].spellID = spell_id;
PermaProcs[i].chance = iChance;
@@ -6010,7 +6059,7 @@ bool Mob::AddProcToWeapon(uint16 spell_id, bool bPerma, uint16 iChance, uint16 b
} else {
// If its a poison proc, replace any existing one if present.
if (base_spell_id == POISON_PROC) {
for (i = 0; i < MAX_PROCS; i++) {
for (i = 0; i < m_max_procs; i++) {
// If we already have a poison proc active replace it and return
if (SpellProcs[i].base_spellID == POISON_PROC) {
SpellProcs[i].spellID = spell_id;
@@ -6027,7 +6076,7 @@ bool Mob::AddProcToWeapon(uint16 spell_id, bool bPerma, uint16 iChance, uint16 b
// or it is poison and no poison procs are currently present.
// Find a slot and use it as normal.
for (i = 0; i < MAX_PROCS; i++) {
for (i = 0; i < m_max_procs; i++) {
if (!IsValidSpell(SpellProcs[i].spellID)) {
SpellProcs[i].spellID = spell_id;
SpellProcs[i].chance = iChance;
@@ -6044,7 +6093,7 @@ bool Mob::AddProcToWeapon(uint16 spell_id, bool bPerma, uint16 iChance, uint16 b
}
bool Mob::RemoveProcFromWeapon(uint16 spell_id, bool bAll) {
for (int i = 0; i < MAX_PROCS; i++) {
for (int i = 0; i < m_max_procs; i++) {
if (bAll || SpellProcs[i].spellID == spell_id) {
SpellProcs[i].spellID = SPELL_UNKNOWN;
SpellProcs[i].chance = 0;
@@ -6063,7 +6112,7 @@ bool Mob::AddDefensiveProc(uint16 spell_id, uint16 iChance, uint16 base_spell_id
return(false);
int i;
for (i = 0; i < MAX_PROCS; i++) {
for (i = 0; i < m_max_procs; i++) {
if (!IsValidSpell(DefensiveProcs[i].spellID)) {
DefensiveProcs[i].spellID = spell_id;
DefensiveProcs[i].chance = iChance;
@@ -6079,7 +6128,7 @@ bool Mob::AddDefensiveProc(uint16 spell_id, uint16 iChance, uint16 base_spell_id
bool Mob::RemoveDefensiveProc(uint16 spell_id, bool bAll)
{
for (int i = 0; i < MAX_PROCS; i++) {
for (int i = 0; i < m_max_procs; i++) {
if (bAll || DefensiveProcs[i].spellID == spell_id) {
DefensiveProcs[i].spellID = SPELL_UNKNOWN;
DefensiveProcs[i].chance = 0;
@@ -6097,7 +6146,7 @@ bool Mob::AddRangedProc(uint16 spell_id, uint16 iChance, uint16 base_spell_id, u
return(false);
int i;
for (i = 0; i < MAX_PROCS; i++) {
for (i = 0; i < m_max_procs; i++) {
if (!IsValidSpell(RangedProcs[i].spellID)) {
RangedProcs[i].spellID = spell_id;
RangedProcs[i].chance = iChance;
@@ -6113,7 +6162,7 @@ bool Mob::AddRangedProc(uint16 spell_id, uint16 iChance, uint16 base_spell_id, u
bool Mob::RemoveRangedProc(uint16 spell_id, bool bAll)
{
for (int i = 0; i < MAX_PROCS; i++) {
for (int i = 0; i < m_max_procs; i++) {
if (bAll || RangedProcs[i].spellID == spell_id) {
RangedProcs[i].spellID = SPELL_UNKNOWN;
RangedProcs[i].chance = 0;
+3 -3
View File
@@ -157,7 +157,7 @@ void NPC::ResumeWandering()
}
else
{
LogError("NPC not paused - can't resume wandering: [{}]", (unsigned long)GetNPCTypeID());
LogPathing("NPC not paused - can't resume wandering: [{}]", (unsigned long)GetNPCTypeID());
return;
}
@@ -173,7 +173,7 @@ void NPC::ResumeWandering()
}
else
{
LogError("NPC not on grid - can't resume wandering: [{}]", (unsigned long)GetNPCTypeID());
LogPathing("NPC not on grid - can't resume wandering: [{}]", (unsigned long)GetNPCTypeID());
}
return;
}
@@ -195,7 +195,7 @@ void NPC::PauseWandering(int pausetime)
}
}
else {
LogError("NPC not on grid - can't pause wandering: [{}]", (unsigned long)GetNPCTypeID());
LogPathing("NPC not on grid - can't pause wandering: [{}]", (unsigned long)GetNPCTypeID());
}
return;
}
+62 -47
View File
@@ -2509,98 +2509,105 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
}
case ServerOP_CZMove:
{
CZMove_Struct* CZM = (CZMove_Struct*) pack->pBuffer;
uint8 update_type = CZM->update_type;
uint8 update_subtype = CZM->update_subtype;
int update_identifier = CZM->update_identifier;
const char* zone_short_name = CZM->zone_short_name;
uint16 instance_id = CZM->instance_id;
const char* client_name = CZM->client_name;
auto s = (CZMove_Struct*) pack->pBuffer;
const std::string& client_name = s->client_name;
const glm::vec4& coordinates = s->coordinates;
const uint16 instance_id = s->instance_id;
const uint32 update_identifier = s->update_identifier;
const uint8 update_type = s->update_type;
const uint8 update_subtype = s->update_subtype;
const std::string& zone_short_name = s->zone_short_name;
if (Strings::IsNumber(client_name) || Strings::IsNumber(zone_short_name)) {
break;
}
if (update_type == CZUpdateType_Character) {
auto client = entity_list.GetClientByCharID(update_identifier);
if (client) {
Client* c = entity_list.GetClientByCharID(update_identifier);
if (c) {
switch (update_subtype) {
case CZMoveUpdateSubtype_MoveZone:
client->MoveZone(zone_short_name);
c->MoveZone(zone_short_name.c_str(), coordinates);
break;
case CZMoveUpdateSubtype_MoveZoneInstance:
client->MoveZoneInstance(instance_id);
c->MoveZoneInstance(instance_id, coordinates);
break;
}
}
} else if (update_type == CZUpdateType_Group) {
auto client_group = entity_list.GetGroupByID(update_identifier);
if (client_group) {
for (int member_index = 0; member_index < MAX_GROUP_MEMBERS; member_index++) {
if (client_group->members[member_index] && client_group->members[member_index]->IsClient()) {
auto group_member = client_group->members[member_index]->CastToClient();
Group* g = entity_list.GetGroupByID(update_identifier);
if (g) {
for (const auto& gm : g->members) {
if (gm->IsClient()) {
Client* c = gm->CastToClient();
switch (update_subtype) {
case CZMoveUpdateSubtype_MoveZone:
group_member->MoveZone(zone_short_name);
c->MoveZone(zone_short_name.c_str(), coordinates);
break;
case CZMoveUpdateSubtype_MoveZoneInstance:
group_member->MoveZoneInstance(instance_id);
c->MoveZoneInstance(instance_id, coordinates);
break;
}
}
}
}
} else if (update_type == CZUpdateType_Raid) {
auto client_raid = entity_list.GetRaidByID(update_identifier);
if (client_raid) {
for (const auto& m : client_raid->members) {
if (m.is_bot) {
Raid* r = entity_list.GetRaidByID(update_identifier);
if (r) {
for (const auto& rm : r->members) {
if (rm.is_bot) {
continue;
}
if (m.member && m.member->IsClient()) {
auto raid_member = m.member->CastToClient();
if (rm.member && rm.member->IsClient()) {
Client* m = rm.member->CastToClient();
switch (update_subtype) {
case CZMoveUpdateSubtype_MoveZone:
raid_member->MoveZone(zone_short_name);
m->MoveZone(zone_short_name.c_str(), coordinates);
break;
case CZMoveUpdateSubtype_MoveZoneInstance:
raid_member->MoveZoneInstance(instance_id);
m->MoveZoneInstance(instance_id, coordinates);
break;
}
}
}
}
} else if (update_type == CZUpdateType_Guild) {
for (auto &client: entity_list.GetClientList()) {
if (client.second->GuildID() > 0 && client.second->GuildID() == update_identifier) {
for (auto& c : entity_list.GetClientList()) {
if (c.second && c.second->IsInAGuild() && c.second->IsInGuild(update_identifier)) {
switch (update_subtype) {
case CZMoveUpdateSubtype_MoveZone:
client.second->MoveZone(zone_short_name);
c.second->MoveZone(zone_short_name.c_str(), coordinates);
break;
case CZMoveUpdateSubtype_MoveZoneInstance:
client.second->MoveZoneInstance(instance_id);
c.second->MoveZoneInstance(instance_id, coordinates);
break;
}
}
}
} else if (update_type == CZUpdateType_Expedition) {
for (auto &client: entity_list.GetClientList()) {
if (client.second->GetExpedition() && client.second->GetExpedition()->GetID() == update_identifier) {
for (auto& c : entity_list.GetClientList()) {
if (c.second && c.second->GetExpeditionID() == update_identifier) {
switch (update_subtype) {
case CZMoveUpdateSubtype_MoveZone:
client.second->MoveZone(zone_short_name);
c.second->MoveZone(zone_short_name.c_str(), coordinates);
break;
case CZMoveUpdateSubtype_MoveZoneInstance:
client.second->MoveZoneInstance(instance_id);
c.second->MoveZoneInstance(instance_id, coordinates);
break;
}
}
}
} else if (update_type == CZUpdateType_ClientName) {
auto client = entity_list.GetClientByName(client_name);
if (client) {
Client* c = entity_list.GetClientByName(client_name.c_str());
if (c) {
switch (update_subtype) {
case CZMoveUpdateSubtype_MoveZone:
client->MoveZone(zone_short_name);
c->MoveZone(zone_short_name.c_str(), coordinates);
break;
case CZMoveUpdateSubtype_MoveZoneInstance:
client->MoveZoneInstance(instance_id);
c->MoveZoneInstance(instance_id, coordinates);
break;
}
}
@@ -3106,21 +3113,29 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
}
case ServerOP_WWMove:
{
WWMove_Struct* WWM = (WWMove_Struct*) pack->pBuffer;
uint8 update_type = WWM->update_type;
uint16 instance_id = WWM->instance_id;
const char* zone_short_name = WWM->zone_short_name;
uint8 min_status = WWM->min_status;
uint8 max_status = WWM->max_status;
auto m = (WWMove_Struct*) pack->pBuffer;
uint16 instance_id = m->instance_id;
uint8 max_status = m->max_status;
uint8 min_status = m->min_status;
uint8 update_type = m->update_type;
std::string zone_short_name = m->zone_short_name;
for (auto &client : entity_list.GetClientList()) {
switch (update_type) {
case WWMoveUpdateType_MoveZone:
if (client.second->Admin() >= min_status && (client.second->Admin() <= max_status || max_status == AccountStatus::Player)) {
client.second->MoveZone(zone_short_name);
if (
client.second->Admin() >= min_status &&
(client.second->Admin() <= max_status || max_status == AccountStatus::Player)
) {
client.second->MoveZone(zone_short_name.c_str());
}
break;
case WWMoveUpdateType_MoveZoneInstance:
if (client.second->Admin() >= min_status && (client.second->Admin() <= max_status || max_status == AccountStatus::Player)) {
if (
client.second->Admin() >= min_status &&
(client.second->Admin() <= max_status || max_status == AccountStatus::Player)
) {
client.second->MoveZoneInstance(instance_id);
}
break;
+11 -2
View File
@@ -2197,12 +2197,21 @@ void Zone::LoadZoneBlockedSpells()
if (zone_total_blocked_spells > 0) {
blocked_spells = new ZoneSpellsBlocked[zone_total_blocked_spells];
if (!content_db.LoadBlockedSpells(zone_total_blocked_spells, blocked_spells, GetZoneID())) {
LogError(" Failed to load blocked spells");
LogError(
"Failed to load blocked spells for {} ({}).",
zone_store.GetZoneName(GetZoneID(), true),
GetZoneID()
);
ClearBlockedSpells();
}
}
LogInfo("Loaded [{}] blocked spells(s)", Strings::Commify(zone_total_blocked_spells));
LogInfo(
"Loaded [{}] blocked spells(s) for {} ({}).",
Strings::Commify(zone_total_blocked_spells),
zone_store.GetZoneName(GetZoneID(), true),
GetZoneID()
);
}
}
+42 -35
View File
@@ -11,6 +11,7 @@
#include "zone.h"
#include "zonedb.h"
#include "aura.h"
#include "../common/repositories/blocked_spells_repository.h"
#include "../common/repositories/character_tribute_repository.h"
#include "../common/repositories/character_disciplines_repository.h"
#include "../common/repositories/npc_types_repository.h"
@@ -19,6 +20,7 @@
#include "../common/repositories/character_pet_inventory_repository.h"
#include "../common/repositories/character_pet_info_repository.h"
#include "../common/repositories/character_buffs_repository.h"
#include "../common/repositories/criteria/content_filter_criteria.h"
#include <ctime>
#include <iostream>
@@ -2845,50 +2847,55 @@ uint8 ZoneDatabase::RaidGroupCount(uint32 raidid, uint32 groupid) {
return Strings::ToInt(row[0]);
}
int32 ZoneDatabase::GetBlockedSpellsCount(uint32 zoneid)
int64 ZoneDatabase::GetBlockedSpellsCount(uint32 zone_id)
{
std::string query = StringFormat("SELECT count(*) FROM blocked_spells WHERE zoneid = %d", zoneid);
auto results = QueryDatabase(query);
if (!results.Success()) {
return -1;
}
if (results.RowCount() == 0)
return -1;
auto& row = results.begin();
return Strings::ToInt(row[0]);
return BlockedSpellsRepository::Count(
database,
fmt::format(
"zoneid = {} {}",
zone_id,
ContentFilterCriteria::apply()
)
);
}
bool ZoneDatabase::LoadBlockedSpells(int32 blockedSpellsCount, ZoneSpellsBlocked* into, uint32 zoneid)
bool ZoneDatabase::LoadBlockedSpells(int64 blocked_spells_count, ZoneSpellsBlocked* into, uint32 zone_id)
{
LogInfo("Loading Blocked Spells from database");
LogInfo("Loading Blocked Spells from database for {} ({}).", zone_store.GetZoneName(zone_id, true), zone_id);
std::string query = StringFormat("SELECT id, spellid, type, x, y, z, x_diff, y_diff, z_diff, message "
"FROM blocked_spells WHERE zoneid = %d ORDER BY id ASC", zoneid);
auto results = QueryDatabase(query);
if (!results.Success()) {
return false;
}
const auto& l = BlockedSpellsRepository::GetWhere(
database,
fmt::format(
"zoneid = {} {} ORDER BY id ASC",
zone_id,
ContentFilterCriteria::apply()
)
);
if (results.RowCount() == 0)
if (l.empty()) {
return true;
}
int32 index = 0;
for(auto& row = results.begin(); row != results.end(); ++row, ++index) {
if(index >= blockedSpellsCount) {
std::cerr << "Error, Blocked Spells Count of " << blockedSpellsCount << " exceeded." << std::endl;
break;
}
int64 i = 0;
memset(&into[index], 0, sizeof(ZoneSpellsBlocked));
into[index].spellid = Strings::ToInt(row[1]);
into[index].type = Strings::ToInt(row[2]);
into[index].m_Location = glm::vec3(Strings::ToFloat(row[3]), Strings::ToFloat(row[4]), Strings::ToFloat(row[5]));
into[index].m_Difference = glm::vec3(Strings::ToFloat(row[6]), Strings::ToFloat(row[7]), Strings::ToFloat(row[8]));
strn0cpy(into[index].message, row[9], 255);
}
for (const auto& e : l) {
if (i >= blocked_spells_count) {
LogError(
"Blocked spells count of {} exceeded for {} ({}).",
blocked_spells_count,
zone_store.GetZoneName(zone_id, true),
zone_id
);
break;
}
memset(&into[i], 0, sizeof(ZoneSpellsBlocked));
into[i].spellid = e.spellid;
into[i].type = e.type;
into[i].m_Location = glm::vec3(e.x, e.y, e.z);
into[i].m_Difference = glm::vec3(e.x_diff, e.y_diff, e.z_diff);
strn0cpy(into[i].message, e.message.c_str(), sizeof(into[i].message));
}
return true;
}
+2 -2
View File
@@ -619,8 +619,8 @@ public:
int GetDoorsDBCountPlusOne(std::string zone_short_name, int16 version);
/* Blocked Spells */
int32 GetBlockedSpellsCount(uint32 zoneid);
bool LoadBlockedSpells(int32 blockedSpellsCount, ZoneSpellsBlocked* into, uint32 zoneid);
int64 GetBlockedSpellsCount(uint32 zone_id);
bool LoadBlockedSpells(int64 blocked_spells_count, ZoneSpellsBlocked* into, uint32 zone_id);
/* Traps */
bool LoadTraps(const char* zonename, int16 version);
+44 -26
View File
@@ -575,32 +575,41 @@ void Client::MovePC(uint32 zoneID, uint32 instanceID, float x, float y, float z,
}
void Client::MoveZone(const char *zone_short_name, const glm::vec4 &location) {
ProcessMovePC(ZoneID(zone_short_name), 0, location.x, location.y, location.z, location.w, 3, ZoneToSafeCoords);
const bool use_coordinates = (
location.x != 0.0f ||
location.y != 0.0f ||
location.z != 0.0f ||
location.w != 0.0f
);
const ZoneMode zone_type = use_coordinates ? ZoneSolicited : ZoneToSafeCoords;
ProcessMovePC(ZoneID(zone_short_name), 0, location.x, location.y, location.z, location.w, 3, zone_type);
}
void Client::MoveZoneGroup(const char *zone_short_name, const glm::vec4 &location) {
if (!GetGroup()) {
Group* g = GetGroup();
if (!g) {
MoveZone(zone_short_name, location);
} else {
auto client_group = GetGroup();
for (int member_index = 0; member_index < MAX_GROUP_MEMBERS; member_index++) {
if (client_group->members[member_index] && client_group->members[member_index]->IsClient()) {
auto group_member = client_group->members[member_index]->CastToClient();
group_member->MoveZone(zone_short_name, location);
for (const auto& gm : g->members) {
if (gm && gm->IsClient()) {
Client* c = gm->CastToClient();
c->MoveZone(zone_short_name, location);
}
}
}
}
void Client::MoveZoneRaid(const char *zone_short_name, const glm::vec4 &location) {
if (!GetRaid()) {
Raid* r = GetRaid();
if (!r) {
MoveZone(zone_short_name, location);
} else {
auto client_raid = GetRaid();
for (int member_index = 0; member_index < MAX_RAID_MEMBERS; member_index++) {
if (client_raid->members[member_index].member && client_raid->members[member_index].member->IsClient()) {
auto raid_member = client_raid->members[member_index].member->CastToClient();
raid_member->MoveZone(zone_short_name, location);
for (const auto& rm : r->members) {
if (rm.member && rm.member->IsClient()) {
Client* c = rm.member->CastToClient();
c->MoveZone(zone_short_name, location);
}
}
}
@@ -611,32 +620,41 @@ void Client::MoveZoneInstance(uint16 instance_id, const glm::vec4 &location) {
database.AddClientToInstance(instance_id, CharacterID());
}
ProcessMovePC(database.GetInstanceZoneID(instance_id), instance_id, location.x, location.y, location.z, location.w, 3, ZoneToSafeCoords);
const bool use_coordinates = (
location.x != 0.0f ||
location.y != 0.0f ||
location.z != 0.0f ||
location.w != 0.0f
);
const ZoneMode zone_type = use_coordinates ? ZoneSolicited : ZoneToSafeCoords;
ProcessMovePC(database.GetInstanceZoneID(instance_id), instance_id, location.x, location.y, location.z, location.w, 3, zone_type);
}
void Client::MoveZoneInstanceGroup(uint16 instance_id, const glm::vec4 &location) {
if (!GetGroup()) {
Group* g = GetGroup();
if (!g) {
MoveZoneInstance(instance_id, location);
} else {
auto client_group = GetGroup();
for (int member_index = 0; member_index < MAX_GROUP_MEMBERS; member_index++) {
if (client_group->members[member_index] && client_group->members[member_index]->IsClient()) {
auto group_member = client_group->members[member_index]->CastToClient();
group_member->MoveZoneInstance(instance_id, location);
for (const auto& gm : g->members) {
if (gm && gm->IsClient()) {
Client* c = gm->CastToClient();
c->MoveZoneInstance(instance_id, location);
}
}
}
}
void Client::MoveZoneInstanceRaid(uint16 instance_id, const glm::vec4 &location) {
if (!GetRaid()) {
Raid* r = GetRaid();
if (!r) {
MoveZoneInstance(instance_id, location);
} else {
auto client_raid = GetRaid();
for (int member_index = 0; member_index < MAX_RAID_MEMBERS; member_index++) {
if (client_raid->members[member_index].member && client_raid->members[member_index].member->IsClient()) {
auto raid_member = client_raid->members[member_index].member->CastToClient();
raid_member->MoveZoneInstance(instance_id, location);
for (const auto& rm : r->members) {
if (rm.member && rm.member->IsClient()) {
Client* c = rm.member->CastToClient();
c->MoveZoneInstance(instance_id, location);
}
}
}