mirror of
https://github.com/mangosfour/server.git
synced 2025-12-16 04:37:00 +00:00
[11964] Implement new conditions system
Tree-like design idea by Faramir118, thanks for that! * Add `conditions` table to store conditions. * REPLACE current handling of conditions for the *_loot_template tables Convert the old conditions in *_loot_template to the new system by SQL-Queries * ADD support for new conditions to gossip_menu and gossip_menu_option. If for these tables no condition_id (new system) is provided, the old conditions will still be used * Add a small helper python script to contrib/convertConditions, see README there for details * Add new command to reload the `conditions` table (.reload conditions) * Add two Meta-Condition types CONDITION_AND (-1) and CONDITION_OR (-2) which are used as: value1 (as condition_entry) AND / OR value2 (as condition_entry) With these meta-conditions it is possible to create tree like and very complicated combined conditions (like HasAura && (HasItem || HasQuest)) NOTE about conversion: For easier convertion all the old table data is still preserved, but will be removed eventually (within a circle of the moon approximately) The python script will not create an optimal initial fill of the `conditions` table. You might want to tweak it manually or suggest some optimized algorithm :) Signed-off-by: Schmoozerd <schmoozerd@scriptdev2.com>
This commit is contained in:
parent
f3b5e1e4bc
commit
8c29893310
18 changed files with 729 additions and 132 deletions
|
|
@ -97,8 +97,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
|
||||
QueryResult *result = WorldDatabase.PQuery("SELECT entry, item, ChanceOrQuestChance, groupid, mincountOrRef, maxcount, condition_id FROM %s",GetName());
|
||||
|
||||
if (result)
|
||||
{
|
||||
|
|
@ -115,9 +115,7 @@ void LootStore::LoadLootTable()
|
|||
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 conditionId = fields[6].GetUInt16();
|
||||
|
||||
if (maxcount > std::numeric_limits<uint8>::max())
|
||||
{
|
||||
|
|
@ -125,21 +123,22 @@ void LootStore::LoadLootTable()
|
|||
continue; // error already printed to log/console.
|
||||
}
|
||||
|
||||
if (mincountOrRef < 0 && condition != CONDITION_NONE)
|
||||
if (mincountOrRef < 0 && conditionId)
|
||||
{
|
||||
sLog.outErrorDb("Table '%s' entry %u mincountOrRef %i < 0 and not allowed has condition, skipped", GetName(), entry, mincountOrRef);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!PlayerCondition::IsValid(condition,cond_value1, cond_value2))
|
||||
if (conditionId)
|
||||
{
|
||||
sLog.outErrorDb("... in table '%s' entry %u item %u", GetName(), entry, item);
|
||||
continue; // error already printed to log/console.
|
||||
const PlayerCondition* condition = sConditionStorage.LookupEntry<PlayerCondition>(conditionId);
|
||||
if (!condition)
|
||||
{
|
||||
sLog.outErrorDb("Table `%s` for entry %u, item %u has condition_id %u that does not exist in `conditions`, ignoring", GetName(), entry,item, conditionId);
|
||||
conditionId = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// (condition + cond_value1/2) are converted into single conditionId
|
||||
uint16 conditionId = sObjectMgr.GetConditionId(condition, cond_value1, cond_value2);
|
||||
|
||||
LootStoreItem storeitem = LootStoreItem(item, chanceOrQuestChance, group, conditionId, mincountOrRef, maxcount);
|
||||
|
||||
if (!storeitem.IsValid(*this,entry)) // Validity checks
|
||||
|
|
@ -363,7 +362,7 @@ LootItem::LootItem(uint32 itemid_, uint32 count_, uint32 randomSuffix_, int32 ra
|
|||
bool LootItem::AllowedForPlayer(Player const * player) const
|
||||
{
|
||||
// DB conditions check
|
||||
if (!sObjectMgr.IsPlayerMeetToCondition(player,conditionId))
|
||||
if (conditionId && !sObjectMgr.IsPlayerMeetToNEWCondition(player, conditionId))
|
||||
return false;
|
||||
|
||||
ItemPrototype const *pProto = ObjectMgr::GetItemPrototype(itemid);
|
||||
|
|
@ -396,7 +395,7 @@ bool LootItem::AllowedForPlayer(Player const * player) const
|
|||
LootSlotType LootItem::GetSlotTypeForSharedLoot(PermissionTypes permission, Player* viewer, bool condition_ok /*= false*/) const
|
||||
{
|
||||
// ignore looted, FFA (each player get own copy) and not allowed items
|
||||
if (is_looted || freeforall || conditionId && !condition_ok || !AllowedForPlayer(viewer))
|
||||
if (is_looted || freeforall || (conditionId && !condition_ok) || !AllowedForPlayer(viewer))
|
||||
return MAX_LOOT_SLOT_TYPE;
|
||||
|
||||
switch (permission)
|
||||
|
|
@ -697,7 +696,7 @@ LootItem* Loot::LootItemInSlot(uint32 lootSlot, Player* player, QuestItem **qite
|
|||
}
|
||||
}
|
||||
}
|
||||
else if(item->conditionId)
|
||||
else if (item->conditionId)
|
||||
{
|
||||
QuestItemMap::const_iterator itr = m_playerNonQuestNonFFAConditionalItems.find(player->GetGUIDLow());
|
||||
if (itr != m_playerNonQuestNonFFAConditionalItems.end())
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue