zone/tradeskills.cpp
Code:
// Perform tradeskill combine
// complete tradeskill rewrite by father nitwit, 8/2004
void Object::HandleCombine(Client* user, const NewCombine_Struct* in_combine, Object *worldo)
{
if (!user || !in_combine) {
LogFile->write(EQEMuLog::Error, "Client or NewCombine_Struct not set in Object::HandleCombine");
return;
}
Inventory& user_inv = user->GetInv();
PlayerProfile_Struct& user_pp = user->GetPP();
ItemInst* container = NULL;
ItemInst* inst = NULL;
<! int8 tstype = 0xE8;
!> uint8 c_type = 0xE8;
<! uint8 passtype = 0;
!> uint32 some_id = 0;
bool worldcontainer=false;
<! if (in_combine->container_slot == SLOT_TRADESKILL) {
!> if (in_combine->container_slot == SLOT_WORLDCONTAINER) {
if(!worldo) {
user->Message(13, "Error: Server is not aware of the tradeskill container you are attempting to use");
return;
}
inst = worldo->m_inst;
!> c_type = worldo->m_type;
worldcontainer=true;
}
else {
inst = user_inv.GetItem(in_combine->container_slot);
if (inst) {
const Item_Struct* item = inst->GetItem();
if (item && inst->IsType(ItemClassContainer)) {
c_type = item->BagType;
!> some_id = item->ID;
}
}
}
if (!inst || !inst->IsType(ItemClassContainer)) {
user->Message(13, "Error: Server does not recognize specified tradeskill container");
return;
}
container = inst;
<! // Convert container type to tradeskill type
<! SkillType tradeskill = TradeskillUnknown;
<! switch (tstype)
<! {
<! 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)
<! 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);
<! return;
<! break;
<! case 10: //Tinkering Still needs completion
<! if (user_pp.race == GNOME)
<! tradeskill = TINKERING;
<! else
<! user->Message(13, "Only gnomes can tinker.");
<! break;
<! case 24: //Research Still needs completion
<! case 25:
<! case 26:
<! case 27:
<! tradeskill = RESEARCH;
<! return;
<! break;
<! case 12:
<! if (user_pp.class_ == ROGUE)
<! tradeskill = MAKE_POISON;
<! else
<! user->Message(13, "Only rogues can mix poisons.");
<! break;
<! case 13: //Quest Containers
<! tradeskill = GENERIC_TRADESKILL;
<! break;
<! case 46: //Fishing Still needs completion
<! tradeskill = FISHING;
<! return;
<! break;
<! }
<!
<! 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)) {
!> 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)
!> {
!> case ALCHEMY:
!> 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);
!> return;
!> break;
!> case TINKERING:
!> if (user_pp.race != GNOME)
!> user->Message(13, "Only gnomes can tinker.");
!> return;
!> break;
!> case MAKE_POISON:
!> if (user_pp.class_ != ROGUE)
!> user->Message(13, "Only rogues can mix poisons.");
!> return;
!> break;
!> }
//do the check and send results...
<! bool success = user->TradeskillExecute(&spec, tradeskill);
!> bool success = user->TradeskillExecute(&spec);
// Send acknowledgement packets to client
EQApplicationPacket* outapp = new EQApplicationPacket(OP_TradeSkillCombine, 0);
user->QueuePacket(outapp);
safe_delete(outapp);
//now clean out the containers.
if(worldcontainer){
container->Clear();
outapp = new EQApplicationPacket(OP_ClearObject,0);
user->QueuePacket(outapp);
safe_delete(outapp);
database.DeleteWorldContainer(worldo->m_id, zone->GetZoneID());
if(success && spec.replace_container) {
//should report this error, but we dont have the recipe ID, so its not very useful
LogFile->write(EQEMuLog::Error, "Replace container combine executed in a world container.");
}
} else{
for (uint8 i=0; i<10; i++){
const ItemInst* inst = container->GetItem(i);
if (inst) {
user->DeleteItemInInventory(Inventory::CalcSlotId(in_combine->container_slot,i),0,true);
}
}
container->Clear();
if(success && spec.replace_container) {
user->DeleteItemInInventory(in_combine->container_slot, 0, true);
}
}
}
Removed references to tstype and passtype as tradeskill info is no longer relevant
Added references to c_type and some_id to be consistent with naming on client_packet.cpp
Removed code to assign tradeskill based on combiner type
Changed function call to pass combiner type and some_id instead of combiner type and tradeskill
After return from getting recipe (which now identifies tradeskill it wants to use) added code to check classes against tradeskill
changed function call to TradeskillExecute to remove tradeskill from parameter list as it is now included in spec.