View Single Post
  #4  
Old 03-04-2007, 05:05 AM
Darkonig
Hill Giant
 
Join Date: Dec 2006
Posts: 102
Default

Tradeskills.cpp
Code:
void Object::HandleAutoCombine(Client* user, const RecipeAutoCombine_Struct* rac) {
	
	//get our packet ready, gotta send one no matter what...
	EQApplicationPacket* outapp = new EQApplicationPacket(OP_RecipeAutoCombine, sizeof(RecipeAutoCombine_Struct));
	RecipeAutoCombine_Struct *outp = (RecipeAutoCombine_Struct *)outapp->pBuffer;
	outp->object_type = rac->object_type;
	outp->some_id = rac->some_id;
	outp->unknown1 = rac->unknown1;
	outp->recipe_id = rac->recipe_id;
	outp->reply_code = 0xFFFFFFF5;	//default fail.
	
	
<!	SkillType tskill = Object::TypeToSkill(rac->object_type);
<!	if(tskill == TradeskillUnknown) {
<!		LogFile->write(EQEMuLog::Error, "Unknown container type for HandleAutoCombine: %d\n", rac->object_type);
<!		user->QueuePacket(outapp);
<!		safe_delete(outapp);
<!		return;
<!	}
<!	
	//ask the database for the recipe to make sure it exists...
	DBTradeskillRecipe_Struct spec;
<!	if (!database.GetTradeRecipe(rac->recipe_id, rac->object_type, tskill, &spec)) {
>!	if (!database.GetTradeRecipe(rac->recipe_id, rac->object_type, rac->some_id, &spec)) {
		LogFile->write(EQEMuLog::Error, "Unknown recipe for HandleAutoCombine: %u\n", rac->recipe_id);
		user->QueuePacket(outapp);
		safe_delete(outapp);
		return;
	}
	
	char errbuf[MYSQL_ERRMSG_SIZE];
    MYSQL_RES *result;
    MYSQL_ROW row;
    char *query = 0;
	
	uint32 qlen = 0;
	uint8 qcount = 0;

	//pull the list of components
	qlen = MakeAnyLenString(&query, "SELECT tre.item_id,tre.componentcount "
	 " FROM tradeskill_recipe_entries AS tre "
	 " WHERE tre.componentcount > 0 AND tre.recipe_id=%u", rac->recipe_id);

	if (!database.RunQuery(query, qlen, errbuf, &result)) {
		LogFile->write(EQEMuLog::Error, "Error in HandleAutoCombine query '%s': %s", query, errbuf);
		safe_delete_array(query);
		user->QueuePacket(outapp);
		safe_delete(outapp);
		return;
	}
	safe_delete_array(query);
	
	qcount = mysql_num_rows(result);
	if(qcount < 1) {
		LogFile->write(EQEMuLog::Error, "Error in HandleAutoCombine: no components returned");
		user->QueuePacket(outapp);
		safe_delete(outapp);
		return;
	}
	if(qcount > 10) {
		LogFile->write(EQEMuLog::Error, "Error in HandleAutoCombine: too many components returned (%u)", qcount);
		user->QueuePacket(outapp);
		safe_delete(outapp);
		return;
	}
	
	uint32 items[10];
	memset(items, 0, sizeof(items));
	uint8 counts[10];
	memset(counts, 0, sizeof(counts));
	
	
	//search for all the crap in their inventory
	Inventory& user_inv = user->GetInv();
	uint8 count = 0;
	uint8 needcount = 0;
	uint8 r,k;
	for(r = 0; r < qcount; r++) {
		row = mysql_fetch_row(result);
		uint32 item = (uint32)atoi(row[0]);
		uint8 num = (uint8) atoi(row[1]);
		
		needcount += num;
		
		//because a HasItem on items with num > 1 only returns the
		//last-most slot... the results of this are useless to us
		//when we go to delete them because we cannot assume it is in a single stack.
		if(user_inv.HasItem(item, num, invWherePersonal) != SLOT_INVALID)
			count += num;
		//dont start deleting anything until we have found it all.
		items[r] = item;
		counts[r] = num;
	}
	mysql_free_result(result);
	
	//make sure we found it all...
	if(count != needcount) {
		user->QueuePacket(outapp);
		safe_delete(outapp);
		return;
	}
	
	//now we know they have everything...
	
	//remove all the items from the players inventory, with updates...
	sint16 slot;
	for(r = 0; r < qcount; r++) {
		if(items[r] == 0 || counts[r] == 0)
			continue;	//skip empties, could prolly break here
		
		//we have to loop here to delete 1 at a time in case its in multiple stacks.
		for(k = 0; k < counts[r]; k++) {
			slot = user_inv.HasItem(items[r], 1, invWherePersonal);
			if(slot == SLOT_INVALID) {
				//WTF... I just checked this above, but just to be sure...
				//we cant undo the previous deletes without a lot of work.
				//so just call it quits, this shouldent ever happen anyways.
				user->QueuePacket(outapp);
				safe_delete(outapp);
				return;
			}
			
			user->DeleteItemInInventory(slot, 1, true);
		}
	}
	
	//otherwise, we found it all...
	outp->reply_code = 0x00000000;	//success for finding it...
	
	user->QueuePacket(outapp);
	//DumpPacket(outapp);
	safe_delete(outapp);
	
	//now actually try to make something...
	
<!	bool success = user->TradeskillExecute(&spec, tskill);
!>	bool success = user->TradeskillExecute(&spec);
	
	//TODO: find in-pack containers in inventory, make sure they are really
	//there, and then use that slot to handle replace_container too.
	if(success && spec.replace_container) {
//		user->DeleteItemInInventory(in_combine->container_slot, 0, true);
	}
	
}
Removed code that determines tradeskill from combiner type as it is no longer relevant
changed function call to GetTradeRecipe to pass some_id instead of tradeskill
changed function call to TradeskillExecute to remove tradeskill from parameter list as it is now included in spec

Last edited by Darkonig; 03-04-2007 at 01:10 PM..
Reply With Quote