|
|
 |
 |
 |
 |
|
 |
 |
|
 |
 |
|
 |
|
Development::Development Forum for development topics and for those interested in EQEMu development. (Not a support forum) |

05-22-2007, 05:41 AM
|
Hill Giant
|
|
Join Date: Dec 2006
Posts: 102
|
|
Fix: Tradeskills - recipe lookups and combines
Here are the diffs for correcting the operation of tradeskills so that they work like they do in live. I am reposting this as right after I posted the original fix there were several patches that affected some of the same functions. I integrated those patches into my fix and am reposting as diffs to make it easier to use. An explanation of the changes can be found in my earlier post http://www.eqemulator.net/forums/showthread.php?t=22490
Since they are too big to fit into a single post, They will appear in the next 2 replies.
|
 |
|
 |

05-22-2007, 05:44 AM
|
Hill Giant
|
|
Join Date: Dec 2006
Posts: 102
|
|
Code:
cvs diff -- client.h client_packet.cpp tradeskills.cpp zonedb.h (in directory M:\cvswork\EQEmuCVS\Source\zone\)
Index: client.h
===================================================================
RCS file: /cvsroot/eqemulator/EQEmuCVS/Source/zone/client.h,v
retrieving revision 1.49
diff -r1.49 client.h
496c496
< bool TradeskillExecute(DBTradeskillRecipe_Struct *spec, SkillType tradeskill);
---
> bool TradeskillExecute(DBTradeskillRecipe_Struct *spec);
Index: client_packet.cpp
===================================================================
RCS file: /cvsroot/eqemulator/EQEmuCVS/Source/zone/client_packet.cpp,v
retrieving revision 1.46
diff -r1.46 client_packet.cpp
3979,3982c3979,3991
< 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);
>
> // results show that object_type is combiner type
> // some_id = 0 if world combiner, item number otherwise
>
> // 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);
4014,4015c4023,4026
< " 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);
4035,4038c4046,4055
< 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;
---
> LogFile->write(EQEMuLog::Debug, "Requested search recipes for: %d - %d\n", rss->object_type, rss->some_id);
>
> // 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);
4059,4060c4076,4080
< " WHERE %s tr.trivial >= %u AND tr.trivial <= %u AND tradeskill=%lu "
< " GROUP BY tr.id LIMIT 200 ", searchclause, rss->mintrivial, rss->maxtrivial, tskill);
---
> " WHERE %s tr.trivial >= %u AND tr.trivial <= %u "
> " 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);
Index: zonedb.h
===================================================================
RCS file: /cvsroot/eqemulator/EQEmuCVS/Source/zone/zonedb.h,v
retrieving revision 1.7
diff -r1.7 zonedb.h
37a38
> Skilltype tradeskill;
226,227c227,228
< bool GetTradeRecipe(const ItemInst* container, uint8 c_type, uint8 tradeskill, DBTradeskillRecipe_Struct *spec);
< bool GetTradeRecipe(uint32 recipe_id, 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, uint32 some_id, DBTradeskillRecipe_Struct *spec);
|
 |
|
 |
 |
|
 |

05-22-2007, 05:49 AM
|
Hill Giant
|
|
Join Date: Dec 2006
Posts: 102
|
|
Code:
Index: tradeskills.cpp
===================================================================
RCS file: /cvsroot/eqemulator/EQEmuCVS/Source/zone/tradeskills.cpp,v
retrieving revision 1.17
diff -r1.17 tradeskills.cpp
108,109c108,109
< int8 tstype = 0xE8;
< uint8 passtype = 0;
---
> uint8 c_type = 0xE8;
> uint32 some_id = 0;
117a118
> c_type = worldo->m_type;
125c126,127
< tstype = item->BagType;
---
> c_type = item->BagType;
> some_id = item->ID;
137,139c139,148
< // Convert container type to tradeskill type
< SkillType tradeskill = TradeskillUnknown;
< switch (tstype)
---
> DBTradeskillRecipe_Struct spec;
> if (!database.GetTradeRecipe(container, c_type, some_id, &spec)) {
> user->Message_StringID(4,TRADESKILL_NOCOMBINE);
> EQApplicationPacket* outapp = new EQApplicationPacket(OP_TradeSkillCombine, 0);
> user->QueuePacket(outapp);
> safe_delete(outapp);
> return;
> }
>
> switch (spec.tradeskill)
141,177c150,151
< case 16:
< tradeskill = TAILORING;
< break;
< case 0xE8: //Generic World Container
< if(!worldcontainer) //just to garuntee that worldo is valid
< return;
< passtype = worldo->m_type;
<
< if(worldo->m_type == OT_MEDICINEBAG) {
< if ((user_pp.class_ == SHAMAN) & (user_pp.level >= MIN_LEVEL_ALCHEMY))
< tradeskill = ALCHEMY;
< else if (user_pp.class_ != SHAMAN)
< user->Message(13, "This tradeskill can only be performed by a shaman.");
< else if (user_pp.level < MIN_LEVEL_ALCHEMY)
< user->Message(13, "You cannot perform alchemy until you reach level %i.", MIN_LEVEL_ALCHEMY);
< break;
< } else {
< tradeskill = TypeToSkill(worldo->m_type);
< }
< break;
< case 18:
< tradeskill = FLETCHING;
< break;
< case 20:
< tradeskill = JEWELRY_MAKING;
< break;
< case 30: //Pottery Still needs completion
< tradeskill = POTTERY;
< break;
< case 14: // Baking
< case 15:
< tradeskill = BAKING;
< break;
< case 9: //Alchemy Still needs completion
< if ((user_pp.class_ == SHAMAN) & (user_pp.level >= MIN_LEVEL_ALCHEMY))
< tradeskill = ALCHEMY;
< else if (user_pp.class_ != SHAMAN)
---
> case ALCHEMY:
> if (user_pp.class_ != SHAMAN)
180a155
> return;
182,185c157,158
< case 10: //Tinkering Still needs completion
< if (user_pp.race == GNOME)
< tradeskill = TINKERING;
< else
---
> case TINKERING:
> if (user_pp.race != GNOME)
186a160
> return;
188,200c162,163
< case 24: //Research Still needs completion
< case 25:
< case 26:
< case 27:
< tradeskill = RESEARCH;
< break;
< case 28: // Another Quest Containers.. Cavedude asked for this
< tradeskill = GENERIC_TRADESKILL;
< break;
< case 12:
< if (user_pp.class_ == ROGUE)
< tradeskill = MAKE_POISON;
< else
---
> case MAKE_POISON:
> if (user_pp.class_ != ROGUE)
202,223d164
< break;
< case 13: //Quest Containers
< tradeskill = GENERIC_TRADESKILL;
< break;
< case 46: //Fishing Still needs completion
< tradeskill = FISHING;
< break;
< default:
< user->Message(13, "This tradeskill has not been implemented yet, if you get this message send a "
< "petition and let them know what tradeskill you were trying to use. and give them the following code: 0x%02X", tradeskill);
< }
<
< if (tradeskill == TradeskillUnknown) {
< return;
< }
<
< DBTradeskillRecipe_Struct spec;
< if (!database.GetTradeRecipe(container, passtype, tradeskill, &spec)) {
< user->Message_StringID(4,TRADESKILL_NOCOMBINE);
< EQApplicationPacket* outapp = new EQApplicationPacket(OP_TradeSkillCombine, 0);
< user->QueuePacket(outapp);
< safe_delete(outapp);
224a166
> break;
228c170
< bool success = user->TradeskillExecute(&spec, tradeskill);
---
> bool success = user->TradeskillExecute(&spec);
272,279d213
< 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;
< }
<
282c216
< if (!database.GetTradeRecipe(rac->recipe_id, rac->object_type, tskill, &spec)) {
---
> if (!database.GetTradeRecipe(rac->recipe_id, rac->object_type, rac->some_id, &spec)) {
395c329
< bool success = user->TradeskillExecute(&spec, tskill);
---
> bool success = user->TradeskillExecute(&spec);
653,654c587,588
< bool Client::TradeskillExecute(DBTradeskillRecipe_Struct *spec, SkillType tradeskill) {
< if(spec == NULL || tradeskill == 0)
---
> bool Client::TradeskillExecute(DBTradeskillRecipe_Struct *spec) {
> if(spec == NULL)
657c591
< int16 user_skill = GetSkill(tradeskill);
---
> int16 user_skill = GetSkill(spec->tradeskill);
676c610
< switch(tradeskill) {
---
> switch(spec->tradeskill) {
698c632
< if (tradeskill == FLETCHING || tradeskill == MAKE_POISON) {
---
> if (spec->tradeskill == FLETCHING || spec->tradeskill == MAKE_POISON) {
701c635
< } else if (tradeskill == BLACKSMITHING) {
---
> } else if (spec->tradeskill == BLACKSMITHING) {
780c714
< if (((tradeskill==75) || GetGM() || (chance > res)) || MakeRandomInt(0, 99) < AAChance){
---
> if (((spec->tradeskill==75) || GetGM() || (chance > res)) || MakeRandomInt(0, 99) < AAChance){
784c718
< CheckIncreaseTradeskill(bonusstat, stat_modifier, skillup_modifier, success_modifier, tradeskill);
---
> CheckIncreaseTradeskill(bonusstat, stat_modifier, skillup_modifier, success_modifier, spec->tradeskill);
801c735
< CheckIncreaseTradeskill(bonusstat, stat_modifier, skillup_modifier, success_modifier, tradeskill);
---
> CheckIncreaseTradeskill(bonusstat, stat_modifier, skillup_modifier, success_modifier, spec->tradeskill);
continued next post, still too big
|
 |
|
 |
 |
|
 |

05-22-2007, 05:49 AM
|
Hill Giant
|
|
Join Date: Dec 2006
Posts: 102
|
|
Code:
858c792
< bool ZoneDatabase::GetTradeRecipe(const ItemInst* container, uint8 c_type, uint8 tradeskill,
---
> bool ZoneDatabase::GetTradeRecipe(const ItemInst* container, uint8 c_type, uint32 some_id,
872,881c806,813
< //use the world item type as type if we have a world item
< //otherwise use the item's ID... this make the assumption that
< //no tradeskill containers will have an item ID which is
< //below the highest ID of objects, which is currently 0x30
< uint32 type = c_type;
<
< //dunno why I have to cast this up to call GetItem
< const Item_Struct *istruct = ((const ItemInst *) container)->GetItem();
< if(c_type == 0 && istruct) {
< type = istruct->ID;
---
> // make where clause segment for container(s)
> char containers[30];
> if (some_id == 0) {
> // world combiner so no item number
> snprintf(containers,29, "= %u", c_type);
> } else {
> // container in inventory
> snprintf(containers,29, "in (%u,%u)", c_type, some_id);
913,916d844
< //add in the container.
< count++;
< sum += type;
<
920,922c848,850
< " OR ( tre.item_id=%u AND tre.iscontainer=1 )"
< " GROUP BY tre.recipe_id HAVING sum(tre.componentcount+tre.iscontainer) = %u"
< " AND sum(tre.item_id * (tre.componentcount+tre.iscontainer)) = %u", buf2, type, count, sum);
---
> " OR ( tre.item_id %s AND tre.iscontainer=1 )"
> " GROUP BY tre.recipe_id HAVING sum(tre.componentcount) = %u"
> " AND sum(tre.item_id * tre.componentcount) = %u", buf2, containers, count, sum);
925c853
< LogFile->write(EQEMuLog::Error, "Error in GetTradeRecept search, query: %s", query);
---
> LogFile->write(EQEMuLog::Error, "Error in GetTradeRecipe search, query: %s", query);
927c855
< LogFile->write(EQEMuLog::Error, "Error in GetTradeRecept search, error: %s", errbuf);
---
> LogFile->write(EQEMuLog::Error, "Error in GetTradeRecipe search, error: %s", errbuf);
956,959c884,886
< " WHERE tre.recipe_id IN (%s) "
< " AND (tre.iscontainer=0 OR tre.item_id=%u) "
< " GROUP BY tre.recipe_id HAVING sum(tre.componentcount+tre.iscontainer) = %u"
< " AND sum(tre.item_id * (tre.componentcount+tre.iscontainer)) = %u", buf2, type, count, sum);
---
> " WHERE tre.recipe_id IN (%s)"
> " GROUP BY tre.recipe_id HAVING sum(tre.componentcount) = %u"
> " AND sum(tre.item_id * tre.componentcount) = %u", buf2, count, sum);
962c889
< LogFile->write(EQEMuLog::Error, "Error in GetTradeRecept, re-query: %s", query);
---
> LogFile->write(EQEMuLog::Error, "Error in GetTradeRecipe, re-query: %s", query);
964c891
< LogFile->write(EQEMuLog::Error, "Error in GetTradeRecept, error: %s", errbuf);
---
> LogFile->write(EQEMuLog::Error, "Error in GetTradeRecipe, error: %s", errbuf);
1018c945
< return(GetTradeRecipe(recipe_id, c_type, tradeskill, spec));
---
> return(GetTradeRecipe(recipe_id, c_type, some_id, spec));
1023c950
< bool ZoneDatabase::GetTradeRecipe(uint32 recipe_id, uint8 c_type, uint8 tradeskill,
---
> bool ZoneDatabase::GetTradeRecipe(uint32 recipe_id, uint8 c_type, uint32 some_id,
1034,1036c961,976
< qlen = MakeAnyLenString(&query, "SELECT tr.skillneeded, tr.trivial, tr.nofail, tr.replace_container"
< " FROM tradeskill_recipe AS tr"
< " WHERE tr.id = %lu AND tr.tradeskill = %u", recipe_id, tradeskill);
---
> // make where clause segment for container(s)
> char containers[30];
> if (some_id == 0) {
> // world combiner so no item number
> snprintf(containers,29, "= %u", c_type);
> } else {
> // container in inventory
> snprintf(containers,29, "in (%u,%u)", c_type, some_id);
> }
>
> qlen = MakeAnyLenString(&query, "SELECT tr.id, tr.tradeskill, tr.skillneeded,"
> " tr.trivial, tr.nofail, tr.replace_container"
> " FROM tradeskill_recipe AS tr inner join tradeskill_recipe_entries as tre"
> " ON tr.id = tre.recipe_id"
> " WHERE tr.id = %lu AND tre.item_id %s"
> " GROUP BY tr.id", recipe_id, containers);
1039c979
< LogFile->write(EQEMuLog::Error, "Error in GetTradeRecept, query: %s", query);
---
> LogFile->write(EQEMuLog::Error, "Error in GetTradeRecipe, query: %s", query);
1041c981
< LogFile->write(EQEMuLog::Error, "Error in GetTradeRecept, error: %s", errbuf);
---
> LogFile->write(EQEMuLog::Error, "Error in GetTradeRecipe, error: %s", errbuf);
1053,1056c993,997
< spec->skill_needed = (sint16)atoi(row[0]);
< spec->trivial = (uint16)atoi(row[1]);
< spec->nofail = atoi(row[2]) ? true : false;
< spec->replace_container = atoi(row[3]) ? true : false;
---
> spec->tradeskill = (SkillType)atoi(row[1]);
> spec->skill_needed = (sint16)atoi(row[2]);
> spec->trivial = (uint16)atoi(row[3]);
> spec->nofail = atoi(row[4]) ? true : false;
> spec->replace_container = atoi(row[5]) ? true : false;
|
 |
|
 |

05-25-2007, 08:38 AM
|
Administrator
|
|
Join Date: Sep 2006
Posts: 1,348
|
|
I was asked to take a look at this stuff. So I am, but SVN has been a little =x lately with all the server issues so might not get in right away of course.
|

05-25-2007, 09:31 AM
|
Administrator
|
|
Join Date: Sep 2006
Posts: 1,348
|
|
Hey, could you post the changed switch statement in tradeskills.cpp?
I'm having trouble reading the diff at that part.
|
Thread Tools |
|
Display Modes |
Hybrid Mode
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
All times are GMT -4. The time now is 09:43 AM.
|
|
 |
|
 |
|
|
|
 |
|
 |
|
 |