rendered paste bodyIndex: src/game/Creature.cpp
===================================================================
--- src/game/Creature.cpp (revision 2652)
+++ src/game/Creature.cpp (working copy)
@@ -1005,13 +1005,13 @@
SetUInt32Value(UNIT_FIELD_FLAGS,cinfo->Flags);
SetUInt32Value(UNIT_DYNAMIC_FLAGS,cinfo->dynamicflags);
- SetArmor(cinfo->armor);
- SetResistance(SPELL_SCHOOL_HOLY,cinfo->resistance1);
- SetResistance(SPELL_SCHOOL_FIRE,cinfo->resistance2);
- SetResistance(SPELL_SCHOOL_NATURE,cinfo->resistance3);
- SetResistance(SPELL_SCHOOL_FROST,cinfo->resistance4);
- SetResistance(SPELL_SCHOOL_SHADOW,cinfo->resistance5);
- SetResistance(SPELL_SCHOOL_ARCANE,cinfo->resistance6);
+ SetBaseArmor(cinfo->armor);
+ SetBaseResistance(SPELL_SCHOOL_HOLY,cinfo->resistance1);
+ SetBaseResistance(SPELL_SCHOOL_FIRE,cinfo->resistance2);
+ SetBaseResistance(SPELL_SCHOOL_NATURE,cinfo->resistance3);
+ SetBaseResistance(SPELL_SCHOOL_FROST,cinfo->resistance4);
+ SetBaseResistance(SPELL_SCHOOL_SHADOW,cinfo->resistance5);
+ SetBaseResistance(SPELL_SCHOOL_ARCANE,cinfo->resistance6);
//this is probably wrong
SetUInt32Value( UNIT_VIRTUAL_ITEM_SLOT_DISPLAY, cinfo->equipmodel[0]);
@@ -1379,12 +1379,12 @@
SetUInt32Value(UNIT_FIELD_BYTES_1,(getloyalty()<<8));
SetHealth( 28 + 10 * level);
SetMaxHealth( 28 + 10 * level);
- SetStat(STAT_STRENGTH,uint32(20+level*1.55));
- SetStat(STAT_AGILITY,uint32(20+level*0.64));
- SetStat(STAT_STAMINA,uint32(20+level*1.27));
- SetStat(STAT_INTELLECT,uint32(20+level*0.18));
- SetStat(STAT_SPIRIT,uint32(20+level*0.36));
- SetArmor(level*50);
+ SetBaseStat(STAT_STRENGTH,uint32(20+level*1.55));
+ SetBaseStat(STAT_AGILITY,uint32(20+level*0.64));
+ SetBaseStat(STAT_STAMINA,uint32(20+level*1.27));
+ SetBaseStat(STAT_INTELLECT,uint32(20+level*0.18));
+ SetBaseStat(STAT_SPIRIT,uint32(20+level*0.36));
+ SetBaseArmor(level*50);
if(level - cinfo->minlevel >= 21)
loyalty = 7;
Index: src/game/Level3.cpp
===================================================================
--- src/game/Level3.cpp (revision 2653)
+++ src/game/Level3.cpp (working copy)
@@ -2570,12 +2570,12 @@
player->SetFloatValue(OBJECT_FIELD_SCALE_X, 1.35f);
}
else player->SetFloatValue(OBJECT_FIELD_SCALE_X, 1.0f);
- player->SetStat(STAT_STRENGTH,info->strength );
- player->SetStat(STAT_AGILITY,info->agility );
- player->SetStat(STAT_STAMINA,info->stamina );
- player->SetStat(STAT_INTELLECT,info->intellect );
- player->SetStat(STAT_SPIRIT,info->spirit );
- player->SetArmor(info->basearmor );
+ player->SetBaseStat(STAT_STRENGTH,info->strength );
+ player->SetBaseStat(STAT_AGILITY,info->agility );
+ player->SetBaseStat(STAT_STAMINA,info->stamina );
+ player->SetBaseStat(STAT_INTELLECT,info->intellect );
+ player->SetBaseStat(STAT_SPIRIT,info->spirit );
+ player->SetBaseArmor(info->basearmor );
player->SetUInt32Value(UNIT_FIELD_ATTACK_POWER, 0 );
player->SetUInt32Value(UNIT_FIELD_RANGED_ATTACK_POWER, 0 );
@@ -2634,11 +2634,11 @@
// reinitilize potential block chance (used if item with Block value equiped)
player->SetFloatValue(PLAYER_BLOCK_PERCENTAGE, 5 + (float(player->GetDefenceSkillValue()) - player->getLevel()*5)*0.04);
player->SetFloatValue(PLAYER_CRIT_PERCENTAGE, 5);
- for (int i = 0; i < 7; i++)
+ for (int i = 0; i < SPELL_SCHOOL_COUNT; i++)
{
- player->SetResistance(SpellSchools(i), 0);
- player->SetResistanceBuffMods(SpellSchools(i), true, 0);
- player->SetResistanceBuffMods(SpellSchools(i), false, 0);
+ player->SetBaseResistance(SpellSchools(i), 0);
+ player->SetResistanceBuff(SpellSchools(i), true, 0);
+ player->SetResistanceBuff(SpellSchools(i), false, 0);
}
return true;
}
Index: src/game/MiscHandler.cpp
===================================================================
--- src/game/MiscHandler.cpp (revision 2652)
+++ src/game/MiscHandler.cpp (working copy)
@@ -711,10 +711,10 @@
GetPlayer()->SpawnCorpseBones();
// set health, mana
- GetPlayer()->ApplyStats(false);
+ GetPlayer()->_RemoveStatsMods();
GetPlayer()->SetHealth(GetPlayer()->GetMaxHealth()/2);
GetPlayer()->SetPower(POWER_MANA,GetPlayer()->GetMaxPower(POWER_MANA)/2);
- GetPlayer()->ApplyStats(true);
+ GetPlayer()->_ApplyStatsMods();
// update world right away
MapManager::Instance().GetMap(GetPlayer()->GetMapId())->Add(GetPlayer());
Index: src/game/NPCHandler.cpp
===================================================================
--- src/game/NPCHandler.cpp (revision 2652)
+++ src/game/NPCHandler.cpp (working copy)
@@ -407,12 +407,12 @@
}
}
- _player->ApplyStats(false);
+ _player->_RemoveStatsMods();
_player->SetHealth( _player->GetMaxHealth()/2 );
_player->SetPower(POWER_MANA, _player->GetMaxPower(POWER_MANA)/2 );
_player->SetPower(POWER_RAGE, 0 );
_player->SetPower(POWER_ENERGY, _player->GetMaxPower(POWER_ENERGY));
- _player->ApplyStats(true);
+ _player->_ApplyStatsMods();
_player->DurabilityLossAll(0.25);
_player->SpawnCorpseBones();
Index: src/game/Pet.cpp
===================================================================
--- src/game/Pet.cpp (revision 2652)
+++ src/game/Pet.cpp (working copy)
@@ -90,12 +90,12 @@
petlevel=owner->getLevel();
SetUInt32Value(UNIT_FIELD_BYTES_0,2048);
- SetStat(STAT_STRENGTH,22);
- SetStat(STAT_AGILITY,22);
- SetStat(STAT_STAMINA,25);
- SetStat(STAT_INTELLECT,28);
- SetStat(STAT_SPIRIT,27);
- SetArmor(petlevel*50);
+ SetBaseStat(STAT_STRENGTH,22);
+ SetBaseStat(STAT_AGILITY,22);
+ SetBaseStat(STAT_STAMINA,25);
+ SetBaseStat(STAT_INTELLECT,28);
+ SetBaseStat(STAT_SPIRIT,27);
+ SetBaseArmor(petlevel*50);
}
else if(owner->getClass() == CLASS_HUNTER && cinfo->type == CREATURE_TYPE_BEAST)
{
@@ -108,12 +108,12 @@
SetMaxPower(POWER_HAPPINESS,1000000);
SetPower( POWER_HAPPINESS,fields[11].GetUInt32());
setPowerType(POWER_FOCUS);
- SetStat(STAT_STRENGTH,uint32(20+petlevel*1.55));
- SetStat(STAT_AGILITY,uint32(20+petlevel*0.64));
- SetStat(STAT_STAMINA,uint32(20+petlevel*1.27));
- SetStat(STAT_INTELLECT,uint32(20+petlevel*0.18));
- SetStat(STAT_SPIRIT,uint32(20+petlevel*0.36));
- SetArmor(petlevel*50);
+ SetBaseStat(STAT_STRENGTH,uint32(20+petlevel*1.55));
+ SetBaseStat(STAT_AGILITY,uint32(20+petlevel*0.64));
+ SetBaseStat(STAT_STAMINA,uint32(20+petlevel*1.27));
+ SetBaseStat(STAT_INTELLECT,uint32(20+petlevel*0.18));
+ SetBaseStat(STAT_SPIRIT,uint32(20+petlevel*0.36));
+ SetBaseArmor(petlevel*50);
}
SetLevel( petlevel);
SetHealth( 28 + 10 * petlevel);
Index: src/game/Player.cpp
===================================================================
--- src/game/Player.cpp (revision 2653)
+++ src/game/Player.cpp (working copy)
@@ -159,6 +159,21 @@
m_resetTalentsCost = 0;
m_resetTalentsTime = 0;
+
+ for(int i = 0; i < MAX_STATS; ++i)
+ m_createStats_field[i] = 0;
+
+ for(int i = 0; i < MAX_STATS; ++i)
+ m_PosStat[i] = 0;
+ for(int i = 0; i < MAX_STATS; ++i)
+ m_NegStat[i] = 0;
+ for(int i = 0; i < MAX_STATS; ++i)
+ m_CreateStat[i] = 0;
+ for(int i = 0; i < SPELL_SCHOOL_COUNT; ++i)
+ {
+ m_ResistanceBuff[i][0] = 0;
+ m_ResistanceBuff[i][1] = 0;
+ }
}
Player::~Player ()
@@ -225,11 +240,11 @@
return false;
}
- m_createStats[STAT_AGILITY] = (float)info->agility;
- m_createStats[STAT_INTELLECT] = (float)info->intellect;
- m_createStats[STAT_SPIRIT] = (float)info->spirit;
- m_createStats[STAT_STAMINA] = (float)info->stamina;
- m_createStats[STAT_STRENGTH] = (float)info->strength;
+ SetCreateStat(STAT_AGILITY, (float)info->agility);
+ SetCreateStat(STAT_INTELLECT,(float)info->intellect);
+ SetCreateStat(STAT_SPIRIT, (float)info->spirit);
+ SetCreateStat(STAT_STAMINA, (float)info->stamina);
+ SetCreateStat(STAT_STRENGTH, (float)info->strength);
for (i = 0; i < BANK_SLOT_BAG_END; i++)
m_items[i] = NULL;
@@ -288,12 +303,13 @@
SetFloatValue(OBJECT_FIELD_SCALE_X, 1.35f);
}
else SetFloatValue(OBJECT_FIELD_SCALE_X, 1.0f);
- SetStat(STAT_STRENGTH,info->strength );
- SetStat(STAT_AGILITY,info->agility );
- SetStat(STAT_STAMINA,info->stamina );
- SetStat(STAT_INTELLECT,info->intellect );
- SetStat(STAT_SPIRIT,info->spirit );
- SetArmor(info->basearmor );
+
+ SetBaseArmor(info->basearmor);
+ SetBaseStat(STAT_STRENGTH,info->strength );
+ SetBaseStat(STAT_AGILITY,info->agility );
+ SetBaseStat(STAT_STAMINA,info->stamina );
+ SetBaseStat(STAT_INTELLECT,info->intellect );
+ SetBaseStat(STAT_SPIRIT,info->spirit );
SetUInt32Value(UNIT_FIELD_ATTACK_POWER, 0 );
SetHealth(info->health);
@@ -1591,7 +1607,7 @@
SetMaxHealth(uint32(newHP)); // only integer part
for(int i = STAT_STRENGTH; i < MAX_STATS; ++i)
- SetStat(Stats(i), uint32(newStats[i])); // only integer part
+ SetBaseStat(Stats(i), uint32(newStats[i])); // only integer part
// update dependent from level part BlockChanceWithoutMods = 5 + (GetDefenceSkillValue() - getLevel()*5)*0.04);
UpdateBlockPercentage();
@@ -4186,15 +4202,11 @@
}
_RemoveStatsMods();
- AuraList& mModBaseResistancePct = GetAurasByType(SPELL_AURA_MOD_BASE_RESISTANCE_PCT);
- for(AuraList::iterator i = mModBaseResistancePct.begin(); i != mModBaseResistancePct.end(); ++i)
- (*i)->ApplyModifier(false);
_ApplyItemBonuses(proto,slot,apply);
- for(AuraList::iterator i = mModBaseResistancePct.begin(); i != mModBaseResistancePct.end(); ++i)
- (*i)->ApplyModifier(true);
_ApplyStatsMods();
+
if(apply)
CastItemEquipSpell(item);
@@ -4235,28 +4247,23 @@
typestr = "Health";
break;
case AGILITY: // modify agility
- ApplyStatMod(STAT_AGILITY, val, apply);
ApplyPosStatMod(STAT_AGILITY, val, apply);
typestr = "AGILITY";
break;
case STRENGHT: //modify strength
- ApplyStatMod(STAT_STRENGTH, val, apply);
ApplyPosStatMod(STAT_STRENGTH, val, apply);
typestr = "STRENGHT";
break;
case INTELLECT: //modify intellect
- ApplyStatMod(STAT_INTELLECT, val, apply);
ApplyPosStatMod(STAT_INTELLECT, val, apply);
//ApplyMaxPowerMod(POWER_MANA, val*15, apply);
typestr = "INTELLECT";
break;
case SPIRIT: //modify spirit
- ApplyStatMod(STAT_SPIRIT, val, apply);
ApplyPosStatMod(STAT_SPIRIT, val, apply);
typestr = "SPIRIT";
break;
case STAMINA: //modify stamina
- ApplyStatMod(STAT_STAMINA ,val, apply);
ApplyPosStatMod(STAT_STAMINA ,val, apply);
//ApplyMaxHealthMod( val*10,apply);
typestr = "STAMINA";
@@ -4269,7 +4276,7 @@
if (proto->Armor)
{
- ApplyArmorMod( proto->Armor, apply);
+ ApplyBaseArmorMod( proto->Armor, apply);
sLog.outDebug("%s Armor: \t\t%u", applystr.c_str(), proto->Armor);
}
@@ -4281,37 +4288,37 @@
if (proto->HolyRes)
{
- ApplyResistanceMod(SPELL_SCHOOL_HOLY, proto->HolyRes, apply);
+ ApplyBaseResistanceMod(SPELL_SCHOOL_HOLY, proto->HolyRes, apply);
sLog.outDebug("%s HolyRes: \t\t%u", applystr.c_str(), proto->HolyRes);
}
if (proto->FireRes)
{
- ApplyResistanceMod(SPELL_SCHOOL_FIRE, proto->FireRes, apply);
+ ApplyBaseResistanceMod(SPELL_SCHOOL_FIRE, proto->FireRes, apply);
sLog.outDebug("%s FireRes: \t\t%u", applystr.c_str(), proto->FireRes);
}
if (proto->NatureRes)
{
- ApplyResistanceMod(SPELL_SCHOOL_NATURE, proto->NatureRes, apply);
+ ApplyBaseResistanceMod(SPELL_SCHOOL_NATURE, proto->NatureRes, apply);
sLog.outDebug("%s NatureRes: \t\t%u", applystr.c_str(), proto->NatureRes);
}
if (proto->FrostRes)
{
- ApplyResistanceMod(SPELL_SCHOOL_FROST, proto->FrostRes, apply);
+ ApplyBaseResistanceMod(SPELL_SCHOOL_FROST, proto->FrostRes, apply);
sLog.outDebug("%s FrostRes: \t\t%u", applystr.c_str(), proto->FrostRes);
}
if (proto->ShadowRes)
{
- ApplyResistanceMod(SPELL_SCHOOL_SHADOW, proto->ShadowRes, apply);
+ ApplyBaseResistanceMod(SPELL_SCHOOL_SHADOW, proto->ShadowRes, apply);
sLog.outDebug("%s ShadowRes: \t\t%u", applystr.c_str(), proto->ShadowRes);
}
if (proto->ArcaneRes)
{
- ApplyResistanceMod(SPELL_SCHOOL_ARCANE, proto->ArcaneRes, apply);
+ ApplyBaseResistanceMod(SPELL_SCHOOL_ARCANE, proto->ArcaneRes, apply);
sLog.outDebug("%s ArcaneRes: \t\t%u", applystr.c_str(), proto->ArcaneRes);
}
@@ -4603,10 +4610,6 @@
_RemoveStatsMods();
- AuraList& mModBaseResistancePct = GetAurasByType(SPELL_AURA_MOD_BASE_RESISTANCE_PCT);
- for(AuraList::iterator i = mModBaseResistancePct.begin(); i != mModBaseResistancePct.end(); ++i)
- (*i)->ApplyModifier(false);
-
for (int i = 0; i < INVENTORY_SLOT_BAG_END; i++)
{
if(m_items[i])
@@ -4622,9 +4625,6 @@
}
}
- for(AuraList::iterator i = mModBaseResistancePct.begin(); i != mModBaseResistancePct.end(); ++i)
- (*i)->ApplyModifier(true);
-
_ApplyStatsMods();
sLog.outDebug("_ApplyAllItemMods complete.");
@@ -7712,7 +7712,7 @@
//uint32 enchant_description = pEnchant->description;
//SpellEntry *enchantSpell_info = sSpellStore.LookupEntry(enchant_spell_id);
if(enchant_display ==4)
- SetArmor(GetArmor()-enchant_value1);
+ ApplyBaseArmorMod(enchant_value1,false);
else if(enchant_display ==2)
{
SetFloatValue(UNIT_FIELD_MINDAMAGE,GetFloatValue(UNIT_FIELD_MINDAMAGE)-enchant_value1);
@@ -9889,12 +9889,19 @@
return false;
}
- m_createStats[STAT_AGILITY] = (float)info->agility;
- m_createStats[STAT_INTELLECT] = (float)info->intellect;
- m_createStats[STAT_SPIRIT] = (float)info->spirit;
- m_createStats[STAT_STAMINA] = (float)info->stamina;
- m_createStats[STAT_STRENGTH] = (float)info->strength;
+ // init create stats before stats initiaization
+ SetCreateStat(STAT_AGILITY, (float)info->agility);
+ SetCreateStat(STAT_INTELLECT,(float)info->intellect);
+ SetCreateStat(STAT_SPIRIT, (float)info->spirit);
+ SetCreateStat(STAT_STAMINA, (float)info->stamina);
+ SetCreateStat(STAT_STRENGTH, (float)info->strength);
+ // currently in m_uint32Values stored base stats, move its to correct fields
+ for(int i = 0; i < SPELL_SCHOOL_COUNT; ++i)
+ SetBaseResistance(SpellSchools(i),GetResistance(SpellSchools(i)));
+ for(int i = 0; i < MAX_STATS; ++i)
+ SetBaseStat(Stats(i),GetStat(Stats(i)));
+
uint32 transGUID = fields[29].GetUInt32();
m_positionX = fields[7].GetFloat();
m_positionY = fields[8].GetFloat();
@@ -10461,7 +10468,18 @@
uint16 i;
for( i = 0; i < m_valuesCount; i++ )
{
- ss << GetUInt32Value(i) << " ";
+ if(i >= UNIT_FIELD_STATS && i < UNIT_FIELD_STATS + MAX_STATS)
+ {
+
+ ss << reinterpret_cast<uint32&>(m_BaseStat[Stats(i-UNIT_FIELD_STATS)]) << " ";
+ }
+ else
+ if(i >= UNIT_FIELD_RESISTANCES && i < UNIT_FIELD_RESISTANCES + SPELL_SCHOOL_COUNT)
+ {
+ ss << reinterpret_cast<uint32&>(m_BaseResistance[SpellSchools(i-UNIT_FIELD_RESISTANCES)]) << " ";
+ }
+ else
+ ss << GetUInt32Value(i) << " ";
}
ss << "', '";
@@ -11098,3 +11116,29 @@
//RestTickUpdate
SetUInt32Value(PLAYER_REST_STATE_EXPERIENCE, rest_bonus);
}
+
+void Player::UpdateStatsBuffs(Stats stat, float totalpct)
+{
+ float stat_pos = m_PosStat[stat];
+ ApplyPercentModFloatVar(stat_pos,totalpct,true);
+ SetFloatValue(PLAYER_FIELD_POSSTAT0+stat,stat_pos);
+
+ float stat_neg = m_NegStat[stat];
+ ApplyPercentModFloatVar(stat_neg,totalpct,true);
+ SetFloatValue(PLAYER_FIELD_NEGSTAT0+stat,stat_neg);
+
+ float stat_create = m_CreateStat[stat];
+ ApplyPercentModFloatVar(stat_create,totalpct,true);
+ m_createStats_field[stat] = stat_create;
+}
+
+void Player::UpdateResistanceBuffs(SpellSchools res, float totalpct)
+{
+ float res_buf_pos = m_ResistanceBuff[res][true];
+ ApplyPercentModFloatVar(res_buf_pos,totalpct,true);
+ SetFloatValue(PLAYER_FIELD_RESISTANCEBUFFMODSPOSITIVE+res,res_buf_pos);
+
+ float res_buf_neg = m_ResistanceBuff[res][false];
+ ApplyPercentModFloatVar(res_buf_neg,totalpct,true);
+ SetFloatValue(PLAYER_FIELD_RESISTANCEBUFFMODSNEGATIVE+res,res_buf_neg);
+}
Index: src/game/Player.h
===================================================================
--- src/game/Player.h (revision 2653)
+++ src/game/Player.h (working copy)
@@ -510,23 +510,6 @@
void UnTamePet(Creature* pet = NULL);
void Uncharm();
- float GetResistanceBuffMods(SpellSchools school, bool positive) const { return GetFloatValue(positive ? PLAYER_FIELD_RESISTANCEBUFFMODSPOSITIVE+school : PLAYER_FIELD_RESISTANCEBUFFMODSNEGATIVE+school ); }
- void SetResistanceBuffMods(SpellSchools school, bool positive, float val) { SetFloatValue(positive ? PLAYER_FIELD_RESISTANCEBUFFMODSPOSITIVE+school : PLAYER_FIELD_RESISTANCEBUFFMODSNEGATIVE+school,val); }
- void ApplyResistanceBuffModsMod(SpellSchools school, bool positive, float val, bool apply) { ApplyModFloatValue(positive ? PLAYER_FIELD_RESISTANCEBUFFMODSPOSITIVE+school : PLAYER_FIELD_RESISTANCEBUFFMODSNEGATIVE+school, val, apply); }
- void ApplyResistanceBuffModsPercentMod(SpellSchools school, bool positive, float val, bool apply) { ApplyPercentModFloatValue(positive ? PLAYER_FIELD_RESISTANCEBUFFMODSPOSITIVE+school : PLAYER_FIELD_RESISTANCEBUFFMODSNEGATIVE+school, val, apply); }
- void SetPosStat(Stats stat, float val) { SetFloatValue(PLAYER_FIELD_POSSTAT0+stat, val); }
- void ApplyPosStatMod(Stats stat, float val, bool apply) { ApplyModFloatValue(PLAYER_FIELD_POSSTAT0+stat, val, apply); }
- void ApplyPosStatPercentMod(Stats stat, float val, bool apply) { ApplyPercentModFloatValue(PLAYER_FIELD_POSSTAT0+stat, val, apply); }
- void SetNegStat(Stats stat, float val) { SetFloatValue(PLAYER_FIELD_NEGSTAT0+stat, val); }
- void ApplyNegStatMod(Stats stat, float val, bool apply) { ApplyModFloatValue(PLAYER_FIELD_NEGSTAT0+stat, val, apply); }
- void ApplyNegStatPercentMod(Stats stat, float val, bool apply) { ApplyPercentModFloatValue(PLAYER_FIELD_NEGSTAT0+stat, val, apply); }
- void SetCreateStat(Stats stat, float val) { m_createStats[stat] = val; }
- void ApplyCreateStatMod(Stats stat, float val, bool apply) { m_createStats[stat] += (apply ? val : -val); }
- void ApplyCreateStatPercentMod(Stats stat, float val, bool apply) { m_createStats[stat] *= (apply?(100.0f+val)/100.0f : 100.0f / (100.0f+val)); }
- float GetPosStat(Stats stat) const { return GetFloatValue(PLAYER_FIELD_POSSTAT0+stat); }
- float GetNegStat(Stats stat) const { return GetFloatValue(PLAYER_FIELD_NEGSTAT0+stat); }
- float GetCreateStat(Stats stat) const { return m_createStats[stat]; }
-
/*********************************************************/
/*** STORAGE SYSTEM ***/
/*********************************************************/
@@ -1111,6 +1094,26 @@
float GetTransOffsetZ() const { return m_transZ; }
float GetTransOffsetO() const { return m_transO; }
+ //// Cascade Update System /////////////////////////
+ // Stats
+ float GetPosStat(Stats stat) const { return GetFloatValue(PLAYER_FIELD_POSSTAT0+stat); }
+ void SetPosStat(Stats stat, float val) { m_PosStat[stat] = val; CascadeUpdateStat(stat); }
+ void ApplyPosStatMod(Stats stat, float addval, bool apply) { m_PosStat[stat] += (apply ? addval : -addval); CascadeUpdateStat(stat); }
+ float GetNegStat(Stats stat) const { return GetFloatValue(PLAYER_FIELD_NEGSTAT0+stat); }
+ void SetNegStat(Stats stat, float val) { m_NegStat[stat] = val; CascadeUpdateStat(stat); }
+ void ApplyNegStatMod(Stats stat, float addval, bool apply) { m_NegStat[stat] += (apply ? addval : -addval); CascadeUpdateStat(stat); }
+ float GetCreateStat(Stats stat) const { return m_createStats_field[stat]; }
+ // called without cascade update, used only at create/load/reset for initial setup
+ void SetCreateStat(Stats stat, float val) { m_CreateStat[stat] = val; m_createStats_field[stat] = val; }
+ void ApplyCreateStatMod(Stats stat, float addval, bool apply) { m_CreateStat[stat] += (apply ? addval : -addval); CascadeUpdateStat(stat); }
+ // ...called from Unit::CascadeUpdateResistance only
+ void UpdateStatsBuffs(Stats stat, float totalpct);
+ // Resistance
+ float GetResistanceBuff(SpellSchools school, bool positive) const { return GetFloatValue(positive ? PLAYER_FIELD_RESISTANCEBUFFMODSPOSITIVE+school : PLAYER_FIELD_RESISTANCEBUFFMODSNEGATIVE+school ); }
+ void SetResistanceBuff(SpellSchools res,bool positive, float value) { m_ResistanceBuff[res][positive] = value; CascadeUpdateResistance(res); }
+ void ApplyResistanceBuffMod(SpellSchools res, bool positive, float addval, bool apply) { m_ResistanceBuff[res][positive] += (apply ? addval : -addval); CascadeUpdateResistance(res); }
+ // ...called from Unit::CascadeUpdateResistance only
+ void UpdateResistanceBuffs(SpellSchools res, float totalpct);
protected:
/*********************************************************/
@@ -1191,7 +1194,7 @@
std::string m_rank_name;
PlayerCreateInfo *info;
- float m_createStats[5];
+ float m_createStats_field[5]; // with applied percent mods
uint32 m_race;
uint32 m_class;
@@ -1291,7 +1294,6 @@
float inn_pos_z;
float rest_bonus;
int rest_type;
- ////////////////////Rest System/////////////////////
// Transports
float m_transX;
@@ -1303,6 +1305,12 @@
uint32 m_resetTalentsCost;
time_t m_resetTalentsTime;
+
+ //// Cascade Update System /////////////////////////
+ float m_PosStat[MAX_STATS]; //(with not applied percent modifiers)
+ float m_NegStat[MAX_STATS]; //(with not applied percent modifiers)
+ float m_CreateStat[MAX_STATS]; //(with not applied percent modifiers)
+ float m_ResistanceBuff[SPELL_SCHOOL_COUNT][2]; //(with not applied percent modifiers)
};
int32 irand(int32 min, int32 max);
Index: src/game/SharedDefines.h
===================================================================
--- src/game/SharedDefines.h (revision 2652)
+++ src/game/SharedDefines.h (working copy)
@@ -91,6 +91,8 @@
SPELL_SCHOOL_ARCANE = 6
};
+#define SPELL_SCHOOL_COUNT 7
+
#define ITEM_QUALITY_POOR 0 //GREY
#define ITEM_QUALITY_NORMAL 1 //WHITE
#define ITEM_QUALITY_UNCOMMON 2 //GREEN
Index: src/game/SpellAuras.cpp
===================================================================
--- src/game/SpellAuras.cpp (revision 2652)
+++ src/game/SpellAuras.cpp (working copy)
@@ -587,9 +587,7 @@
if( m_modifier.m_auraname==SPELL_AURA_MOD_REGEN || m_modifier.m_auraname==SPELL_AURA_MOD_POWER_REGEN )
m_periodicTimer = 5000;
- m_target->ApplyStats(false);
ApplyModifier(true);
- m_target->ApplyStats(true);
sLog.outDebug("Aura %u now is in use", m_modifier.m_auraname);
@@ -644,7 +642,6 @@
if( m_target->GetTypeId() == TYPEID_PLAYER )
UpdateAuraDuration();
}
-
}
void Aura::_RemoveAura()
@@ -653,10 +650,10 @@
if(m_modifier.m_auraname == SPELL_AURA_MOD_SHAPESHIFT) // remove the shapeshift aura's boosts
HandleShapeshiftBoosts(false, this);
- m_target->ApplyStats(false);
+ m_target->_RemoveStatsMods();
sLog.outDebug("Aura %u now is remove", m_modifier.m_auraname);
ApplyModifier(false);
- m_target->ApplyStats(true);
+ m_target->_ApplyStatsMods();
Unit* caster = GetCaster();
@@ -915,10 +912,8 @@
return;
SpellCastTargets targets;
targets.setUnitTarget(target);
- // prevent double stat apply for triggered auras
- target->ApplyStats(true);
+
spell.prepare(&targets);
- target->ApplyStats(false);
}
}
}
@@ -1854,90 +1849,20 @@
void Aura::HandleAuraModResistanceExclusive(bool apply)
{
- if(m_modifier.m_miscvalue < IMMUNE_SCHOOL_PHYSICAL || m_modifier.m_miscvalue > 127)
- {
- sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_BASE_RESISTANCE_PCT not valid");
- return;
- }
-
- bool positive = m_modifier.m_miscvalue2 == 0;
-
- for(int8 x=0;x < 7;x++)
- {
- if(m_modifier.m_miscvalue & int32(1<<x))
- {
- SpellSchools school = SpellSchools(SPELL_SCHOOL_NORMAL + x);
-
- m_target->ApplyResistanceMod(school,m_modifier.m_amount, apply);
- if(m_target->GetTypeId() == TYPEID_PLAYER)
- ((Player*)m_target)->ApplyResistanceBuffModsMod(school,positive,m_modifier.m_amount, apply);
- }
- }
+ // applied at aura add/remove
}
void Aura::HandleAuraModResistance(bool apply)
{
- if(m_modifier.m_miscvalue < IMMUNE_SCHOOL_PHYSICAL || m_modifier.m_miscvalue > 127)
- {
- sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_BASE_RESISTANCE_PCT not valid");
- return;
- }
-
- bool positive = m_modifier.m_miscvalue2 == 0;
-
- for(int8 x=0;x < 7;x++)
- {
- if(m_modifier.m_miscvalue & int32(1<<x))
- {
- SpellSchools school = SpellSchools(SPELL_SCHOOL_NORMAL + x);
-
- m_target->ApplyResistanceMod(school,m_modifier.m_amount, apply);
- if(m_target->GetTypeId() == TYPEID_PLAYER)
- ((Player*)m_target)->ApplyResistanceBuffModsMod(school,positive,m_modifier.m_amount, apply);
- }
- }
}
void Aura::HandleAuraModBaseResistancePCT(bool apply)
{
- if(m_modifier.m_miscvalue < IMMUNE_SCHOOL_PHYSICAL || m_modifier.m_miscvalue > 127)
- {
- sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_BASE_RESISTANCE_PCT not valid");
- return;
- }
-
- // only players have base stats
- if(m_target->GetTypeId() != TYPEID_PLAYER)
- return;
- Player *p_target = (Player*)m_target;
-
- for(int8 x=0;x < 7;x++)
- {
- if(m_modifier.m_miscvalue & int32(1<<x))
- {
- SpellSchools school = SpellSchools(SPELL_SCHOOL_NORMAL + x);
- float curRes = p_target->GetResistance(school);
- float baseRes = curRes + p_target->GetResistanceBuffMods(school, false) - p_target->GetResistanceBuffMods(school, true);
- float baseRes_new = baseRes * (apply?(100.0f+m_modifier.m_amount)/100.0f : 100.0f / (100.0f+m_modifier.m_amount));
- p_target->SetResistance(school, curRes + baseRes_new - baseRes);
- }
- }
}
void Aura::HandleModResistancePercent(bool apply)
{
- for(int8 i = 0; i < 7; i++)
- {
- if(m_modifier.m_miscvalue & int32(1<<i))
- {
- m_target->ApplyResistancePercentMod(SpellSchools(i), m_modifier.m_amount, apply );
- if(m_target->GetTypeId() == TYPEID_PLAYER)
- {
- ((Player*)m_target)->ApplyResistanceBuffModsPercentMod(SpellSchools(i),true,m_modifier.m_amount, apply);
- ((Player*)m_target)->ApplyResistanceBuffModsPercentMod(SpellSchools(i),false,m_modifier.m_amount, apply);
- }
- }
- }
+ // all done in cascade update system and at aura add/remove
}
void Aura::HandleModBaseResistance(bool apply)
@@ -1949,7 +1874,7 @@
for(int i = 0; i < 7; i++)
if(m_modifier.m_miscvalue & (1<<i))
- p_target->ApplyResistanceMod(SpellSchools(SPELL_SCHOOL_NORMAL + i),m_modifier.m_amount, apply);
+ p_target->ApplyBaseResistanceMod(SpellSchools(SPELL_SCHOOL_NORMAL + i),m_modifier.m_amount, apply);
}
/********************************/
@@ -1968,7 +1893,6 @@
{
if (m_modifier.m_miscvalue == -1 || m_modifier.m_miscvalue == i)
{
- m_target->ApplyStatMod(Stats(i), m_modifier.m_amount,apply);
if(m_target->GetTypeId() == TYPEID_PLAYER)
{
if (m_modifier.m_miscvalue2 == 0)
@@ -1976,57 +1900,19 @@
else
((Player*)m_target)->ApplyNegStatMod(Stats(i),m_modifier.m_amount,apply);
}
+ else
+ m_target->ApplyBaseStatMod(Stats(i), m_modifier.m_amount,apply);
}
}
}
void Aura::HandleModPercentStat(bool apply)
{
- if (m_modifier.m_miscvalue < -1 || m_modifier.m_miscvalue > 4)
- {
- sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_PERCENT_STAT not valid");
- return;
- }
-
- // only players have base stats
- if (m_target->GetTypeId() != TYPEID_PLAYER)
- return;
- Player *p_target = (Player*)m_target;
-
- for (int32 i = 0; i < 5; i++)
- {
- if(m_modifier.m_miscvalue == i || m_modifier.m_miscvalue == -1)
- {
- float curStat = p_target->GetStat(Stats(i));
- float baseStat = curStat + p_target->GetNegStat(Stats(i)) - p_target->GetPosStat(Stats(i));
- float baseStat_new = baseStat * (apply?(100.0f+m_modifier.m_amount)/100.0f : 100.0f / (100.0f+m_modifier.m_amount));
- p_target->SetStat(Stats(i), curStat + baseStat_new - baseStat);
- p_target->ApplyCreateStatPercentMod(Stats(i), m_modifier.m_amount, apply );
- }
- }
}
void Aura::HandleModTotalPercentStat(bool apply)
{
- if (m_modifier.m_miscvalue < -1 || m_modifier.m_miscvalue > 4)
- {
- sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_PERCENT_STAT not valid");
- return;
- }
-
- for (int32 i = 0; i < 5; i++)
- {
- if(m_modifier.m_miscvalue == i || m_modifier.m_miscvalue == -1)
- {
- m_target->ApplyStatPercentMod(Stats(i), m_modifier.m_amount, apply );
- if (m_target->GetTypeId() == TYPEID_PLAYER)
- {
- ((Player*)m_target)->ApplyPosStatPercentMod(Stats(i), m_modifier.m_amount, apply );
- ((Player*)m_target)->ApplyNegStatPercentMod(Stats(i), m_modifier.m_amount, apply );
- ((Player*)m_target)->ApplyCreateStatPercentMod(Stats(i), m_modifier.m_amount, apply );
- }
- }
- }
+ // all done in cascade update system and at aura add/remove
}
/********************************/
@@ -2520,3 +2406,112 @@
double healthPercentage = (double)unit_target->GetHealth() / (double)unit_target->GetMaxHealth();
unit_target->SetHealth(uint32(ceil((double)unit_target->GetMaxHealth() * healthPercentage)));
}
+
+//// Cascade Update System
+void Aura::ApplyModResistancePercent(bool)
+{
+ for(int8 i = 0; i < SPELL_SCHOOL_COUNT; ++i)
+ {
+ if(m_modifier.m_miscvalue & int32(1<<i))
+ m_target->CascadeUpdateResistance(SpellSchools(i));
+ }
+}
+
+void Aura::ApplyAuraModResistanceExclusive(bool apply)
+{
+ if(m_modifier.m_miscvalue < IMMUNE_SCHOOL_PHYSICAL || m_modifier.m_miscvalue > 127)
+ {
+ sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_BASE_RESISTANCE_PCT not valid");
+ return;
+ }
+
+ bool positive = m_modifier.m_miscvalue2 == 0;
+
+ for(int8 x=0;x < SPELL_SCHOOL_COUNT; ++x)
+ {
+ if(m_modifier.m_miscvalue & int32(1<<x))
+ {
+ SpellSchools school = SpellSchools(SPELL_SCHOOL_NORMAL + x);
+
+ if(m_target->GetTypeId() == TYPEID_PLAYER)
+ ((Player*)m_target)->ApplyResistanceBuffMod(school,positive,m_modifier.m_amount, apply);
+ else
+ m_target->ApplyBaseResistanceMod(school,m_modifier.m_amount, apply);
+ }
+ }
+}
+
+void Aura::ApplyModTotalPercentStat(bool)
+{
+ if (m_modifier.m_miscvalue < -1 || m_modifier.m_miscvalue > 4)
+ {
+ sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_PERCENT_STAT not valid");
+ return;
+ }
+
+ for (int32 i = 0; i < MAX_STATS; ++i)
+ {
+ if(m_modifier.m_miscvalue == i || m_modifier.m_miscvalue == -1)
+ m_target->CascadeUpdateStat(Stats(i));
+ }
+}
+
+void Aura::ApplyAuraModResistance(bool apply)
+{
+ if(m_modifier.m_miscvalue < IMMUNE_SCHOOL_PHYSICAL || m_modifier.m_miscvalue > 127)
+ {
+ sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_BASE_RESISTANCE_PCT not valid");
+ return;
+ }
+
+ bool positive = m_modifier.m_miscvalue2 == 0;
+
+ for(int8 x=0;x < SPELL_SCHOOL_COUNT;x++)
+ {
+ if(m_modifier.m_miscvalue & int32(1<<x))
+ {
+ SpellSchools school = SpellSchools(SPELL_SCHOOL_NORMAL + x);
+
+ if(m_target->GetTypeId() == TYPEID_PLAYER)
+ ((Player*)m_target)->ApplyResistanceBuffMod(school,positive,m_modifier.m_amount, apply);
+ else
+ m_target->ApplyBaseResistanceMod(school,m_modifier.m_amount, apply);
+ }
+ }
+}
+
+void Aura::ApplyAuraModBaseResistancePCT(bool)
+{
+ if(m_modifier.m_miscvalue < IMMUNE_SCHOOL_PHYSICAL || m_modifier.m_miscvalue > 127)
+ {
+ sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_BASE_RESISTANCE_PCT not valid");
+ return;
+ }
+
+ // only players have base stats
+ if(m_target->GetTypeId() != TYPEID_PLAYER)
+ return;
+ Player *p_target = (Player*)m_target;
+
+ for(int8 x=0;x < SPELL_SCHOOL_COUNT;x++)
+ if(m_modifier.m_miscvalue & int32(1<<x))
+ m_target->CascadeUpdateResistance(SpellSchools(SPELL_SCHOOL_NORMAL + x));
+}
+
+void Aura::ApplyModPercentStat(bool apply)
+{
+ if (m_modifier.m_miscvalue < -1 || m_modifier.m_miscvalue > 4)
+ {
+ sLog.outError("WARNING: Misc Value for SPELL_AURA_MOD_PERCENT_STAT not valid");
+ return;
+ }
+
+ // only players have base stats
+ if (m_target->GetTypeId() != TYPEID_PLAYER)
+ return;
+ Player *p_target = (Player*)m_target;
+
+ for (int32 i = 0; i < MAX_STATS; i++)
+ if(m_modifier.m_miscvalue == i || m_modifier.m_miscvalue == -1)
+ p_target->CascadeUpdateStat(Stats(i));
+}
Index: src/game/SpellAuras.h
===================================================================
--- src/game/SpellAuras.h (revision 2652)
+++ src/game/SpellAuras.h (working copy)
@@ -144,6 +144,15 @@
void HandleRangedAmmoHaste(bool Apply);
void HandleModTotalPercentStat(bool Apply);
+ // Cascade updates at aura adding/removing
+ void ApplyModTotalPercentStat(bool);
+ void ApplyModPercentStat(bool);
+ void ApplyModResistancePercent(bool);
+ void ApplyAuraModBaseResistancePCT(bool);
+ void ApplyAuraModResistanceExclusive(bool apply);
+ void ApplyAuraModResistance(bool apply);
+
+ // Common methods
Aura(SpellEntry* spellproto, uint32 eff, Unit *target, Unit *caster = NULL, Item* castItem = NULL);
virtual ~Aura();
Index: src/game/SpellEffects.cpp
===================================================================
--- src/game/SpellEffects.cpp (revision 2652)
+++ src/game/SpellEffects.cpp (working copy)
@@ -804,7 +804,7 @@
spawnCreature->SetStat(STAT_INTELLECT,int(20+level*0.18));
spawnCreature->SetStat(STAT_SPIRIT,int(20+level*0.36));
*/
- spawnCreature->SetArmor(level*50);
+ spawnCreature->SetBaseArmor(level*50);
spawnCreature->AIM_Initialize();
std::string name;
@@ -1048,7 +1048,7 @@
spawnCreature->SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP,1000);
spawnCreature->SetUInt64Value(UNIT_FIELD_CREATEDBY, m_caster->GetGUID());
- spawnCreature->SetArmor(level*50);
+ spawnCreature->SetBaseArmor(level*50);
spawnCreature->AIM_Initialize();
MapManager::Instance().GetMap(m_caster->GetMapId())->Add((Creature*)spawnCreature);
@@ -1311,11 +1311,11 @@
NewSummon->SetUInt32Value(UNIT_FIELD_PETEXPERIENCE,0);
NewSummon->SetUInt32Value(UNIT_FIELD_PETNEXTLEVELEXP,1000);
NewSummon->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id);
- NewSummon->SetStat(STAT_STRENGTH,22);
- NewSummon->SetStat(STAT_AGILITY,22);
- NewSummon->SetStat(STAT_STAMINA,25);
- NewSummon->SetStat(STAT_INTELLECT,28);
- NewSummon->SetStat(STAT_SPIRIT,27);
+ NewSummon->SetBaseStat(STAT_STRENGTH,22);
+ NewSummon->SetBaseStat(STAT_AGILITY,22);
+ NewSummon->SetBaseStat(STAT_STAMINA,25);
+ NewSummon->SetBaseStat(STAT_INTELLECT,28);
+ NewSummon->SetBaseStat(STAT_SPIRIT,27);
for(uint32 i=0; i < CREATURE_MAX_SPELLS; i++)
NewSummon->m_spells[i] = 0;
Index: src/game/Unit.cpp
===================================================================
--- src/game/Unit.cpp (revision 2652)
+++ src/game/Unit.cpp (working copy)
@@ -81,6 +81,11 @@
m_baseSpellCritChance = 5;
m_modCastSpeedPct = 0;
m_CombatTimer = 0;
+
+ for(int i = 0; i < MAX_STATS; ++i)
+ m_BaseStat[i] = 0;
+ for(int i = 0; i < SPELL_SCHOOL_COUNT; ++i)
+ m_BaseResistance[i] = 0;
}
Unit::~Unit()
@@ -1673,14 +1678,38 @@
}
}
+ if(Aur->GetTarget())
+ {
+ Aur->GetTarget()->_RemoveStatsMods();
+ }
+
Aur->_AddAura();
+
m_Auras.insert(AuraMap::value_type(spellEffectPair(Aur->GetId(), Aur->GetEffIndex()), Aur));
+
if (Aur->GetModifier()->m_auraname < TOTAL_AURAS)
{
m_modAuras[Aur->GetModifier()->m_auraname].push_back(Aur);
m_AuraModifiers[Aur->GetModifier()->m_auraname] += (Aur->GetModifier()->m_amount);
}
+ //// Cascaded Update System
+ switch(Aur->GetModifier()->m_auraname)
+ {
+ case SPELL_AURA_MOD_RESISTANCE_PCT: Aur->ApplyModResistancePercent(true); break;
+ case SPELL_AURA_MOD_RESISTANCE_EXCLUSIVE: Aur->ApplyAuraModResistanceExclusive(true); break;
+ case SPELL_AURA_MOD_BASE_RESISTANCE_PCT: Aur->ApplyAuraModBaseResistancePCT(true); break;
+ case SPELL_AURA_MOD_RESISTANCE: Aur->ApplyAuraModResistance(true); break;
+ case SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE: Aur->ApplyModTotalPercentStat(true); break;
+ case SPELL_AURA_MOD_PERCENT_STAT: Aur->ApplyModPercentStat(true); break;
+ }
+
+ if(Aur->GetTarget())
+ {
+ Aur->GetTarget()->_ApplyStatsMods();
+ }
+
+
if (IsSingleTarget(Aur->GetId()) && Aur->GetTarget() && Aur->GetSpellProto())
{
if(Unit* caster = Aur->GetCaster())
@@ -1932,6 +1961,7 @@
}
}
}
+
if ((*i).second->GetModifier()->m_auraname < TOTAL_AURAS)
{
m_AuraModifiers[(*i).second->GetModifier()->m_auraname] -= ((*i).second->GetModifier()->m_amount);
@@ -1939,9 +1969,23 @@
}
(*i).second->SetRemoveOnDeath(onDeath);
(*i).second->_RemoveAura();
- delete (*i).second;
+
+ Aura* Aur = (*i).second;
m_Auras.erase(i++);
m_removedAuras++; // internal count used by unit update
+
+ //// Cascaded Update System
+ switch(Aur->GetModifier()->m_auraname)
+ {
+ case SPELL_AURA_MOD_RESISTANCE_PCT: Aur->ApplyModResistancePercent(false); break;
+ case SPELL_AURA_MOD_RESISTANCE_EXCLUSIVE: Aur->ApplyAuraModResistanceExclusive(false);break;
+ case SPELL_AURA_MOD_BASE_RESISTANCE_PCT: Aur->ApplyAuraModBaseResistancePCT(false); break;
+ case SPELL_AURA_MOD_RESISTANCE: Aur->ApplyAuraModResistance(false); break;
+ case SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE: Aur->ApplyModTotalPercentStat(false); break;
+ case SPELL_AURA_MOD_PERCENT_STAT: Aur->ApplyModPercentStat(false); break;
+ }
+
+ delete Aur;
}
bool Unit::SetAurDuration(uint32 spellId, uint32 effindex,uint32 duration)
@@ -2001,15 +2045,15 @@
void Unit::_RemoveStatsMods()
{
- ApplyStats(false);
+ _ApplyStats(false);
}
void Unit::_ApplyStatsMods()
{
- ApplyStats(true);
+ _ApplyStats(true);
}
-void Unit::ApplyStats(bool apply)
+void Unit::_ApplyStats(bool apply)
{
// TODO:
// -- add --
@@ -2021,71 +2065,7 @@
float val;
int32 val2,tem_att_power;
- float totalstatmods[5] = {1,1,1,1,1};
- float totalresmods[7] = {1,1,1,1,1,1,1};
- AuraList& mModTotalStatPct = GetAurasByType(SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE);
- for(AuraList::iterator i = mModTotalStatPct.begin(); i != mModTotalStatPct.end(); ++i)
- {
- if((*i)->GetModifier()->m_miscvalue != -1)
- totalstatmods[(*i)->GetModifier()->m_miscvalue] *= (100.0f + (*i)->GetModifier()->m_amount) / 100.0f;
- else
- for (uint8 j = 0; j < 5; j++)
- totalstatmods[j] *= (100.0f + (*i)->GetModifier()->m_amount) / 100.0f;
- }
- AuraList& mModResistancePct = GetAurasByType(SPELL_AURA_MOD_RESISTANCE_PCT);
- for(AuraList::iterator i = mModResistancePct.begin(); i != mModResistancePct.end(); ++i)
- for(uint8 j = 0; j <= 6; j++)
- if((*i)->GetModifier()->m_miscvalue & (1<<j))
- totalresmods[j] *= (100.0f + (*i)->GetModifier()->m_amount) / 100.0f;
-
- for (uint8 i = 0; i < 5; i++)
- totalstatmods[i] = totalstatmods[i] * 100.0f - 100.0f;
- for (uint8 i = 0; i < 7; i++)
- totalresmods[i] = totalresmods[i] * 100.0f - 100.0f;
-
- // restore percent mods
- if (apply)
- {
- for (uint8 i = 0; i < 5; i++)
- {
- if (totalstatmods[i] != 0)
- {
- ApplyStatPercentMod(Stats(i),totalstatmods[i], apply );
- ((Player*)this)->ApplyPosStatPercentMod(Stats(i),totalstatmods[i], apply );
- ((Player*)this)->ApplyNegStatPercentMod(Stats(i),totalstatmods[i], apply );
- }
- }
- for (uint8 i = 0; i < 7; i++)
- {
- if (totalresmods[i] != 0)
- {
- ApplyResistancePercentMod(SpellSchools(i), totalresmods[i], apply );
- ((Player*)this)->ApplyResistanceBuffModsPercentMod(SpellSchools(i),true, totalresmods[i], apply);
- ((Player*)this)->ApplyResistanceBuffModsPercentMod(SpellSchools(i),false, totalresmods[i], apply);
- }
- }
- }
-
- // Armor
- val = 2*(GetStat(STAT_AGILITY) - ((Player*)this)->GetCreateStat(STAT_AGILITY));
-
- ApplyArmorMod( val, apply);
-
- // HP
- val2 = uint32((GetStat(STAT_STAMINA) - ((Player*)this)->GetCreateStat(STAT_STAMINA))*10);
-
- ApplyMaxHealthMod( val2, apply);
-
- // MP
- if(getClass() != WARRIOR && getClass() != ROGUE)
- {
- val2 = uint32((GetStat(STAT_INTELLECT) - ((Player*)this)->GetCreateStat(STAT_INTELLECT))*15);
-
- ApplyMaxPowerMod(POWER_MANA, val2, apply);
-
- }
-
float classrate = 0;
// Melee Attack Power
@@ -2174,80 +2154,26 @@
ApplyModFloatValue(PLAYER_PARRY_PERCENTAGE, val, apply);
- // remove percent mods to see original stats when adding buffs/items
- if (!apply)
- {
- for (uint8 i = 0; i < 5; i++)
- {
- if (totalstatmods[i])
- {
- ApplyStatPercentMod(Stats(i),totalstatmods[i], apply );
- ((Player*)this)->ApplyPosStatPercentMod(Stats(i),totalstatmods[i], apply );
- ((Player*)this)->ApplyNegStatPercentMod(Stats(i),totalstatmods[i], apply );
- }
- }
- for (uint8 i = 0; i < 7; i++)
- {
- if (totalresmods[i])
- {
- ApplyResistancePercentMod(SpellSchools(i), totalresmods[i], apply );
- ((Player*)this)->ApplyResistanceBuffModsPercentMod(SpellSchools(i),true, totalresmods[i], apply);
- ((Player*)this)->ApplyResistanceBuffModsPercentMod(SpellSchools(i),false, totalresmods[i], apply);
- }
- }
- }
}
void Unit::_RemoveAllAuraMods()
{
- ApplyStats(false);
+ _RemoveStatsMods();
+
for (AuraMap::iterator i = m_Auras.begin(); i != m_Auras.end(); ++i)
- {
- switch ((*i).second->GetModifier()->m_auraname)
- {
- case SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE:
- case SPELL_AURA_MOD_RESISTANCE_PCT:
- // these are already removed by applystats
- break;
- default:
- (*i).second->ApplyModifier(false);
- }
- }
- ApplyStats(true);
+ (*i).second->ApplyModifier(false);
- // these must be removed after applystats
- AuraList& mModTotalStatPct = GetAurasByType(SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE);
- for(AuraList::iterator i = mModTotalStatPct.begin(); i != mModTotalStatPct.end(); ++i)
- (*i)->ApplyModifier(false);
- AuraList& mModResistancePct = GetAurasByType(SPELL_AURA_MOD_RESISTANCE_PCT);
- for(AuraList::iterator i = mModResistancePct.begin(); i != mModResistancePct.end(); ++i)
- (*i)->ApplyModifier(false);
+ _ApplyStatsMods();
}
void Unit::_ApplyAllAuraMods()
{
- // these must be applied before applystats
- AuraList& mModTotalStatPct = GetAurasByType(SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE);
- for(AuraList::iterator i = mModTotalStatPct.begin(); i != mModTotalStatPct.end(); ++i)
- (*i)->ApplyModifier(true);
- AuraList& mModResistancePct = GetAurasByType(SPELL_AURA_MOD_RESISTANCE_PCT);
- for(AuraList::iterator i = mModResistancePct.begin(); i != mModResistancePct.end(); ++i)
- (*i)->ApplyModifier(true);
- ApplyStats(false);
+ _RemoveStatsMods();
for (AuraMap::iterator i = m_Auras.begin(); i != m_Auras.end(); ++i)
- {
- switch ((*i).second->GetModifier()->m_auraname)
- {
- case SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE:
- case SPELL_AURA_MOD_RESISTANCE_PCT:
- // these are already applied by applystats
- break;
- default:
- (*i).second->ApplyModifier(true);
- }
- }
- ApplyStats(true);
+ (*i).second->ApplyModifier(true);
+
+ _ApplyStatsMods();
}
// TODO: FIX-ME!!!
@@ -2355,7 +2281,7 @@
if(enchant_display ==4)
{
- ApplyArmorMod(enchant_value1,apply);
+ ApplyBaseArmorMod(enchant_value1,apply);
}
else if(enchant_display ==2)
{
@@ -3273,3 +3199,94 @@
if(curPower != maxPower)
SetPower(power,maxPower);
}
+
+//#### Cascade update methods
+float Unit::GetResistance(SpellSchools res) const {
+ return GetFloatValue(UNIT_FIELD_RESISTANCES+res) +
+ (GetTypeId()==TYPEID_PLAYER ? (((Player*)this)->GetResistanceBuff(res,true) - ((Player*)this)->GetResistanceBuff(res,false)) : 0);
+}
+
+void Unit::CascadeUpdateResistance(SpellSchools res)
+{
+
+ // base percent modifiers
+ float basePercentModifier = 0;
+ AuraList& mModBaseResistancePct = GetAurasByType(SPELL_AURA_MOD_BASE_RESISTANCE_PCT);
+ for(AuraList::iterator i = mModBaseResistancePct .begin(); i != mModBaseResistancePct .end(); ++i)
+ if((*i)->GetModifier()->m_miscvalue & int32(1<<res))
+ basePercentModifier += (*i)->GetModifier()->m_amount;
+
+ // total percent modifiers
+ float totalPercentModifier = 0;
+ AuraList& mModResistancePct = GetAurasByType(SPELL_AURA_MOD_RESISTANCE_PCT);
+ for(AuraList::iterator i = mModResistancePct.begin(); i != mModResistancePct.end(); ++i)
+ if((*i)->GetModifier()->m_miscvalue & int32(1<<res))
+ totalPercentModifier += (*i)->GetModifier()->m_amount;
+
+ float cur_res = m_BaseResistance[res];
+ ApplyPercentModFloatVar(cur_res,basePercentModifier,true);
+ ApplyPercentModFloatVar(cur_res,totalPercentModifier,true);
+
+ // calculate total resistance
+ if(GetTypeId()==TYPEID_PLAYER)
+ {
+ ((Player*)this)->UpdateResistanceBuffs(res,totalPercentModifier);
+ }
+
+ SetFloatValue(UNIT_FIELD_RESISTANCES+res,cur_res);
+}
+
+void Unit::CascadeUpdateStat(Stats stat)
+{
+ // temporary until not converted to cascade update
+ _RemoveStatsMods();
+
+ // base stat percent modifier
+ float basePercentModifier = 0;
+ AuraList& mModBaseStatPct = GetAurasByType(SPELL_AURA_MOD_PERCENT_STAT);
+ for(AuraList::iterator i = mModBaseStatPct.begin(); i != mModBaseStatPct.end(); ++i)
+ if((*i)->GetModifier()->m_miscvalue & int32(1<<stat))
+ basePercentModifier += (*i)->GetModifier()->m_amount;
+
+ // total stat modifier
+ float totalPercentModifier = 0;
+ AuraList& mModStatPct = GetAurasByType(SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE);
+ for(AuraList::iterator i = mModStatPct .begin(); i != mModStatPct .end(); ++i)
+ if((*i)->GetModifier()->m_miscvalue & int32(1<<stat))
+ totalPercentModifier += (*i)->GetModifier()->m_amount;
+
+ float cur_stat = m_BaseStat[stat];
+ ApplyPercentModFloatVar(cur_stat,basePercentModifier,true);
+ ApplyPercentModFloatVar(cur_stat,totalPercentModifier,true);
+
+ float stat_delta = 0;
+
+ // calculate total resistance
+ if(GetTypeId()==TYPEID_PLAYER)
+ {
+
+ stat_delta = -(GetStat(stat) - ((Player*)this)->GetCreateStat(stat));
+
+ ((Player*)this)->UpdateStatsBuffs(stat,totalPercentModifier);
+
+ cur_stat += ((Player*)this)->GetPosStat(stat) - ((Player*)this)->GetNegStat(stat);
+
+ stat_delta += cur_stat - ((Player*)this)->GetCreateStat(stat);
+ }
+
+ SetFloatValue(UNIT_FIELD_STATS+stat,cur_stat);
+
+ switch(stat)
+ {
+ case STAT_AGILITY: ApplyBaseArmorMod(2*stat_delta,true); break;
+ case STAT_STAMINA: ApplyMaxHealthMod(int32(10*stat_delta),true); break;
+ case STAT_INTELLECT:
+ if(getClass() != WARRIOR && getClass() != ROGUE)
+ ApplyMaxPowerMod(POWER_MANA,int32(10*stat_delta),true);
+ break;
+ }
+
+
+ // temporary until not converted to cascade update
+ _ApplyStatsMods();
+}
Index: src/game/Unit.h
===================================================================
--- src/game/Unit.h (revision 2652)
+++ src/game/Unit.h (working copy)
@@ -389,27 +389,12 @@
uint32 getClassMask() const { return 1 << (getClass()-1); };
uint8 getGender() const { return (uint8)((GetUInt32Value(UNIT_FIELD_BYTES_0) >> 16) & 0xFF); };
- float GetStat(Stats stat) const { return GetFloatValue(UNIT_FIELD_STATS+stat); }
- void SetStat(Stats stat, float val) { SetFloatValue(UNIT_FIELD_STATS+stat, val); }
- void ApplyStatMod(Stats stat, float val, bool apply) { ApplyModFloatValue(UNIT_FIELD_STATS+stat, val, apply); }
- void ApplyStatPercentMod(Stats stat, float val, bool apply) { ApplyPercentModFloatValue(UNIT_FIELD_STATS+stat, val, apply); }
-
- float GetArmor() const { return GetResistance(SPELL_SCHOOL_NORMAL) ; }
- void SetArmor(float val) { SetResistance(SPELL_SCHOOL_NORMAL, val); }
- void ApplyArmorMod(float val, bool apply) { ApplyResistanceMod(SPELL_SCHOOL_NORMAL, val, apply); }
- void ApplyArmorPercentMod(float val, bool apply) { ApplyResistancePercentMod(SPELL_SCHOOL_NORMAL, val, apply); }
-
- float GetResistance(SpellSchools school) const { return GetFloatValue(UNIT_FIELD_RESISTANCES+school); }
- void SetResistance(SpellSchools school, float val) { SetFloatValue(UNIT_FIELD_RESISTANCES+school,val); }
- void ApplyResistanceMod(SpellSchools school, float val, bool apply) { ApplyModFloatValue(UNIT_FIELD_RESISTANCES+school, val, apply); }
- void ApplyResistancePercentMod(SpellSchools school, float val, bool apply) { ApplyPercentModFloatValue(UNIT_FIELD_RESISTANCES+school, val, apply); }
-
uint32 GetHealth() const { return GetUInt32Value(UNIT_FIELD_HEALTH); }
uint32 GetMaxHealth() const { return (uint32)GetFloatValue(UNIT_FIELD_MAXHEALTH); }
void SetHealth( uint32 val) { SetUInt32Value(UNIT_FIELD_HEALTH,val); }
void SetMaxHealth(uint32 val) { SetFloatValue(UNIT_FIELD_MAXHEALTH,val); }
void ModifyHealth(int32 val);
- void ApplyMaxHealthMod(uint32 val, bool apply) { ApplyModFloatValue(UNIT_FIELD_MAXHEALTH, val, apply); }
+ void ApplyMaxHealthMod(int32 val, bool apply) { ApplyModFloatValue(UNIT_FIELD_MAXHEALTH, val, apply); }
void ApplyMaxHealthPercentMod(float val, bool apply) { ApplyPercentModFloatValue(UNIT_FIELD_MAXHEALTH, val, apply); }
Powers getPowerType() const { return Powers((GetUInt32Value(UNIT_FIELD_BYTES_0) >> 24) & 0xFF); };
@@ -419,9 +404,9 @@
void SetPower( Powers power, uint32 val) { SetFloatValue(UNIT_FIELD_POWER1 +power,val); }
void SetMaxPower(Powers power, uint32 val) { SetFloatValue(UNIT_FIELD_MAXPOWER1+power,val); }
void ModifyPower(Powers power, int32 val);
- void ApplyPowerMod(Powers power, uint32 val, bool apply) { ApplyModFloatValue(UNIT_FIELD_POWER1+power, val, apply); }
+ void ApplyPowerMod(Powers power, int32 val, bool apply) { ApplyModFloatValue(UNIT_FIELD_POWER1+power, val, apply); }
void ApplyPowerPercentMod(Powers power, float val, bool apply) { ApplyPercentModFloatValue(UNIT_FIELD_POWER1+power, val, apply); }
- void ApplyMaxPowerMod(Powers power, uint32 val, bool apply) { ApplyModFloatValue(UNIT_FIELD_MAXPOWER1+power, val, apply); }
+ void ApplyMaxPowerMod(Powers power, int32 val, bool apply) { ApplyModFloatValue(UNIT_FIELD_MAXPOWER1+power, val, apply); }
void ApplyMaxPowerPercentMod(Powers power, float val, bool apply) { ApplyPercentModFloatValue(UNIT_FIELD_MAXPOWER1+power, val, apply); }
uint32 GetAttackTime(WeaponAttackType att) const { return (uint32)GetFloatValue(UNIT_FIELD_BASEATTACKTIME+att); }
@@ -629,7 +614,6 @@
uint32 CalculateDamage(WeaponAttackType attType);
void SetStateFlag(uint32 index, uint32 newFlag );
void RemoveStateFlag(uint32 index, uint32 oldFlag );
- void ApplyStats(bool apply);
void UnsummonTotem(int8 slot = -1);
uint32 SpellDamageBonus(Unit *pVictim, SpellEntry *spellProto, uint32 damage);
uint32 SpellHealingBonus(SpellEntry *spellProto, uint32 healamount);
@@ -637,11 +621,28 @@
void MeleeDamageBonus(Unit *pVictim, uint32 *damage);
void ApplySpellImmune(uint32 spellId, uint32 op, uint32 type, bool apply);
+ void _RemoveStatsMods();
+ void _ApplyStatsMods();
+
+ //// Cascade Update System /////////////////////////
+ // Stats
+ float GetStat(Stats stat) const { return GetFloatValue(UNIT_FIELD_STATS+stat); }
+ void SetBaseStat(Stats stat, float value) { m_BaseStat[stat] = value; CascadeUpdateStat(stat); }
+ void ApplyBaseStatMod(Stats stat, float addvalue, bool apply) { m_BaseStat[stat] += (apply ? addvalue : -addvalue); CascadeUpdateStat(stat); }
+ void CascadeUpdateStat(Stats stat);
+
+ // Resistance
+ float GetArmor() const { return GetResistance(SPELL_SCHOOL_NORMAL) ; }
+ float GetResistance(SpellSchools school) const;
+ void SetBaseArmor(float addvalue) { SetBaseResistance(SPELL_SCHOOL_NORMAL,addvalue); }
+ void ApplyBaseArmorMod(float addvalue,bool apply) { ApplyBaseResistanceMod(SPELL_SCHOOL_NORMAL,addvalue,apply); }
+ void SetBaseResistance(SpellSchools res,float value) { m_BaseResistance[res] = value; CascadeUpdateResistance(res); }
+ void ApplyBaseResistanceMod(SpellSchools res,float addvalue,bool apply) { m_BaseResistance[res] += (apply ? addvalue : -addvalue); CascadeUpdateResistance(res); }
+ void CascadeUpdateResistance(SpellSchools res);
protected:
Unit ( );
- void _RemoveStatsMods();
- void _ApplyStatsMods();
+ void _ApplyStats(bool apply);
void _RemoveAllAuraMods();
void _ApplyAllAuraMods();
@@ -673,6 +674,9 @@
long m_AuraModifiers[TOTAL_AURAS];
//std::list< spellEffectPair > AuraSpells[TOTAL_AURAS]; // TODO: use this if ok for mem
+ //// Cascade Update System /////////////////////////
+ float m_BaseStat[MAX_STATS]; // Base Stats (with not applied percent modifiers)
+ float m_BaseResistance[SPELL_SCHOOL_COUNT]; // Base Resistance (with not applied percent modifiers)
private:
void SendAttackStop(Unit* victim); // only from AttackStop(Unit*)
void SendAttackStart(Unit* pVictim); // only from Unit::AttackStart(Unit*)