Loot

EQ2Emulator Development forum.

Moderator: Team Members

Post Reply
User avatar
Gangrenous
Posts: 812
Joined: Sun Apr 24, 2016 6:54 am
Characters: Dinsmoor

Loot

Post by Gangrenous » Wed May 11, 2016 1:49 pm

Just a thought here, a few things I have noticed. One is that loot appears to not be random, as I mentioned in another post. The loot seems to be limited to no percentages. If it is below 1%, like .001 then it is just not going to happen. I made a few changes in my source, probably needs to be looked over because I am really not a great programmer, not like the rest of you guys. I am not sure how efficient this is, I do know that if you do not have a min count, the one block will be skipped so there is that...

Oh yeah I added some code for a min_count and the column in my database. I could see instances where you would need a minimum count. Some mobs are always supposed to drop one item, this is more efficient instead of a different loot table for just one item at 100%

So overall the changes I made are the loot is rolled in random order, there is a min drop and a float for the random chance. From my testing it appears solid, but I would need to test it for a few days to be sure.

Code: Select all

void ZoneServer::AddLoot(NPC* npc){
	vector<int32> loot_tables = GetSpawnLootList(npc->GetDatabaseID(), GetZoneID(), npc->GetLevel(), race_types_list.GetRaceType(npc->GetModelType()));
	if(loot_tables.size() > 0){
		vector<LootDrop*>* loot_drops = 0;
		vector<LootDrop*>::iterator loot_drop_itr;
		LootTable* table = 0;
		vector<int32>::iterator loot_list_itr;
		float chance = 0;
		for(loot_list_itr = loot_tables.begin(); loot_list_itr != loot_tables.end(); loot_list_itr++){
			table = GetLootTable(*loot_list_itr);
			if(table && table->maxcoin > 0){
				chance = rand()%100;
				if(table->coin_probability >= chance){
					if(table->maxcoin > table->mincoin)
						npc->AddLootCoins(table->mincoin + rand()%(table->maxcoin - table->mincoin));
				}
			}
			chance = rand()%100;
			if(table && (table->lootdrop_probability < 100 || table->lootdrop_probability >= chance)){
				loot_drops = GetLootDrops(*loot_list_itr);
				if(loot_drops){
					LootDrop* drop = 0;
					int16 count = 0;

					unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();

					std::shuffle(loot_drops->begin(), loot_drops->end(), std::default_random_engine(seed));
					
					while(count < table->minlootitems){
						for(loot_drop_itr = loot_drops->begin(); loot_drop_itr != loot_drops->end(); loot_drop_itr++){
							drop = *loot_drop_itr;
				
							chance = (float)rand()/((float)(RAND_MAX))*100;
							if(drop->probability >= chance){
								count++;
								npc->AddLootItem(drop->item_id, drop->item_charges);
								LogWrite(MISC__TODO, 1, "TODO", "Auto-Equip new looted items\n\t(%s, function: %s, line #: %i)", __FILE__, __FUNCTION__, __LINE__);
								//if(drop->equip_item) 

							}
							if(table->maxlootitems > 0 && count >= table->maxlootitems)
								break;
						}
					}

					for(loot_drop_itr = loot_drops->begin(); loot_drop_itr != loot_drops->end(); loot_drop_itr++){
						drop = *loot_drop_itr;
					
						chance = (float)rand()/((float)(RAND_MAX))*100;
						if(drop->probability >= chance){
							count++;
							npc->AddLootItem(drop->item_id, drop->item_charges);
							LogWrite(MISC__TODO, 1, "TODO", "Auto-Equip new looted items\n\t(%s, function: %s, line #: %i)", __FILE__, __FUNCTION__, __LINE__);
							//if(drop->equip_item) 

						}
						if(table->maxlootitems > 0 && count >= table->maxlootitems)
							break;
					}
				}
			}
		}
	}
}

Also in world.h

Code: Select all

struct LootTable{
	string	name;
	int32	mincoin;
	int32	maxcoin;
	int16   minlootitems;
	int16	maxlootitems;
	float	lootdrop_probability;
	float	coin_probability;
};
Also in lootDB.cpp

Code: Select all

	if (database_new.Select(&result, "SELECT id, name, mincoin, maxcoin, minlootitems, maxlootitems, lootdrop_probability, coin_probability FROM loottable")) {
		LogWrite(LOOT__DEBUG, 0, "Loot", "--Loading LootTables...");
		LootTable* table = 0;
		// Load loottable from DB
		while(result.Next()) {
			int32 id = result.GetInt32Str("id");
			
			table = new LootTable;
			table->name = result.GetStringStr("name");
			table->mincoin = result.GetInt32Str("mincoin");
			table->maxcoin = result.GetInt32Str("maxcoin");
			table->minlootitems = result.GetInt16Str("minlootitems");
			table->maxlootitems = result.GetInt16Str("maxlootitems");
			table->lootdrop_probability = result.GetFloatStr("lootdrop_probability");
			table->coin_probability = result.GetFloatStr("coin_probability");
			zone->AddLootTable(id, table);

			LogWrite(LOOT__DEBUG, 5, "Loot", "---Loading LootTable '%s' (id: %u)", table->name.c_str(), id);
			LogWrite(LOOT__DEBUG, 5, "Loot", "---min_coin: %u, max_coin: %u, min_items: %i, max_items: %i, prob: %.2f, coin_prob: %.2f", table->mincoin, table->maxcoin, table->minlootitems, table->maxlootitems, table->lootdrop_probability, table->coin_probability);
			count++;
		}
		LogWrite(LOOT__DEBUG, 0, "Loot", "--Loaded %u loot table%s.", count, count == 1 ? "" : "s");
	}
Resident Dirty Hippy

Post Reply

Who is online

Users browsing this forum: No registered users and 0 guests