aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/game/DBCStructure.h11
-rw-r--r--src/game/DBCfmt.h2
-rw-r--r--src/game/Player.cpp41
-rw-r--r--src/game/Player.h5
-rw-r--r--src/game/SpellAuras.cpp20
-rw-r--r--src/game/SpellMgr.cpp12
-rw-r--r--src/game/Unit.cpp25
7 files changed, 79 insertions, 37 deletions
diff --git a/src/game/DBCStructure.h b/src/game/DBCStructure.h
index e6ab168d852..08248576820 100644
--- a/src/game/DBCStructure.h
+++ b/src/game/DBCStructure.h
@@ -1488,6 +1488,8 @@ struct SpellRuneCostEntry
bool NoRunicPowerGain() const { return runePowerGain == 0; }
};
+#define MAX_SHAPESHIFT_SPELLS 8
+
struct SpellShapeshiftEntry
{
uint32 ID; // 0
@@ -1502,14 +1504,7 @@ struct SpellShapeshiftEntry
//uint32 unk2; // 24 unused
//uint32 unk3; // 25 unused
//uint32 unk4; // 26 unused
- //uint32 unk5; // 27 unused
- //uint32 unk6; // 28 unused
- //uint32 unk7; // 29 unused
- //uint32 unk8; // 30 unused
- //uint32 unk9; // 31 unused
- //uint32 unk10; // 32 unused
- //uint32 unk11; // 33 unused
- //uint32 unk12; // 34 unused
+ uint32 stanceSpell[MAX_SHAPESHIFT_SPELLS]; // 27 - 34 unused
};
struct SpellDurationEntry
diff --git a/src/game/DBCfmt.h b/src/game/DBCfmt.h
index e4bef193dd1..a6a4c1027d2 100644
--- a/src/game/DBCfmt.h
+++ b/src/game/DBCfmt.h
@@ -93,7 +93,7 @@ const char SpellItemEnchantmentConditionfmt[]="nbbbbbxxxxxbbbbbbbbbbiiiiiXXXXX";
const char SpellRadiusfmt[]="nfxf";
const char SpellRangefmt[]="nffffixxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
const char SpellRuneCostfmt[]="niiii";
-const char SpellShapeshiftfmt[]="nxxxxxxxxxxxxxxxxxxiixixxxxxxxxxxxx";
+const char SpellShapeshiftfmt[]="nxxxxxxxxxxxxxxxxxxiixixxxxiiiiiiii";
const char StableSlotPricesfmt[] = "ni";
const char SummonPropertiesfmt[] = "niiiii";
const char TalentEntryfmt[]="niiiiiiiixxxxixxixxxxxx";
diff --git a/src/game/Player.cpp b/src/game/Player.cpp
index b2689f6572c..c73a9b3a623 100644
--- a/src/game/Player.cpp
+++ b/src/game/Player.cpp
@@ -2756,7 +2756,11 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
bool superceded_old = false;
PlayerSpellMap::iterator itr = m_spells.find(spell_id);
- if (itr != m_spells.end())
+
+ // Remove temporary spell if found to prevent conflicts
+ if (itr != m_spells.end() && itr->second->state == PLAYERSPELL_TEMPORARY)
+ RemoveTemporarySpell(spell_id);
+ else if (itr != m_spells.end())
{
uint32 next_active_spell_id = 0;
// fix activate state for non-stackable low rank (and find next spell for !active case)
@@ -3069,6 +3073,33 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
return active && !disabled && !superceded_old;
}
+void Player::AddTemporarySpell(uint32 spellId)
+{
+ PlayerSpellMap::iterator itr = m_spells.find(spellId);
+ // spell already added - do not do anything
+ if (itr != m_spells.end())
+ return;
+ PlayerSpell *newspell = new PlayerSpell;
+ newspell->state = PLAYERSPELL_TEMPORARY;
+ newspell->active = true;
+ newspell->dependent = false;
+ newspell->disabled = false;
+ m_spells[spellId] = newspell;
+}
+
+void Player::RemoveTemporarySpell(uint32 spellId)
+{
+ PlayerSpellMap::iterator itr = m_spells.find(spellId);
+ // spell already not in list - do not do anything
+ if (itr == m_spells.end())
+ return;
+ // spell has other state than temporary - do not change it
+ if (itr->second->state != PLAYERSPELL_TEMPORARY)
+ return;
+ delete itr->second;
+ m_spells.erase(itr);
+}
+
bool Player::IsNeedCastPassiveSpellAtLearn(SpellEntry const* spellInfo) const
{
bool need_cast = false;
@@ -3130,7 +3161,7 @@ void Player::removeSpell(uint32 spell_id, bool disabled, bool update_action_bar_
if (itr == m_spells.end())
return;
- if(itr->second->state == PLAYERSPELL_REMOVED || disabled && itr->second->disabled)
+ if(itr->second->state == PLAYERSPELL_REMOVED || disabled && itr->second->disabled || itr->second->state == PLAYERSPELL_TEMPORARY)
return;
// unlearn non talent higher ranks (recursive)
@@ -17084,7 +17115,10 @@ void Player::RestoreSpellMods(Spell * spell)
mod->charges = 1;
else
mod->charges++;
- assert (mod->ownerAura->GetAuraCharges() <= mod->charges);
+
+ // Skip this check for now - aura charges may change due to various reason
+ // TODO: trac these changes correctly
+ //assert (mod->ownerAura->GetAuraCharges() <= mod->charges);
}
}
}
@@ -17547,6 +17581,7 @@ void Player::InitDataForForm(bool reapplyMods)
switch(m_form)
{
+ case FORM_GHOUL:
case FORM_CAT:
{
if(getPowerType()!=POWER_ENERGY)
diff --git a/src/game/Player.h b/src/game/Player.h
index 12d9c4c5efd..a2a2135024c 100644
--- a/src/game/Player.h
+++ b/src/game/Player.h
@@ -83,7 +83,8 @@ enum PlayerSpellState
PLAYERSPELL_UNCHANGED = 0,
PLAYERSPELL_CHANGED = 1,
PLAYERSPELL_NEW = 2,
- PLAYERSPELL_REMOVED = 3
+ PLAYERSPELL_REMOVED = 3,
+ PLAYERSPELL_TEMPORARY = 4
};
struct PlayerSpell
@@ -1363,6 +1364,8 @@ class TRINITY_DLL_SPEC Player : public Unit
void learnQuestRewardedSpells();
void learnQuestRewardedSpells(Quest const* quest);
void learnSpellHighRank(uint32 spellid);
+ void AddTemporarySpell(uint32 spellId);
+ void RemoveTemporarySpell(uint32 spellId);
uint32 GetFreeTalentPoints() const { return GetUInt32Value(PLAYER_CHARACTER_POINTS1); }
void SetFreeTalentPoints(uint32 points) { SetUInt32Value(PLAYER_CHARACTER_POINTS1,points); }
diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp
index b6c44b8cc60..7bf6463fadf 100644
--- a/src/game/SpellAuras.cpp
+++ b/src/game/SpellAuras.cpp
@@ -1434,9 +1434,9 @@ void AuraEffect::HandleShapeshiftBoosts(bool apply)
spellId = 27792;
spellId2 = 27795; // must be second, this important at aura remove to prevent to early iterator invalidation.
break;
+ case FORM_GHOUL:
case FORM_GHOSTWOLF:
case FORM_AMBIENT:
- case FORM_GHOUL:
case FORM_SHADOW:
case FORM_STEALTH:
case FORM_CREATURECAT:
@@ -3035,8 +3035,8 @@ void AuraEffect::HandleAuraModShapeshift(bool apply, bool Real, bool changeAmoun
PowerType = POWER_RAGE;
break;
case FORM_GHOUL:
- if(Player::TeamForRace(m_target->getRace())==ALLIANCE)
- modelid = 10045;
+ modelid = 24994;
+ PowerType = POWER_ENERGY;
break;
case FORM_DIREBEAR:
if(Player::TeamForRace(m_target->getRace())==ALLIANCE)
@@ -3249,6 +3249,20 @@ void AuraEffect::HandleAuraModShapeshift(bool apply, bool Real, bool changeAmoun
m_target->HandleAuraEffect(aurEff, false);
}
}
+ if (m_target->GetTypeId()==TYPEID_PLAYER)
+ {
+ SpellShapeshiftEntry const *shapeInfo = sSpellShapeshiftStore.LookupEntry(form);
+ // Learn spells for shapeshift form - no need to send action bars or add spells to spellbook
+ for (uint8 i = 0;i<MAX_SHAPESHIFT_SPELLS;++i)
+ {
+ if (!shapeInfo->stanceSpell[i])
+ continue;
+ if (apply)
+ ((Player*)m_target)->AddTemporarySpell(shapeInfo->stanceSpell[i]);
+ else
+ ((Player*)m_target)->RemoveTemporarySpell(shapeInfo->stanceSpell[i]);
+ }
+ }
}
void AuraEffect::HandleAuraTransform(bool apply, bool Real, bool /*changeAmount*/)
diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp
index ae3f72cdcad..9a4c03ddbc0 100644
--- a/src/game/SpellMgr.cpp
+++ b/src/game/SpellMgr.cpp
@@ -884,9 +884,10 @@ SpellCastResult GetErrorAtShapeshiftedCast (SpellEntry const *spellInfo, uint32
return SPELL_CAST_OK;
bool actAsShifted = false;
+ SpellShapeshiftEntry const *shapeInfo = NULL;
if (form > 0)
{
- SpellShapeshiftEntry const *shapeInfo = sSpellShapeshiftStore.LookupEntry(form);
+ shapeInfo = sSpellShapeshiftStore.LookupEntry(form);
if (!shapeInfo)
{
sLog.outError("GetErrorAtShapeshiftedCast: unknown shapeshift %u", form);
@@ -909,6 +910,15 @@ SpellCastResult GetErrorAtShapeshiftedCast (SpellEntry const *spellInfo, uint32
return SPELL_FAILED_ONLY_SHAPESHIFT;
}
+ // Check if stance disables cast of not-stance spells
+ // Example: cannot cast any other spells in zombie or ghoul form
+ // TODO: Find a way to disable use of these spells clientside
+ if (shapeInfo && shapeInfo->flags1 & 0x400)
+ {
+ if(!(stanceMask & spellInfo->Stances))
+ return SPELL_FAILED_ONLY_SHAPESHIFT;
+ }
+
return SPELL_CAST_OK;
}
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index d614b743b7b..82efd2e54a4 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -1987,20 +1987,6 @@ void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffe
case SPELLFAMILY_PRIEST:
{
// Guardian Spirit
- // Two implementation please check it
- /*if (spellProto->Id==47788)
- {
- if (pVictim->GetHealth() <= RemainingDamage) // Killing Blow
- {
- healAmount = pVictim->GetMaxHealth()/2;
- healCaster = pVictim;
- healSpell = 48153;
- (*i)->SetAmount(0);
- RemainingDamage=0;
- }
- continue;
- }*/
-
if (spellProto->SpellIconID == 2873)
{
preventDeathSpell = (*i)->GetSpellProto();
@@ -2083,9 +2069,8 @@ void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffe
case SPELLFAMILY_DEATHKNIGHT:
{
// Shadow of Death
- if (spellProto->SpellIconID == 1958)
+ if (spellProto->Id == 49157)
{
- // TODO: absorb only while transform
continue;
}
// Anti-Magic Shell (on self)
@@ -2287,7 +2272,6 @@ void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffe
{
switch(preventDeathSpell->SpellFamilyName)
{
- // Cheat Death
case SPELLFAMILY_ROGUE:
{
// Cheat Death
@@ -2301,7 +2285,6 @@ void Unit::CalcAbsorbResist(Unit *pVictim,SpellSchoolMask schoolMask, DamageEffe
}
break;
}
- // Guardian Spirit
case SPELLFAMILY_PRIEST:
{
// Guardian Spirit
@@ -8762,7 +8745,7 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3
if(!spellProto || !pVictim || damagetype==DIRECT_DAMAGE )
return pdamage;
- // For totems get damage bonus from owner (statue isn't totem in fact)
+ // For totems get damage bonus from owner
if( GetTypeId()==TYPEID_UNIT && ((Creature*)this)->isTotem())
{
if(Unit* owner = GetOwner())
@@ -8988,7 +8971,9 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3
{
AuraEffectList const& mDamageDoneMechanic = pVictim->GetAurasByType(SPELL_AURA_MOD_MECHANIC_DAMAGE_TAKEN_PERCENT);
for(AuraEffectList::const_iterator i = mDamageDoneMechanic.begin();i != mDamageDoneMechanic.end(); ++i)
- if(mechanicMask & uint32(1<<((*i)->GetMiscValue())))
+ if((mechanicMask & uint32(1<<((*i)->GetMiscValue())))
+ // Shred - "Effects which increase Bleed damage also increase Shred damage"
+ || ((*i)->GetMiscValue() == MECHANIC_BLEED && spellProto->SpellFamilyName == SPELLFAMILY_DRUID && spellProto->SpellFamilyFlags[0] & 0x8000))
TakenTotalMod *= ((*i)->GetAmount()+100.0f)/100.0f;
}