All pastes #957118 Raw Edit

My mangos loot modif

public diff v1 · immutable
#957118 ·published 2008-03-25 19:57 UTC
rendered paste body
Index: sql/mangos.sql===================================================================--- sql/mangos.sql	(revision 5478)+++ sql/mangos.sql	(working copy)@@ -659,6 +659,8 @@   `civilian` tinyint(3) unsigned NOT NULL default '0',   `flag1` int(11) unsigned default '0',   `lootid` int(10) unsigned NOT NULL default '0',+  `lootMinCount` tinyint(3) unsigned NOT NULL default '0',+  `lootMaxCount` tinyint(3) unsigned NOT NULL default '0',   `pickpocketloot` int(10) unsigned NOT NULL default '0',   `skinloot` int(10) unsigned NOT NULL default '0',   `resistance1` int(10) unsigned NOT NULL default '0',Index: sql/updates/5XXX_mangos_creature_template.sql===================================================================--- sql/updates/5478_mangos_creature_template.sql	(revision 0)+++ sql/updates/5478_mangos_creature_template.sql	(revision 0)@@ -0,0 +1,6 @@+ALTER TABLE creature_template ADD COLUMN lootMinCount tinyint(3) unsigned NOT NULL default '0' AFTER `lootid`;+ALTER TABLE creature_template ADD COLUMN lootMaxCount tinyint(3) unsigned NOT NULL default '0' AFTER `lootMinCount`;++INSERT INTO `mangos_string` (`entry`, `content_default`) values('580','Loot count range for creature entry #%u has been modified to (%u,%u)');+INSERT INTO `mangos_string` (`entry`, `content_default`) values('581','Invalid value for loot count range');+INSERT INTO `command` (`name`, `security`, `help`) values('setlootrange','3','Syntax: .setlootrange #max_count [#min_count]\r\n  Set the lootMaxCount and lootMinCount in creature_template for selected creature. min_count default is 0.');Index: src/game/Chat.cpp===================================================================--- src/game/Chat.cpp	(revision 5478)+++ src/game/Chat.cpp	(working copy)@@ -392,7 +392,7 @@         { "setvalue",    SEC_ADMINISTRATOR, &ChatHandler::HandleSetValue,                "",   NULL },         { "getvalue",    SEC_ADMINISTRATOR, &ChatHandler::HandleGetValue,                "",   NULL },         { "Mod32Value",  SEC_ADMINISTRATOR, &ChatHandler::HandleMod32Value,              "",   NULL },-+        { "setlootrange",SEC_ADMINISTRATOR, &ChatHandler::HandleSetLootRangeCommand,     "",   NULL },         { NULL,          0, NULL,                                        "",   NULL }     }; Index: src/game/Chat.h===================================================================--- src/game/Chat.h	(revision 5478)+++ src/game/Chat.h	(working copy)@@ -339,6 +339,7 @@         bool HandleRemoveQuest(const char * args);         bool HandleSaveAllCommand(const char* args);         bool HandleGetItemState(const char * args);+        bool HandleSetLootRangeCommand(const char* arg);          Player*   getSelectedPlayer();         Creature* getSelectedCreature();Index: src/game/Creature.h===================================================================--- src/game/Creature.h	(revision 5478)+++ src/game/Creature.h	(working copy)@@ -162,7 +162,7 @@     uint32  faction_H;     uint32  npcflag;     float   speed;-    float   scale;    +    float   scale;     uint32  rank;     float   mindmg;     float   maxdmg;@@ -184,6 +184,8 @@     bool    civilian;     uint32  flag1;     uint32  lootid;+    uint32  lootMinCount;+    uint32  lootMaxCount;     uint32  pickpocketLootId;     uint32  SkinLootId;     uint32  resistance1;Index: src/game/Language.h===================================================================--- src/game/Language.h	(revision 5478)+++ src/game/Language.h	(working copy)@@ -481,6 +481,8 @@     LANG_INVISIBLE_INVISIBLE            = 577,     LANG_INVISIBLE_VISIBLE              = 578,     LANG_SELECTED_TARGET_NOT_HAVE_VICTIM = 579,+    LANG_CREATURE_LOOT_RANGE_MODIFIED   = 580,+    LANG_CREATURE_LOOT_RANGE_INVALID    = 581,      // Battleground     LANG_BG_A_WINS                      = 600,Index: src/game/Level3.cpp===================================================================--- src/game/Level3.cpp	(revision 5478)+++ src/game/Level3.cpp	(working copy)@@ -44,6 +44,50 @@ #include "SystemConfig.h" #include "Config/ConfigEnv.h" ++++++bool ChatHandler::HandleSetLootRangeCommand(const char* args)+{+    if(!*args)+        return false;++    Creature* pCreature = getSelectedCreature();+    if (!pCreature)+    {+        PSendSysMessage(LANG_SELECT_CREATURE);+        return false;+    }++    char* pMax = strtok((char*)args, " ");+    char* pMin = strtok(NULL, " ");+    int iMax, iMin = 0;+    +    if ( !pMax )+    {+        SendSysMessage(LANG_CMD_SYNTAX);+        return false;+    }++    iMax = atoi( pMax );+    if ( pMin ) iMin = atoi( pMin );+    +    if ( iMax < iMin || iMax<0 || iMin<0 )+    {+        SendSysMessage( LANG_CREATURE_LOOT_RANGE_INVALID );+        return false;+    }++    WorldDatabase.PExecuteLog("UPDATE creature_template SET lootMinCount = '%d', lootMaxCount = '%d' WHERE entry = '%u'", iMin, iMax, pCreature->GetEntry());+    const_cast<CreatureInfo*>(pCreature->GetCreatureInfo())->lootMinCount = iMin;+    const_cast<CreatureInfo*>(pCreature->GetCreatureInfo())->lootMaxCount = iMax;+    PSendSysMessage( LANG_CREATURE_LOOT_RANGE_MODIFIED, pCreature->GetEntry(), iMin, iMax );+    return true;+}++ //reload commands bool ChatHandler::HandleReloadCommand(const char* arg) {Index: src/game/LootMgr.cpp===================================================================--- src/game/LootMgr.cpp	(revision 5478)+++ src/game/LootMgr.cpp	(working copy)@@ -74,7 +74,7 @@      sLog.outString( "%s :", tablename); -    //                                                 0        1       2              3                     4           5           6                          7                   8+    //                                                   0      1       2              3                4          5         6              7                8                9     QueryResult *result = WorldDatabase.PQuery("SELECT entry, item, ChanceOrRef, QuestChanceOrGroup, mincount, maxcount, freeforall, lootcondition, condition_value1, condition_value2 FROM %s",tablename);      if (result)@@ -254,6 +254,21 @@     LoadLootTable(LootTemplates_Prospecting,  "prospecting_loot_template"); } ++struct LootedItem {+    float value;+    LootStoreItem *item;++    LootedItem(LootStoreItem *_item, float _value) : value(_value), item(_item) {};+    bool operator<(const LootedItem &_2) const+    {+        return value < _2.value;+    }+};++typedef std::set<LootedItem> LootItems;++ struct HasChance {     struct GroupChance@@ -267,10 +282,12 @@     typedef std::vector<GroupChance> GroupChances;      LootStore* m_store;+    LootItems &m_items;+    int m_min, m_max;      GroupChances groupChance; -    explicit HasChance(LootStore* _store) : m_store(_store)+    explicit HasChance(LootStore* _store, LootItems &_items, int _min, int _max) : m_store(_store), m_items(_items), m_min(_min), m_max(_max)     {     } @@ -284,8 +301,43 @@         if (itm.questChanceOrGroup == 0)         {             // reference non group loot ( itm.chanceOrRef < 0) handled separatly-            if ( itm.chanceOrRef > 0 && roll_chance_f(itm.chanceOrRef * sWorld.getRate(RATE_DROP_ITEMS)) )-                return &itm;+            if ( itm.chanceOrRef > 0 )+            {+                float chance = rand_chance();+                float itm_chance = itm.chanceOrRef * sWorld.getRate(RATE_DROP_ITEMS);+                if ( m_min==0 && m_max==0  )+                {+                    //sLog.outDebug("HasChance: min=max=0 returning item as usual");+                    if ( chance < itm_chance ) +                        return &itm;+                    return NULL;+                }++                float n_chance = chance / itm_chance; // normalize chance+                if ( chance > itm_chance ) n_chance *= -1;+                //sLog.outDebug("HasChance: item %u has normalized chance: %f", itm.itemid, n_chance);+                if ( m_items.size() < m_min )+                {+                    //sLog.outDebug("HasChance: itemcount: %d, min: %d not reached", m_items.size(), m_min);+                    m_items.insert( LootedItem(&itm, n_chance) );+                }+                else if ( m_items.size() >= m_max || m_items.begin()->value < 0 )+                {+                    //sLog.outDebug("HasChance: itemcount: %d, max: %d reached or begin->value < 0 (%f)", m_items.size(), m_max, m_items.begin()->value);+                    // see if the lowest value in the set is lower than this, in this case replace the item+                    if ( m_items.begin()->value < n_chance )+                    {+                        //sLog.outDebug("HasChance: lowest value (%f) is smaller than chance %f, dropping %u, adding %u", m_items.begin()->value, n_chance, m_items.begin()->item->itemid, itm.itemid);+                        m_items.erase( m_items.begin() );+                        m_items.insert( LootedItem(&itm, n_chance) );+                    }+                } else {+                    //sLog.outDebug("HasChance:%d count. min (%d) reached, max (%d) not. Adding %u as ususal. %f<%f ? nchance: %f,min_nchance: %f", m_items.size(), m_min, m_max, itm.itemid, chance, itm_chance, n_chance, m_items.begin()->value);+                    if ( chance < itm_chance )+                        m_items.insert( LootedItem(&itm, n_chance) );+                }+                // return NULL, no to add item to lootlist yet+            }             return NULL;         } @@ -349,7 +401,7 @@     inline bool operator() ( LootStoreItem &itm )   { return roll_chance_i(itm.questChanceOrGroup); } }; -void FillLoot(Loot* loot, uint32 loot_id, LootStore& store, Player* loot_owner, bool referenced)+void FillLoot(Loot* loot, uint32 loot_id, LootStore& store, Player* loot_owner, bool referenced, int min, int max) {     LootStore::iterator tab = store.find(loot_id); @@ -363,7 +415,8 @@     loot->quest_items.reserve(min(tab->second.size(),MAX_NR_QUEST_ITEMS));      // fill loot with all normal and quest items that have a chance-    HasChance      hasChance(&store);+    LootItems items;+    HasChance      hasChance(&store, items, min, max);     HasQuestChance hasQuestChance;      for(LootStoreItemList::iterator item_iter = tab->second.begin(); item_iter != tab->second.end(); ++item_iter)@@ -383,7 +436,7 @@                 // Reference to another loot                 int LootId = -int(item_iter->chanceOrRef); -                FillLoot(loot,LootId,store,loot_owner,true);+                FillLoot(loot,LootId,store,loot_owner,true, item_iter->mincount, item_iter->maxcount);                 continue;             } @@ -405,6 +458,26 @@         }     } +    if ( items.size() )+    {+        //sLog.outDebug("FillLoot: items.size() is not 0");+        for (LootItems::iterator it = items.begin(); it != items.end(); ++it)+        {+            //sLog.outDebug("FillLoot: adding 'items' to loot: %u (had value:%f)", it->item->itemid, it->value);+            loot->items.push_back(+                LootItem(*it->item, urand(it->item->mincount, it->item->maxcount),+                GenerateEnchSuffixFactor(it->item->itemid),+                Item::GenerateItemRandomPropertyId(it->item->itemid))+                );++            // non-conditional one-player only items are counted here,+            // free for all items are counted in FillFFALoot(),+            // non-ffa conditionals are counted in FillNonQuestNonFFAConditionalLoot()+            if( ! it->item->freeforall && ! it->item->condition)+                ++loot->unlootedCount;+        }+    }+     if(referenced)         return;     if(!loot_owner)Index: src/game/LootMgr.h===================================================================--- src/game/LootMgr.h	(revision 5478)+++ src/game/LootMgr.h	(working copy)@@ -258,7 +258,7 @@ QuestItemList* FillFFALoot(Player* player, Loot *loot); QuestItemList* FillQuestLoot(Player* player, Loot *loot); QuestItemList* FillNonQuestNonFFAConditionalLoot(Player* player, Loot *loot);-void FillLoot(Loot *loot, uint32 loot_id, LootStore& store, Player* loot_owner, bool referenced = false);+void FillLoot(Loot *loot, uint32 loot_id, LootStore& store, Player* loot_owner, bool referenced = false, int min_loot_count = 0, int max_loot_count = 0); void LoadLootTables(); void LoadLootTable(LootStore& lootstore,char const* tablename); Index: src/game/ObjectMgr.cpp===================================================================--- src/game/ObjectMgr.cpp	(revision 5478)+++ src/game/ObjectMgr.cpp	(working copy)@@ -541,6 +541,12 @@             const_cast<CreatureInfo*>(cInfo)->scale = ScaleEntry ? ScaleEntry->scale : 1.0f;         } +        if ( cInfo->lootMaxCount < cInfo->lootMinCount ) +        {+            sLog.outErrorDb("Creature (Entry: %u) has wrong minLoot,maxLoot value (%u, %u), set to 0,0.",cInfo->Entry,cInfo->lootMinCount, cInfo->lootMaxCount);+            const_cast<CreatureInfo*>(cInfo)->lootMinCount = 0;+            const_cast<CreatureInfo*>(cInfo)->lootMaxCount = 0;+        }     } } Index: src/game/Player.cpp===================================================================--- src/game/Player.cpp	(revision 5478)+++ src/game/Player.cpp	(working copy)@@ -6897,7 +6897,7 @@                 if (!creature->HasFlag(UNIT_NPC_FLAGS,UNIT_NPC_FLAG_VENDOR) && lootid)                 {                     loot->clear();-                    FillLoot(loot, lootid, LootTemplates_Creature, recipient);+                    FillLoot(loot, lootid, LootTemplates_Creature, recipient, false, creature->GetCreatureInfo()->lootMinCount, creature->GetCreatureInfo()->lootMaxCount);                 }                  loot->generateMoneyLoot(creature->GetCreatureInfo()->mingold,creature->GetCreatureInfo()->maxgold);Index: src/shared/Database/SQLStorage.cpp===================================================================--- src/shared/Database/SQLStorage.cpp	(revision 5478)+++ src/shared/Database/SQLStorage.cpp	(working copy)@@ -27,7 +27,7 @@ extern DatabaseMysql  WorldDatabase; #endif -const char CreatureInfofmt[]="iiiiisssiiiiiiiiiiffiffiiiiiiiiiiiffiiliiiiiiiiiiiiiiiisiilliis";+const char CreatureInfofmt[]="iiiiisssiiiiiiiiiiffiffiiiiiiiiiiiffiiliiiiiiiiiiiiiiiiiisiilliis"; const char CreatureDataAddonInfofmt[]="iiiiiis"; const char CreatureModelfmt[]="iffii"; const char CreatureInfoAddonInfofmt[]="iiiiiis";