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

changes made for tradeskills

files changed:
common/item.h
zone/zonedb.h
zone/client.h
zone/client_packet.cpp
zone/tradeskills.cpp

common/item.h
Code:
<!	SLOT_TRADESKILL	= 1000,
!>	SLOT_WORLDCONTAINER = 1000,
This change is to make the purpose of the slot more clear. Although the object in the slot can be used for tradeskills, it is a worldcontainer object.

zone/zonedb.h
Code:
struct DBTradeskillRecipe_Struct {
!>	SkillType tradeskill;
	sint16 skill_needed;
	uint16 trivial;
	bool nofail;
	bool replace_container;
	vector< pair<uint32,uint8> > onsuccess;
	vector< pair<uint32,uint8> > onfail;
};
added SkillType tradeskill; to the structure because the tradeskill should actually be determined by the recipe, not by the type of container you are trying to perform the recipe in.
Code:
<!	bool	GetTradeRecipe(const ItemInst* container, uint8 c_type, uint8 tradeskill, DBTradeskillRecipe_Struct *spec);
!>	bool	GetTradeRecipe(const ItemInst* container, uint8 c_type, uint32 some_id, DBTradeskillRecipe_Struct *spec);
<!	bool	GetTradeRecipe(uint32 recipe_id, uint8 c_type, uint8 tradeskill, DBTradeskillRecipe_Struct *spec);
!>	bool	GetTradeRecipe(uint32 recipe_id, uint8 c_type, uint32 some_id, DBTradeskillRecipe_Struct *spec);
Changed signitures. These should be receiving the item qualifier instead of the tradeskill.

zone/client.h
Code:
<!	bool TradeskillExecute(DBTradeskillRecipe_Struct *spec, SkillType tradeskill);
!>	bool TradeskillExecute(DBTradeskillRecipe_Struct *spec);
Changed signitures. Since SkillType tradeskill is now included in DBTradeskillRecipe_Struct it does not need to be passed separately.

zone/client_packet.cpp
Code:
void Client::Handle_OP_RecipesFavorite(const EQApplicationPacket *app)
{
	if (app->size != sizeof(TradeskillFavorites_Struct)) {
		LogFile->write(EQEMuLog::Error, "Invalid size for TradeskillFavorites_Struct: Expected: %i, Got: %i",
			sizeof(TradeskillFavorites_Struct), app->size);
		return;
	}
	
	TradeskillFavorites_Struct* tsf = (TradeskillFavorites_Struct*)app->pBuffer;
	
<!	uint32 tskill = Object::TypeToSkill(tsf->object_type);
<!	if(tskill == 0) {
<!		LogFile->write(EQEMuLog::Error, "Unknown container type for OP_RecipesFavorite: %d\n", tsf->object_type);
<!		return;
<!	}

!>	LogFile->write(EQEMuLog::Debug, "Requested Favorites for: %d - %d\n", tsf->object_type, tsf->some_id);

!>	// make where clause segment for container(s)
!>	char containers[30];
!>	if (tsf->some_id == 0) {
!>		// world combiner so no item number
!>		snprintf(containers,29, "= %u", tsf->object_type);
!>	} else {
!>		// container in inventory
!>		snprintf(containers,29, "in (%u,%u)", tsf->object_type, tsf->some_id);
!>	}

char *query = 0;
	char buf[1100];	//gotta be big enough for 100 IDs
	
	bool first = true;
	uint8 r;
	char *pos = buf;
	
	//Assumes item IDs are <10 characters long
	for(r = 0; r < 100; r++) {
		if(tsf->favorite_recipes[r] == 0)
			break;	//assume the first 0 is the end...
		
		if(first) {
			pos += snprintf(pos, 10, "%u", tsf->favorite_recipes[r]);
			first = false;
		} else {
			pos += snprintf(pos, 10, ",%u", tsf->favorite_recipes[r]);
		}
	}
	
	if(first)	//no favorites....
		return;
	
	//To be a good kid, I should move this SQL somewhere else...
	//but im lazy right now, so it stays here
	uint32 qlen = 0;
	qlen = MakeAnyLenString(&query, "SELECT tr.id,tr.name,tr.trivial,SUM(tre.componentcount) "
		" FROM tradeskill_recipe AS tr "
		" LEFT JOIN tradeskill_recipe_entries AS tre ON tr.id=tre.recipe_id "
<!		" WHERE tr.id IN (%s) AND tradeskill=%lu "
<!		" GROUP BY tr.id LIMIT 100 ", buf, tskill);
!>		" WHERE tr.id IN (%s) "
!>		" GROUP BY tr.id "
!>		" HAVING sum(if(tre.item_id %s AND tre.iscontainer > 0,1,0)) > 0 "
!>		" LIMIT 100 ", buf, containers);
	
	TradeskillSearchResults(query, qlen, tsf->object_type, tsf->some_id);
	
	safe_delete_array(query);
	return;
}
Removed type to skill lookup because results should be determined by container, not by what tradeskill container is normally used in.
Added code to use containers in the lookup. If either the type or some_id is listed as a container in the recipe we want it.
Code:
void Client::Handle_OP_RecipesSearch(const EQApplicationPacket *app)
{
	if (app->size != sizeof(RecipesSearch_Struct)) {
		LogFile->write(EQEMuLog::Error, "Invalid size for RecipesSearch_Struct: Expected: %i, Got: %i",
			sizeof(RecipesSearch_Struct), app->size);
		return;
	}
	
	RecipesSearch_Struct* rss = (RecipesSearch_Struct*)app->pBuffer;
	rss->query[55] = '\0';	//just to be sure.

<!	uint32 tskill = Object::TypeToSkill(rss->object_type);
<!	if(tskill == 0) {
<!		LogFile->write(EQEMuLog::Error, "Unknown container type for OP_RecipesSearch: %d\n", rss->object_type);
<!		return;
<!	}

!>	// make where clause segment for container(s)
!>	char containers[30];
!>	if (rss->some_id == 0) {
!>		// world combiner so no item number
!>		snprintf(containers,29, "= %u", rss->object_type);
!>	} else {
!>		// container in inventory
!>		snprintf(containers,29, "in (%u,%u)", rss->object_type, rss->some_id);
!>	}

	char *query = 0;
	char searchclause[140];	//2X rss->query + SQL crap
	
	//omit the rlike clause if query is empty
	if(rss->query[0] != 0) {
		char buf[120];	//larger than 2X rss->query
		database.DoEscapeString(buf, rss->query, strlen(rss->query));
		
		snprintf(searchclause, 139, "name rlike '%s' AND", buf);
	} else {
		searchclause[0] = '\0';
	}
	uint32 qlen = 0;
	
	//arbitrary limit of 200 recipes, makes sense to me.
	qlen = MakeAnyLenString(&query, "SELECT tr.id,tr.name,tr.trivial,SUM(tre.componentcount) "
		" FROM tradeskill_recipe AS tr "
		" LEFT JOIN tradeskill_recipe_entries AS tre ON tr.id=tre.recipe_id "
<!		" WHERE %s tr.trivial >= %u AND tr.trivial <= %u AND tradeskill=%lu "
!>		" WHERE %s tr.trivial >= %u AND tr.trivial <= %u "
<!		" GROUP BY tr.id LIMIT 200 ", searchclause, rss->mintrivial, rss->maxtrivial, tskill);
!>		" GROUP BY tr.id "
!>		" HAVING sum(if(tre.item_id %s AND tre.iscontainer > 0,1,0)) > 0 "
!>		" LIMIT 200 "
!>		, searchclause, rss->mintrivial, rss->maxtrivial, containers);
	
	TradeskillSearchResults(query, qlen, rss->object_type, rss->some_id);
	
	safe_delete_array(query);
	return;
}
Removed type to skill lookup because results should be determined by container, not by what tradeskill container is normally used in.
Added code to use containers in the lookup. If either the type or some_id is listed as a container in the recipe we want it.
Reply With Quote