feat(Core/Loot): Implement player_loot_template (#9198)

* Also fix AV player loot
This commit is contained in:
Skjalf
2021-11-17 08:07:21 -03:00
committed by GitHub
parent 0c5b307e7d
commit 39425e0c1f
7 changed files with 116 additions and 12 deletions

View File

@@ -763,7 +763,7 @@ bool ConditionMgr::CanHaveSourceGroupSet(ConditionSourceType sourceType) const
{
return (sourceType == CONDITION_SOURCE_TYPE_CREATURE_LOOT_TEMPLATE || sourceType == CONDITION_SOURCE_TYPE_DISENCHANT_LOOT_TEMPLATE || sourceType == CONDITION_SOURCE_TYPE_FISHING_LOOT_TEMPLATE || sourceType == CONDITION_SOURCE_TYPE_GAMEOBJECT_LOOT_TEMPLATE || sourceType == CONDITION_SOURCE_TYPE_ITEM_LOOT_TEMPLATE || sourceType == CONDITION_SOURCE_TYPE_MAIL_LOOT_TEMPLATE || sourceType == CONDITION_SOURCE_TYPE_MILLING_LOOT_TEMPLATE ||
sourceType == CONDITION_SOURCE_TYPE_PICKPOCKETING_LOOT_TEMPLATE || sourceType == CONDITION_SOURCE_TYPE_PROSPECTING_LOOT_TEMPLATE || sourceType == CONDITION_SOURCE_TYPE_REFERENCE_LOOT_TEMPLATE || sourceType == CONDITION_SOURCE_TYPE_SKINNING_LOOT_TEMPLATE || sourceType == CONDITION_SOURCE_TYPE_SPELL_LOOT_TEMPLATE || sourceType == CONDITION_SOURCE_TYPE_GOSSIP_MENU || sourceType == CONDITION_SOURCE_TYPE_GOSSIP_MENU_OPTION || sourceType == CONDITION_SOURCE_TYPE_VEHICLE_SPELL ||
sourceType == CONDITION_SOURCE_TYPE_SPELL_IMPLICIT_TARGET || sourceType == CONDITION_SOURCE_TYPE_SPELL_CLICK_EVENT || sourceType == CONDITION_SOURCE_TYPE_SMART_EVENT || sourceType == CONDITION_SOURCE_TYPE_NPC_VENDOR);
sourceType == CONDITION_SOURCE_TYPE_SPELL_IMPLICIT_TARGET || sourceType == CONDITION_SOURCE_TYPE_SPELL_CLICK_EVENT || sourceType == CONDITION_SOURCE_TYPE_SMART_EVENT || sourceType == CONDITION_SOURCE_TYPE_NPC_VENDOR || sourceType == CONDITION_SOURCE_TYPE_PLAYER_LOOT_TEMPLATE);
}
bool ConditionMgr::CanHaveSourceIdSet(ConditionSourceType sourceType) const
@@ -876,6 +876,7 @@ void ConditionMgr::LoadConditions(bool isReload)
LootTemplates_Disenchant.ResetConditions();
LootTemplates_Prospecting.ResetConditions();
LootTemplates_Spell.ResetConditions();
LootTemplates_Player.ResetConditions();
LOG_INFO("server.loading", "Re-Loading `gossip_menu` Table for Conditions!");
sObjectMgr->LoadGossipMenu();
@@ -1003,7 +1004,7 @@ void ConditionMgr::LoadConditions(bool isReload)
cond->ErrorTextId = 0;
}
if (cond->SourceGroup)
if (cond->SourceGroup || cond->SourceType == CONDITION_SOURCE_TYPE_PLAYER_LOOT_TEMPLATE)
{
bool valid = false;
// handle grouped conditions
@@ -1084,6 +1085,11 @@ void ConditionMgr::LoadConditions(bool isReload)
++count;
continue;
}
case CONDITION_SOURCE_TYPE_PLAYER_LOOT_TEMPLATE:
{
valid = addToLootTemplate(cond, LootTemplates_Player.GetLootForConditionFill(cond->SourceGroup));
break;
}
default:
break;
}
@@ -1615,6 +1621,23 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
}
break;
}
case CONDITION_SOURCE_TYPE_PLAYER_LOOT_TEMPLATE:
{
if (!LootTemplates_Player.HaveLootFor(cond->SourceGroup))
{
LOG_ERROR("sql.sql", "SourceGroup %u in `condition` table, does not exist in `player_loot_template`, ignoring.", cond->SourceGroup);
return false;
}
LootTemplate* loot = LootTemplates_Player.GetLootForConditionFill(cond->SourceGroup);
ItemTemplate const* pItemProto = sObjectMgr->GetItemTemplate(cond->SourceEntry);
if (!pItemProto && !loot->isReference(cond->SourceEntry))
{
LOG_ERROR("sql.sql", "SourceType %u, SourceEntry %u in `condition` table, does not exist in `item_template`, ignoring.", cond->SourceType, cond->SourceEntry);
return false;
}
break;
}
case CONDITION_SOURCE_TYPE_GOSSIP_MENU:
case CONDITION_SOURCE_TYPE_GOSSIP_MENU_OPTION:
case CONDITION_SOURCE_TYPE_SMART_EVENT:

View File

@@ -147,7 +147,8 @@ enum ConditionSourceType
CONDITION_SOURCE_TYPE_TERRAIN_SWAP = 25, // don't use on 3.3.5a
CONDITION_SOURCE_TYPE_PHASE = 26, // don't use on 3.3.5a
CONDITION_SOURCE_TYPE_GRAVEYARD = 27, // don't use on 3.3.5a
CONDITION_SOURCE_TYPE_MAX = 28 // placeholder
CONDITION_SOURCE_TYPE_PLAYER_LOOT_TEMPLATE = 28,
CONDITION_SOURCE_TYPE_MAX = 29 // placeholder
};
enum RelationType

View File

@@ -7706,15 +7706,7 @@ void Player::SendLoot(ObjectGuid guid, LootType loot_type)
uint32 pLevel = bones->loot.gold;
bones->loot.clear();
// Xinef: For AV Achievement
if (Battleground* bg = GetBattleground())
{
if (bg->GetBgTypeID(true) == BATTLEGROUND_AV)
loot->FillLoot(1, LootTemplates_Creature, this, true);
}
// Xinef: For wintergrasp Quests
else if (GetZoneId() == AREA_WINTERGRASP)
loot->FillLoot(1, LootTemplates_Creature, this, true);
loot->FillLoot(GetTeamId(), LootTemplates_Player, this, true);
// It may need a better formula
// Now it works like this: lvl10: ~6copper, lvl70: ~9silver

View File

@@ -51,6 +51,7 @@ LootStore LootTemplates_Prospecting("prospecting_loot_template", "item entry
LootStore LootTemplates_Reference("reference_loot_template", "reference id", false);
LootStore LootTemplates_Skinning("skinning_loot_template", "creature skinning id", true);
LootStore LootTemplates_Spell("spell_loot_template", "spell id (random item creating)", false);
LootStore LootTemplates_Player("player_loot_template", "team id", true);
// Selects invalid loot items to be removed from group possible entries (before rolling)
struct LootGroupInvalidSelector : public Acore::unary_function<LootStoreItem*, bool>
@@ -2252,6 +2253,27 @@ void LoadLootTemplates_Spell()
LOG_INFO("server.loading", " ");
}
void LoadLootTemplates_Player()
{
LOG_INFO("server.loading", "Loading player loot templates...");
uint32 oldMSTime = getMSTime();
LootIdSet lootIdSet;
uint32 count = LootTemplates_Player.LoadAndCollectLootIds(lootIdSet);
if (count)
{
LOG_INFO("server.loading", ">> Loaded %u player loot templates in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
}
else
{
LOG_ERROR("sql.sql", ">> Loaded 0 player loot templates. DB table `player_loot_template` is empty");
}
LOG_INFO("server.loading", " ");
}
void LoadLootTemplates_Reference()
{
LOG_INFO("server.loading", "Loading reference loot templates...");

View File

@@ -421,6 +421,7 @@ extern LootStore LootTemplates_Skinning;
extern LootStore LootTemplates_Disenchant;
extern LootStore LootTemplates_Prospecting;
extern LootStore LootTemplates_Spell;
extern LootStore LootTemplates_Player;
void LoadLootTemplates_Creature();
void LoadLootTemplates_Fishing();
@@ -436,6 +437,8 @@ void LoadLootTemplates_Prospecting();
void LoadLootTemplates_Spell();
void LoadLootTemplates_Reference();
void LoadLootTemplates_Player();
inline void LoadLootTables()
{
LoadLootTemplates_Creature();
@@ -451,6 +454,8 @@ inline void LoadLootTables()
LoadLootTemplates_Spell();
LoadLootTemplates_Reference();
LoadLootTemplates_Player();
}
#endif

View File

@@ -156,6 +156,7 @@ public:
{ "spell_target_position", HandleReloadSpellTargetPositionCommand, SEC_ADMINISTRATOR, Console::Yes },
{ "spell_threats", HandleReloadSpellThreatsCommand, SEC_ADMINISTRATOR, Console::Yes },
{ "spell_group_stack_rules", HandleReloadSpellGroupStackRulesCommand, SEC_ADMINISTRATOR, Console::Yes },
{ "player_loot_template", HandleReloadLootTemplatesPlayerCommand, SEC_ADMINISTRATOR, Console::Yes },
{ "acore_string", HandleReloadAcoreStringCommand, SEC_ADMINISTRATOR, Console::Yes },
{ "warden_action", HandleReloadWardenactionCommand, SEC_ADMINISTRATOR, Console::Yes },
{ "waypoint_scripts", HandleReloadWpScriptsCommand, SEC_ADMINISTRATOR, Console::Yes },
@@ -658,6 +659,16 @@ public:
return true;
}
static bool HandleReloadLootTemplatesPlayerCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading Loot Tables... (`player_loot_template`)");
LoadLootTemplates_Player();
LootTemplates_Player.CheckLootRefs();
handler->SendGlobalGMSysMessage("DB table `player_loot_template` reloaded.");
sConditionMgr->LoadConditions(true);
return true;
}
static bool HandleReloadAcoreStringCommand(ChatHandler* handler)
{
LOG_INFO("server.loading", "Re-Loading acore_string Table!");