PDA

View Full Version : AddLootDropToNPC replacement


amraist
08-08-2009, 12:17 AM
I wrote an alternative function for AddLootDropToNPC. I didn't like seeing the same item drop multiple times on a single mob kill. This function checks for lore items as it adds them to the npc. If its a lore item, it reduces its future chance of being added to 0. It hasn't been tested too rigorously, but I think it otherwise maintains functionality of the original AddLootDropToNPC. Here is the code to use it.

--- zonedb.h 2009-08-07 21:28:10.000000000 -0500
+++ zonedb.h.new 2009-08-07 22:49:44.000000000 -0500
@@ -245,6 +245,7 @@ public:
bool GetPetEntry(const char *pet_type, PetRecord *into);
void AddLootTableToNPC(NPC* npc,int32 loottable_id, ItemList* itemlist, int32* copper, int32* silver, int32* gold, int32* plat);
void AddLootDropToNPC(NPC* npc,int32 lootdrop_id, ItemList* itemlist);
+ void AddUniqueLootDropToNPC(NPC* npc, int32 lootdrop_id, ItemList*, int32 tableProbability, int32 lootdrop_mult);
int32 GetMaxNPCSpellsID();
DBnpcspells_Struct* GetNPCSpells(int32 iDBSpellsID);

--- loottables.cpp 2009-05-02 13:13:20.000000000 -0500
+++ loottables.cpp.new 2009-08-07 22:56:26.000000000 -0500
@@ -300,13 +300,63 @@ void ZoneDatabase::AddLootTableToNPC(NPC

// Do items
for (int32 i=0; i<lts->NumEntries; i++) {
- for (int32 k = 1; k <= lts->Entries[i].multiplier; k++) {
- if ( MakeRandomInt(0,99) < lts->Entries[i].probability) {
- AddLootDropToNPC(npc,lts->Entries[i].lootdrop_id, itemlist);
- }
- }
+ AddUniqueLootDropToNPC(npc,lts->Entries[i].lootdrop_id, itemlist, lts->Entries[i].probability,lts->Entries[i].multiplier);
}
}
+// Attempts to adds a max of one each lore item from the loot table
+void ZoneDatabase::AddUniqueLootDropToNPC(NPC* npc, int32 lootdrop_id, ItemList* itemlist, int32 tableProbability, int32 lootdrop_mult ) {
+
+const LootDrop_Struct* lds = GetLootDrop(lootdrop_id);
+int32 s;
+int32 r;
+int32 drop_chance;
+int32* chances;
+int32 itemsAdded = 0;
+int32 found;
+int32 totalchance = 0;
+int32 table_chance = 0;
+if (lds) {
+ if(lds->NumEntries > 0) { //something to add
+ chances = new int32 [lds->NumEntries];
+ for ( r = 0; r < lootdrop_mult;r++) {
+ table_chance = MakeRandomInt(0,99);
+ if ( table_chance < tableProbability ) {
+ if ( totalchance <= 0 ) { // If total chance drops to 0 or below, then reset chances for everything and keep going
+ totalchance = 0;
+ for (s = 0; s < lds->NumEntries; s++) {
+ chances[s]=lds->Entries[s].chance;
+ totalchance += chances[s];
+ }
+ }
+ drop_chance = MakeRandomInt(0,totalchance);
+ found = false;
+ s = 0;
+ while ((!found) && (s < lds->NumEntries)) { // Put a constraint to only cycle through entries once
+ if (drop_chance < chances[s]) {
+ found = true;
+ const Item_Struct* dbitem = GetItem(lds->Entries[s].item_id);
+ npc->AddLootDrop(dbitem, itemlist, lds->Entries[s].item_charges, lds->Entries[s].equip_item, false);
+ itemsAdded++;
+ if (dbitem->LoreFlag) {
+ totalchance-=chances[s];
+ chances[s] = 0;
+ }
+ }
+ else {
+ drop_chance-=chances[s];
+ s++;
+ }
+ }// end while loop
+ } //end table_chance < tableProbability
+ }//end for loop
+ delete[] chances;
+ } //end If NumEntries < 0
+} //end if lds
+else
+ LogFile->write(EQEMuLog::Error, "Database Or Memory error GetLootDrop(%i) == 0, npc:%s", lootdrop_id, npc->GetName());
+
+
+}//End::AddUniqueLootDropToNPC

// Called by AddLootTableToNPC
// maxdrops = size of the array npcd