diff options
author | maximius <none@none> | 2009-10-28 16:31:19 -0700 |
---|---|---|
committer | maximius <none@none> | 2009-10-28 16:31:19 -0700 |
commit | f4d76b8216c911901e8a13996c55128bbfa4b08e (patch) | |
tree | d1db8d946c29cb9bdca5e0bf4d0da0a029f46d45 /src | |
parent | d5b8ad0080d45c2f02ef5a4fdd4d8853da286b6d (diff) |
*Implement new LootMode system, and add some basic support in boss_sartharion.cpp. Requires database support.
--HG--
branch : trunk
Diffstat (limited to 'src')
-rw-r--r-- | src/bindings/scripts/scripts/northrend/obsidian_sanctum/boss_sartharion.cpp | 17 | ||||
-rw-r--r-- | src/game/Creature.cpp | 2 | ||||
-rw-r--r-- | src/game/Creature.h | 8 | ||||
-rw-r--r-- | src/game/GameObject.cpp | 2 | ||||
-rw-r--r-- | src/game/GameObject.h | 9 | ||||
-rw-r--r-- | src/game/LootMgr.cpp | 48 | ||||
-rw-r--r-- | src/game/LootMgr.h | 11 | ||||
-rw-r--r-- | src/game/Player.cpp | 4 | ||||
-rw-r--r-- | src/game/SharedDefines.h | 3 |
9 files changed, 75 insertions, 29 deletions
diff --git a/src/bindings/scripts/scripts/northrend/obsidian_sanctum/boss_sartharion.cpp b/src/bindings/scripts/scripts/northrend/obsidian_sanctum/boss_sartharion.cpp index d40ed2dc2e7..d7557370174 100644 --- a/src/bindings/scripts/scripts/northrend/obsidian_sanctum/boss_sartharion.cpp +++ b/src/bindings/scripts/scripts/northrend/obsidian_sanctum/boss_sartharion.cpp @@ -214,6 +214,8 @@ struct TRINITY_DLL_DECL boss_sartharionAI : public ScriptedAI if (m_creature->HasAura(SPELL_TWILIGHT_REVENGE)) m_creature->RemoveAurasDueToSpell(SPELL_TWILIGHT_REVENGE); + + m_creature->ResetLootMode(); } void JustReachedHome() @@ -247,6 +249,18 @@ struct TRINITY_DLL_DECL boss_sartharionAI : public ScriptedAI DoScriptText(RAND(SAY_SARTHARION_SLAY_1,SAY_SARTHARION_SLAY_2,SAY_SARTHARION_SLAY_3), m_creature); } + // m_creature->ResetLootMode() is called from Reset() + // AddDrakeLootMode() should only ever be called from FetchDragons(), which is called from Aggro() + void AddDrakeLootMode() + { + if (m_creature->HasLootMode(4)) // Has two Drake loot modes + m_creature->AddLootMode(8); // Add 3rd Drake loot mode + else if (m_creature->HasLootMode(2)) // Has one Drake loot mode + m_creature->AddLootMode(4); // Add 2nd Drake loot mode + else // Has no Drake loot modes + m_creature->AddLootMode(2); // Add 1st Drake loot mode + } + void FetchDragons() { Unit* pTene = Unit::GetUnit(*m_creature, pInstance->GetData64(DATA_TENEBRON)); @@ -258,6 +272,7 @@ struct TRINITY_DLL_DECL boss_sartharionAI : public ScriptedAI if (pTene && pTene->isAlive() && !pTene->getVictim()) { + AddDrakeLootMode(); bCanUseWill = true; pTene->GetMotionMaster()->MovePoint(POINT_ID_INIT, m_aTene[0].m_fX, m_aTene[0].m_fY, m_aTene[0].m_fZ); @@ -267,6 +282,7 @@ struct TRINITY_DLL_DECL boss_sartharionAI : public ScriptedAI if (pShad && pShad->isAlive() && !pShad->getVictim()) { + AddDrakeLootMode(); bCanUseWill = true; pShad->GetMotionMaster()->MovePoint(POINT_ID_INIT, m_aShad[0].m_fX, m_aShad[0].m_fY, m_aShad[0].m_fZ); @@ -276,6 +292,7 @@ struct TRINITY_DLL_DECL boss_sartharionAI : public ScriptedAI if (pVesp && pVesp->isAlive() && !pVesp->getVictim()) { + AddDrakeLootMode(); bCanUseWill = true; pVesp->GetMotionMaster()->MovePoint(POINT_ID_INIT, m_aVesp[0].m_fX, m_aVesp[0].m_fY, m_aVesp[0].m_fZ); diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp index 82afa402ff7..6b85cdfd887 100644 --- a/src/game/Creature.cpp +++ b/src/game/Creature.cpp @@ -157,6 +157,8 @@ m_creatureInfo(NULL), m_reactState(REACT_AGGRESSIVE), m_formation(NULL) m_SightDistance = sWorld.getConfig(CONFIG_SIGHT_MONSTER); m_CombatDistance = 0;//MELEE_RANGE; + + ResetLootMode(); // restore default loot mode } Creature::~Creature() diff --git a/src/game/Creature.h b/src/game/Creature.h index 5fbe4a07a28..2ee2a3997d7 100644 --- a/src/game/Creature.h +++ b/src/game/Creature.h @@ -621,6 +621,13 @@ class TRINITY_DLL_SPEC Creature : public Unit void SetLootRecipient (Unit* unit); void AllLootRemovedFromCorpse(); + uint16 GetLootMode() { return m_LootMode; } + bool HasLootMode(uint16 lootMode) { return m_LootMode & lootMode; } + void SetLootMode(uint16 lootMode) { m_LootMode = lootMode; } + void AddLootMode(uint16 lootMode) { m_LootMode |= lootMode; } + void RemoveLootMode(uint16 lootMode) { m_LootMode &= ~lootMode; } + void ResetLootMode() { m_LootMode = DEFAULT_LOOT_MODE; } + SpellEntry const *reachWithSpellAttack(Unit *pVictim); SpellEntry const *reachWithSpellCure(Unit *pVictim); @@ -778,6 +785,7 @@ class TRINITY_DLL_SPEC Creature : public Unit CreatureInfo const* m_creatureInfo; // in heroic mode can different from ObjMgr::GetCreatureTemplate(GetEntry()) CreatureData const* m_creatureData; + uint16 m_LootMode; // bitmask, default DEFAULT_LOOT_MODE, determines what loot will be lootable private: //WaypointMovementGenerator vars uint32 m_waypointID; diff --git a/src/game/GameObject.cpp b/src/game/GameObject.cpp index 1d1b56f0bef..f95fb9643d8 100644 --- a/src/game/GameObject.cpp +++ b/src/game/GameObject.cpp @@ -60,6 +60,8 @@ GameObject::GameObject() : WorldObject(), m_goValue(new GameObjectValue) m_DBTableGuid = 0; m_rotation = 0; + + ResetLootMode(); // restore default loot mode } GameObject::~GameObject() diff --git a/src/game/GameObject.h b/src/game/GameObject.h index 1386e220317..232b711bcf9 100644 --- a/src/game/GameObject.h +++ b/src/game/GameObject.h @@ -672,6 +672,13 @@ class TRINITY_DLL_SPEC GameObject : public WorldObject LootState getLootState() const { return m_lootState; } void SetLootState(LootState s) { m_lootState = s; } + uint16 GetLootMode() { return m_LootMode; } + bool HasLootMode(uint16 lootMode) { return m_LootMode & lootMode; } + void SetLootMode(uint16 lootMode) { m_LootMode = lootMode; } + void AddLootMode(uint16 lootMode) { m_LootMode |= lootMode; } + void RemoveLootMode(uint16 lootMode) { m_LootMode &= ~lootMode; } + void ResetLootMode() { m_LootMode = DEFAULT_LOOT_MODE; } + void AddToSkillupList(uint32 PlayerGuidLow) { m_SkillupList.push_back(PlayerGuidLow); } bool IsInSkillupList(uint32 PlayerGuidLow) const { @@ -738,6 +745,8 @@ class TRINITY_DLL_SPEC GameObject : public WorldObject GameObjectValue * const m_goValue; uint64 m_rotation; + + uint16 m_LootMode; // bitmask, default DEFAULT_LOOT_MODE, determines what loot will be lootable private: void SwitchDoorOrButton(bool activate, bool alternative = false); diff --git a/src/game/LootMgr.cpp b/src/game/LootMgr.cpp index 29c19a4eecf..e7337b78333 100644 --- a/src/game/LootMgr.cpp +++ b/src/game/LootMgr.cpp @@ -57,11 +57,11 @@ class LootTemplate::LootGroup // A set of loot def bool HasQuestDrop() const; // True if group includes at least 1 quest drop entry bool HasQuestDropForPlayer(Player const * player) const; // The same for active quests of the player - void Process(Loot& loot) const; // Rolls an item from the group (if any) and adds the item to the loot + void Process(Loot& loot, uint16 lootMode) const; // Rolls an item from the group (if any) and adds the item to the loot float RawTotalChance() const; // Overall chance for the group (without equal chanced items) float TotalChance() const; // Overall chance for the group - void Verify(LootStore const& lootstore, uint32 id, uint32 group_id) const; + void Verify(LootStore const& lootstore, uint32 id, uint8 group_id) const; void CollectLootIds(LootIdSet& set) const; void CheckLootRefs(LootTemplateMap const& store, LootIdSet* ref_set) const; private: @@ -99,8 +99,8 @@ void LootStore::LoadLootTable() sLog.outString( "%s :", GetName()); - // 0 1 2 3 4 5 6 7 8 - QueryResult *result = WorldDatabase.PQuery("SELECT entry, item, ChanceOrQuestChance, groupid, mincountOrRef, maxcount, lootcondition, condition_value1, condition_value2 FROM %s",GetName()); + // 0 1 2 3 4 5 6 7 8 9 + QueryResult *result = WorldDatabase.PQuery("SELECT entry, item, ChanceOrQuestChance, lootmode, groupid, mincountOrRef, maxcount, lootcondition, condition_value1, condition_value2 FROM %s",GetName()); if (result) { @@ -114,12 +114,13 @@ void LootStore::LoadLootTable() uint32 entry = fields[0].GetUInt32(); uint32 item = fields[1].GetUInt32(); float chanceOrQuestChance = fields[2].GetFloat(); - uint8 group = fields[3].GetUInt8(); - int32 mincountOrRef = fields[4].GetInt32(); - uint32 maxcount = fields[5].GetUInt32(); - ConditionType condition = (ConditionType)fields[6].GetUInt8(); - uint32 cond_value1 = fields[7].GetUInt32(); - uint32 cond_value2 = fields[8].GetUInt32(); + uint16 lootmode = fields[3].GetUInt16(); + uint8 group = fields[4].GetUInt8(); + int32 mincountOrRef = fields[5].GetInt32(); + uint32 maxcount = fields[6].GetUInt32(); + ConditionType condition = (ConditionType)fields[7].GetUInt8(); + uint32 cond_value1 = fields[8].GetUInt32(); + uint32 cond_value2 = fields[9].GetUInt32(); if(maxcount > std::numeric_limits<uint8>::max()) { @@ -136,7 +137,7 @@ void LootStore::LoadLootTable() // (condition + cond_value1/2) are converted into single conditionId uint16 conditionId = objmgr.GetConditionId(condition, cond_value1, cond_value2); - LootStoreItem storeitem = LootStoreItem(item, chanceOrQuestChance, group, conditionId, mincountOrRef, maxcount); + LootStoreItem storeitem = LootStoreItem(item, chanceOrQuestChance, lootmode, group, conditionId, mincountOrRef, maxcount); if (!storeitem.IsValid(*this,entry)) // Validity checks continue; @@ -387,7 +388,7 @@ void Loot::AddItem(LootStoreItem const & item) } // Calls processor of corresponding LootTemplate (which handles everything including references) -void Loot::FillLoot(uint32 loot_id, LootStore const& store, Player* loot_owner, bool personal) +void Loot::FillLoot(uint32 loot_id, LootStore const& store, Player* loot_owner, bool personal, uint16 lootMode /*= DEFAULT_LOOT_MODE*/) { // Must be provided if(!loot_owner) @@ -404,7 +405,7 @@ void Loot::FillLoot(uint32 loot_id, LootStore const& store, Player* loot_owner, items.reserve(MAX_NR_LOOT_ITEMS); quest_items.reserve(MAX_NR_QUEST_ITEMS); - tab->Process(*this, store,store.IsRatesAllowed ()); // Processing is done there, callback via Loot::AddItem() + tab->Process(*this, store, store.IsRatesAllowed(), lootMode); // Processing is done there, callback via Loot::AddItem() // Setting access rights for group loot case Group * pGroup=loot_owner->GetGroup(); @@ -857,10 +858,10 @@ bool LootTemplate::LootGroup::HasQuestDropForPlayer(Player const * player) const } // Rolls an item from the group (if any takes its chance) and adds the item to the loot -void LootTemplate::LootGroup::Process(Loot& loot) const +void LootTemplate::LootGroup::Process(Loot& loot, uint16 lootMode) const { LootStoreItem const * item = Roll(); - if (item != NULL) + if (item != NULL && item->lootmode & lootMode) // only add this item if roll succeeds and the mode matches loot.AddItem(*item); } @@ -887,7 +888,7 @@ float LootTemplate::LootGroup::TotalChance() const return result; } -void LootTemplate::LootGroup::Verify(LootStore const& lootstore, uint32 id, uint32 group_id) const +void LootTemplate::LootGroup::Verify(LootStore const& lootstore, uint32 id, uint8 group_id) const { float chance = RawTotalChance(); if (chance > 101.0f) // TODO: replace with 100% when DBs will be ready @@ -944,20 +945,23 @@ void LootTemplate::AddEntry(LootStoreItem& item) } // Rolls for every item in the template and adds the rolled items the the loot -void LootTemplate::Process(Loot& loot, LootStore const& store, bool rate, uint8 groupId) const +void LootTemplate::Process(Loot& loot, LootStore const& store, bool rate, uint16 lootMode, uint8 groupId) const { if (groupId) // Group reference uses own processing of the group { if (groupId > Groups.size()) return; // Error message already printed at loading stage - Groups[groupId-1].Process(loot); + Groups[groupId-1].Process(loot, lootMode); return; } // Rolling non-grouped items for (LootStoreItemList::const_iterator i = Entries.begin() ; i != Entries.end() ; ++i ) { + if (i->lootmode &~ lootMode) // Do not add if mode mismatch + continue; + if (!i->Roll(rate)) continue; // Bad luck for the entry @@ -968,16 +972,16 @@ void LootTemplate::Process(Loot& loot, LootStore const& store, bool rate, uint8 if(!Referenced) continue; // Error message already printed at loading stage - for (uint32 loop=0; loop < i->maxcount; ++loop )// Ref multiplicator - Referenced->Process(loot, store, rate, i->group); + for (uint32 loop=0; loop < i->maxcount; ++loop) // Ref multiplicator + Referenced->Process(loot, store, rate, lootMode, i->group); } else // Plain entries (not a reference, not grouped) loot.AddItem(*i); // Chance is already checked, just add } // Now processing groups - for (LootGroups::const_iterator i = Groups.begin( ) ; i != Groups.end( ) ; ++i ) - i->Process(loot); + for (LootGroups::const_iterator i = Groups.begin(); i != Groups.end(); ++i) + i->Process(loot, lootMode); } // True if template includes at least 1 quest drop entry diff --git a/src/game/LootMgr.h b/src/game/LootMgr.h index c629977ea67..be20c57ec9a 100644 --- a/src/game/LootMgr.h +++ b/src/game/LootMgr.h @@ -81,14 +81,15 @@ struct LootStoreItem float chance; // always positive, chance to drop for both quest and non-quest items, chance to be used for refs int32 mincountOrRef; // mincount for drop items (positive) or minus referenced TemplateleId (negative) uint8 group :7; + uint16 lootmode; bool needs_quest :1; // quest drop (negative ChanceOrQuestChance in DB) uint8 maxcount :8; // max drop count for the item (mincountOrRef positive) or Ref multiplicator (mincountOrRef negative) uint16 conditionId :16; // additional loot condition Id // Constructor, converting ChanceOrQuestChance -> (chance, needs_quest) // displayid is filled in IsValid() which must be called after - LootStoreItem(uint32 _itemid, float _chanceOrQuestChance, int8 _group, uint8 _conditionId, int32 _mincountOrRef, uint8 _maxcount) - : itemid(_itemid), chance(fabs(_chanceOrQuestChance)), mincountOrRef(_mincountOrRef), + LootStoreItem(uint32 _itemid, float _chanceOrQuestChance, uint8 _group, uint16 _lootmode, uint8 _conditionId, int32 _mincountOrRef, uint8 _maxcount) + : itemid(_itemid), chance(fabs(_chanceOrQuestChance)), mincountOrRef(_mincountOrRef), lootmode(_lootmode), group(_group), needs_quest(_chanceOrQuestChance < 0), maxcount(_maxcount), conditionId(_conditionId) {} @@ -183,12 +184,12 @@ class LootTemplate // Adds an entry to the group (at loading stage) void AddEntry(LootStoreItem& item); // Rolls for every item in the template and adds the rolled items the the loot - void Process(Loot& loot, LootStore const& store, bool rate, uint8 GroupId = 0) const; + void Process(Loot& loot, LootStore const& store, bool rate, uint16 lootMode, uint8 groupId = 0) const; // True if template includes at least 1 quest drop entry bool HasQuestDrop(LootTemplateMap const& store, uint8 GroupId = 0) const; // True if template includes at least 1 quest drop for an active quest of the player - bool HasQuestDropForPlayer(LootTemplateMap const& store, Player const * player, uint8 GroupId = 0) const; + bool HasQuestDropForPlayer(LootTemplateMap const& store, Player const * player, uint8 groupId = 0) const; // Checks integrity of the template void Verify(LootStore const& store, uint32 Id) const; @@ -285,7 +286,7 @@ struct Loot void RemoveLooter(uint64 GUID) { PlayersLooting.erase(GUID); } void generateMoneyLoot(uint32 minAmount, uint32 maxAmount); - void FillLoot(uint32 loot_id, LootStore const& store, Player* loot_owner, bool personal); + void FillLoot(uint32 loot_id, LootStore const& store, Player* loot_owner, bool personal, uint16 lootMode = DEFAULT_LOOT_MODE); // Inserts the item into the loot (called by LootTemplate processors) void AddItem(LootStoreItem const & item); diff --git a/src/game/Player.cpp b/src/game/Player.cpp index 09f6226e400..292cde60ea9 100644 --- a/src/game/Player.cpp +++ b/src/game/Player.cpp @@ -7856,7 +7856,7 @@ void Player::SendLoot(uint64 guid, LootType loot_type) { sLog.outDebug(" if(lootid)"); loot->clear(); - loot->FillLoot(lootid, LootTemplates_Gameobject, this, false); + loot->FillLoot(lootid, LootTemplates_Gameobject, this, false, go->GetLootMode()); } if (loot_type == LOOT_FISHING) @@ -7985,7 +7985,7 @@ void Player::SendLoot(uint64 guid, LootType loot_type) loot->clear(); if (uint32 lootid = creature->GetCreatureInfo()->lootid) - loot->FillLoot(lootid, LootTemplates_Creature, recipient, false); + loot->FillLoot(lootid, LootTemplates_Creature, recipient, false, creature->GetLootMode()); loot->generateMoneyLoot(creature->GetCreatureInfo()->mingold,creature->GetCreatureInfo()->maxgold); diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h index 8fbd95403c3..eaeb583d0e9 100644 --- a/src/game/SharedDefines.h +++ b/src/game/SharedDefines.h @@ -24,6 +24,9 @@ #include "Platform/Define.h" #include <cassert> +// default loot mode for creatures and gameobjects +#define DEFAULT_LOOT_MODE 1 + enum Gender { GENDER_MALE = 0, |