//returns the number of points received from the tribute int32 Client::TributeItem(uint32 slot, uint32 quantity) { const ItemInst*inst = m_inv[slot]; if(inst == nullptr) return(0); //figure out what its worth int32 pts = inst->GetItem()->Favor; pts = mod_tribute_item_value(pts, m_inv[slot]); if(pts < 1) { Message(13, "This item is worthless for favor."); return(0); } /* Make sure they have enough of them and remove it from inventory */ if(inst->IsStackable()) { if(inst->GetCharges() < (int32)quantity) //dont have enough.... return(0); DeleteItemInInventory(slot, quantity, false); } else { quantity = 1; DeleteItemInInventory(slot, 0, false); } pts *= quantity; /* Add the tribute value in points */ AddTributePoints(pts); return(pts); }
void Client::DoTributeUpdate() { EQApplicationPacket outapp(OP_TributeUpdate, sizeof(TributeInfo_Struct)); TributeInfo_Struct *tis = (TributeInfo_Struct *) outapp.pBuffer; tis->active = m_pp.tribute_active ? 1 : 0; tis->tribute_master_id = tribute_master_id; //Dont know what this is for int r; for (r = 0; r < EQEmu::legacy::TRIBUTE_SIZE; r++) { if(m_pp.tributes[r].tribute != TRIBUTE_NONE) { tis->tributes[r] = m_pp.tributes[r].tribute; tis->tiers[r] = m_pp.tributes[r].tier; } else { tis->tributes[r] = TRIBUTE_NONE; tis->tiers[r] = 0; } } QueuePacket(&outapp); SendTributeTimer(); if(m_pp.tribute_active) { //send and equip tribute items... for (r = 0; r < EQEmu::legacy::TRIBUTE_SIZE; r++) { uint32 tid = m_pp.tributes[r].tribute; if(tid == TRIBUTE_NONE) { if (m_inv[EQEmu::legacy::TRIBUTE_BEGIN + r]) DeleteItemInInventory(EQEmu::legacy::TRIBUTE_BEGIN + r, 0, false); continue; } if(tribute_list.count(tid) != 1) { if (m_inv[EQEmu::legacy::TRIBUTE_BEGIN + r]) DeleteItemInInventory(EQEmu::legacy::TRIBUTE_BEGIN + r, 0, false); continue; } //sanity check if(m_pp.tributes[r].tier >= MAX_TRIBUTE_TIERS) { if (m_inv[EQEmu::legacy::TRIBUTE_BEGIN + r]) DeleteItemInInventory(EQEmu::legacy::TRIBUTE_BEGIN + r, 0, false); m_pp.tributes[r].tier = 0; continue; } TributeData &d = tribute_list[tid]; TributeLevel_Struct &tier = d.tiers[m_pp.tributes[r].tier]; uint32 item_id = tier.tribute_item_id; //summon the item for them const ItemInst* inst = database.CreateItem(item_id, 1); if(inst == nullptr) continue; PutItemInInventory(EQEmu::legacy::TRIBUTE_BEGIN + r, *inst, false); SendItemPacket(EQEmu::legacy::TRIBUTE_BEGIN + r, inst, ItemPacketTributeItem); safe_delete(inst); } } else { //unequip tribute items... for (r = 0; r < EQEmu::legacy::TRIBUTE_SIZE; r++) { if (m_inv[EQEmu::legacy::TRIBUTE_BEGIN + r]) DeleteItemInInventory(EQEmu::legacy::TRIBUTE_BEGIN + r, 0, false); } } CalcBonuses(); }
void Client::GoFish() { //TODO: generate a message if we're already fishing /*if (!fishing_timer.Check()) { //this isn't the right check, may need to add something to the Client class like 'bool is_fishing' Message_StringID(0, ALREADY_FISHING); //You are already fishing! return; }*/ fishing_timer.Disable(); //we're doing this a second time (1st in Client::Handle_OP_Fishing) to make sure that, between when we started fishing & now, we're still able to fish (in case we move, change equip, etc) if (!CanFish()) //if we can't fish here, we don't need to bother with the rest return; //multiple entries yeilds higher probability of dropping... uint32 common_fish_ids[MAX_COMMON_FISH_IDS] = { 1038, // Tattered Cloth Sandals 1038, // Tattered Cloth Sandals 1038, // Tattered Cloth Sandals 13019, // Fresh Fish 13076, // Fish Scales 13076, // Fish Scales 7007, // Rusty Dagger 7007, // Rusty Dagger 7007 // Rusty Dagger }; //success formula is not researched at all int fishing_skill = GetSkill(SkillFishing); //will take into account skill bonuses on pole & bait //make sure we still have a fishing pole on: int32 bslot = m_inv.HasItemByUse(ItemTypeFishingBait, 1, invWhereWorn|invWherePersonal); const ItemInst* Bait = nullptr; if (bslot != INVALID_INDEX) Bait = m_inv.GetItem(bslot); //if the bait isnt equipped, need to add its skill bonus if(bslot >= EmuConstants::GENERAL_BEGIN && Bait->GetItem()->SkillModType == SkillFishing) { fishing_skill += Bait->GetItem()->SkillModValue; } if (fishing_skill > 100) { fishing_skill = 100+((fishing_skill-100)/2); } if (zone->random.Int(0,175) < fishing_skill) { uint32 food_id = 0; //25% chance to fish an item. if (zone->random.Int(0, 399) <= fishing_skill ) { uint32 npc_id = 0; uint8 npc_chance = 0; food_id = database.GetZoneFishing(m_pp.zone_id, fishing_skill, npc_id, npc_chance); //check for add NPC if(npc_chance > 0 && npc_id) { if(npc_chance < zone->random.Int(0, 99)) { const NPCType* tmp = database.GetNPCType(npc_id); if(tmp != nullptr) { NPC* npc = new NPC(tmp, nullptr, GetX()+3, GetY(), GetZ(), GetHeading(), FlyMode3); npc->AddLootTable(); npc->AddToHateList(this, 1, 0, false); //no help yelling entity_list.AddNPC(npc); Message(MT_Emote, "You fish up a little more than you bargained for..."); } } } } //consume bait, should we always consume bait on success? DeleteItemInInventory(bslot, 1, true); //do we need client update? if(food_id == 0) { int index = zone->random.Int(0, MAX_COMMON_FISH_IDS-1); food_id = common_fish_ids[index]; } const Item_Struct* food_item = database.GetItem(food_id); Message_StringID(MT_Skills, FISHING_SUCCESS); ItemInst* inst = database.CreateItem(food_item, 1); if(inst != nullptr) { if(CheckLoreConflict(inst->GetItem())) { Message_StringID(0, DUP_LORE); safe_delete(inst); } else { PushItemOnCursor(*inst); SendItemPacket(MainCursor, inst, ItemPacketSummonItem); if(RuleB(TaskSystem, EnableTaskSystem)) UpdateTasksForItem(ActivityFish, food_id); safe_delete(inst); inst = m_inv.GetItem(MainCursor); } if(inst) { std::vector<EQEmu::Any> args; args.push_back(inst); parse->EventPlayer(EVENT_FISH_SUCCESS, this, "", inst->GetID(), &args); } } } else { //chance to use bait when you dont catch anything... if (zone->random.Int(0, 4) == 1) { DeleteItemInInventory(bslot, 1, true); //do we need client update? Message_StringID(MT_Skills, FISHING_LOST_BAIT); //You lost your bait! } else { if (zone->random.Int(0, 15) == 1) //give about a 1 in 15 chance to spill your beer. we could make this a rule, but it doesn't really seem worth it //TODO: check for & consume an alcoholic beverage from inventory when this triggers, and set it as a rule that's disabled by default Message_StringID(MT_Skills, FISHING_SPILL_BEER); //You spill your beer while bringing in your line. else Message_StringID(MT_Skills, FISHING_FAILED); //You didn't catch anything. } parse->EventPlayer(EVENT_FISH_FAILURE, this, "", 0); } //chance to break fishing pole... //this is potentially exploitable in that they can fish //and then swap out items in primary slot... too lazy to fix right now if (zone->random.Int(0, 49) == 1) { Message_StringID(MT_Skills, FISHING_POLE_BROKE); //Your fishing pole broke! DeleteItemInInventory(MainPrimary, 0, true); } if(CheckIncreaseSkill(SkillFishing, nullptr, 5)) { if(title_manager.IsNewTradeSkillTitleAvailable(SkillFishing, GetRawSkill(SkillFishing))) NotifyNewTitlesAvailable(); } }