diff options
| author | Traesh <Traesh@users.noreply.github.com> | 2018-11-07 20:23:30 +0100 |
|---|---|---|
| committer | Shauren <shauren.trinity@gmail.com> | 2018-11-07 20:23:30 +0100 |
| commit | 9d210476e57949094fdd286001ef4900564edca5 (patch) | |
| tree | 1e8ed5d261698e633ee3371779d30f8c1666526e /src/server/game/Entities | |
| parent | 31f0186d20a1944e5d0ff47d71ca8f560074de4b (diff) | |
Core/Creatures: Update creature model handling with new display scale (#22567)
Diffstat (limited to 'src/server/game/Entities')
| -rw-r--r-- | src/server/game/Entities/Creature/Creature.cpp | 144 | ||||
| -rw-r--r-- | src/server/game/Entities/Creature/Creature.h | 3 | ||||
| -rw-r--r-- | src/server/game/Entities/Creature/CreatureData.h | 31 | ||||
| -rw-r--r-- | src/server/game/Entities/Pet/Pet.cpp | 4 | ||||
| -rw-r--r-- | src/server/game/Entities/Pet/Pet.h | 2 | ||||
| -rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 8 | ||||
| -rw-r--r-- | src/server/game/Entities/Unit/Unit.h | 5 |
7 files changed, 111 insertions, 86 deletions
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index b6d6e44a3fe..f521cdfd3b0 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -77,68 +77,67 @@ VendorItem const* VendorItemData::FindItemCostPair(uint32 item_id, uint32 extend return nullptr; } -uint32 CreatureTemplate::GetRandomValidModelId() const -{ - uint8 c = 0; - uint32 modelIDs[4]; - - if (Modelid1) modelIDs[c++] = Modelid1; - if (Modelid2) modelIDs[c++] = Modelid2; - if (Modelid3) modelIDs[c++] = Modelid3; - if (Modelid4) modelIDs[c++] = Modelid4; +CreatureModel const CreatureModel::DefaultInvisibleModel(11686, 1.0f, 1.0f); +CreatureModel const CreatureModel::DefaultVisibleModel(17519, 1.0f, 1.0f); - return ((c>0) ? modelIDs[urand(0, c-1)] : 0); -} - -uint32 CreatureTemplate::GetFirstValidModelId() const +CreatureModel const* CreatureTemplate::GetModelByIdx(uint32 idx) const { - if (Modelid1) return Modelid1; - if (Modelid2) return Modelid2; - if (Modelid3) return Modelid3; - if (Modelid4) return Modelid4; - return 0; + return idx < Models.size() ? &Models[idx] : nullptr; } -uint32 CreatureTemplate::GetFirstInvisibleModel() const +CreatureModel const* CreatureTemplate::GetRandomValidModel() const { - CreatureModelInfo const* modelInfo = sObjectMgr->GetCreatureModelInfo(Modelid1); - if (modelInfo && modelInfo->is_trigger) - return Modelid1; + if (!Models.size()) + return nullptr; - modelInfo = sObjectMgr->GetCreatureModelInfo(Modelid2); - if (modelInfo && modelInfo->is_trigger) - return Modelid2; + // If only one element, ignore the Probability (even if 0) + if (Models.size() == 1) + return &Models[0]; - modelInfo = sObjectMgr->GetCreatureModelInfo(Modelid3); - if (modelInfo && modelInfo->is_trigger) - return Modelid3; + auto selectedItr = Trinity::Containers::SelectRandomWeightedContainerElement(Models, [](CreatureModel const& model) + { + return model.Probability; + }); - modelInfo = sObjectMgr->GetCreatureModelInfo(Modelid4); - if (modelInfo && modelInfo->is_trigger) - return Modelid4; + return &(*selectedItr); +} + +CreatureModel const* CreatureTemplate::GetFirstValidModel() const +{ + for (CreatureModel const& model : Models) + if (model.CreatureDisplayID) + return &model; - return 11686; + return nullptr; } -uint32 CreatureTemplate::GetFirstVisibleModel() const +CreatureModel const* CreatureTemplate::GetModelWithDisplayId(uint32 displayId) const { - CreatureModelInfo const* modelInfo = sObjectMgr->GetCreatureModelInfo(Modelid1); - if (modelInfo && !modelInfo->is_trigger) - return Modelid1; + for (CreatureModel const& model : Models) + if (displayId == model.CreatureDisplayID) + return &model; - modelInfo = sObjectMgr->GetCreatureModelInfo(Modelid2); - if (modelInfo && !modelInfo->is_trigger) - return Modelid2; + return nullptr; +} + +CreatureModel const* CreatureTemplate::GetFirstInvisibleModel() const +{ + for (CreatureModel const& model : Models) + if (CreatureModelInfo const* modelInfo = sObjectMgr->GetCreatureModelInfo(model.CreatureDisplayID)) + if (modelInfo && modelInfo->is_trigger) + return &model; - modelInfo = sObjectMgr->GetCreatureModelInfo(Modelid3); - if (modelInfo && !modelInfo->is_trigger) - return Modelid3; + return &CreatureModel::DefaultInvisibleModel; +} - modelInfo = sObjectMgr->GetCreatureModelInfo(Modelid4); - if (modelInfo && !modelInfo->is_trigger) - return Modelid4; +CreatureModel const* CreatureTemplate::GetFirstVisibleModel() const +{ + for (CreatureModel const& model : Models) + if (CreatureModelInfo const* modelInfo = sObjectMgr->GetCreatureModelInfo(model.CreatureDisplayID)) + if (modelInfo && !modelInfo->is_trigger) + return &model; - return 17519; + return &CreatureModel::DefaultVisibleModel; } bool AssistDelayEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/) @@ -343,22 +342,22 @@ bool Creature::InitEntry(uint32 entry, CreatureData const* data /*= nullptr*/) SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_CLASS, uint8(cinfo->unit_class)); // Cancel load if no model defined - if (!(cinfo->GetFirstValidModelId())) + if (!(cinfo->GetFirstValidModel())) { TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) has no model defined in table `creature_template`, can't load. ", entry); return false; } - uint32 displayID = ObjectMgr::ChooseDisplayId(GetCreatureTemplate(), data); - CreatureModelInfo const* minfo = sObjectMgr->GetCreatureModelRandomGender(&displayID); + CreatureModel model = *ObjectMgr::ChooseDisplayId(cinfo, data); + CreatureModelInfo const* minfo = sObjectMgr->GetCreatureModelRandomGender(&model, cinfo); if (!minfo) // Cancel load if no model defined { - TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) has invalid model %u defined in table `creature_template`, can't load.", entry, displayID); + TC_LOG_ERROR("sql.sql", "Creature (Entry: %u) has invalid model %u defined in table `creature_template`, can't load.", entry, model.CreatureDisplayID); return false; } - SetDisplayId(displayID); - SetNativeDisplayId(displayID); + SetDisplayId(model.CreatureDisplayID, model.DisplayScale); + SetNativeDisplayId(model.CreatureDisplayID, model.DisplayScale); SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_GENDER, minfo->gender); // Load creature equipment @@ -384,7 +383,7 @@ bool Creature::InitEntry(uint32 entry, CreatureData const* data /*= nullptr*/) SetSpeedRate(MOVE_SWIM, 1.0f); // using 1.0 rate SetSpeedRate(MOVE_FLIGHT, 1.0f); // using 1.0 rate - // Will set UNIT_FIELD_BOUNDINGRADIUS and UNIT_FIELD_COMBATREACH + // Will set UNIT_FIELD_BOUNDINGRADIUS, UNIT_FIELD_COMBATREACH and UNIT_FIELD_DISPLAYSCALE SetObjectScale(cinfo->scale); SetFloatValue(UNIT_FIELD_HOVERHEIGHT, cinfo->HoverHeight); @@ -892,7 +891,8 @@ bool Creature::Create(ObjectGuid::LowType guidlow, Map* map, uint32 entry, float if (!CreateFromProto(guidlow, entry, data, vehId)) return false; - switch (GetCreatureTemplate()->rank) + cinfo = GetCreatureTemplate(); // might be different than initially requested + switch (cinfo->rank) { case CREATURE_ELITE_RARE: m_corpseDelay = sWorld->getIntConfig(CONFIG_CORPSE_DECAY_RARE); @@ -922,12 +922,12 @@ bool Creature::Create(ObjectGuid::LowType guidlow, Map* map, uint32 entry, float Relocate(x, y, z, ang); } - uint32 displayID = GetNativeDisplayId(); - CreatureModelInfo const* minfo = sObjectMgr->GetCreatureModelRandomGender(&displayID); + CreatureModel display(GetNativeDisplayId(), GetNativeDisplayScale(), 1.0f); + CreatureModelInfo const* minfo = sObjectMgr->GetCreatureModelRandomGender(&display, cinfo); if (minfo && !IsTotem()) // Cancel load if no model defined or if totem { - SetDisplayId(displayID); - SetNativeDisplayId(displayID); + SetDisplayId(display.CreatureDisplayID, display.DisplayScale); + SetNativeDisplayId(display.CreatureDisplayID, display.DisplayScale); SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_GENDER, minfo->gender); } @@ -940,10 +940,10 @@ bool Creature::Create(ObjectGuid::LowType guidlow, Map* map, uint32 entry, float m_serverSideVisibilityDetect.SetValue(SERVERSIDE_VISIBILITY_GHOST, GHOST_VISIBILITY_GHOST); } - if (GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_IGNORE_PATHFINDING) + if (cinfo->flags_extra & CREATURE_FLAG_EXTRA_IGNORE_PATHFINDING) AddUnitState(UNIT_STATE_IGNORE_PATHFINDING); - if (GetCreatureTemplate()->flags_extra & CREATURE_FLAG_EXTRA_IMMUNITY_KNOCKBACK) + if (cinfo->flags_extra & CREATURE_FLAG_EXTRA_IMMUNITY_KNOCKBACK) { ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, true); ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK_DEST, true); @@ -1127,9 +1127,9 @@ void Creature::SaveToDB(uint32 mapid, std::vector<Difficulty> const& spawnDiffic CreatureTemplate const* cinfo = GetCreatureTemplate(); if (cinfo) { - if (displayId == cinfo->Modelid1 || displayId == cinfo->Modelid2 || - displayId == cinfo->Modelid3 || displayId == cinfo->Modelid4) - displayId = 0; + for (CreatureModel model : cinfo->Models) + if (displayId && displayId == model.CreatureDisplayID) + displayId = 0; if (npcflag == cinfo->npcflag) npcflag = 0; @@ -1842,12 +1842,12 @@ void Creature::Respawn(bool force) setDeathState(JUST_RESPAWNED); - uint32 displayID = GetNativeDisplayId(); - CreatureModelInfo const* minfo = sObjectMgr->GetCreatureModelRandomGender(&displayID); + CreatureModel display(GetNativeDisplayId(), GetNativeDisplayScale(), 1.0f); + CreatureModelInfo const* minfo = sObjectMgr->GetCreatureModelRandomGender(&display, GetCreatureTemplate()); if (minfo) // Cancel load if no model defined { - SetDisplayId(displayID); - SetNativeDisplayId(displayID); + SetDisplayId(display.CreatureDisplayID, display.DisplayScale); + SetNativeDisplayId(display.CreatureDisplayID, display.DisplayScale); SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_GENDER, minfo->gender); } @@ -2847,9 +2847,9 @@ void Creature::SetObjectScale(float scale) } } -void Creature::SetDisplayId(uint32 modelId) +void Creature::SetDisplayId(uint32 modelId, float displayScale /*= 1.f*/) { - Unit::SetDisplayId(modelId); + Unit::SetDisplayId(modelId, displayScale); if (CreatureModelInfo const* minfo = sObjectMgr->GetCreatureModelInfo(modelId)) { @@ -2858,6 +2858,12 @@ void Creature::SetDisplayId(uint32 modelId) } } +void Creature::SetDisplayFromModel(uint32 modelIdx) +{ + if (CreatureModel const* model = GetCreatureTemplate()->GetModelByIdx(modelIdx)) + SetDisplayId(model->CreatureDisplayID, model->DisplayScale); +} + void Creature::SetTarget(ObjectGuid const& guid) { if (IsFocusing(nullptr, true)) diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index 90c84fb843a..b56fe8c9137 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -69,7 +69,8 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma void RemoveFromWorld() override; void SetObjectScale(float scale) override; - void SetDisplayId(uint32 modelId) override; + void SetDisplayId(uint32 displayId, float displayScale = 1.f) override; + void SetDisplayFromModel(uint32 modelIdx); void DisappearAndDie(); diff --git a/src/server/game/Entities/Creature/CreatureData.h b/src/server/game/Entities/Creature/CreatureData.h index 45a13c6f603..813aaa27e27 100644 --- a/src/server/game/Entities/Creature/CreatureData.h +++ b/src/server/game/Entities/Creature/CreatureData.h @@ -300,16 +300,29 @@ struct CreatureLevelScaling int16 DeltaLevelMax; }; +struct CreatureModel +{ + static CreatureModel const DefaultInvisibleModel; + static CreatureModel const DefaultVisibleModel; + + CreatureModel() : + CreatureDisplayID(0), DisplayScale(0.0f), Probability(0.0f) { } + + CreatureModel(uint32 creatureDisplayID, float displayScale, float probability) : + CreatureDisplayID(creatureDisplayID), DisplayScale(displayScale), Probability(probability) { } + + uint32 CreatureDisplayID; + float DisplayScale; + float Probability; +}; + // from `creature_template` table struct TC_GAME_API CreatureTemplate { uint32 Entry; uint32 DifficultyEntry[MAX_CREATURE_DIFFICULTIES]; uint32 KillCredit[MAX_KILL_CREDIT]; - uint32 Modelid1; - uint32 Modelid2; - uint32 Modelid3; - uint32 Modelid4; + std::vector<CreatureModel> Models; std::string Name; std::string FemaleName; std::string SubName; @@ -368,10 +381,12 @@ struct TC_GAME_API CreatureTemplate uint32 MechanicImmuneMask; uint32 flags_extra; uint32 ScriptID; - uint32 GetRandomValidModelId() const; - uint32 GetFirstValidModelId() const; - uint32 GetFirstInvisibleModel() const; - uint32 GetFirstVisibleModel() const; + CreatureModel const* GetModelByIdx(uint32 idx) const; + CreatureModel const* GetRandomValidModel() const; + CreatureModel const* GetFirstValidModel() const; + CreatureModel const* GetModelWithDisplayId(uint32 displayId) const; + CreatureModel const* GetFirstInvisibleModel() const; + CreatureModel const* GetFirstVisibleModel() const; // helpers SkillType GetRequiredLootSkill() const diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp index 67fa6c00554..d8ab46e6b07 100644 --- a/src/server/game/Entities/Pet/Pet.cpp +++ b/src/server/game/Entities/Pet/Pet.cpp @@ -1778,9 +1778,9 @@ Player* Pet::GetOwner() const return Minion::GetOwner()->ToPlayer(); } -void Pet::SetDisplayId(uint32 modelId) +void Pet::SetDisplayId(uint32 modelId, float displayScale /*= 1.f*/) { - Guardian::SetDisplayId(modelId); + Guardian::SetDisplayId(modelId, displayScale); if (!isControlled()) return; diff --git a/src/server/game/Entities/Pet/Pet.h b/src/server/game/Entities/Pet/Pet.h index e411d2251af..f82c88e6b44 100644 --- a/src/server/game/Entities/Pet/Pet.h +++ b/src/server/game/Entities/Pet/Pet.h @@ -52,7 +52,7 @@ class TC_GAME_API Pet : public Guardian void AddToWorld() override; void RemoveFromWorld() override; - void SetDisplayId(uint32 modelId) override; + void SetDisplayId(uint32 modelId, float displayScale = 1.f) override; PetType getPetType() const { return m_petType; } void setPetType(PetType type) { m_petType = type; } diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index bb6a3e9dc5d..87d8bad3de6 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -10317,9 +10317,11 @@ bool Unit::IsPolymorphed() const return spellInfo->GetSpellSpecific() == SPELL_SPECIFIC_MAGE_POLYMORPH; } -void Unit::SetDisplayId(uint32 modelId) +void Unit::SetDisplayId(uint32 modelId, float displayScale /*= 1.f*/) { SetUInt32Value(UNIT_FIELD_DISPLAYID, modelId); + SetFloatValue(UNIT_FIELD_DISPLAY_SCALE, displayScale); + // Set Gender by modelId if (CreatureModelInfo const* minfo = sObjectMgr->GetCreatureModelInfo(modelId)) SetByteValue(UNIT_FIELD_BYTES_0, UNIT_BYTES_0_OFFSET_GENDER, minfo->gender); @@ -10342,7 +10344,7 @@ void Unit::RestoreDisplayId(bool ignorePositiveAurasPreventingMounting /*= false if (!ignorePositiveAurasPreventingMounting) handledAura = (*i); else if (CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate((*i)->GetMiscValue())) - if (!IsDisallowedMountForm((*i)->GetId(), FORM_NONE, sObjectMgr->ChooseDisplayId(ci))) + if (!IsDisallowedMountForm((*i)->GetId(), FORM_NONE, ObjectMgr::ChooseDisplayId(ci)->CreatureDisplayID)) handledAura = (*i); } // prefer negative auras @@ -13732,7 +13734,7 @@ void Unit::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target) if (cinfo->flags_extra & CREATURE_FLAG_EXTRA_TRIGGER) if (target->IsGameMaster()) - displayId = cinfo->GetFirstVisibleModel(); + displayId = cinfo->GetFirstVisibleModel()->CreatureDisplayID; } *data << uint32(displayId); diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 77e23462cd8..ad8ecf37733 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1684,10 +1684,11 @@ class TC_GAME_API Unit : public WorldObject void UpdateInterruptMask(); uint32 GetDisplayId() const { return GetUInt32Value(UNIT_FIELD_DISPLAYID); } - virtual void SetDisplayId(uint32 modelId); + virtual void SetDisplayId(uint32 modelId, float displayScale = 1.f); uint32 GetNativeDisplayId() const { return GetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID); } + float GetNativeDisplayScale() const { return GetFloatValue(UNIT_FIELD_NATIVE_X_DISPLAY_SCALE); } void RestoreDisplayId(bool ignorePositiveAurasPreventingMounting = false); - void SetNativeDisplayId(uint32 modelId) { SetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID, modelId); } + void SetNativeDisplayId(uint32 displayId, float displayScale = 1.f) { SetUInt32Value(UNIT_FIELD_NATIVEDISPLAYID, displayId); SetFloatValue(UNIT_FIELD_NATIVE_X_DISPLAY_SCALE, displayScale); } void setTransForm(uint32 spellid) { m_transform = spellid;} uint32 getTransForm() const { return m_transform;} |
