# Notes
- Perl was sending `UpdateAdmin()` after `SetGMStatus()`, Lua wasn't, so only Perl was updating properly.
- Fix is to just put `UpdateAdmin()` inside `SetGMStatus()`.
* [Bots] Add support for Bot scripting.
# Perl
- Add support for `zone/bot.pl` and `zone/bot_v#.pl`.
- Add support for `global/global_bot.pl`.
- Add `$bot->SignalBot(signal_id)` to Perl.
- Add `$bot->OwnerMessage(message)` to Perl.
- Add `$entity_list->SignalAllBotsByOwnerCharacterID(character_id, signal_id)` to Perl.
- Add `$entity_list->SignalBotByBotID(bot_id, signal_id)` to Perl.
- Add `$entity_list->SignalBotByBotName(bot_name, signal_id)` to Perl.
- Add `EVENT_SPELL_EFFECT_BOT` to Perl.
- Add `EVENT_SPELL_EFFECT_BUFF_TIC_BOT` to Perl.
# Lua
- Add support for `zone/bot.lua` and `zone/bot_v#.lua`.
- Add support for `global/global_bot.lua`.
- Add `bot:SignalBot(signal_id)` to Lua.
- Add `bot:OwnerMessage(message)` to Lua.
- Add `entity_list:SignalAllBotsByOwnerCharacterID(character_id, signal_id)` to Lua.
- Add `entity_list:SignalBotByBotID(bot_id, signal_id)` to Lua.
- Add `entity_list:SignalBotByBotName(bot_name, signal_id)` to Lua.
- Add `EVENT_SPELL_EFFECT_BOT` to Lua.
- Add `EVENT_SPELL_EFFECT_BUFF_TIC_BOT` to Lua.
# Supported Bot Events
1. `EVENT_CAST`
2. `EVENT_CAST_BEGIN`
3. `EVENT_CAST_ON`
4. `EVENT_COMBAT`
5. `EVENT_DEATH`
6. `EVENT_DEATH_COMPLETE`
7. `EVENT_SAY`
8. `EVENT_SIGNAL`
9. `EVENT_SLAY`
10. `EVENT_SLAY_NPC`
11. `EVENT_SPAWN`
12. `EVENT_TARGET_CHANGE`
13. `EVENT_TIMER`
14. `EVENT_USE_SKILL`
# Common
- Convert NPC pointers in common events to Mob pointers so bots are supported.
- Convert signal IDs to `int` where it wasn't already, allowing negative signals to be sent properly.
* Add EVENT_POPUP_RESPONSE.
* Cleanup and fix EVENT_COMBAT/EVENT_SLAY/EVENT_NPC_SLAY.
* Fix DoNPCEmote calls.
* Update attack.cpp
* Update event_codes.h
* Update bot_command.cpp
* [Bots] Add Quest API Support for Limits.
# Perl
- Add `$client->GetBotCreationLimit()` to Perl.
- Add `$client->GetBotCreationLimit(class_id)` to Perl.
- Add `$client->GetBotRequiredLevel()` to Perl.
- Add `$client->GetBotRequiredLevel(class_id)` to Perl.
- Add `$client->GetBotSpawnLimit()` to Perl.
- Add `$client->GetBotSpawnLimit(class_id)` to Perl.
- Add `$client->SetBotCreationLimit(creation_limit)` to Perl.
- Add `$client->SetBotCreationLimit(creation_limit, class_id)` to Perl.
- Add `$client->SetBotRequiredLevel(required_level)` to Perl.
- Add `$client->SetBotRequiredLevel(required_level, class_id)` to Perl.
- Add `$client->SetBotSpawnLimit(spawn_limit)` to Perl.
- Add `$client->SetBotSpawnLimit(spawn_limit, class_id)` to Perl.
- Add `$entity_list->GetBotListByCharacterID(character_id, class_id)` to Perl.
# Lua
- Add `client:GetBotCreationLimit()` to Lua.
- Add `client:GetBotCreationLimit(class_id)` to Lua.
- Add `client:GetBotRequiredLevel()` to Lua.
- Add `client:GetBotRequiredLevel(class_id)` to Lua.
- Add `client:GetBotSpawnLimit()` to Lua.
- Add `client:GetBotSpawnLimit(class_id)` to Lua.
- Add `client:SetBotCreationLimit(creation_limit)` to Lua.
- Add `client:SetBotCreationLimit(creation_limit, class_id)` to Lua.
- Add `client:SetBotRequiredLevel(required_level)` to Lua.
- Add `client:SetBotRequiredLevel(required_level, class_id)` to Lua.
- Add `client:SetBotSpawnLimit(spawn_limit)` to Lua.
- Add `client:SetBotSpawnLimit(spawn_limit, class_id)` to Lua.
- Add `entity_list:GetBotListByCharacterID(character_id, class_id)` to Lua.
# Notes
- Allows operators to set creation and spawn limits based on class, as well as required level.
- Using the class-inspecific methods sets the global limit or required level.
- Global limits are checked prior to class-specific limits and if they are not met, creation or spawn is disallowed.
- Modified preexisting Quest API to make use of this new stuff under the hood.
* Update bot_command.cpp
* Add client bot file.
* [Quest API] Add GetRandomBot() to Perl/lua.
# Perl
- Add `$entity_list->GetRandomBot()` to Perl.
- Add `$entity_list->GetRandomBot(x, y, z, distance)` to Perl.
- Add `$entity_list->GetRandomBot(x, y, z, distance, exclude_bot)` to Perl.
# Lua
- Add `eq.get_entity_list():GetRandomBot()` to Lua.
- Add `eq.get_entity_list():GetRandomBot(x, y, z, distance)` to Lua.
- Add `eq.get_entity_list():GetRandomBot(x, y, z, distance, exclude_bot)` to Lua.
# Notes
- Allows operators to grab a random Bot from entity list similar to Client, Mob, and NPC.
* Cleanup and fix Perl distance.
- Perl distance was sending as already squared, Lua was not.
- Send as non-squared and square in the method so that both work the same.
* Update entity.cpp
* Update entity.cpp
* [Bots] Add Expansion Bitmask Quest APIs.
- Add `$bot->GetExpansionBitmask()` to Perl.
- Add `$bot->SetExpansionBitmask(expansion_bitmask)` to Perl.
- Add `bot:GetExpansionBitmask()` to Lua.
- Add `bot:SetExpansionBitmask(expansion_bitmask)` to Lua.
- Adds `expansion_bitmask` column to `bot_data` table.
- Allows server operators to limit expansion settings on a bot-by-bot basis.
- Allows limiting or allowing of AAs in `Bot::LoadAAs()` based on expansion bitmask.
- Default value is `-1` which just defaults to the `Bots:BotExpansionSettings` rule value.
- Setting bitmask saves to database and reloads AAs so bots automatically recalculate bonuses.
* Add save parameter.
* Typo.
* [Quest API] Add Mob Hate Methods to Perl/Lua.
# Perl
- Add `$mob->DamageHateList(damage)` to Perl.
- Add `$mob->DamageHateList(damage, distance)` to Perl.
- Add `$mob->DamageHateListPercentage(damage)` to Perl.
- Add `$mob->DamageHateListPercentage(damage, distance)` to Perl.
- Add `$mob->DamageHateListBots(damage)` to Perl.
- Add `$mob->DamageHateListBots(damage, distance)` to Perl.
- Add `$mob->DamageHateListBotsPercentage(damage)` to Perl.
- Add `$mob->DamageHateListBotsPercentage(damage, distance)` to Perl.
- Add `$mob->DamageHateListClients(damage)` to Perl.
- Add `$mob->DamageHateListClients(damage, distance)` to Perl.
- Add `$mob->DamageHateListClientsPercentage(damage)` to Perl.
- Add `$mob->DamageHateListClientsPercentage(damage, distance)` to Perl.
- Add `$mob->DamageHateListNPCs(damage)` to Perl.
- Add `$mob->DamageHateListNPCs(damage, distance)` to Perl.
- Add `$mob->DamageHateListNPCsPercentage(damage)` to Perl.
- Add `$mob->DamageHateListNPCsPercentage(damage, distance)` to Perl.
- Add `$mob->GetHateListBots()` to Perl.
- Add `$mob->GetHateListBots(distance)` to Perl.
- Add `$mob->GetHateListClients()` to Perl.
- Add `$mob->GetHateListClients(distance)` to Perl.
- Add `$mob->GetHateListNPCs()` to Perl.
- Add `$mob->GetHateListNPCs(distance)` to Perl.
# Lua
- Add `mob:DamageHateList(damage)` to Lua.
- Add `mob:DamageHateList(damage, distance)` to Lua.
- Add `mob:DamageHateListPercentage(damage)` to Lua.
- Add `mob:DamageHateListPercentage(damage, distance)` to Lua.
- Add `mob:DamageHateListBots(damage)` to Lua.
- Add `mob:DamageHateListBots(damage, distance)` to Lua.
- Add `mob:DamageHateListBotsPercentage(damage)` to Lua.
- Add `mob:DamageHateListBotsPercentage(damage, distance)` to Lua.
- Add `mob:DamageHateListClients(damage)` to Lua.
- Add `mob:DamageHateListClients(damage, distance)` to Lua.
- Add `mob:DamageHateListClientsPercentage(damage)` to Lua.
- Add `mob:DamageHateListClientsPercentage(damage, distance)` to Lua.
- Add `mob:DamageHateListNPCs(damage)` to Lua.
- Add `mob:DamageHateListNPCs(damage, distance)` to Lua.
- Add `mob:DamageHateListNPCsPercentage(damage)` to Lua.
- Add `mob:DamageHateListNPCsPercentage(damage, distance)` to Lua.
- Add `mob:GetHateListBots()` to Lua.
- Add `mob:GetHateListBots(distance)` to Lua.
- Add `mob:GetHateListClients()` to Lua.
- Add `mob:GetHateListClients(distance)` to Lua.
- Add `mob:GetHateListNPCs()` to Lua.
- Add `mob:GetHateListNPCs(distance)` to Lua.
# Notes
- Offers an extreme amount of short hands when grabbing hate list entities by a specific type or damaging a specific type of entity on an NPC's hatelist.
- Should save operators having to use `GetHateList()` then loop it to get the entries they want to do something.
* Cleanup.
* [Quest API] Add Owner methods to Perl/Lua.
# Perl
- Add `$mob->GetOwner()` to Perl.
# Lua
- Add `mob:GetOwnerID()` to Lua.
# Notes
- `GetOwner()` exists in Lua, but not Perl.
- `GetOwnerID()` exists in Perl, but not Lua.
* Update lua_mob.cpp
# Perl
- Add `$mob->RandomizeFeatures()` to Perl.
- Add `$mob->RandomizeFeatures(send_illusion)` to Perl.
- Add `$mob->RandomizeFeatures(send_illusion, set_variables)` to Perl.
# Lua
- Add `mob:RandomizeFeatures()` to Lua.
- Add `mob:RandomizeFeatures(send_illusion)` to Lua.
- Add `mob:RandomizeFeatures(send_illusion, set_variables)` to Lua.
# Notes
- Previous overload required `send_illusion` and `set_variables` despite both default values being `true`, this will allow you to just send nothing if you want both to be `true`.
- Change `RandomizeFeatures()` type to `bool` from `void` to match source method, returns `false` when used on a race that has no features to randomize.
- This allows operators to do something different if the NPC can't use this method.
* [Quest API] Add SendGMCommand() to Perl/Lua.
# Perl
- Add `$client->SendGMCommand(message)` to Perl.
- Add `$client->SendGMCommand(message, ignore_status)` to Perl.
# Lua
- Add `client:SendGMCommand(message)` to Lua.
- Add `client:SendGMCommand(message, ignore_status)` to Lua.
# Notes
- `ignore_status` allows you to have players use GM commands that they are not the required status level for through the Quest API.
- `ignore_status` is default false, so if you don't send it, it checks and makes sure the player can use the command you're sending before allowing it.
* Typo.
* Formatting.
* [Commands] Cleanup #doanim Command.
- Cleanup messages and logic.
- Allow you to use animation names or IDs, could possibly extend this to quest API in the future.
* Update dialogue_window.h
* [Quest API] Add GetRandomClient(), GetRandomMob() and GetRandomNPC() overloads to Perl/Lua.
# Perl
- Add `$entity_list->GetRandomClient()` to Perl.
- Add `$entity_list->GetRandomMob()` to Perl.
- Add `$entity_list->GetRandomNPC()` to Perl.
# Lua
- Add `eq.get_entity_list():GetRandomClient()` to Lua.
- Add `eq.get_entity_list():GetRandomMob()` to Lua.
- Add `eq.get_entity_list():GetRandomNPC()` to Lua.
# Notes
- We didn't have overloads before without XYZ, so was harder to do a zone-wide random.
* Update lua_entity_list.cpp
* [Quest API] Add Popup methods to Perl/Lua.
# Perl
- Add `quest::popupcentermessage(message)` to Perl.
- Add `quest::popupcolormessage(color, message)` to Perl.
- Add `quest::popupindent()` to Perl.
- Add `quest::popuplink(link)` to Perl.
- Add `quest::popuplink(link, message)` to Perl.
# Lua
- Add `eq.popup(title, message)` to Lua.
- Add `eq.popup(title, message, popup_id)` to Lua.
- Add `eq.popup(title, message, popup_id, buttons)` to Lua.
- Add `eq.popup_center_message(message)` to Lua.
- Add `eq.popup_color_message(color, message)` to Lua.
- Add `eq.popup_indent()` to Lua.
- Add `eq.popup_link(link)` to Lua.
- Add `eq.popup_link(link, message)` to Lua.
# Notes
- Adds the Perl plugins like PWAutoCenter, PWIndent, and PWHyperlink.
- Parses out HTML `<>` tags automatically in `popupautocenter` to properly center stuff like colored messages. (Doesn't work with links)
- This lets Lua users have similar functionality to Perl users.
* Add tables and break.
* Add indent_count to indent method.
* Move to Dialogue Window.
* [Quest API] Add CloneAppearance() to Perl/Lua.
# Perl
- Add `$client->CloneAppearance(other)` to Perl.
- Add `$client->CloneAppearance(other, clone_name)` to Perl.
# Lua
- Add `client:CloneAppearance(other)` to Lua.
- Add `client:CloneAppearance(other, clone_name)` to Lua.
# Notes
- Allows operators to easily clone appearance between mobs in a script without relying on a plugin or module.
* Update mob_appearance.cpp
* Update mob.cpp
# Perl
- Add `$group->GetAverageLevel()` to Perl.
# Lua
- Add `group:GetAverageLevel()` to Lua.
- Convert `group:GetHighestLevel()` from `int` to `uint32` in Lua.
- Convert `group:GetLowestLevel()` from `int` to `uint32` in Lua.
* Change #scribespells to be aware of spellgroups & ranks
* Formatting
* Fix Formatting, and change stored return data type to match function return type.
* Compact If Statements
* Implemented SQL Query to reduce number of iterations required.
* Cleaned up Query, and improved performance
* Cleaned up SQL Queries
* Formatting
* Indenting fix.
* Update client.cpp
* Fix Formatting in spells.cpp
* Fix ValueWithin.
Co-authored-by: Kinglykrab <kinglykrab@gmail.com>
Co-authored-by: Kinglykrab <89047260+Kinglykrab@users.noreply.github.com>
This restores sending items to EVENT_TRADE that are updated by source
controlled delivery tasks which was removed in 7cf96ca2d8.
That patch filtered out items consumed by task updates to fix a few bugs
with items being returned despite incrementing a task:
- If an npc without a quest trade event handler was the target of a
delivery task for a NoDrop/non-Quest item, the npc would auto return
it due to the `ReturnNonQuestNoDropItems` rule.
- If an npc without a quest trade event handler was the target of a
delivery task for a non-NoDrop item, the item would be added to the
npc's loot.
- If an npc with an EVENT_ITEM/EVENT_TRADE quest handler used the Lua
or Perl trade plugins, the plugins would return task items unless
specific checks for the turned in slots existed.
The quest plugin item returns are problematic for this since they just
summon to return items not handled by the script
e.g. For a task to deliver N Large Fruit Bat Wings (item id 19616),
if a player turned in 1 Wing in slot 1 and a stack of 20 Wings in slot
2, the task would be incremented 21 times and the following Lua trade
handler would return the stack of 20 from the 2nd trade slot:
```lua
function event_trade(e)
local item_lib = require("items")
if item_lib.check_turn_in(e.trade, { item1 = 19616 }) then
eq.debug("Lua consumed 1 slot and will return other slots")
end
item_lib.return_items(e.self, e.other, e.trade)
end
```
This also occured with the perl plugin though slightly differently
since that plugin returns all slots unless the exact handin slot count
matches (requiring check_handin conditions for all slots):
```perl
sub EVENT_ITEM {
if (plugin::check_handin(\%itemcount, 19616 => 1)) {
# No issue if only one slot used for trade (item not returned)
}
# Perl fails handin check if multiple slots not checked and returns all
plugin::return_items(\%itemcount);
}
```
While that patch solved the issue, it's inconvenient and wrong to not
receive items in trade events used in a source task update. It breaks
existing trade scripts for tasks that aren't quest controlled and it
forces tasks to be changed to quest controlled and manually updated to
script any extra behavior.
This patch stores the task update count on the item instance before
dispatching it to quests. The burden is now on quests and plugins to
use that value in order to prevent returning items consumed by tasks.
`ItemInstance::RemoveTaskDeliveredItems` has been added to simplify
handling this in plugins which is also used for non-quest item returns.
This required some minor shared task refactoring
- Shared task expiration handling was moved to world. Previously this
was handled by zone and had clients self remove when a shared task
expired. This resulted in wrong messages when a task ended.
- FailTask is now implemented for shared tasks which previously only
made the client quit the shared task. It now fails the task for all
members by ending the shared task.
The `Client::EndSharedTask` api will end the client's current shared
task (removing all members). This is similiar to the `FailTask` api
except it doesn't require a `task_id` and the red task fail banner is
optional (live doesn't use it for shared tasks).
The global `end_dz_task` api was added for when a client context isn't
available. This will end a shared task if the current zone is a dynamic
zone for a shared task mission. Currently only shared tasks use dynamic
zones but this api can be expanded if support is added for tasks/quests.
The global `get_dz_task_id` was added to conveniently get the task id
for the current dynamic zone if it's used for a mission. Note this is
a database hit since that information is not available at zone level.
It wasn't possible to easily obtain the corpse from post-death events
because the killed entity id is assigned to the corpse and reset to 0
on the entity before the events are dispatched.
This exposes the killed entity's corpse to EVENT_DEATH_COMPLETE and
EVENT_DEATH_ZONE. Lua exports a Corpse object and perl exports a corpse
entity id.
The purpose of this is to make it easier to add items dynamically on
death. Ideally this would be done in EVENT_DEATH before the corpse is
made, but there's currently some combat system bugs that make that event
unusable since it can be dispatched multiple times.
A follow up will provide an api to reset corpse decay times since adding
items after corpse creation will require quests to manually reset the
decay timer in case the corpse had zero items.
# Perl
- Add `$from_instance_id` to EVENT_ZONE in Perl.
- Add `$from_instance_version` to EVENT_ZONE in Perl.
- Add `$target_instance_id` to EVENT_ZONE in Perl.
- Add `$target_instance_version` to EVENT_ZONE in Perl.
# Lua
- Add `e.from_instance_id` to EVENT_ZONE in Lua.
- Add `e.from_instance_version` to EVENT_ZONE in Lua.
- Add `e.instance_id` to EVENT_ZONE in Lua.
- Add `e.instance_version` to EVENT_ZONE in Lua.
# Notes
- This will allow Operators to prevent people from entering zones by Instance ID or Instance Version.
This cleans up some of the NPC::Death event dispatch code.
Adds handlers for EVENT_SPAWN_ZONE and EVENT_DEATH_ZONE used by zone
controller and fixes the death handler exports which were incorrect.
This fixes a bug that allowed looting items from a player's corpse to
increment a task if it didn't have an npc target defined. It looks
like this bug existed before the changes in 7482cfc0.
This also now passes count for task loot updates to handle item stacks.
Also fixes incorrectly casting Corpse to NPC on loot update
# Perl
- Add `$mob->GetUltimateOwner()` to Perl.
# Lua
- Add `mob:GetUltimateOwner()` to Lua.
# Notes
- Allows operators to get ultimate owner of something like a pet's pet or a pet's swarm pet.
* [Commands] Cleanup #emoteview Command.
Cleanup command messages and logic.
Add constants for Emote Events and Emote Types and replace all the old constants with the new constants.
* Update emoteview.cpp
* Cleanup #emotesearch Command.
* [Commands] Cleanup #modifynpcstat Command.
Cleanup messages and logic,
Add map and loop through it to display all stats, can add to this in the future if we add more stuff modifiable by this command.
* Delete settings.json
* Update modifynpcstat.cpp
* Update modifynpcstat.cpp
* Update questmgr.h
Returning non-zero from EVENT_TASK_COMPLETE will prevent task rewards
and completion emote. This is necessary for a DoN mission which scripts
a mission failure but still gives the lockout.