aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormegamage <none@none>2009-06-17 18:35:40 -0500
committermegamage <none@none>2009-06-17 18:35:40 -0500
commita2f10c496fcacbfd3dcb976807c8c23012aba03d (patch)
treecdc8a358411fcfe4199b1a3628735d763e31103b
parent7e4fcb17934bfd37a771334e36131ea402559d9b (diff)
[8030] Fixed spell 64901 work and related target selection code refactoring. Author: VladimirMangos
* Replace 64904 by 64901 in spellbook and action bars. * Implement proper max mana percent buff * Implement proper target selection. * Move group/raid targets seelction code to functions for reuse code. --HG-- branch : trunk
-rw-r--r--sql/characters.sql2
-rw-r--r--sql/mangos.sql2
-rw-r--r--sql/updates/4105_8030_01_characters_character_spell.sql7
-rw-r--r--sql/updates/4105_8030_02_characters_character_action.sql5
-rw-r--r--sql/updates/4105_8030_03_mangos_npc_trainer.sql2
-rw-r--r--src/game/Spell.cpp141
-rw-r--r--src/game/Spell.h5
-rw-r--r--src/game/SpellAuras.cpp13
8 files changed, 144 insertions, 33 deletions
diff --git a/sql/characters.sql b/sql/characters.sql
index fc4b3e0d2e8..1ae05b869ed 100644
--- a/sql/characters.sql
+++ b/sql/characters.sql
@@ -23,7 +23,7 @@
DROP TABLE IF EXISTS `character_db_version`;
CREATE TABLE `character_db_version` (
- `required_7988_07_characters_characters` bit(1) default NULL
+ `required_8030_02_characters_character_action` bit(1) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Last applied sql update to DB';
--
diff --git a/sql/mangos.sql b/sql/mangos.sql
index 7316cd17dfa..42920a97b66 100644
--- a/sql/mangos.sql
+++ b/sql/mangos.sql
@@ -23,7 +23,7 @@ DROP TABLE IF EXISTS `db_version`;
CREATE TABLE `db_version` (
`version` varchar(120) default NULL,
`creature_ai_version` varchar(120) default NULL,
- `required_8021_01_mangos_spell_proc_event` bit(1) default NULL
+ `required_8030_03_mangos_npc_trainer` bit(1) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes';
--
diff --git a/sql/updates/4105_8030_01_characters_character_spell.sql b/sql/updates/4105_8030_01_characters_character_spell.sql
new file mode 100644
index 00000000000..332d0e4d071
--- /dev/null
+++ b/sql/updates/4105_8030_01_characters_character_spell.sql
@@ -0,0 +1,7 @@
+-- ALTER TABLE character_db_version CHANGE COLUMN required_7988_07_characters_characters required_8030_01_characters_character_spell bit;
+
+UPDATE IGNORE character_spell
+ SET spell = 64901
+ WHERE spell = 64904;
+
+DELETE FROM character_spell WHERE spell = 64904; \ No newline at end of file
diff --git a/sql/updates/4105_8030_02_characters_character_action.sql b/sql/updates/4105_8030_02_characters_character_action.sql
new file mode 100644
index 00000000000..5588350efe0
--- /dev/null
+++ b/sql/updates/4105_8030_02_characters_character_action.sql
@@ -0,0 +1,5 @@
+-- ALTER TABLE character_db_version CHANGE COLUMN required_8030_01_characters_character_spell required_8030_02_characters_character_action bit;
+
+UPDATE character_action
+ SET action = 64901
+ WHERE action = 64904 AND type = '0';
diff --git a/sql/updates/4105_8030_03_mangos_npc_trainer.sql b/sql/updates/4105_8030_03_mangos_npc_trainer.sql
new file mode 100644
index 00000000000..a1a5a45e862
--- /dev/null
+++ b/sql/updates/4105_8030_03_mangos_npc_trainer.sql
@@ -0,0 +1,2 @@
+-- ALTER TABLE db_version CHANGE COLUMN required_8021_01_mangos_spell_proc_event required_8030_03_mangos_npc_trainer bit;
+
diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
index a58e56be0fb..adcffee15b7 100644
--- a/src/game/Spell.cpp
+++ b/src/game/Spell.cpp
@@ -63,54 +63,55 @@ bool IsQuestTameSpell(uint32 spellId)
&& spellproto->Effect[1] == SPELL_EFFECT_APPLY_AURA && spellproto->EffectApplyAuraName[1] == SPELL_AURA_DUMMY;
}
-class PrioritizeManaWraper
+class PrioritizeManaUnitWraper
{
- friend struct PrioritizeMana;
-
public:
- explicit PrioritizeManaWraper(Unit * unit) : unit(unit)
+ explicit PrioritizeManaUnitWraper(Unit* unit) : i_unit(unit)
{
uint32 maxmana = unit->GetMaxPower(POWER_MANA);
- percentMana = maxmana ? unit->GetPower(POWER_MANA) * 100 / maxmana : 101;
+ i_percent = maxmana ? unit->GetPower(POWER_MANA) * 100 / maxmana : 101;
}
- Unit* getUnit() const { return unit; }
+ Unit* getUnit() const { return i_unit; }
+ uint32 getPercent() const { return i_percent; }
private:
- Unit* unit;
- uint32 percentMana;
+ Unit* i_unit;
+ uint32 i_percent;
};
struct PrioritizeMana
{
- int operator()( PrioritizeManaWraper const& x, PrioritizeManaWraper const& y ) const
+ int operator()( PrioritizeManaUnitWraper const& x, PrioritizeManaUnitWraper const& y ) const
{
- return x.percentMana > y.percentMana;
+ return x.getPercent() < y.getPercent();
}
};
-class PrioritizeHealthWraper
-{
- friend struct PrioritizeHealth;
+typedef std::priority_queue<PrioritizeManaUnitWraper, std::vector<PrioritizeManaUnitWraper>, PrioritizeMana> PrioritizeManaUnitQueue;
- public:
- explicit PrioritizeHealthWraper(Unit * unit) : unit(unit)
- {
- uint32 maxhp = unit->GetMaxHealth();
- percentHealth = maxhp ? unit->GetHealth() * 100 / maxhp : 101;
- }
- Unit* getUnit() const { return unit; }
- private:
- Unit* unit;
- uint32 percentHealth;
+class PrioritizeHealthUnitWraper
+{
+public:
+ explicit PrioritizeHealthUnitWraper(Unit* unit) : i_unit(unit)
+ {
+ i_percent = unit->GetHealth() * 100 / unit->GetMaxHealth();
+ }
+ Unit* getUnit() const { return i_unit; }
+ uint32 getPercent() const { return i_percent; }
+private:
+ Unit* i_unit;
+ uint32 i_percent;
};
struct PrioritizeHealth
{
- int operator()( PrioritizeHealthWraper const& x, PrioritizeHealthWraper const& y ) const
+ int operator()( PrioritizeHealthUnitWraper const& x, PrioritizeHealthUnitWraper const& y ) const
{
- return x.percentHealth > y.percentHealth;
+ return x.getPercent() < y.getPercent();
}
};
+typedef std::priority_queue<PrioritizeHealthUnitWraper, std::vector<PrioritizeHealthUnitWraper>, PrioritizeHealth> PrioritizeHealthUnitQueue;
+
SpellCastTargets::SpellCastTargets()
{
m_unitTarget = NULL;
@@ -2298,13 +2299,13 @@ void Spell::SetTargetMap(uint32 i, uint32 cur)
break;
case 57699: //Replenishment (special target selection) 10 targets with lowest mana
{
- typedef std::priority_queue<PrioritizeManaWraper, std::vector<PrioritizeManaWraper>, PrioritizeMana> TopMana;
+ typedef std::priority_queue<PrioritizeManaUnitWraper, std::vector<PrioritizeManaUnitWraper>, PrioritizeMana> TopMana;
TopMana manaUsers;
for (std::list<Unit*>::iterator itr = unitList.begin() ; itr != unitList.end();++itr)
{
if ((*itr)->getPowerType() == POWER_MANA)
{
- PrioritizeManaWraper WTarget(*itr);
+ PrioritizeManaUnitWraper WTarget(*itr);
manaUsers.push(WTarget);
}
}
@@ -2319,11 +2320,11 @@ void Spell::SetTargetMap(uint32 i, uint32 cur)
}
case 52759: // Ancestral Awakening
{
- typedef std::priority_queue<PrioritizeHealthWraper, std::vector<PrioritizeHealthWraper>, PrioritizeHealth> TopHealth;
+ typedef std::priority_queue<PrioritizeHealthUnitWraper, std::vector<PrioritizeHealthUnitWraper>, PrioritizeHealth> TopHealth;
TopHealth healedMembers;
for (std::list<Unit*>::iterator itr = unitList.begin() ; itr != unitList.end();++itr)
{
- PrioritizeHealthWraper WTarget(*itr);
+ PrioritizeHealthUnitWraper WTarget(*itr);
healedMembers.push(WTarget);
}
@@ -2339,13 +2340,13 @@ void Spell::SetTargetMap(uint32 i, uint32 cur)
if (m_spellInfo->EffectImplicitTargetA[i] == TARGET_DEST_TARGET_ANY
&& m_spellInfo->EffectImplicitTargetB[i] == TARGET_UNIT_AREA_ALLY_DST)// Wild Growth, Circle of Healing, Glyph of holy light target special selection
{
- typedef std::priority_queue<PrioritizeHealthWraper, std::vector<PrioritizeHealthWraper>, PrioritizeHealth> TopHealth;
+ typedef std::priority_queue<PrioritizeHealthUnitWraper, std::vector<PrioritizeHealthUnitWraper>, PrioritizeHealth> TopHealth;
TopHealth healedMembers;
for (std::list<Unit*>::iterator itr = unitList.begin() ; itr != unitList.end();++itr)
{
if ((*itr)->IsInRaidWith(m_targets.getUnitTarget()))
{
- PrioritizeHealthWraper WTarget(*itr);
+ PrioritizeHealthUnitWraper WTarget(*itr);
healedMembers.push(WTarget);
}
}
@@ -6234,3 +6235,81 @@ void Spell::SetSpellValue(SpellValueMod mod, int32 value)
break;
}
}
+
+void Spell::FillRaidOrPartyTargets( UnitList &TagUnitMap, Unit* target, float radius, bool raid, bool withPets, bool withcaster )
+{
+ Player *pTarget = target->GetCharmerOrOwnerPlayerOrPlayerItself();
+ Group *pGroup = pTarget ? pTarget->GetGroup() : NULL;
+
+ if (pGroup)
+ {
+ uint8 subgroup = pTarget->GetSubGroup();
+
+ for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next())
+ {
+ Player* Target = itr->getSource();
+
+ // IsHostileTo check duel and controlled by enemy
+ if (Target && (raid || subgroup==Target->GetSubGroup())
+ && !m_caster->IsHostileTo(Target))
+ {
+ if (Target==m_caster && withcaster ||
+ Target!=m_caster && m_caster->IsWithinDistInMap(Target, radius))
+ TagUnitMap.push_back(Target);
+
+ if (withPets)
+ if (Pet* pet = Target->GetPet())
+ if (pet==m_caster && withcaster ||
+ pet!=m_caster && m_caster->IsWithinDistInMap(pet, radius))
+ TagUnitMap.push_back(pet);
+ }
+ }
+ }
+ else
+ {
+ Unit* ownerOrSelf = pTarget ? pTarget : target->GetCharmerOrOwnerOrSelf();
+ if (ownerOrSelf==m_caster && withcaster ||
+ ownerOrSelf!=m_caster && m_caster->IsWithinDistInMap(ownerOrSelf, radius))
+ TagUnitMap.push_back(ownerOrSelf);
+
+ if (withPets)
+ if (Guardian* pet = ownerOrSelf->GetGuardianPet())
+ if (pet==m_caster && withcaster ||
+ pet!=m_caster && m_caster->IsWithinDistInMap(pet, radius))
+ TagUnitMap.push_back(pet);
+ }
+}
+
+void Spell::FillRaidOrPartyManaPriorityTargets( UnitList &TagUnitMap, Unit* target, float radius, uint32 count, bool raid, bool withPets, bool withCaster )
+{
+ FillRaidOrPartyTargets(TagUnitMap,target,radius,raid,withPets,withCaster);
+
+ PrioritizeManaUnitQueue manaUsers;
+ for(UnitList::const_iterator itr = TagUnitMap.begin(); itr != TagUnitMap.end() && manaUsers.size() < count; ++itr)
+ if ((*itr)->getPowerType() == POWER_MANA && !(*itr)->isDead())
+ manaUsers.push(PrioritizeManaUnitWraper(*itr));
+
+ TagUnitMap.clear();
+ while(!manaUsers.empty())
+ {
+ TagUnitMap.push_back(manaUsers.top().getUnit());
+ manaUsers.pop();
+ }
+}
+
+void Spell::FillRaidOrPartyHealthPriorityTargets( UnitList &TagUnitMap, Unit* target, float radius, uint32 count, bool raid, bool withPets, bool withCaster )
+{
+ FillRaidOrPartyTargets(TagUnitMap,target,radius,raid,withPets,withCaster);
+
+ PrioritizeHealthUnitQueue healthQueue;
+ for(UnitList::const_iterator itr = TagUnitMap.begin(); itr != TagUnitMap.end() && healthQueue.size() < count; ++itr)
+ if (!(*itr)->isDead())
+ healthQueue.push(PrioritizeHealthUnitWraper(*itr));
+
+ TagUnitMap.clear();
+ while(!healthQueue.empty())
+ {
+ TagUnitMap.push_back(healthQueue.top().getUnit());
+ healthQueue.pop();
+ }
+} \ No newline at end of file
diff --git a/src/game/Spell.h b/src/game/Spell.h
index adc661e206b..6aa539808df 100644
--- a/src/game/Spell.h
+++ b/src/game/Spell.h
@@ -105,6 +105,8 @@ namespace Trinity
struct SpellNotifierCreatureAndPlayer;
}
+typedef std::list<Unit*> UnitList;
+
class SpellCastTargets
{
public:
@@ -401,6 +403,9 @@ class Spell
void FillTargetMap();
void SetTargetMap(uint32 i, uint32 cur);
+ void FillRaidOrPartyTargets( UnitList &TagUnitMap, Unit* target, float radius, bool raid, bool withPets, bool withcaster );
+ void FillRaidOrPartyManaPriorityTargets( UnitList &TagUnitMap, Unit* target, float radius, uint32 count, bool raid, bool withPets, bool withcaster );
+ void FillRaidOrPartyHealthPriorityTargets( UnitList &TagUnitMap, Unit* target, float radius, uint32 count, bool raid, bool withPets, bool withcaster );
template<typename T> WorldObject* FindCorpseUsing();
diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp
index d55510b47ff..e33fa8a5b9d 100644
--- a/src/game/SpellAuras.cpp
+++ b/src/game/SpellAuras.cpp
@@ -5137,6 +5137,19 @@ void AuraEffect::HandleAuraModIncreaseEnergy(bool apply, bool Real, bool /*chang
UnitMods unitMod = UnitMods(UNIT_MOD_POWER_START + powerType);
+ // Special case with temporary increase max/current power (percent)
+ if (GetId()==64904) // Hymn of Hope
+ {
+ if(Real)
+ {
+ uint32 val = m_target->GetPower(powerType);
+ m_target->HandleStatModifier(unitMod, TOTAL_PCT, float(m_amount), apply);
+ m_target->SetPower(powerType, apply ? val*(100+m_amount)/100 : val*100/(100+m_amount));
+ }
+ return;
+ }
+
+ // generic flat case
m_target->HandleStatModifier(unitMod, TOTAL_VALUE, float(m_amount), apply);
}