bool CChar::ItemEquipWeapon( bool fForce ) { ADDTOCALLSTACK("CChar::ItemEquipWeapon"); // Find my best weapon and equip it if ( !fForce && m_uidWeapon.IsValidUID() ) // we already have a weapon equipped return true; CCharBase *pCharDef = Char_GetDef(); CItemContainer *pPack = GetPack(); if ( !pPack || !pCharDef || !pCharDef->Can(CAN_C_USEHANDS) ) return false; // Loop through all my weapons and come up with a score for it's usefulness CItem *pBestWeapon = NULL; int iWeaponScoreMax = NPC_GetWeaponUseScore(NULL); // wrestling for ( CItem *pItem = pPack->GetContentHead(); pItem != NULL; pItem = pItem->GetNext() ) { int iWeaponScore = NPC_GetWeaponUseScore(pItem); if ( iWeaponScore > iWeaponScoreMax ) { iWeaponScoreMax = iWeaponScore; pBestWeapon = pItem; } } if ( pBestWeapon ) return ItemEquip(pBestWeapon); return true; }
bool CChar::ItemEquipArmor( bool fForce ) { ADDTOCALLSTACK("CChar::ItemEquipArmor"); // Equip ourselves as best as possible. CCharBase *pCharDef = Char_GetDef(); CItemContainer *pPack = GetPack(); if ( !pPack || !pCharDef || !pCharDef->Can(CAN_C_EQUIP) ) return false; int iBestScore[LAYER_HORSE]; memset(iBestScore, 0, sizeof(iBestScore)); CItem *pBestArmor[LAYER_HORSE]; memset(pBestArmor, 0, sizeof(pBestArmor)); if ( !fForce ) { // Block those layers that are already used for ( size_t i = 0; i < COUNTOF(iBestScore); i++ ) { pBestArmor[i] = LayerFind(static_cast<LAYER_TYPE>(i)); if ( pBestArmor[i] != NULL ) iBestScore[i] = INT_MAX; } } for ( CItem *pItem = pPack->GetContentHead(); pItem != NULL; pItem = pItem->GetNext() ) { int iScore = pItem->Armor_GetDefense(); if ( !iScore ) // might not be armor continue; // Can I even equip this? LAYER_TYPE layer = CanEquipLayer(pItem, LAYER_QTY, NULL, true); if ( layer == LAYER_NONE ) continue; if ( iScore > iBestScore[layer] ) { iBestScore[layer] = iScore; pBestArmor[layer] = pItem; } } // Equip all the stuff we found for ( size_t i = 0; i < COUNTOF(iBestScore); i++ ) { if ( pBestArmor[i] ) ItemEquip(pBestArmor[i], this); } return true; }
void CChar::NPC_PetClearOwners(bool bResendTooltip) { ADDTOCALLSTACK("CChar::NPC_PetClearOwners"); CChar *pOwner = NPC_PetGetOwner(); Memory_ClearTypes(MEMORY_IPET|MEMORY_FRIEND); if ( m_pNPC ) m_pNPC->m_bonded = 0; // pets without owner cannot be bonded if ( NPC_IsVendor() ) { StatFlag_Clear(STATF_INVUL); if ( pOwner ) // give back to NPC owner all the stuff we are trying to sell { CItemContainer *pBankVendor = GetContainerCreate(LAYER_BANKBOX); CItemContainer *pBankOwner = pOwner->GetContainerCreate(LAYER_BANKBOX); pOwner->AddGoldToPack(pBankVendor->m_itEqBankBox.m_Check_Amount, pBankOwner); pBankVendor->m_itEqBankBox.m_Check_Amount = 0; for ( size_t i = 0; i < COUNTOF(sm_VendorLayers); i++ ) { CItemContainer *pCont = GetContainerCreate(sm_VendorLayers[i]); if ( !pCont ) continue; CItem *pItemNext = NULL; for ( CItem *pItem = pCont->GetContentHead(); pItem != NULL; pItem = pItemNext ) { pItemNext = pItem->GetNext(); pBankOwner->ContentAdd(pItem); } } } } if ( IsStatFlag(STATF_Ridden) ) { CChar *pCharRider = Horse_GetMountChar(); if ( pCharRider ) pCharRider->Horse_UnMount(); } if ( pOwner ) { if ( IsSetOF(OF_PetSlots) ) pOwner->FollowersUpdate(this, static_cast<short>(-maximum(1, GetDefNum("FOLLOWERSLOTS", true)))); if ( bResendTooltip ) ResendTooltip(); } }
bool CChar::NPC_StablePetSelect( CChar * pCharPlayer ) { ADDTOCALLSTACK("CChar::NPC_StablePetSelect"); // I am a stable master. // I will stable a pet for the player. if ( pCharPlayer == NULL ) return false; if ( ! pCharPlayer->IsClient()) return false; // Might have too many pets already ? int iCount = 0; CItemContainer * pBank = GetBank(); if ( pBank->GetCount() >= MAX_ITEMS_CONT ) { Speak( g_Cfg.GetDefaultMsg( DEFMSG_NPC_STABLEMASTER_FULL ) ); return false; } // Calculate the max limit of pets that the NPC can hold for the player double iSkillTaming = pCharPlayer->Skill_GetAdjusted(SKILL_TAMING); double iSkillAnimalLore = pCharPlayer->Skill_GetAdjusted(SKILL_ANIMALLORE); double iSkillVeterinary = pCharPlayer->Skill_GetAdjusted(SKILL_VETERINARY); double iSkillSum = iSkillTaming + iSkillAnimalLore + iSkillVeterinary; int iPetMax; if ( iSkillSum >= 240.0 ) iPetMax = 5; else if ( iSkillSum >= 200.0 ) iPetMax = 4; else if ( iSkillSum >= 160.0 ) iPetMax = 3; else iPetMax = 2; if ( iSkillTaming >= 100.0 ) iPetMax += (int)((iSkillTaming - 90.0) / 10); if ( iSkillAnimalLore >= 100.0 ) iPetMax += (int)((iSkillAnimalLore - 90.0) / 10); if ( iSkillVeterinary >= 100.0 ) iPetMax += (int)((iSkillVeterinary - 90.0) / 10); if ( m_TagDefs.GetKey("MAXPLAYERPETS") ) iPetMax = (int)(m_TagDefs.GetKeyNum("MAXPLAYERPETS")); for ( CItem *pItem = pBank->GetContentHead(); pItem != NULL; pItem = pItem->GetNext() ) { if ( pItem->IsType(IT_FIGURINE) && pItem->m_uidLink == pCharPlayer->GetUID() ) iCount++; } if ( iCount >= iPetMax ) { Speak( g_Cfg.GetDefaultMsg( DEFMSG_NPC_STABLEMASTER_TOOMANY ) ); return false; } pCharPlayer->m_pClient->m_Targ_PrvUID = GetUID(); pCharPlayer->m_pClient->addTarget( CLIMODE_TARG_PET_STABLE, g_Cfg.GetDefaultMsg( DEFMSG_NPC_STABLEMASTER_TARG ) ); return true; }
void CItemContainer::Trade_Status( bool bCheck ) { ADDTOCALLSTACK("CItemContainer::Trade_Status"); // Update trade status check boxes to both sides. CItemContainer *pPartner = dynamic_cast<CItemContainer*>(m_uidLink.ItemFind()); if ( !pPartner ) return; CChar *pChar1 = dynamic_cast<CChar*>(GetParent()); if ( !pChar1 ) return; CChar *pChar2 = dynamic_cast<CChar*>(pPartner->GetParent()); if ( !pChar2 ) return; m_itEqTradeWindow.m_bCheck = bCheck ? 1 : 0; if ( !bCheck ) pPartner->m_itEqTradeWindow.m_bCheck = 0; PacketTradeAction cmd(SECURE_TRADE_CHANGE); if ( pChar1->IsClient() ) { cmd.prepareReadyChange(this, pPartner); cmd.send(pChar1->GetClient()); } if ( pChar2->IsClient() ) { cmd.prepareReadyChange(pPartner, this); cmd.send(pChar2->GetClient()); } // Check if both clients had pressed the 'accept' buttom if ( pPartner->m_itEqTradeWindow.m_bCheck == 0 || m_itEqTradeWindow.m_bCheck == 0 ) return; CItem *pItem, *pItemNext; int iCont1, iCont2; unsigned short i; CScriptTriggerArgs Args1(pChar1); pItem = pPartner->GetContentHead(); for ( i = 1; pItem != NULL; pItem = pItemNext, ++i ) { pItemNext = pItem->GetNext(); Args1.m_VarObjs.Insert(i, pItem, true); } Args1.m_iN1 = iCont1 = --i; pItemNext = NULL; CScriptTriggerArgs Args2(pChar2); pItem = GetContentHead(); for ( i = 1; pItem != NULL; pItem = pItemNext, ++i ) { pItemNext = pItem->GetNext(); Args2.m_VarObjs.Insert(i, pItem, true); } Args2.m_iN1 = iCont2 = --i; pItemNext = NULL; if ( (IsTrigUsed(TRIGGER_TRADEACCEPTED)) || (IsTrigUsed(TRIGGER_CHARTRADEACCEPTED)) ) { Args1.m_iN2 = iCont2; Args2.m_iN2 = iCont1; if ( (pChar1->OnTrigger(CTRIG_TradeAccepted, pChar2, &Args1) == TRIGRET_RET_TRUE) || (pChar2->OnTrigger(CTRIG_TradeAccepted, pChar1, &Args2) == TRIGRET_RET_TRUE) ) Delete(); } // Transfer items pItem = GetContentHead(); for ( ; pItem != NULL; pItem = pItemNext ) { pItemNext = pItem->GetNext(); pChar2->ItemBounce(pItem); } pItemNext = NULL; pItem = pPartner->GetContentHead(); for ( ; pItem != NULL; pItem = pItemNext ) { pItemNext = pItem->GetNext(); pChar1->ItemBounce(pItem); } // Transfer gold/platinum if ( g_Cfg.m_iFeatureTOL & FEATURE_TOL_VIRTUALGOLD ) { INT64 iGold1 = m_itEqTradeWindow.m_iGold + (m_itEqTradeWindow.m_iPlatinum * 1000000000); INT64 iGold2 = pPartner->m_itEqTradeWindow.m_iGold + (pPartner->m_itEqTradeWindow.m_iPlatinum * 1000000000); pChar1->m_virtualGold += iGold2 - iGold1; pChar2->m_virtualGold += iGold1 - iGold2; pChar1->UpdateStatsFlag(); pChar2->UpdateStatsFlag(); } // done with trade. Delete(); }