Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: SQL script to use the create_template_model/Feature: level-appropriate buffs #30

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions conf/npc_buffer.conf.dist
Original file line number Diff line number Diff line change
Expand Up @@ -44,23 +44,32 @@ Buff.CureRes = 1

Buff.ByLevel = 1

#
# Buff.MaxLevel
# Description: The highest character level at which buffs are scaled.
# Characters at this level or higher receive the maximum
# strength of buffs.
#

Buff.MaxLevel = 80

#
# Buff.Spells
# Description: Buff Defaults (Leave blank to disable a buff)
# This function is not active if Buff.ByLevel = 1
#
# 1. Prayer of Fortitude (48162)
# 2. Greater Blessing of Kings (43223)
# 3. Mark of the Wild (48469)
# 4. Prayer of Spirit (48074)
# 5. Prayer of Shadow Protection (48170)
# 6. Arcane Intellect (42995)
# 7. Thorns (53307)
#
# Fun Stuff
# 48612 (Dalron the Controller)
#

Buff.Spells = "48162;43223;48469;48074;48170;42995;"
Buff.Spells = "48162;43223;48469;48074;48170;42995;53307;"

#
# Buff.MessageTimer
Expand Down Expand Up @@ -90,7 +99,6 @@ BF.P1 = "Come get buffed, taste my stuff, the elven females can't get enuff!"
BF.P2 = "She never shook the stars from the swirling cosmos, but she loved good tauren and rode good kodos."
BF.P3 = "Mr. Grubbs is the toughest grub around. No doubt about it."
BF.P4 = "Those trolls sure now how to dance! I hear they like to party in the mountains of Darkshore."

#
# Buff.NumWhispers
# Description: How many whispers does the NPC have?
Expand All @@ -117,6 +125,7 @@ BF.W8 = "Indeed.. %s. The dwarves keep many secrets about that which lies beyond
BF.W9 = "A little bit of this.. a dab of that.. ahh.. there we go %s."
BF.W10 = "No %s, I never did hear if they found the children that disappeared from Nagrand and Zangarmarsh."


#
# Buff.EmoteSpell
# Description: The spell cast to get the player's attention
Expand Down
9 changes: 6 additions & 3 deletions data/sql/db-world/npc_buffer_00.sql
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,19 @@ SET

-- NPC
DELETE FROM `creature_template` WHERE `entry`=@Entry;
INSERT INTO `creature_template` (`entry`, `modelid1`, `name`, `subname`, `IconName`, `gossip_menu_id`, `minlevel`, `maxlevel`, `faction`, `npcflag`, `speed_walk`, `speed_run`, `scale`, `rank`, `unit_class`, `unit_flags`, `type`, `type_flags`, `RegenHealth`, `flags_extra`, `AiName`, `ScriptName`) VALUES
(@Entry, @Model, @Name, @Title, @Icon, @GossipMenu, @MinLevel, @MaxLevel, @Faction, @NPCFlag, 1, 1.14286, @Scale, @Rank, 1, 2, @Type, @TypeFlags, 1, @FlagsExtra, @AIName, @Script);
INSERT INTO `creature_template` (`entry`, `name`, `subname`, `IconName`, `gossip_menu_id`, `minlevel`, `maxlevel`, `faction`, `npcflag`, `speed_walk`, `speed_run`, `scale`, `rank`, `unit_class`, `unit_flags`, `type`, `type_flags`, `RegenHealth`, `flags_extra`, `AiName`, `ScriptName`) VALUES
(@Entry, @Name, @Title, @Icon, @GossipMenu, @MinLevel, @MaxLevel, @Faction, @NPCFlag, 1, 1.14286, @Scale, @Rank, 1, 2, @Type, @TypeFlags, 1, @FlagsExtra, @AIName, @Script);

-- NPC MODEL
INSERT INTO `creature_template_model` (`CreatureID`, `Idx`, `CreatureDisplayID`, `DisplayScale`, `Probability`) VALUES (@Entry, 0, @Model, 1, 1);

-- NPC EQUIPPED
-- War Axe(14824), Torch
DELETE FROM `creature_equip_template` WHERE `CreatureID`=@Entry AND `ID`=1;
INSERT INTO `creature_equip_template` VALUES
(@Entry, 1, 1906, 0, 0, 18019);

-- creatture_template_movement
-- creature_template_movement
DELETE FROM `creature_template_movement` WHERE `CreatureId`=@Entry;
INSERT INTO `creature_template_movement` (`CreatureId`, `Ground`, `Swim`, `Flight`, `Rooted`, `Chase`, `Random`, `InteractionPauseTimer`) VALUES
(@Entry, 1, 1, 0, 0, 0, 0, NULL);
132 changes: 57 additions & 75 deletions src/npc_buffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ the player using configurable emote options.

### Version
------------------------------------------------------------------------------------------------------------------
- v2024.07.01 - Fix database script to use creature_template_model table. Updated spell list/scaling code. Added Thorns to spell list
- v2019.04.17 - Fix Cure Resurrection Sickness, works now! Courtesy of Poszer and Milestorme
- v2019.04.15 - Ported to AzerothCore by gtao725 (https://github.com/gtao725/)
- v2019.02.13 - Added phrases/emotes, config options, updated AI
Expand Down Expand Up @@ -69,6 +70,7 @@ This code and content is released under the [GNU AGPL v3](https://github.com/aze
#include "Player.h"
#include "ScriptedCreature.h"
#include "ScriptedGossip.h"
#include "Log.h"

static bool BFEnableModule;
static bool BFAnnounceModule;
Expand All @@ -79,6 +81,7 @@ static uint32 BuffNumWhispers;
static uint32 BuffMessageTimer;
static uint32 BuffEmoteSpell;
static uint32 BuffEmoteCommand;
static uint32 MaxLevel = 80;

class BufferConfig : public WorldScript
{
Expand All @@ -97,6 +100,8 @@ class BufferConfig : public WorldScript
BuffEmoteSpell = sConfigMgr->GetOption<uint32>("Buff.EmoteSpell", 44940);
BuffEmoteCommand = sConfigMgr->GetOption<uint32>("Buff.EmoteCommand", 3);

MaxLevel = sConfigMgr->GetOption<uint32>("Buff.MaxLevel", 80);

// Enforce Min/Max Time
if (BuffMessageTimer != 0)
{
Expand Down Expand Up @@ -128,6 +133,53 @@ class buff_npc : public CreatureScript
public:
buff_npc() : CreatureScript("buff_npc") {}

/** Get the most level-appropriate spell from the chain,
* based on character level compared to max level (MaxLevel)
* */
static uint GetSpellForLevel(uint32 spell_id, Player *player)
{
uint32 level = player->getLevel();

// if the character is level max level or higher, return the last spell in the chain
if (level >= MaxLevel)
{
return sSpellMgr->GetLastSpellInChain(spell_id);
}

uint32 first_spell = sSpellMgr->GetFirstSpellInChain(spell_id);
uint32 next_spell = first_spell;
uint32 number_of_spells_in_chain = 0;
for (; next_spell; next_spell = sSpellMgr->GetNextSpellInChain(next_spell))
{
number_of_spells_in_chain++;
}

// if the chain is empty, return the first spell
if (number_of_spells_in_chain == 0)
{
LOG_WARN("module.buffernpc", "Unable to find a spell chain for spell with id {}", spell_id);
return first_spell;
}

// if the chain has only one spell, return that spell
if (number_of_spells_in_chain == 1)
{
return first_spell;
}

// if the chain has more than one spell, calculate the level-appropriate spell
uint32 spell_index = (level * number_of_spells_in_chain) / MaxLevel;
uint32 spell = first_spell;
LOG_DEBUG("module.buffernpc", "{}, level {}, gets spell {} of {} from spell {}", player->GetName(), level, (spell_index+1), number_of_spells_in_chain, spell_id);
for (uint32 i = 0; i < spell_index; i++)
{
// traverse to the level-appropriate spell
spell = sSpellMgr->GetNextSpellInChain(spell);
}

return spell;
}

static bool replace(std::string &str, const std::string &from, const std::string &to)
{
size_t start_pos = str.find(from);
Expand Down Expand Up @@ -184,7 +236,6 @@ class buff_npc : public CreatureScript
// Who are we dealing with?
std::string CreatureWhisper = "Init";
std::string PlayerName = player->GetName();
uint32 PlayerLevel = player->getLevel();

// Store Buff IDs
std::vector<uint32> vecBuffs = {};
Expand All @@ -206,80 +257,12 @@ class buff_npc : public CreatureScript
// Are we buffing based on level
if (BuffByLevel == true)
{
// Apply (10-19, 20-29, ..., 70-79, 80)
if (PlayerLevel < 10)
{
// Dish out the buffs
player->CastSpell(player, 21562, true); // Prayer of Fortitude (Rank 1)
player->CastSpell(player, 1126, true); // Mark of the Wild (Rank 1)
player->CastSpell(player, 27683, true); // Prayer of Shadow Protection (Rank 1)
} // 1-9
else if (PlayerLevel >= 10 && PlayerLevel < 20)
{
player->CastSpell(player, 21562, true); // Prayer of Fortitude (Rank 1)
player->CastSpell(player, 1126, true); // Mark of the Wild (Rank 1)
player->CastSpell(player, 27683, true); // Prayer of Shadow Protection (Rank 1)
} // 10-19
else if (PlayerLevel >= 20 && PlayerLevel < 30)
{
player->CastSpell(player, 21562, true); // Prayer of Fortitude (Rank 1)
player->CastSpell(player, 1126, true); // Mark of the Wild (Rank 1)
player->CastSpell(player, 27683, true); // Prayer of Shadow Protection (Rank 1)
player->CastSpell(player, 13326, true); // Arcane Intellect (Rank 1)
} // 20-29
else if (PlayerLevel >= 30 && PlayerLevel < 40)
{
player->CastSpell(player, 21562, true); // Prayer of Fortitude (Rank 1)
player->CastSpell(player, 25898, true); // Greater Blessing of Kings (Rank 1)
player->CastSpell(player, 1126, true); // Mark of the Wild (Rank 1)
player->CastSpell(player, 27681, true); // Prayer of Spirit (Rank 1)
player->CastSpell(player, 27683, true); // Prayer of Shadow Protection (Rank 1)
player->CastSpell(player, 13326, true); // Arcane Intellect (Rank 1)
} // 30-39
else if (PlayerLevel >= 40 && PlayerLevel < 50)
{
player->CastSpell(player, 21562, true); // Prayer of Fortitude (Rank 1)
player->CastSpell(player, vecBuffs[2], true); // Mark of the Wild(48469)
player->CastSpell(player, 27681, true); // Prayer of Spirit (Rank 1)
player->CastSpell(player, vecBuffs[4], true); // Prayer of Shadow Protection(48170)
player->CastSpell(player, 13326, true); // Arcane Intellect (Rank 1)
} // 40-49
else if (PlayerLevel >= 50 && PlayerLevel < 60)
{
player->CastSpell(player, vecBuffs[0], true); // Prayer of Fortitude(48162)
player->CastSpell(player, vecBuffs[1], true); // Greater Blessing of Kings(43223)
player->CastSpell(player, vecBuffs[2], true); // Mark of the Wild(48469)
player->CastSpell(player, vecBuffs[3], true); // Prayer of Spirit(48074)
player->CastSpell(player, vecBuffs[4], true); // Prayer of Shadow Protection(48170)
player->CastSpell(player, vecBuffs[5], true); // Arcane Intellect(42995)
} // 50-59
else if (PlayerLevel >= 60 && PlayerLevel < 70)
{
player->CastSpell(player, vecBuffs[0], true); // Prayer of Fortitude(48162)
player->CastSpell(player, vecBuffs[1], true); // Greater Blessing of Kings(43223)
player->CastSpell(player, vecBuffs[2], true); // Mark of the Wild(48469)
player->CastSpell(player, vecBuffs[3], true); // Prayer of Spirit(48074)
player->CastSpell(player, vecBuffs[4], true); // Prayer of Shadow Protection(48170)
player->CastSpell(player, vecBuffs[5], true); // Arcane Intellect(42995)
} // 60-69
else if (PlayerLevel >= 70 && PlayerLevel < 80)
{
player->CastSpell(player, vecBuffs[0], true); // Prayer of Fortitude(48162)
player->CastSpell(player, vecBuffs[1], true); // Greater Blessing of Kings(43223)
player->CastSpell(player, vecBuffs[2], true); // Mark of the Wild(48469)
player->CastSpell(player, vecBuffs[3], true); // Prayer of Spirit(48074)
player->CastSpell(player, vecBuffs[4], true); // Prayer of Shadow Protection(48170)
player->CastSpell(player, vecBuffs[5], true); // Arcane Intellect(42995)
} // 70-79
else
for (std::vector<uint32>::const_iterator itr = vecBuffs.begin(); itr != vecBuffs.end(); itr++)
{
player->CastSpell(player, vecBuffs[0], true); // Prayer of Fortitude (48162)
player->CastSpell(player, vecBuffs[1], true); // Greater Blessing of Kings (43223)
player->CastSpell(player, vecBuffs[2], true); // Mark of the Wild (48469)
player->CastSpell(player, vecBuffs[3], true); // Prayer of Spirit (48074)
player->CastSpell(player, vecBuffs[4], true); // Prayer of Shadow Protection (48170)
player->CastSpell(player, vecBuffs[5], true); // Arcane Intellect (42995)
} // LEVEL 80
uint32 spell_id = *itr; // get the spell id from the list of spells
uint32 spell = GetSpellForLevel(spell_id, player); // get the level-appropriate spell
player->CastSpell(player, spell, true); // cast the buff
}
}
else
{
Expand All @@ -292,7 +275,6 @@ class buff_npc : public CreatureScript

// Choose and speak a random phrase to the player
// Phrases are stored in the config file

if (BuffNumWhispers > 0)
{
creature->Whisper(PickWhisper(PlayerName).c_str(), LANG_UNIVERSAL, player);
Expand Down
Loading