Skip to content

Commit 952533a

Browse files
authored
Merge pull request #30 from pappons/feature/Update-spell-list-to-use-spell-chains-for-scaling
Fix: SQL script to use the create_template_model/Feature: level-appropriate buffs
2 parents a004f5a + f34c1de commit 952533a

File tree

3 files changed

+75
-81
lines changed

3 files changed

+75
-81
lines changed

conf/npc_buffer.conf.dist

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,23 +44,32 @@ Buff.CureRes = 1
4444

4545
Buff.ByLevel = 1
4646

47+
#
48+
# Buff.MaxLevel
49+
# Description: The highest character level at which buffs are scaled.
50+
# Characters at this level or higher receive the maximum
51+
# strength of buffs.
52+
#
53+
54+
Buff.MaxLevel = 80
55+
4756
#
4857
# Buff.Spells
4958
# Description: Buff Defaults (Leave blank to disable a buff)
50-
# This function is not active if Buff.ByLevel = 1
5159
#
5260
# 1. Prayer of Fortitude (48162)
5361
# 2. Greater Blessing of Kings (43223)
5462
# 3. Mark of the Wild (48469)
5563
# 4. Prayer of Spirit (48074)
5664
# 5. Prayer of Shadow Protection (48170)
5765
# 6. Arcane Intellect (42995)
66+
# 7. Thorns (53307)
5867
#
5968
# Fun Stuff
6069
# 48612 (Dalron the Controller)
6170
#
6271

63-
Buff.Spells = "48162;43223;48469;48074;48170;42995;"
72+
Buff.Spells = "48162;43223;48469;48074;48170;42995;53307;"
6473

6574
#
6675
# Buff.MessageTimer
@@ -90,7 +99,6 @@ BF.P1 = "Come get buffed, taste my stuff, the elven females can't get enuff!"
9099
BF.P2 = "She never shook the stars from the swirling cosmos, but she loved good tauren and rode good kodos."
91100
BF.P3 = "Mr. Grubbs is the toughest grub around. No doubt about it."
92101
BF.P4 = "Those trolls sure now how to dance! I hear they like to party in the mountains of Darkshore."
93-
94102
#
95103
# Buff.NumWhispers
96104
# Description: How many whispers does the NPC have?
@@ -117,6 +125,7 @@ BF.W8 = "Indeed.. %s. The dwarves keep many secrets about that which lies beyond
117125
BF.W9 = "A little bit of this.. a dab of that.. ahh.. there we go %s."
118126
BF.W10 = "No %s, I never did hear if they found the children that disappeared from Nagrand and Zangarmarsh."
119127

128+
120129
#
121130
# Buff.EmoteSpell
122131
# Description: The spell cast to get the player's attention

data/sql/db-world/npc_buffer_00.sql

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,19 @@ SET
2222

2323
-- NPC
2424
DELETE FROM `creature_template` WHERE `entry`=@Entry;
25-
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
26-
(@Entry, @Model, @Name, @Title, @Icon, @GossipMenu, @MinLevel, @MaxLevel, @Faction, @NPCFlag, 1, 1.14286, @Scale, @Rank, 1, 2, @Type, @TypeFlags, 1, @FlagsExtra, @AIName, @Script);
25+
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
26+
(@Entry, @Name, @Title, @Icon, @GossipMenu, @MinLevel, @MaxLevel, @Faction, @NPCFlag, 1, 1.14286, @Scale, @Rank, 1, 2, @Type, @TypeFlags, 1, @FlagsExtra, @AIName, @Script);
27+
28+
-- NPC MODEL
29+
INSERT INTO `creature_template_model` (`CreatureID`, `Idx`, `CreatureDisplayID`, `DisplayScale`, `Probability`) VALUES (@Entry, 0, @Model, 1, 1);
2730

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

34-
-- creatture_template_movement
37+
-- creature_template_movement
3538
DELETE FROM `creature_template_movement` WHERE `CreatureId`=@Entry;
3639
INSERT INTO `creature_template_movement` (`CreatureId`, `Ground`, `Swim`, `Flight`, `Rooted`, `Chase`, `Random`, `InteractionPauseTimer`) VALUES
3740
(@Entry, 1, 1, 0, 0, 0, 0, NULL);

src/npc_buffer.cpp

Lines changed: 57 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ the player using configurable emote options.
3030
3131
### Version
3232
------------------------------------------------------------------------------------------------------------------
33+
- v2024.07.01 - Fix database script to use creature_template_model table. Updated spell list/scaling code. Added Thorns to spell list
3334
- v2019.04.17 - Fix Cure Resurrection Sickness, works now! Courtesy of Poszer and Milestorme
3435
- v2019.04.15 - Ported to AzerothCore by gtao725 (https://github.com/gtao725/)
3536
- v2019.02.13 - Added phrases/emotes, config options, updated AI
@@ -69,6 +70,7 @@ This code and content is released under the [GNU AGPL v3](https://github.com/aze
6970
#include "Player.h"
7071
#include "ScriptedCreature.h"
7172
#include "ScriptedGossip.h"
73+
#include "Log.h"
7274

7375
static bool BFEnableModule;
7476
static bool BFAnnounceModule;
@@ -79,6 +81,7 @@ static uint32 BuffNumWhispers;
7981
static uint32 BuffMessageTimer;
8082
static uint32 BuffEmoteSpell;
8183
static uint32 BuffEmoteCommand;
84+
static uint32 MaxLevel = 80;
8285

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

103+
MaxLevel = sConfigMgr->GetOption<uint32>("Buff.MaxLevel", 80);
104+
100105
// Enforce Min/Max Time
101106
if (BuffMessageTimer != 0)
102107
{
@@ -128,6 +133,53 @@ class buff_npc : public CreatureScript
128133
public:
129134
buff_npc() : CreatureScript("buff_npc") {}
130135

136+
/** Get the most level-appropriate spell from the chain,
137+
* based on character level compared to max level (MaxLevel)
138+
* */
139+
static uint GetSpellForLevel(uint32 spell_id, Player *player)
140+
{
141+
uint32 level = player->getLevel();
142+
143+
// if the character is level max level or higher, return the last spell in the chain
144+
if (level >= MaxLevel)
145+
{
146+
return sSpellMgr->GetLastSpellInChain(spell_id);
147+
}
148+
149+
uint32 first_spell = sSpellMgr->GetFirstSpellInChain(spell_id);
150+
uint32 next_spell = first_spell;
151+
uint32 number_of_spells_in_chain = 0;
152+
for (; next_spell; next_spell = sSpellMgr->GetNextSpellInChain(next_spell))
153+
{
154+
number_of_spells_in_chain++;
155+
}
156+
157+
// if the chain is empty, return the first spell
158+
if (number_of_spells_in_chain == 0)
159+
{
160+
LOG_WARN("module.buffernpc", "Unable to find a spell chain for spell with id {}", spell_id);
161+
return first_spell;
162+
}
163+
164+
// if the chain has only one spell, return that spell
165+
if (number_of_spells_in_chain == 1)
166+
{
167+
return first_spell;
168+
}
169+
170+
// if the chain has more than one spell, calculate the level-appropriate spell
171+
uint32 spell_index = (level * number_of_spells_in_chain) / MaxLevel;
172+
uint32 spell = first_spell;
173+
LOG_DEBUG("module.buffernpc", "{}, level {}, gets spell {} of {} from spell {}", player->GetName(), level, (spell_index+1), number_of_spells_in_chain, spell_id);
174+
for (uint32 i = 0; i < spell_index; i++)
175+
{
176+
// traverse to the level-appropriate spell
177+
spell = sSpellMgr->GetNextSpellInChain(spell);
178+
}
179+
180+
return spell;
181+
}
182+
131183
static bool replace(std::string &str, const std::string &from, const std::string &to)
132184
{
133185
size_t start_pos = str.find(from);
@@ -184,7 +236,6 @@ class buff_npc : public CreatureScript
184236
// Who are we dealing with?
185237
std::string CreatureWhisper = "Init";
186238
std::string PlayerName = player->GetName();
187-
uint32 PlayerLevel = player->getLevel();
188239

189240
// Store Buff IDs
190241
std::vector<uint32> vecBuffs = {};
@@ -206,80 +257,12 @@ class buff_npc : public CreatureScript
206257
// Are we buffing based on level
207258
if (BuffByLevel == true)
208259
{
209-
// Apply (10-19, 20-29, ..., 70-79, 80)
210-
if (PlayerLevel < 10)
211-
{
212-
// Dish out the buffs
213-
player->CastSpell(player, 21562, true); // Prayer of Fortitude (Rank 1)
214-
player->CastSpell(player, 1126, true); // Mark of the Wild (Rank 1)
215-
player->CastSpell(player, 27683, true); // Prayer of Shadow Protection (Rank 1)
216-
} // 1-9
217-
else if (PlayerLevel >= 10 && PlayerLevel < 20)
218-
{
219-
player->CastSpell(player, 21562, true); // Prayer of Fortitude (Rank 1)
220-
player->CastSpell(player, 1126, true); // Mark of the Wild (Rank 1)
221-
player->CastSpell(player, 27683, true); // Prayer of Shadow Protection (Rank 1)
222-
} // 10-19
223-
else if (PlayerLevel >= 20 && PlayerLevel < 30)
224-
{
225-
player->CastSpell(player, 21562, true); // Prayer of Fortitude (Rank 1)
226-
player->CastSpell(player, 1126, true); // Mark of the Wild (Rank 1)
227-
player->CastSpell(player, 27683, true); // Prayer of Shadow Protection (Rank 1)
228-
player->CastSpell(player, 13326, true); // Arcane Intellect (Rank 1)
229-
} // 20-29
230-
else if (PlayerLevel >= 30 && PlayerLevel < 40)
231-
{
232-
player->CastSpell(player, 21562, true); // Prayer of Fortitude (Rank 1)
233-
player->CastSpell(player, 25898, true); // Greater Blessing of Kings (Rank 1)
234-
player->CastSpell(player, 1126, true); // Mark of the Wild (Rank 1)
235-
player->CastSpell(player, 27681, true); // Prayer of Spirit (Rank 1)
236-
player->CastSpell(player, 27683, true); // Prayer of Shadow Protection (Rank 1)
237-
player->CastSpell(player, 13326, true); // Arcane Intellect (Rank 1)
238-
} // 30-39
239-
else if (PlayerLevel >= 40 && PlayerLevel < 50)
240-
{
241-
player->CastSpell(player, 21562, true); // Prayer of Fortitude (Rank 1)
242-
player->CastSpell(player, vecBuffs[2], true); // Mark of the Wild(48469)
243-
player->CastSpell(player, 27681, true); // Prayer of Spirit (Rank 1)
244-
player->CastSpell(player, vecBuffs[4], true); // Prayer of Shadow Protection(48170)
245-
player->CastSpell(player, 13326, true); // Arcane Intellect (Rank 1)
246-
} // 40-49
247-
else if (PlayerLevel >= 50 && PlayerLevel < 60)
248-
{
249-
player->CastSpell(player, vecBuffs[0], true); // Prayer of Fortitude(48162)
250-
player->CastSpell(player, vecBuffs[1], true); // Greater Blessing of Kings(43223)
251-
player->CastSpell(player, vecBuffs[2], true); // Mark of the Wild(48469)
252-
player->CastSpell(player, vecBuffs[3], true); // Prayer of Spirit(48074)
253-
player->CastSpell(player, vecBuffs[4], true); // Prayer of Shadow Protection(48170)
254-
player->CastSpell(player, vecBuffs[5], true); // Arcane Intellect(42995)
255-
} // 50-59
256-
else if (PlayerLevel >= 60 && PlayerLevel < 70)
257-
{
258-
player->CastSpell(player, vecBuffs[0], true); // Prayer of Fortitude(48162)
259-
player->CastSpell(player, vecBuffs[1], true); // Greater Blessing of Kings(43223)
260-
player->CastSpell(player, vecBuffs[2], true); // Mark of the Wild(48469)
261-
player->CastSpell(player, vecBuffs[3], true); // Prayer of Spirit(48074)
262-
player->CastSpell(player, vecBuffs[4], true); // Prayer of Shadow Protection(48170)
263-
player->CastSpell(player, vecBuffs[5], true); // Arcane Intellect(42995)
264-
} // 60-69
265-
else if (PlayerLevel >= 70 && PlayerLevel < 80)
266-
{
267-
player->CastSpell(player, vecBuffs[0], true); // Prayer of Fortitude(48162)
268-
player->CastSpell(player, vecBuffs[1], true); // Greater Blessing of Kings(43223)
269-
player->CastSpell(player, vecBuffs[2], true); // Mark of the Wild(48469)
270-
player->CastSpell(player, vecBuffs[3], true); // Prayer of Spirit(48074)
271-
player->CastSpell(player, vecBuffs[4], true); // Prayer of Shadow Protection(48170)
272-
player->CastSpell(player, vecBuffs[5], true); // Arcane Intellect(42995)
273-
} // 70-79
274-
else
260+
for (std::vector<uint32>::const_iterator itr = vecBuffs.begin(); itr != vecBuffs.end(); itr++)
275261
{
276-
player->CastSpell(player, vecBuffs[0], true); // Prayer of Fortitude (48162)
277-
player->CastSpell(player, vecBuffs[1], true); // Greater Blessing of Kings (43223)
278-
player->CastSpell(player, vecBuffs[2], true); // Mark of the Wild (48469)
279-
player->CastSpell(player, vecBuffs[3], true); // Prayer of Spirit (48074)
280-
player->CastSpell(player, vecBuffs[4], true); // Prayer of Shadow Protection (48170)
281-
player->CastSpell(player, vecBuffs[5], true); // Arcane Intellect (42995)
282-
} // LEVEL 80
262+
uint32 spell_id = *itr; // get the spell id from the list of spells
263+
uint32 spell = GetSpellForLevel(spell_id, player); // get the level-appropriate spell
264+
player->CastSpell(player, spell, true); // cast the buff
265+
}
283266
}
284267
else
285268
{
@@ -292,7 +275,6 @@ class buff_npc : public CreatureScript
292275

293276
// Choose and speak a random phrase to the player
294277
// Phrases are stored in the config file
295-
296278
if (BuffNumWhispers > 0)
297279
{
298280
creature->Whisper(PickWhisper(PlayerName).c_str(), LANG_UNIVERSAL, player);

0 commit comments

Comments
 (0)