// Called by AddLootTableToNPC // maxdrops = size of the array npcd void Database::AddLootDropToNPC(int32 lootdrop_id, ItemList* itemlist) { char errbuf[MYSQL_ERRMSG_SIZE]; char *query = 0; MYSQL_RES *result; MYSQL_ROW row; // This is Wiz's updated Pool Looting functionality. Eventually, the database format should be moved over to use this // or implemented to support both methods. (A unique identifier in lootable_entries indicates to roll for a pool item // in another table. #ifdef POOLLOOTING int32 chancepool = 0; int32 items[50]; int32 itemchance[50]; int16 itemcharges[50]; int8 i = 0; for (int m=0;m < 50;m++) { items[m]=0; itemchance[m]=0; itemcharges[m]=0; } if (RunQuery(query, MakeAnyLenString(&query, "SELECT lootdrop_id, item_id, item_charges, equip_item, chance FROM lootdrop_entries WHERE lootdrop_id=%i order by chance desc", lootdrop_id), errbuf, &result)) { delete[] query; while (row = mysql_fetch_row(result)) { items[i] = atoi(row[1]); itemchance[i] = atoi(row[4]) + chancepool; itemcharges[i] = atoi(row[2]); chancepool += atoi(row[4]); i++; } int32 res; i = 0; if (chancepool!=0) //avoid divide by zero if some mobs have 0 for chancepool { res = rand()%chancepool; } else { res = 0; } while (items[i] != 0) { if (res <= itemchance[i]) break; else i++; } const Item_Struct* dbitem = database.GetItem(items[i]); if (dbitem == 0) { cerr << "Error in AddLootDropToNPC: dbitem=0, item#=" << items[i] << ", lootdrop_id=" << lootdrop_id << endl; } else { printf("Adding item2: %i",item->item_nr); cout << "Adding item to Mob" << endl; ServerLootItem_Struct* item = new ServerLootItem_Struct; item->item_nr = dbitem->item_nr; item->charges = itemcharges[i]; item->equipSlot = 0; (*itemlist).Append(item); } mysql_free_result(result); } #else if (RunQuery(query, MakeAnyLenString(&query, "SELECT lootdrop_id, item_id, item_charges, equip_item, chance FROM lootdrop_entries WHERE lootdrop_id=%i order by chance desc", lootdrop_id), errbuf, &result)) { delete[] query; while ((row = mysql_fetch_row(result))) { int8 LootDropMod=1; // place holder till I put it in a database variable to make it configurable. if( (rand()%100) < ((atoi(row[4]) * LootDropMod)) ) { int32 itemid = atoi(row[1]); const Item_Struct* dbitem = database.GetItem(itemid); if (dbitem == 0) { cerr << "Error in AddLootDropToNPC: dbitem=0, item#=" << itemid << ", lootdrop_id=" << lootdrop_id << endl; } else { printf("Adding item: %i",item->item_nr); ServerLootItem_Struct* item = new ServerLootItem_Struct; item->item_nr = dbitem->item_nr; item->charges = atoi(row[2]); item->equipSlot = 0; (*itemlist).Append(item); } //mysql_free_result(result); //return; } } mysql_free_result(result); } #endif else { cerr << "Error in AddLootDropToNPC query '" << query << "' " << errbuf << endl; delete[] query; return; } return; }
// Called by AddLootTableToNPC // maxdrops = size of the array npcd void Database::AddLootDropToNPC(NPC* npc,int32 lootdrop_id, ItemList* itemlist) { const LootDrop_Struct* lds = GetLootDrop(lootdrop_id); if (!lds) return; // This is Wiz's updated Pool Looting functionality. Eventually, the database format should be moved over to use this // or implemented to support both methods. (A unique identifier in lootable_entries indicates to roll for a pool item // in another table. #ifdef POOLLOOTING printf("POOL!\n"); int32 chancepool = 0; int32 items[50]; int32 itemchance[50]; int16 itemcharges[50]; int8 i = 0; for (int m=0;m < 50;m++) { items[m]=0; itemchance[m]=0; itemcharges[m]=0; } for (int k=0; k<lds->NumEntries; k++) { items[i] = lds->Entries[k].item_id; itemchance[i] = lds->Entries[k].chance + chancepool; itemcharges[i] = lds->Entries[k].item_charges; chancepool += lds->Entries[k].chance; i++; } int32 res; i = 0; if (chancepool!=0) { //avoid divide by zero if some mobs have 0 for chancepool res = rand()%chancepool; } else { res = 0; } while (items[i] != 0) { if (res <= itemchance[i]) break; else i++; } const Item_Struct* dbitem = database.GetItem(items[i]); if (dbitem == 0) { cerr << "Error in AddLootDropToNPC: dbitem=0, item#=" << items[i] << ", lootdrop_id=" << lootdrop_id << endl; } else { cout << "Adding item to Mob" << endl; ServerLootItem_Struct* item = new ServerLootItem_Struct; item->item_nr = dbitem->item_nr; item->charges = itemcharges[i]; item->equipSlot = 0; (*itemlist).Append(item); } #else int x=0; int32 k; int32 totalchance = 0; for (k=0; k<lds->NumEntries; k++) { totalchance += lds->Entries[k].chance; } int32 thischance = 0; for (k=0; k<lds->NumEntries; k++) { x++; LinkedListIterator<ServerLootItem_Struct*> iterator(*itemlist); iterator.Reset(); int itemon=0; while(iterator.MoreElements()){ const Item_Struct* item = database.GetItem(iterator.GetData()->item_nr); if(item) if(iterator.GetData()->item_nr==lds->Entries[k].item_id) itemon=1; iterator.Advance(); } thischance += lds->Entries[k].chance; if (totalchance == 0 || (lds->Entries[k].chance != 0 && rand()%totalchance < thischance && (lds->Entries[k].chance!=100 && itemon==0)) || (lds->Entries[k].chance==100 && itemon==0)) { int32 itemid = lds->Entries[k].item_id; const Item_Struct* dbitem = database.GetItem(itemid); if (dbitem == 0) { cerr << "Error in AddLootDropToNPC: dbitem=0, item#=" << itemid << ", lootdrop_id=" << lootdrop_id << endl; } else { ServerLootItem_Struct* item = new ServerLootItem_Struct; item->item_nr = dbitem->item_nr; item->charges = lds->Entries[k].item_charges; if (lds->Entries[k].equip_item==1){ const Item_Struct* item2= database.GetItem(item->item_nr); char tmp[20]; char newid[20]; memset(newid, 0, sizeof(newid)); for(int i=0;i<7;i++){ if (!isalpha(item2->idfile[i])){ strncpy(newid, &item2->idfile[i],5); i=8; } } //printf("Npc Name: %s, Item: %i\n",npc->GetName(),item2->item_nr); if (((item2->equipableSlots==24576) || (item2->equipableSlots==8192)) && (npc->d_meele_texture1==0)) { npc->d_meele_texture1=atoi(newid); npc->equipment[7]=item2->item_nr; if (item2->common.spellId0!=0) npc->CastToMob()->AddProcToWeapon(item2->common.spellId0,true); npc->AC+=item2->common.AC; npc->STR+=item2->common.STR; npc->INT+=item2->common.INT; } else if (((item2->equipableSlots==24576) || (item2->equipableSlots==16384)) && (npc->d_meele_texture2 ==0) && ((npc->GetLevel()>=13) || (item2->common.damage==0))) { if (item2->common.spellId0!=0) npc->CastToMob()->AddProcToWeapon(item2->common.spellId0,true); npc->equipment[8]=item2->item_nr; npc->d_meele_texture2=atoi(newid); npc->AC+=item2->common.AC; npc->STR+=item2->common.STR; npc->INT+=item2->common.INT; } else if ((item2->equipableSlots==4) && (npc->equipment[0]==0)){ npc->equipment[0]=item2->item_nr; npc->AC+=item2->common.AC; npc->STR+=item2->common.STR; npc->INT+=item2->common.INT; } else if ((item2->equipableSlots==131072) && (npc->equipment[1]==0)){ npc->equipment[1]=item2->common.material; npc->texture=item2->common.material; npc->AC+=item2->common.AC; npc->STR+=item2->common.STR; npc->INT+=item2->common.INT; } else if ((item2->equipableSlots==128) && (npc->equipment[2]==0)){ npc->equipment[2]=item2->common.material; npc->AC+=item2->common.AC; npc->STR+=item2->common.STR; npc->INT+=item2->common.INT; } else if ((item2->equipableSlots==1536) && (npc->equipment[3]==0)){ npc->equipment[3]=item2->common.material; npc->AC+=item2->common.AC; npc->STR+=item2->common.STR; npc->INT+=item2->common.INT; } else if ((item2->equipableSlots==4096) && (npc->equipment[4]==0)){ npc->equipment[4]=item2->common.material; npc->AC+=item2->common.AC; npc->STR+=item2->common.STR; npc->INT+=item2->common.INT; } else if ((item2->equipableSlots==262144) && (npc->equipment[5]==0)){ npc->equipment[5]=item2->common.material; npc->AC+=item2->common.AC; npc->STR+=item2->common.STR; npc->INT+=item2->common.INT; } else if ((item2->equipableSlots==524288) && (npc->equipment[6]==0)){ npc->equipment[6]=item2->common.material; npc->AC+=item2->common.AC; npc->STR+=item2->common.STR; npc->INT+=item2->common.INT; } item->equipSlot = dbitem->equipableSlots; } (*itemlist).Append(item); } break; } } #endif }