diff options
author | XTZGZoReX <none@none> | 2010-01-10 22:02:03 +0100 |
---|---|---|
committer | XTZGZoReX <none@none> | 2010-01-10 22:02:03 +0100 |
commit | a66152215edba3def43f3db88318e92dc61e7b60 (patch) | |
tree | eab9a5bab9a224d1dde609701dba6c877c6f4b50 /src | |
parent | 997a861a4199b2693107a8b2b9005a7ad818867a (diff) |
* Add support for base armor values in creature_classlevelstats.
* Change the table structure to be more core-friendly.
* Remove armor field in creature_template and add Armor_mod field.
* Also add static CreatureBaseStats::GetBaseStats() function for scripts.
--HG--
branch : trunk
Diffstat (limited to 'src')
-rw-r--r-- | src/bindings/scripts/scripts/world/npcs_special.cpp | 8 | ||||
-rw-r--r-- | src/game/Creature.cpp | 67 | ||||
-rw-r--r-- | src/game/Creature.h | 35 | ||||
-rw-r--r-- | src/game/ObjectMgr.cpp | 59 | ||||
-rw-r--r-- | src/game/ObjectMgr.h | 3 | ||||
-rw-r--r-- | src/shared/Database/SQLStorage.cpp | 4 |
6 files changed, 87 insertions, 89 deletions
diff --git a/src/bindings/scripts/scripts/world/npcs_special.cpp b/src/bindings/scripts/scripts/world/npcs_special.cpp index f3ccb1076cc..7908e2989f1 100644 --- a/src/bindings/scripts/scripts/world/npcs_special.cpp +++ b/src/bindings/scripts/scripts/world/npcs_special.cpp @@ -1586,14 +1586,14 @@ struct TRINITY_DLL_DECL npc_snake_trap_serpentsAI : public ScriptedAI IsViper = false; //We have to reload the states from db for summoned guardians - BaseHealthManaPair pair = m_creature->GenerateHealthMana(); - m_creature->SetMaxHealth(pair.first); - m_creature->SetHealth(pair.second); + CreatureBaseStats const* stats = CreatureBaseStats::GetBaseStats(m_creature->getLevel(), Info->unit_class); + m_creature->SetMaxHealth(stats->GenerateHealth(Info)); + m_creature->SetHealth(stats->GenerateMana(Info)); m_creature->SetStatFloatValue(UNIT_FIELD_MINDAMAGE, Info->mindmg); m_creature->SetStatFloatValue(UNIT_FIELD_MAXDAMAGE, Info->maxdmg); //Add delta to make them not all hit the same time - uint32 delta = (rand() % 7) *100; + uint32 delta = (rand() % 7) * 100; m_creature->SetStatFloatValue(UNIT_FIELD_BASEATTACKTIME, Info->baseattacktime + delta); m_creature->SetStatFloatValue(UNIT_FIELD_RANGED_ATTACK_POWER , Info->attackpower); } diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index 9795671ef22..0a74b64d320 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -132,6 +132,11 @@ bool AssistDelayEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/) return true; } +CreatureBaseStats const* CreatureBaseStats::GetBaseStats(uint32 level, uint8 unitClass) +{ + return objmgr.GetCreatureBaseStats(level, unitClass); +} + Creature::Creature() : Unit(), lootForPickPocketed(false), lootForBody(false), m_groupLootTimer(0), lootingGroupLeaderGUID(0), @@ -352,45 +357,49 @@ bool Creature::UpdateEntry(uint32 Entry, uint32 team, const CreatureData *data ) if(!InitEntry(Entry,team,data)) return false; - m_regenHealth = GetCreatureInfo()->RegenHealth; + CreatureInfo const* cInfo = GetCreatureInfo(); + + m_regenHealth = cInfo->RegenHealth; // creatures always have melee weapon ready if any SetSheath(SHEATH_STATE_MELEE); SelectLevel(GetCreatureInfo()); if (team == HORDE) - setFaction(GetCreatureInfo()->faction_H); + setFaction(cInfo->faction_H); else - setFaction(GetCreatureInfo()->faction_A); + setFaction(cInfo->faction_A); - if(GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_WORLDEVENT) - SetUInt32Value(UNIT_NPC_FLAGS,GetCreatureInfo()->npcflag | gameeventmgr.GetNPCFlag(this)); + if(cInfo->flags_extra & CREATURE_FLAG_EXTRA_WORLDEVENT) + SetUInt32Value(UNIT_NPC_FLAGS,cInfo->npcflag | gameeventmgr.GetNPCFlag(this)); else - SetUInt32Value(UNIT_NPC_FLAGS,GetCreatureInfo()->npcflag); + SetUInt32Value(UNIT_NPC_FLAGS,cInfo->npcflag); - SetAttackTime(BASE_ATTACK, GetCreatureInfo()->baseattacktime); - SetAttackTime(OFF_ATTACK, GetCreatureInfo()->baseattacktime); - SetAttackTime(RANGED_ATTACK,GetCreatureInfo()->rangeattacktime); + SetAttackTime(BASE_ATTACK, cInfo->baseattacktime); + SetAttackTime(OFF_ATTACK, cInfo->baseattacktime); + SetAttackTime(RANGED_ATTACK,cInfo->rangeattacktime); - SetUInt32Value(UNIT_FIELD_FLAGS,GetCreatureInfo()->unit_flags); - SetUInt32Value(UNIT_DYNAMIC_FLAGS,GetCreatureInfo()->dynamicflags); + SetUInt32Value(UNIT_FIELD_FLAGS,cInfo->unit_flags); + SetUInt32Value(UNIT_DYNAMIC_FLAGS,cInfo->dynamicflags); RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IN_COMBAT); - SetMeleeDamageSchool(SpellSchools(GetCreatureInfo()->dmgschool)); - SetModifierValue(UNIT_MOD_ARMOR, BASE_VALUE, float(GetCreatureInfo()->armor)); - SetModifierValue(UNIT_MOD_RESISTANCE_HOLY, BASE_VALUE, float(GetCreatureInfo()->resistance1)); - SetModifierValue(UNIT_MOD_RESISTANCE_FIRE, BASE_VALUE, float(GetCreatureInfo()->resistance2)); - SetModifierValue(UNIT_MOD_RESISTANCE_NATURE, BASE_VALUE, float(GetCreatureInfo()->resistance3)); - SetModifierValue(UNIT_MOD_RESISTANCE_FROST, BASE_VALUE, float(GetCreatureInfo()->resistance4)); - SetModifierValue(UNIT_MOD_RESISTANCE_SHADOW, BASE_VALUE, float(GetCreatureInfo()->resistance5)); - SetModifierValue(UNIT_MOD_RESISTANCE_ARCANE, BASE_VALUE, float(GetCreatureInfo()->resistance6)); + SetMeleeDamageSchool(SpellSchools(cInfo->dmgschool)); + CreatureBaseStats const* stats = objmgr.GetCreatureBaseStats(getLevel(), cInfo->unit_class); + float armor = stats->GenerateArmor(cInfo); // TODO: Why is this treated as uint32 when it's a float? + SetModifierValue(UNIT_MOD_ARMOR, BASE_VALUE, armor); + SetModifierValue(UNIT_MOD_RESISTANCE_HOLY, BASE_VALUE, float(cInfo->resistance1)); + SetModifierValue(UNIT_MOD_RESISTANCE_FIRE, BASE_VALUE, float(cInfo->resistance2)); + SetModifierValue(UNIT_MOD_RESISTANCE_NATURE, BASE_VALUE, float(cInfo->resistance3)); + SetModifierValue(UNIT_MOD_RESISTANCE_FROST, BASE_VALUE, float(cInfo->resistance4)); + SetModifierValue(UNIT_MOD_RESISTANCE_SHADOW, BASE_VALUE, float(cInfo->resistance5)); + SetModifierValue(UNIT_MOD_RESISTANCE_ARCANE, BASE_VALUE, float(cInfo->resistance6)); SetCanModifyStats(true); UpdateAllStats(); // checked and error show at loading templates - if (FactionTemplateEntry const* factionTemplate = sFactionTemplateStore.LookupEntry(GetCreatureInfo()->faction_A)) + if (FactionTemplateEntry const* factionTemplate = sFactionTemplateStore.LookupEntry(cInfo->faction_A)) { if (factionTemplate->factionFlags & FACTION_TEMPLATE_FLAG_PVP) SetPvP(true); @@ -410,16 +419,17 @@ bool Creature::UpdateEntry(uint32 Entry, uint32 team, const CreatureData *data ) else SetReactState(REACT_AGGRESSIVE); - if(GetCreatureInfo()->flags_extra & CREATURE_FLAG_EXTRA_NO_TAUNT) + if(cInfo->flags_extra & CREATURE_FLAG_EXTRA_NO_TAUNT) { ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true); ApplySpellImmune(0, IMMUNITY_EFFECT,SPELL_EFFECT_ATTACK_ME, true); } - if(GetCreatureInfo()->InhabitType & INHABIT_AIR) + // TODO: In fact monster move flags should be set - not movement flags. + if(cInfo->InhabitType & INHABIT_AIR) AddUnitMovementFlag(MOVEMENTFLAG_FLY_MODE | MOVEMENTFLAG_FLYING); - if(GetCreatureInfo()->InhabitType & INHABIT_WATER) + if(cInfo->InhabitType & INHABIT_WATER) AddUnitMovementFlag(MOVEMENTFLAG_SWIMMING); return true; @@ -1062,12 +1072,12 @@ void Creature::SelectLevel(const CreatureInfo *cinfo) uint8 level = minlevel == maxlevel ? minlevel : urand(minlevel, maxlevel); SetLevel(level); - BaseHealthManaPair pair = objmgr.GenerateCreatureStats(level, cinfo); + CreatureBaseStats const* stats = objmgr.GetCreatureBaseStats(level, cinfo->unit_class); // health float healthmod = _GetHealthMod(rank); - uint32 basehp = pair.first; + uint32 basehp = stats->GenerateHealth(cinfo); uint32 health = uint32(basehp * healthmod); SetCreateHealth(health); @@ -1076,7 +1086,7 @@ void Creature::SelectLevel(const CreatureInfo *cinfo) ResetPlayerDamageReq(); // mana - uint32 mana = pair.second; + uint32 mana = stats->GenerateMana(cinfo); SetCreateMana(mana); SetMaxPower(POWER_MANA, mana); //MAX Mana @@ -2342,8 +2352,3 @@ time_t Creature::GetLinkedCreatureRespawnTime() const return 0; } - -BaseHealthManaPair Creature::GenerateHealthMana() -{ - return objmgr.GenerateCreatureStats(getLevel(), GetCreatureInfo()); -} diff --git a/src/game/Creature.h b/src/game/Creature.h index 2ec18efbcff..6bad39de566 100644 --- a/src/game/Creature.h +++ b/src/game/Creature.h @@ -83,7 +83,6 @@ struct CreatureInfo uint32 minlevel; uint32 maxlevel; uint32 expansion; - uint32 armor; uint32 faction_A; uint32 faction_H; uint32 npcflag; @@ -129,6 +128,7 @@ struct CreatureInfo uint32 InhabitType; float ModHealth; float ModMana; + float ModArmor; bool RacialLeader; uint32 questItems[6]; uint32 movementId; @@ -163,23 +163,27 @@ struct CreatureInfo } }; -// Defines base stats for creatures (used to calculate HP/mana). -struct CreatureBaseStats +// Represents max amount of expansions. +// TODO: Add MAX_EXPANSION constant. +#define MAX_CREATURE_BASE_HP 3 + +// Defines base stats for creatures (used to calculate HP/mana/armor). +struct TRINITY_DLL_SPEC CreatureBaseStats { - uint8 Expansion; - uint8 Class; uint32 Level; - uint32 BaseHealth; + uint8 Class; + uint32 BaseHealth[MAX_CREATURE_BASE_HP]; uint32 BaseMana; + uint32 BaseArmor; // Helpers - uint32 GenerateHealth(uint32 level, CreatureInfo const* info) const + uint32 GenerateHealth(CreatureInfo const* info) const { - return uint32((BaseHealth * info->ModHealth) + 0.5f); + return uint32((BaseHealth[info->expansion] * info->ModHealth) + 0.5f); } - uint32 GenerateMana(uint32 level, CreatureInfo const* info) const + uint32 GenerateMana(CreatureInfo const* info) const { // Mana can be 0. if (!BaseMana) @@ -187,10 +191,16 @@ struct CreatureBaseStats return uint32((BaseMana * info->ModMana) + 0.5f); } + + uint32 GenerateArmor(CreatureInfo const* info) const + { + return uint32((BaseArmor * info->ModArmor) + 0.5f); + } + + static CreatureBaseStats const* GetBaseStats(uint32 level, uint8 unitClass); }; -typedef std::list<CreatureBaseStats> CreatureBaseStatsList; -typedef std::pair<uint32, uint32> BaseHealthManaPair; +typedef std::vector<CreatureBaseStats> CreatureBaseStatsList; struct CreatureLocale { @@ -650,9 +660,6 @@ class TRINITY_DLL_SPEC Creature : public Unit, public GridObject<Creature> void SetOriginalEntry(uint32 entry) { m_originalEntry = entry; } - // Provided for script access. - BaseHealthManaPair GenerateHealthMana(); - static float _GetDamageMod(int32 Rank); float m_SightDistance, m_CombatDistance; diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp index ba8f403e0ef..abcae59a427 100644 --- a/src/game/ObjectMgr.cpp +++ b/src/game/ObjectMgr.cpp @@ -1484,7 +1484,7 @@ uint32 ObjectMgr::AddCreData(uint32 entry, uint32 team, uint32 mapId, float x, f return 0; uint32 level = cInfo->minlevel == cInfo->maxlevel ? cInfo->minlevel : urand(cInfo->minlevel, cInfo->maxlevel); // Only used for extracting creature base stats - BaseHealthManaPair pair = objmgr.GenerateCreatureStats(level, cInfo); + CreatureBaseStats const* stats = objmgr.GetCreatureBaseStats(level, cInfo->unit_class); uint32 guid = GenerateLowGuid(HIGHGUID_UNIT); CreatureData& data = NewOrExistCreatureData(guid); @@ -1499,8 +1499,8 @@ uint32 ObjectMgr::AddCreData(uint32 entry, uint32 team, uint32 mapId, float x, f data.spawntimesecs = spawntimedelay; data.spawndist = 0; data.currentwaypoint = 0; - data.curhealth = pair.first; - data.curmana = pair.second; + data.curhealth = stats->GenerateHealth(cInfo); + data.curmana = stats->GenerateMana(cInfo); data.is_dead = false; data.movementType = cInfo->MovementType; data.spawnMask = 1; @@ -8899,38 +8899,21 @@ void ObjectMgr::RemoveGMTicket(uint64 ticketGuid, int64 source, bool permanently RemoveGMTicket(ticket, source, permanently); } -CreatureBaseStats const* ObjectMgr::GetCreatureBaseStats(uint8 expansion, uint8 unitClass, uint32 level) +CreatureBaseStats const* ObjectMgr::GetCreatureBaseStats(uint32 level, uint8 unitClass) { for (CreatureBaseStatsList::const_iterator it = m_creatureBaseStatsList.begin(); it != m_creatureBaseStatsList.end(); ++it) { CreatureBaseStats const& stats = (*it); - if (stats.Expansion == expansion && stats.Class == unitClass && stats.Level == level) + if (stats.Level == level && stats.Class == unitClass) return &stats; } return NULL; } -BaseHealthManaPair ObjectMgr::GenerateCreatureStats(uint32 level, CreatureInfo const* info) -{ - uint32 health = 1; - uint32 mana = 1; - - CreatureBaseStats const* stats = GetCreatureBaseStats(info->expansion, info->unit_class, level); - if (!stats) - sLog.outError("Could not find base stats for creature entry %u (base stats: expansion %u, class %u, level %u)", info->Entry, info->expansion, info->unit_class, level); - else - { - health = stats->GenerateHealth(level, info); - mana = stats->GenerateMana(level, info); - } - - return BaseHealthManaPair(health, mana); -} - void ObjectMgr::LoadCreatureClassLevelStats() { - QueryResult *result = WorldDatabase.Query("SELECT exp, class, level, basehp, basemana FROM creature_classlevelstats"); + QueryResult *result = WorldDatabase.Query("SELECT level, class, basehp0, basehp1, basehp2, basemana, basearmor FROM creature_classlevelstats"); if (!result) { @@ -8948,28 +8931,32 @@ void ObjectMgr::LoadCreatureClassLevelStats() { Field *fields = result->Fetch(); CreatureBaseStats stats = CreatureBaseStats(); - stats.Expansion = fields[0].GetUInt8(); + stats.Level = fields[0].GetUInt32(); stats.Class = fields[1].GetUInt8(); - stats.Level = fields[2].GetUInt32(); - stats.BaseHealth = fields[3].GetUInt32(); - stats.BaseMana = fields[4].GetUInt32(); + for (uint8 i = 0; i < MAX_CREATURE_BASE_HP; ++i) + stats.BaseHealth[i] = fields[i + 2].GetUInt32(); + stats.BaseMana = fields[5].GetUInt32(); + stats.BaseArmor = fields[6].GetUInt32(); if (stats.Level > MAX_LEVEL) { - sLog.outErrorDb("Creature base stats for expansion %u, class %u has invalid level %u (max is %u) - set to %u", - stats.Expansion, stats.Class, stats.Level, MAX_LEVEL, DEFAULT_MAX_LEVEL); + sLog.outErrorDb("Creature base stats for class %u has invalid level %u (max is %u) - set to %u", + stats.Class, stats.Level, MAX_LEVEL, DEFAULT_MAX_LEVEL); stats.Level = DEFAULT_MAX_LEVEL; } - if (!stats.Class || ((1 << (stats.Class-1)) & CLASSMASK_ALL_CREATURES) == 0) - sLog.outErrorDb("Creature base stats for expansion %u, level %u has invalid class %u", - stats.Expansion, stats.Level, stats.Class); + if (!stats.Class || ((1 << (stats.Class - 1)) & CLASSMASK_ALL_CREATURES) == 0) + sLog.outErrorDb("Creature base stats for level %u has invalid class %u", + stats.Level, stats.Class); - if (stats.BaseHealth < 1) + for (uint8 i = 0; i < MAX_CREATURE_BASE_HP; ++i) { - sLog.outErrorDb("Creature base stats for expansion %u, class %u, level %u has invalid zero base HP - set to 1", - stats.Expansion, stats.Class, stats.Level); - stats.BaseHealth = 1; + if (stats.BaseHealth[i] < 1) + { + sLog.outErrorDb("Creature base stats for class %u, level %u has invalid zero base HP[%u] - set to 1", + stats.Class, stats.Level, i); + stats.BaseHealth[i] = 1; + } } m_creatureBaseStatsList.push_back(stats); diff --git a/src/game/ObjectMgr.h b/src/game/ObjectMgr.h index 98c818838e5..93b74d649f8 100644 --- a/src/game/ObjectMgr.h +++ b/src/game/ObjectMgr.h @@ -654,8 +654,7 @@ class ObjectMgr void ReturnOrDeleteOldMails(bool serverUp); - CreatureBaseStats const* GetCreatureBaseStats(uint8 expansion, uint8 unitClass, uint32 level); - BaseHealthManaPair GenerateCreatureStats(uint32 level, CreatureInfo const* info); + CreatureBaseStats const* GetCreatureBaseStats(uint32 level, uint8 unitClass); void SetHighestGuids(); uint32 GenerateLowGuid(HighGuid guidhigh); diff --git a/src/shared/Database/SQLStorage.cpp b/src/shared/Database/SQLStorage.cpp index 484c2278c1b..d6d79c730ea 100644 --- a/src/shared/Database/SQLStorage.cpp +++ b/src/shared/Database/SQLStorage.cpp @@ -27,8 +27,8 @@ extern DatabasePostgre WorldDatabase; extern DatabaseMysql WorldDatabase; #endif -const char CreatureInfosrcfmt[]="iiiiiiiiiisssiiiiiiiiffiffiifiiiiiiiiiiffiiiiiiiiiiiiiiiiiiiiiiiisiiffliiiiiiiliiis"; -const char CreatureInfodstfmt[]="iiiiiiiiiisssiiiiiiiiffiffiifiiiiiiiiiiffiiiiiiiiiiiiiiiiiiiiiiiisiiffliiiiiiiliiii"; +const char CreatureInfosrcfmt[]="iiiiiiiiiisssiiiiiiiffiffiifiiiiiiiiiiffiiiiiiiiiiiiiiiiiiiiiiiisiifffliiiiiiiliiis"; +const char CreatureInfodstfmt[]="iiiiiiiiiisssiiiiiiiffiffiifiiiiiiiiiiffiiiiiiiiiiiiiiiiiiiiiiiisiifffliiiiiiiliiii"; const char CreatureDataAddonInfofmt[]="iiiiiis"; const char CreatureModelfmt[]="iffbi"; const char CreatureInfoAddonInfofmt[]="iiiiiis"; |