Skip to content

feat(Core/DB/Scripts): add creature_text_options engine for data-driven talk conditions#25188

Open
Nyeriah wants to merge 7 commits intoazerothcore:masterfrom
Nyeriah:creature-text-options
Open

feat(Core/DB/Scripts): add creature_text_options engine for data-driven talk conditions#25188
Nyeriah wants to merge 7 commits intoazerothcore:masterfrom
Nyeriah:creature-text-options

Conversation

@Nyeriah
Copy link
Copy Markdown
Member

@Nyeriah Nyeriah commented Mar 22, 2026

Changes Proposed:

This PR proposes changes to:

  • Core (units, players, creatures, game systems).
  • Scripts (bosses, spell scripts, creature scripts).
  • Database (SAI, creatures, etc).

AI-assisted Pull Requests

Important

While the use of AI tools when preparing pull requests is not prohibited, contributors must clearly disclose when such tools have been used and specify the model involved.

Contributors are also expected to fully understand the changes they are submitting and must be able to explain and justify those changes when requested by maintainers.

  • AI tools (e.g. ChatGPT, Claude, or similar) were used entirely or partially in preparing this pull request. Claude Opus 4.6 was used.

Summary

Introduces a data-driven creature_text_options engine that allows SendChat() to automatically enforce cooldown, trigger chance, and player-only filtering for creature text groups — without requiring per-script boilerplate.

Core changes:

  • New CreatureTextOptions struct and loader in CreatureTextMgr that reads from two new DB tables
  • SendChat() checks options (PlayerOnly, TriggerChance, Cooldown) before sending and sets cooldown after
  • Creature class gains cooldown tracking (IsTextOnCooldown, SetTextCooldown)

DB schema (two-table ruleset design to avoid data duplication):

  • creature_text_option_sets: Defines reusable rulesets (e.g. "6s cooldown, 100% chance, no player filter")
  • creature_text_options: Assigns a ruleset to a specific (CreatureID, GroupID) pair

Script cleanup (21 files):
Removes manual talk-throttling boilerplate from boss scripts across Black Temple, Azjol-Nerub, ICC, Ruby Sanctum, Drak'Tharon Keep, Gundrak, Nexus, and Naxxramas. Patterns removed include:

  • _canTalk boolean flags with ScheduleUniqueTimedEvent / AddEventAtOffset
  • EVENT_KILL_TALK with HasTimeUntilEvent / ScheduleEvent
  • _lastTalkTimeKill GameTime timestamp comparisons
  • roll_chance_i() wrappers

Issues Addressed:

  • N/A — Quality-of-life improvement to reduce script duplication

SOURCE:

The changes have been validated through:

  • Video evidence, knowledge databases or other public sources (e.g forums, Wowhead, etc.)

All cooldown values (5-6s) and trigger chances (30% for Razuvious) match the original hand-coded values in each script.

Tests Performed:

This PR has been:

  • Tested in-game by the author.
  • Tested in-game by other community members/someone else other than the author/has been live on production servers.
  • This pull request requires further testing and may have edge cases to be tested.

How to Test the Changes:

  • This pull request requires further testing. Provide steps to test your changes. If it requires any specific setup e.g multiple players please specify it as well.
  1. Build and start worldserver — verify Loading Creature Text Options... log line with correct row count
  2. Enter any dungeon/raid with a boss that has a kill yell (e.g. Gundrak, Nexus, Black Temple)
  3. Kill players near the boss rapidly — verify the boss yells on first kill but is throttled for ~6 seconds
  4. For Halion/Najentus/Teron/LK: verify kill yell only fires on player deaths, not pet/guardian deaths
  5. For Razuvious: verify kill yell fires ~30% of the time

Known Issues and TODO List:

  • Additional bosses with the same patterns exist (e.g. Moroes, Hyjal bosses) and can be migrated in follow-up PRs
  • Future enhancement: SAI integration so SmartAI scripts can also reference option sets

How to Test AzerothCore PRs

When a PR is ready to be tested, it will be marked as [WAITING TO BE TESTED].

You can help by testing PRs and writing your feedback here on the PR's page on GitHub. Follow the instructions here:

http://www.azerothcore.org/wiki/How-to-test-a-PR

REMEMBER: when testing a PR that changes something generic (i.e. a part of code that handles more than one specific thing), the tester should not only check that the PR does its job (e.g. fixing spell XXX) but especially check that the PR does not cause any regression (i.e. introducing new bugs).

For example: if a PR fixes spell X by changing a part of code that handles spells X, Y, and Z, we should not only test X, but we should test Y and Z as well.

Copilot AI review requested due to automatic review settings March 22, 2026 18:14
@Nyeriah Nyeriah added Waiting to be Tested Ready to be Reviewed Requires WIKI Update Wiki sources will need to be updated after merging this PR. labels Mar 22, 2026
@github-actions github-actions bot added DB related to the SQL database CORE Related to the core Script Refers to C++ Scripts for the Core file-cpp Used to trigger the matrix build labels Mar 22, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a data-driven “creature text options” layer so CreatureTextMgr::SendChat() can enforce per-(CreatureID, GroupID) talk rules (cooldown, proc chance, player-only) via DB configuration, allowing many boss scripts to remove custom talk-throttling logic.

Changes:

  • Core: introduce CreatureTextOptions, load options from new DB tables, and enforce them inside SendChat().
  • Core: add per-creature text cooldown tracking in Creature.
  • Scripts/DB: remove per-script kill-yell throttling/chance code and add SQL schema + mappings for affected bosses.

Reviewed changes

Copilot reviewed 30 out of 30 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/server/scripts/Outland/BlackTemple/boss_warlord_najentus.cpp Removes local slay talk throttling in favor of text options engine
src/server/scripts/Outland/BlackTemple/boss_teron_gorefiend.cpp Removes local slay talk throttling in favor of text options engine
src/server/scripts/Outland/BlackTemple/boss_mother_shahraz.cpp Removes local slay talk throttling in favor of text options engine
src/server/scripts/Outland/BlackTemple/boss_illidari_council.cpp Removes local kill-talk event gating in favor of text options engine
src/server/scripts/Outland/BlackTemple/boss_illidan.cpp Removes local kill yell cooldown logic in favor of text options engine
src/server/scripts/Northrend/Nexus/Nexus/boss_ormorok.cpp Removes local kill-talk event gating in favor of text options engine
src/server/scripts/Northrend/Nexus/Nexus/boss_magus_telestra.cpp Removes local kill-talk event gating in favor of text options engine
src/server/scripts/Northrend/Nexus/Nexus/boss_keristrasza.cpp Removes local kill-talk event gating in favor of text options engine
src/server/scripts/Northrend/Naxxramas/boss_razuvious.cpp Removes local 30% roll; relies on options for proc chance
src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp Removes local kill-yell cooldown timestamp; relies on options
src/server/scripts/Northrend/Gundrak/boss_slad_ran.cpp Removes local kill-talk event gating in favor of text options engine
src/server/scripts/Northrend/Gundrak/boss_moorabi.cpp Removes local kill-talk event gating in favor of text options engine
src/server/scripts/Northrend/Gundrak/boss_gal_darah.cpp Removes local kill-talk event gating in favor of text options engine
src/server/scripts/Northrend/DraktharonKeep/boss_trollgore.cpp Removes local kill-talk event gating in favor of text options engine
src/server/scripts/Northrend/DraktharonKeep/boss_tharon_ja.cpp Removes local kill-talk event gating in favor of text options engine
src/server/scripts/Northrend/DraktharonKeep/boss_novos.cpp Removes local kill-talk event gating in favor of text options engine
src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_saviana_ragefire.cpp Removes local kill-talk event gating in favor of text options engine
src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp Removes local player-only + kill-talk gating in favor of text options engine
src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_general_zarithrian.cpp Removes local kill-talk event gating in favor of text options engine
src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_baltharus_the_warborn.cpp Removes local kill-talk event gating in favor of text options engine
src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_krikthir_the_gatewatcher.cpp Removes local kill yell cooldown logic in favor of text options engine
src/server/scripts/Northrend/AzjolNerub/AzjolNerub/boss_anubarak.cpp Removes local kill-talk event gating in favor of text options engine
src/server/game/World/World.cpp Adds startup loading call for creature text options
src/server/game/Texts/CreatureTextMgr.h Adds CreatureTextOptions types and APIs
src/server/game/Texts/CreatureTextMgr.cpp Implements options loader + enforces options inside SendChat()
src/server/game/Entities/Creature/Creature.h Adds text cooldown tracking fields/APIs
src/server/game/Entities/Creature/Creature.cpp Implements text cooldown tracking
src/server/database/Database/Implementation/WorldDatabase.h Adds prepared statement id for options query
src/server/database/Database/Implementation/WorldDatabase.cpp Adds prepared query joining options to option sets
data/sql/updates/pending_db_world/creature_text_options.sql Adds schema + data mapping bosses to option sets

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

_lastTalkTimeKill = GameTime::GetGameTime().count();
Talk(SAY_LK_KILL);
}
if (!me->IsInEvadeMode() && _phase != PHASE_OUTRO)
Copy link

Copilot AI Mar 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change removes the script-side victim->IsPlayer() and cooldown gating and relies entirely on creature_text_options being present and successfully loaded. If the DB update isn’t applied (or the options query fails / returns empty), this will regress to yelling on non-player kills (pets/guardians) and can spam without cooldown. To keep behavior correct under partial deployments/misconfigured DBs, consider retaining the minimal victim->IsPlayer() guard in scripts where it previously existed (while still letting the engine handle cooldown/chance), or make options loading a hard requirement (clear startup failure/logging and/or disable affected groups when options are unavailable).

Suggested change
if (!me->IsInEvadeMode() && _phase != PHASE_OUTRO)
if (victim->IsPlayer() && !me->IsInEvadeMode() && _phase != PHASE_OUTRO)

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dismissed — the DB update is part of this PR and AzerothCore's update system applies pending SQL files atomically during startup. If the SQL hasn't run, the server wouldn't have the updated binaries either. The system is designed to be transparent: no options row = no filtering, so a missing DB entry doesn't break anything — it just means no throttling (which is the same behavior as before this PR for any creature without an entry).

Nyeriah and others added 5 commits March 22, 2026 18:57
…en talk conditions

Introduces creature_text_option_sets and creature_text_options tables that
let SendChat() enforce cooldown, trigger chance, and player-only filtering
without per-script boilerplate. Removes manual _canTalk booleans,
EVENT_KILL_TALK scheduling, GameTime timestamps, and roll_chance_i wrappers
from 21 boss scripts across Black Temple, Azjol-Nerub, ICC, Ruby Sanctum,
Drak'Tharon Keep, Gundrak, Nexus, and Naxxramas.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Migrates 22 more boss scripts to the creature_text_options engine:
- 16 _recentlySpoken pattern scripts (Karazhan, Hyjal, SSC, Gruul's,
  Magtheridon, TK Eye, Black Temple)
- 6 roll_chance_i KilledUnit scripts (Molten Core, Sunwell, TK Eye)
- Removes dead _recentlySpoken variable from Leotheras

Adds 3 new option sets (5s standard, 25% chance, 50% chance) and
26 new creature_text_options assignments.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
- Use ceiling division for cooldown to avoid truncating sub-second values
- Clarify log message for empty/failed options query
- Cache options pointer in SendChat() to avoid duplicate hash lookup

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
@Nyeriah Nyeriah force-pushed the creature-text-options branch from e9790ec to 443935a Compare March 22, 2026 21:58
Nyeriah and others added 2 commits March 29, 2026 22:07
BossAI base class already sets this validator. These were left over
from the creature_text_options refactor and conflict with the cleanup
done in PR azerothcore#25189.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CORE Related to the core DB related to the SQL database file-cpp Used to trigger the matrix build Ready to be Reviewed Requires WIKI Update Wiki sources will need to be updated after merging this PR. Script Refers to C++ Scripts for the Core Waiting to be Tested

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants