//--------------------------------------------------- // createItem : // //--------------------------------------------------- //CGameItemPtr CGameItemManager::createItem( CEntityId& id, CSheetId& sheetId, uint16 quality, sint16 slot, bool destroyable, bool dropable , const CEntityId &creatorId ) CGameItemPtr CGameItemManager::createItem( const CSheetId& sheetId, uint16 quality, bool destroyable, bool dropable , const CEntityId &creatorId ) { H_AUTO(GIM_createItem1); // test if the item already exists // map<CEntityId,CGameItemPtr>::iterator itIt = _Items.find( id ); // if( itIt != _Items.end() ) // { // nlwarning("<CGameItemManager::createItem> The item %s already exists",id.toString().c_str()); // return NULL; // } // MALKAV 22/01/03 : get owner, if owner not found, returns before creating the item and display a simple warning // CGameItemPtr ownerItem = NULL; // if( owner != CEntityId::Unknown ) // { // ownerItem = getItem( owner ); // BOMB_IF(ownerItem == NULL ,"Bad owner found for item",return NULL); // } // // create a new item // CGameItemPtr item = getNewItem( id, sheetId, quality, destroyable, dropable ); CGameItemPtr item = getNewItem(sheetId, quality, destroyable, dropable ); if( item != NULL ) { // nldebug("<CGameItemManager::createItem> create item %s with owner %s",id.toString().c_str(), owner.toString().c_str()); // (*item)->Owner = owner; (*item)->setCreator( creatorId ); // insert the item in the map // _Items.insert( make_pair(id,item) ); // _Items.insert( item ); // insert the item in the children of the owner // MALKAV 22/01/03 : test the owner existence sooner and use a warning instead of an nlerror to keep going // if( owner != CEntityId::Unknown ) // { // CGameItemPtr ownerItem = getItem( owner ); // if( ownerItem!=NULL ) // { // (*ownerItem)->addChild( item, slot ); // } // else // { // nlerror("<CGameItemManager::createItem> Can't find the owner item %s",owner.toString().c_str()); // } // } } else { // nlwarning("<CGameItemManager::createItem> Can't create the item %s with invalid sheet '%s'", id.toString().c_str(), sheetId.toString().c_str()); nlwarning("<CGameItemManager::createItem> Can't create an item with invalid sheet '%s'", sheetId.toString().c_str()); } log_Item_Create(item->getItemId(), item->getSheetId(), item->getStackSize(), item->quality()); return item; } // createItem //
//---------------------------------------------------------------------------- bool CPVPFaction::isTPValid( CCharacter* actor, CGameItemPtr TeleportTicket ) const { bool result = ! actor->getPvPRecentActionFlag(); if( TeleportTicket != 0 && TeleportTicket->getStaticForm() != 0 && result ) { // if character have is not PvP faction flagged (Tag PvP off), only recent PvP action can forbid TP usage if( actor->getPVPFlag() == false ) return true; // check if war occurs between player character allegiances and region destination clan owner uint16 idx = CZoneManager::getInstance().getTpSpawnZoneIdByName( TeleportTicket->getStaticForm()->Destination ); const CTpSpawnZone * zone = CZoneManager::getInstance().getTpSpawnZone( idx ); if( zone != 0 ) { PVP_CLAN::TPVPClan regionFactionOwner = CPVPFactionRewardManager::getInstance().getRegionOwner( zone->getRegion() ); pair<PVP_CLAN::TPVPClan, PVP_CLAN::TPVPClan> actorAllegiance = actor->getAllegiance(); if( regionFactionOwner == PVP_CLAN::Neutral ) return true; else { if( CPVPManager2::getInstance()->factionWarOccurs(actorAllegiance.first, regionFactionOwner) == false && CPVPManager2::getInstance()->factionWarOccurs(actorAllegiance.second, regionFactionOwner) == false ) return true; } } } return false; }
// **************************************************************************** CGameItemPtr CRefInventory::removeItem(uint32 slot, uint32 quantity, TInventoryOpResult * res) { nlassert(slot < _Items.size()); CGameItemPtr ret = _Items[slot]; if (_Items[slot] != NULL) { // unlink the item _Items[slot]->setRefInventory(CInventoryPtr(NULL), INVENTORIES::INVALID_INVENTORY_SLOT); CGameItemPtr item = _Items[slot]; _Items[slot] = NULL; ++_FreeSlotCount; updateWeightAndBulk(ret, -sint32(ret->getStackSize())); // callbacks for derived class onItemChanged(slot, INVENTORIES::itc_removed); // callback views INVENTORIES::TInventoryChangeFlags flagInvChg(INVENTORIES::ic_total_bulk); flagInvChg.setEnumValue(INVENTORIES::ic_total_weight); flagInvChg.setEnumValue(INVENTORIES::ic_item_list); TViewCont::iterator first(_InventoryViews.begin()), last(_InventoryViews.end()); for (; first != last; ++first) { CInventoryViewPtr view = *first; view->onInventoryChanged(flagInvChg); view->onItemChanged(slot, INVENTORIES::itc_removed); } } if (res != NULL) *res = ior_ok; return ret; }
//---------------------------------------------------------------------------- // CGameItemManager::buildNpcSpecificItems //---------------------------------------------------------------------------- void CGameItemManager::buildNpcSpecificItems() { if (EGSLight) return; for( CAllStaticItems::const_iterator it = CSheets::getItemMapForm().begin(); it != CSheets::getItemMapForm().end(); ++it ) { // only keep npc items // if( (*it).first.toString().substr(0,4) != "npc_" ) //obsolete, now we want be able to have all non craftable item if( (*it).first.toString().substr(0,2) == "ic" ) { continue; } CGameItemPtr item; // item.newItem( CEntityId::Unknown, (*it).first, 1, 0, false,false ); item.newItem( it->first, 1, false,false ); _NpcSpecificItems.push_back(item); #ifdef NL_DEBUG nldebug("built npc item item %s", (*it).first.toString().c_str()); #endif } } // CGameItemManager //
// **************************************************************************** CInventoryBase::TInventoryOpResult CInventoryBase::moveItem( CInventoryBase* srcInv, uint32 srcSlot, CInventoryBase* dstInv, uint32 dstSlot, uint32 quantity, bool bestEffort ) { CGameItemPtr srcItem = srcInv->getItem( srcSlot ); if (srcItem == NULL) return ior_error; log_Item_Move(srcItem->getItemId(), srcInv->getInventoryId(), dstInv->getInventoryId()); // Try to move it nlctassert( INVENTORIES::REMOVE_MAX_STACK_QUANTITY == UINT_MAX ); // default arg must be compatible TInventoryOpResult res; CGameItemPtr removedItem = srcInv->removeItem( srcSlot, quantity, &res ); if (res != ior_ok) return res; // if there was no item to remove, just return ok if (removedItem == NULL) return ior_ok; res = dstInv->insertItem( removedItem, dstSlot, true ); if (res != ior_ok) { // In case of failure, put it back (assume the stack was compliant with the boundaries of the inventory (bulk, weight...) srcInv->insertItem( removedItem, srcSlot, true ); return res; } return ior_ok; }
// **************************************************************************** uint32 CInventoryBase::deleteStackItem(uint32 slot, uint32 quantity, TInventoryOpResult * res) { nlassert(slot < _Items.size()); uint32 nbDeletedItem = 0; CGameItemPtr item = getItem(slot); if(item->getStackSize() > quantity) { nbDeletedItem = quantity; item->setStackSize( item->getStackSize() - quantity ); // log_Item_UpdateQuantity(item->getItemId(), item->getStackSize(), item->getStackSize() - quantity); if( res != NULL ) *res = ior_ok; } else { nbDeletedItem = item->getStackSize(); deleteItem(slot); if( res != NULL ) { if( quantity == nbDeletedItem ) *res = ior_ok; else *res = ior_stack_undersize; } } return nbDeletedItem; }
////////////////////////////////////////////////////////////////////////////////////////////////////////// // create a system crafted item static CGameItemPtr createSystemCraftedItem( uint16 quantity, const NLMISC::CSheetId& sheet ) { if (quantity == 0) return NULL; // if quantity > 1, check if item is stackable and check stack quantity if (quantity > 1) { const CStaticItem* form = CSheets::getForm( sheet ); if( form ) { if( form->Stackable < quantity ) { quantity = (uint16) form->Stackable; } } else { nlwarning("<CFaberActionCommon::createACraftedItem> can't found form for item %s", sheet.toString().c_str()); } } if (quantity > 1) { CSheetId idSheetStack("stack.sitem"); CGameItemPtr stackItem = GameItemManager.createItem( idSheetStack, (uint16)1, CEntityId::Unknown, (sint16)0, false, CEntityId::Unknown ); if( stackItem == NULL ) { nlwarning("<CFaberActionCommon::createACraftedItem> Error while creating stack bag %s -> returned a NULL pointer", idSheetStack.toString().c_str() ); return NULL; } else { uint32 hp = 0; uint32 hpmax = 0; for( int q = 0; q < quantity; ++q ) { CGameItemPtr itemTmp = GameItemManager.createItem( const_cast< CSheetId& > ( sheet ), 1, const_cast<NLMISC::CEntityId&>(stackItem->getId()), (sint16)-1, true, CEntityId::Unknown ); if (!hp && itemTmp != NULL) { hp = itemTmp->hp(); hpmax = itemTmp->standardHP(); } } return stackItem; } } else // do not create a stack, as there is only one object { CGameItemPtr item = GameItemManager.createItem( const_cast< CSheetId& > ( sheet ), (uint16)1, CEntityId::Unknown, (sint16)0, true, CEntityId::Unknown ); if( item == NULL) { nlwarning("<CFaberActionCommon::createACraftedItem> Error while creating item %s -> returned a NULL pointer", sheet.toString().c_str() ); return NULL; } return item; } } // createSystemCraftedItem //
//----------------------------------------------------------------------------- CGameItemPtr CNamedItems::createNamedItem(const std::string & name, uint32 quantity) { if (quantity == 0) return NULL; CGameItemPtr itemSrc = getNamedItemRef(name); if( itemSrc == NULL ) return NULL; CGameItemPtr item = itemSrc->getItemCopy(); return item; }
//--------------------------------------------------- // getNewItem : // //--------------------------------------------------- //CGameItemPtr CGameItemManager::getNewItem( CEntityId& id, CSheetId& sheetId, uint16 quality, bool destroyable , bool dropable) CGameItemPtr CGameItemManager::getNewItem( const CSheetId& sheetId, uint16 quality, bool destroyable , bool dropable) { CAllStaticItems::iterator itForm = CSheets::getItemMapFormNoConst().find( sheetId ); if( itForm != CSheets::getItemMapFormNoConst().end() ) { // get the slot count // sint16 slotCount = 0; //nldebug("<CGameItemManager::getNewItem> Family type: %s", ITEMFAMILY::toString( (*itForm).second.Family ).c_str() ); // if( ( (*itForm).second.Family == ITEMFAMILY::BAG ) || ( (*itForm).second.Family == ITEMFAMILY::STACK ) ) // { // slotCount = (*itForm).second.SlotCount; // } // create the item CGameItemPtr item; // item.newItem( id, sheetId, quality, slotCount, destroyable, dropable ); item.newItem( sheetId, quality, destroyable, dropable ); // if( item!=NULL ) // { // init the dynamic values from sheet -> DONE in CGameItemCreator //(*item).Quality = (*itForm).second.Quality; //(*item).HP = (*itForm).second.HitPoints; // if this item contains sub items we create them // if( (*itForm).second.Family == ITEMFAMILY::CORPSE || (*itForm).second.Family == ITEMFAMILY::CARRION ) // { // create the content /* for (uint i=0; i < (*itForm).second.Content.size(); i++) { CSheetId itemSheetId( (*itForm).second.Content[i] ); createItem( itemSheetId, quality, id, -1, destroyable,dropable ); } */ // if the item is a corpse, we push it to list and erase the olds one if we reached max corpse count // if( (*itForm).second.Family == ITEMFAMILY::CORPSE ) // { // _Corpses.push( item ); // if( _Corpses.size() > CorpseMaxCount ) // { // CGameItemPtr itemTmp = _Corpses.front(); // destroyItem( itemTmp ); // _Corpses.pop(); // } // } // } // } return item; } return NULL; } // getNewItem //
/// Delete the nth item from this inventory // **************************************************************************** void CInventoryBase::deleteItem(uint32 slot) { nlassert(slot < _Items.size()); if (_Items[slot] != NULL) { // unlink the item CGameItemPtr item = removeItem(slot,_Items[slot]->getStackSize()); // delete it item.deleteItem(); } }
//--------------------------------------------------- void CCharacterVersionAdapter::adaptToVersion14(CCharacter &character) const { // parse all inventories and set items to max Hp when current Hp == 0 const uint sizeInv = INVENTORIES::NUM_INVENTORY; for ( uint i = 0; i < sizeInv ; ++i ) if (character._Inventory[i] != NULL) { CInventoryPtr childSrc = character._Inventory[i]; for ( uint j = 0; j < childSrc->getSlotCount(); j++ ) { CGameItemPtr item = childSrc->getItem(j); if (item != NULL) { if (item->getSheetId() != CSheetId("stack.sitem") ) { if (item->durability() == 0 && item->maxDurability() > 0) { nlinfo("player %s, patching item %s HP, new value= %u", character.getId().toString().c_str(), item->getSheetId().toString().c_str(), item->maxDurability()); item->addHp(item->maxDurability()); } } } } } }
// **************************************************************************** void CInventoryBase::onItemStackSizeChanged(uint32 slot, uint32 previousStackSize) { CGameItemPtr item = getItem(slot); sint32 deltaSize = item->getStackSize() - previousStackSize; updateWeightAndBulk(item, deltaSize); // callback all the views TViewCont::iterator first(_InventoryViews.begin()), last(_InventoryViews.end()); for (; first!= last; ++first) { CInventoryViewPtr view = *first; view->onItemStackSizeChanged(slot, previousStackSize); } }
// **************************************************************************** void CInventoryBase::updateWeightAndBulk(const CGameItemPtr &item, sint32 deltaQt) { const CStaticItem *form = item->getStaticForm(); if (form != NULL) { _InventoryBulk = uint32(max(sint32(0), sint32(_InventoryBulk + form->Bulk*deltaQt))); _InventoryWeight = uint32(max(sint32(0), sint32(_InventoryWeight + item->weight()*deltaQt))); if (_InventoryWeight > getMaxWeight()) { nlwarning("Inventory '%s' : weight is overload", INVENTORIES::toString(_InventoryId).c_str()); } if (_InventoryBulk > getMaxBulk()) { nlwarning("Inventory '%s' : bulk is overload", INVENTORIES::toString(_InventoryId).c_str()); } } }
// **************************************************************************** CInventoryBase::TInventoryOpResult CRefInventory::doInsertItem(CGameItemPtr &item, uint32 slot, bool autoStack, bool ignoreWeightAndBulk) { nlassert(item != NULL); nlassert(item->getRefInventory() == NULL); nlassert(slot < _Items.size() || slot == INVENTORIES::INVALID_INVENTORY_SLOT); if (!ignoreWeightAndBulk) { if (item->getStackWeight() + getInventoryWeight() > getMaxWeight()) return ior_overweight; if (item->getStackBulk() + getInventoryBulk() > getMaxBulk()) return ior_overbulk; } // check that we still have a free slot if (getFreeSlotCount() == 0) return ior_no_free_slot; if (slot == INVENTORIES::INSERT_IN_FIRST_FREE_SLOT) slot = getFirstFreeSlot(); // remove any item referenced here removeItem(slot); // insert and link the new item _Items[slot] = item; item->setRefInventory(CInventoryPtr(this), slot); updateWeightAndBulk(item, item->getStackSize()); --_FreeSlotCount; // callbacks for derived class onItemChanged(slot, INVENTORIES::itc_inserted); // callback views /*TViewCont::iterator first(_InventoryViews.begin()), last(_InventoryViews.end()); for (; first != last; ++first) { CInventoryViewPtr view = *first; view->onItemChanged(slot, itc_inserted); }*/ return ior_ok; }
void CMissionItem::setItemParam(CGameItemPtr item) { const CStaticRolemasterPhrase * phrase = NULL; if ( _SPhraseId != CSheetId::Unknown ) { phrase = CSheets::getSRolemasterPhrase(_SPhraseId); if (phrase == NULL) { nlwarning("<CMissionItem setItemParam> Invalid sheet %s",_SPhraseId.toString().c_str()); return; } } // if ( item->getSheetId() == CSheetId("stack.sitem") ) // { // const uint size = item->getChildren().size(); // for (uint i = 0; i < size; i++ ) // { // if ( item->getChildren()[i] != NULL ) // { // if( phrase != 0 ) // item->applyEnchantment(phrase->Bricks); // item->getChildren()[i]->setCraftParameters(_Params); // if ( _NoDrop ) // { // item->getChildren()[i]->destroyable(false); // item->getChildren()[i]->dropable(false); // } // } // } // } // else { if( phrase != 0 ) item->applyEnchantment(phrase->Bricks); item->setCraftParameters(_Params); if (_NoDrop) { item->destroyable(false); item->dropable(false); } } }// CMissionItem::setItemParam
/// test if we can stack an item on an existing one // **************************************************************************** CInventoryBase::TInventoryOpResult CInventoryBase::canStackItem(const CGameItemPtr &item, uint32 slotDst) { if (item == NULL || slotDst >= getSlotCount()) return ior_error; CGameItemPtr dstItem = getItem(slotDst); // ok if slot is empty if (dstItem == NULL) return ior_ok; // check item sheet and craft params if (!CGameItem::areStackable(item, dstItem)) return ior_item_incompatible; const CStaticItem *srcForm = CSheets::getForm(item->getSheetId()); if (dstItem->getStackSize() + item->getStackSize() > dstItem->getMaxStackSize()) return ior_stack_oversize; return ior_ok; }
bool CInterShardExchangeValidator::isExchangeAllowed(const CGameItemPtr& theItem, TShardId shardId0, TShardId shardId1) const { // allow all exchanges between characters from the same shard if (shardId0==shardId1) return true; // allow all exchanges of plot items if ( theItem->getStaticForm()->Family == ITEMFAMILY::SCROLL_R2 ) return true; // determine the maximum level for items exchanged between the 2 shards TLevelCap levelLimit= std::min(getLevelCap(shardId0),getLevelCap(shardId1)); // if item is too high level then refuse if (theItem->quality()>levelLimit) return false; // if item is flagged as non-shardExchangeable then refuse if (theItem->getStaticForm()->ShardExchangeable==false) return false; // if item is named (and not a plot item) then refuse if (!theItem->getPhraseId().empty()) return false; // we've found no reason to refuse so return true return true; }
// **************************************************************************** void CInventoryBase::dumpInventory(NLMISC::CLog & log, bool dumpItems) const { // inventory description log.displayNL("Inventory: %s", INVENTORIES::toString(_InventoryId).c_str()); log.displayRawNL("Slots: max=%u, count=%u, free=%u", getMaxSlot(), _SlotCount, _FreeSlotCount); log.displayRawNL("Weight: %u", _InventoryWeight); log.displayRawNL("Bulk: %u", _InventoryBulk); log.displayRawNL("Nb views: %u", _InventoryViews.size()); log.displayNL("(DEBUG) _Items.size() = %u", _Items.size()); if (dumpItems) { for (uint i = 0; i < _Items.size(); i++) { CGameItemPtr item = _Items[i]; if (item == NULL) continue; // short display of the item description log.displayRawNL( "%u: ", i ); item->displayInLog( log ); } } }
// **************************************************************************** void CCharacterInvView::onItemChanged(uint32 slot, INVENTORIES::TItemChangeFlags changeFlags) { H_AUTO(OnItemChange); if ( changeFlags.checkEnumValue(INVENTORIES::itc_inserted) || changeFlags.checkEnumValue(INVENTORIES::itc_lock_state) || changeFlags.checkEnumValue(INVENTORIES::itc_enchant) || changeFlags.checkEnumValue(INVENTORIES::itc_worned) ) { const CGameItemPtr item = getInventory()->getItem(slot); nlassert(item != NULL); updateClientSlot(slot, item); } else if (changeFlags.checkEnumValue(INVENTORIES::itc_removed)) { // Cleanup the item in player inventory updateClientSlot(slot, NULL); } else if (changeFlags.checkEnumValue(INVENTORIES::itc_hp)) { const CGameItemPtr item = getInventory()->getItem(slot); nlassert(item != NULL); // get new worn state ITEM_WORN_STATE::TItemWornState wornState = item->getItemWornState(); item->computeItemWornState(); // if states differs send a message if (wornState != item->getItemWornState()) { if (getCharacter() != NULL) { string msgName = ITEM_WORN_STATE::getMessageForState(item->getItemWornState()); if ( !msgName.empty()) { SM_STATIC_PARAMS_1(params, STRING_MANAGER::item); params[0].SheetId = item->getSheetId(); CCharacter::sendDynamicSystemMessage( getCharacter()->getEntityRowId(), msgName, params); } } } // send slot update to the client updateClientSlot(slot, item); } if (changeFlags.checkEnumValue(INVENTORIES::itc_info_version)) { getCharacter()->_InventoryUpdater.syncInfoVersion(getInventory()->getInventoryId(), slot); } }
//--------------------------------------------------- void CCharacterVersionAdapter::adaptToVersion17(CCharacter &character) const { // only for pre-order players CPlayer * p = PlayerManager.getPlayer( PlayerManager.getPlayerId( character.getId() ) ); if (p != NULL && p->isPreOrder()) { INVENTORIES::TInventory inventories[] = { INVENTORIES::bag, INVENTORIES::pet_animal1, INVENTORIES::pet_animal2, INVENTORIES::pet_animal3, INVENTORIES::pet_animal4, INVENTORIES::player_room }; CSheetId preOrderSheet("pre_order.sitem"); BOMB_IF(preOrderSheet == CSheetId::Unknown, "cannot find pre_order.sitem!", return); // restore pre-order item hp to the max if any bool foundPreOrderItem = false; for (uint i = 0; i < sizeof(inventories)/sizeof(inventories[0]); ++i) { CInventoryPtr inv = character.getInventory(inventories[i]); if (inv == NULL) continue; for (uint slot = 0; slot < inv->getSlotCount(); ++slot) { CGameItemPtr item = inv->getItem(slot); if (item == NULL) continue; if (item->getSheetId() == preOrderSheet) { foundPreOrderItem = true; item->addHp(item->maxDurability()); } } } // give a new pre-order item to players who lost it if (!foundPreOrderItem) { CGameItemPtr item = character.createItem(10, 1, preOrderSheet); BOMB_IF(item == NULL, "cannot create pre_order.sitem!", return); if (!character.addItemToInventory(INVENTORIES::bag, item)) if (!character.addItemToInventory(INVENTORIES::temporary, item)) item.deleteItem(); }
//--------------------------------------------------- // destroyItem : // //--------------------------------------------------- void CGameItemManager::destroyItem( CGameItemPtr &ptr ) { H_AUTO(GIM_destroyItem); if (ptr == NULL) return; // used to know if we modified the content of a bag on the ground CGameItemPtr modifiedBag = NULL; // Remove the item from it's inventory (if any) if (ptr->getInventory() != NULL) { ptr->getInventory()->removeItem(ptr->getInventorySlot()); } if (ptr->getRefInventory() != NULL) { ptr->getRefInventory()->removeItem(ptr->getRefInventorySlot()); } ptr.deleteItem(); } // destroyItem //
/* * Report the accumulated XP to a participant */ void CForageProgress::reportXPTo( CCharacter *player, float factor, CGameItemPtr toolUsed ) { H_AUTO(CForageProgress_reportXPTo); // Calculate delta level between obtained quality (level) and extractor's level, add bonus for quantity sint32 deltaLevel = player->getSkillBaseValue( _UsedSkill ) - ((sint32)quality()); deltaLevel -= (sint32)(((float)(amount() - 1)) * ForageQuantityXPDeltaLevelBonusRate.get()); // Action report for xp gain TReportAction report; report.ActorRowId = player->getEntityRowId(); report.ActionNature = ACTNATURE::SEARCH_MP; report.DeltaLvl = deltaLevel; report.factor = factor; // factor=10 and deltaLevel=0 => clientXP=1000 report.Skill = _UsedSkill; // send a message if tol is worned if ( (toolUsed != NULL) && (toolUsed->getItemWornState() == ITEM_WORN_STATE::Worned) ) { const CStaticItem * form = toolUsed->getStaticForm(); if( form ) { const string msgName = ITEM_WORN_STATE::getMessageForState(ITEM_WORN_STATE::Worned); if ( !msgName.empty()) { SM_STATIC_PARAMS_1(params, STRING_MANAGER::item); params[0].SheetId = toolUsed->getSheetId(); PHRASE_UTILITIES::sendDynamicSystemMessage( report.ActorRowId, msgName, params); } } } else { // compute wear of used tool (must be in right hand) if ( toolUsed != NULL ) player->wearRightHandItem(); // report Xp Gain unless used tool is worned PROGRESSIONPVE::CCharacterProgressionPVE::getInstance()->actionReport( report, true, false ); // don't scale delta level at low level PROGRESSIONPVP::CCharacterProgressionPVP::getInstance()->reportAction(report); } // wear armor, shield and jewels player->wearArmor(); player->wearShield(); player->wearJewels(); // Store stats about progression CSheetId hl, hr; uint32 qualityl, qualityr; CGameItemPtr item = player->getLeftHandItem(); if( item == 0 ) { qualityl = 0; } else { hl = item->getSheetId(); qualityl = item->quality(); } item = player->getRightHandItem(); if( item == 0 ) { qualityr = 0; } else { hr = item->getSheetId(); qualityr = item->quality(); } //Bsi.append( StatPath, NLMISC::toString("[EAE] %s %s %d %s %d %1.2f", player->getId().toString().c_str(), hl.toString().c_str(), qualityl, hr.toString().c_str(), qualityr, report.factor) ); //EgsStat.displayNL("[EAE] %s %s %d %s %d %1.2f", player->getId().toString().c_str(), hl.toString().c_str(), qualityl, hr.toString().c_str(), qualityr, report.factor); // EGSPD::executeActionMagic(player->getId(), hl.toString(), qualityl, hr.toString(), qualityr, report.factor); }
//-------------------------------------------------------------- // CCombatDefenderPlayer::getShield //-------------------------------------------------------------- bool CCombatDefenderPlayer::getShield(CCombatShield &shield) const { CCharacter *character = PlayerManager.getChar(_RowId); if ( !character) { return false; } CGameItemPtr shieldPtr = character->getLeftHandItem(); if (shieldPtr == NULL || shieldPtr->getStaticForm() == NULL || shieldPtr->getStaticForm()->Family != ITEMFAMILY::SHIELD ) return false; shield.Quality = shieldPtr->quality(); shield.Skill = shieldPtr->getStaticForm()->Skill; if ( shield.Skill < SKILLS::NUM_SKILLS ) { shield.SkillValue = character->getSkills()._Skills[ shield.Skill ].Current; } else shield.SkillValue = 0; shield.MaxBluntProtection = shieldPtr->getProtection(DMGTYPE::BLUNT).Max; shield.MaxPiercingProtection = shieldPtr->getProtection(DMGTYPE::PIERCING).Max; shield.MaxSlashingProtection = shieldPtr->getProtection(DMGTYPE::SLASHING).Max; shield.BluntProtectionFactor = shieldPtr->getProtection(DMGTYPE::BLUNT).Factor; shield.PiercingProtectionFactor = shieldPtr->getProtection(DMGTYPE::PIERCING).Factor; shield.SlashingProtectionFactor = shieldPtr->getProtection(DMGTYPE::BLUNT).Factor; shield.ShieldType = shieldPtr->getStaticForm()->Shield->ShieldType; shield.ArmorType = shieldPtr->getStaticForm()->Shield->ArmorType; return true; } // CCombatDefenderPlayer::getShield //
//-------------------------------------------------------------- // CCombatDefenderPlayer::getArmor //-------------------------------------------------------------- bool CCombatDefenderPlayer::getArmor( SLOT_EQUIPMENT::TSlotEquipment slot, CCombatArmor &armor ) const { CCharacter *character = PlayerManager.getChar(_RowId); if ( !character) { return false; } CGameItemPtr armorPtr = character->getItem(INVENTORIES::equipment, slot); if (armorPtr == NULL || armorPtr->getStaticForm() == NULL || armorPtr->getStaticForm()->Family != ITEMFAMILY::ARMOR) return false; armor.Quality = armorPtr->quality(); armor.Skill = armorPtr->getStaticForm()->Skill; if( armor.Skill < 0 ) { nlwarning("<CCombatDefenderPlayer::getArmor> armor.Skill negative !!!!"); armor.SkillValue = 0; } else if ( armor.Skill < SKILLS::NUM_SKILLS ) { armor.SkillValue = character->getSkills()._Skills[ armor.Skill ].Current; } else armor.SkillValue = 0; armor.MaxBluntProtection = armorPtr->getProtection(DMGTYPE::BLUNT).Max; armor.MaxPiercingProtection = armorPtr->getProtection(DMGTYPE::PIERCING).Max; armor.MaxSlashingProtection = armorPtr->getProtection(DMGTYPE::SLASHING).Max; armor.BluntProtectionFactor = armorPtr->getProtection(DMGTYPE::BLUNT).Factor; armor.PiercingProtectionFactor = armorPtr->getProtection(DMGTYPE::PIERCING).Factor; armor.SlashingProtectionFactor = armorPtr->getProtection(DMGTYPE::BLUNT).Factor; armor.ArmorType = armorPtr->getStaticForm()->Armor->ArmorType; return true; } // CCombatDefenderPlayer::getArmor //
//-------------------------------------------------------------- // apply() //-------------------------------------------------------------- void CSpecialPowerEnchantWeapon::apply() { if (!_Phrase) return; CCharacter* actor = PlayerManager.getChar(_ActorRowId); if (!actor) { nlwarning("<CSpecialPowerEnchantWeapon::apply> Cannot find actor entity or not a player"); return; } CInventoryPtr inv = actor->getInventory(INVENTORIES::handling); nlassert(inv != NULL); // Test some cases that should be avoided on client (so don't bother adding an error message) // If we have no equipped item if (inv->getSlotCount()<=0) return; // If equipped item is invalid CGameItemPtr item = inv->getItem(0); if (item == NULL) return; // If item sheet is unknown CSheetId itemSheet = item->getSheetId(); if (itemSheet==CSheetId::Unknown) return; // If item sheet is invalid const CStaticItem * form = item->getStaticForm(); if (!form) return; // If item is not a melee weapon ITEMFAMILY::EItemFamily family = form->Family; if (family!=ITEMFAMILY::MELEE_WEAPON) return; // Here equipped item is valid. Enchant removal will be done on unequip. // disable power actor->forbidPower(_PowerType, _Phrase->getConsumableFamilyId(), CTickEventHandler::getGameCycle() + _DisablePowerTime + _Duration); // create effect and apply it on actor TGameCycle const endDate = _Duration + CTickEventHandler::getGameCycle(); float damageBonus = _DpsBonus * 10.f / item->hitRate(); CEnchantWeaponEffect* effect = new CEnchantWeaponEffect(_ActorRowId, _ActorRowId, _EffectFamily, _ParamValue, endDate, _DamageType, SCORES::hit_points, damageBonus, DMGTYPE::UNDEFINED); if (effect) { effect->endsAtCasterDeath(true); effect->stackable(true); actor->addSabrinaEffect(effect); } else return; // send messages // TVectorParamCheck params; // for actor if (actor->getId().getType() == RYZOMID::player) { SM_STATIC_PARAMS_1(params, STRING_MANAGER::power_type); params[0].Enum = _PowerType; PHRASE_UTILITIES::sendDynamicSystemMessage(_ActorRowId, "POWER_USE", params); } // for spectators // { // vector<CEntityId> excluded; // excluded.push_back(actor->getId()); // // params.resize(2); // params[0].Type = STRING_MANAGER::entity; // params[0].EId = actor->getId(); // params[1].Type = STRING_MANAGER::power_type; // params[1].Enum = _PowerType; // PHRASE_UTILITIES::sendDynamicGroupSystemMessage(_ActorRowId, excluded, "POWER_USE_SPECTATORS", params); // } }
////////////////////////////////////////////////////////////////////////////////////////////////////////// // Create crafted item, consume Mps and character xp gain static void createCraftedItem( CFaberPhrase * phrase, CCharacter * c, SKILLS::ESkills skill, sint16 deltaLvl, const CSheetId& sheet, uint16 quality, uint16 nbItemsPerUnit, uint32 durability, float weight, uint16 dmg, float speed, uint16 sapLoad, float range, uint16 maxSlashingProtection, float slashingProtectionFactor, uint16 maxBluntProtection, float bluntProtectionFactor, uint16 maxPiercingProtection, float piercingProtectionFactor, uint16 DodgeBonus, uint16 ParryBonus, uint8 color ) { CGameItemPtr item; if( c != 0 ) { item = c->createItemInBag( quality, nbItemsPerUnit, sheet, c->getId() ); } else { item = createSystemCraftedItem( nbItemsPerUnit, sheet ); } if( item != 0 ) { if( item->getSheetId() == CSheetId("stack.sitem") ) { const vector< CGameItemPtr >& items = item->getChildren(); uint nbItems = items.size(); CGameItemPtr itemEvent = NULL; uint realNb = nbItems; for( uint i = 0; i < nbItems; ++i ) { if( items[ i ] != 0 ) { itemEvent = items[ i ]; items[ i ]->setHp( durability ); items[ i ]->setWeight( weight ); items[ i ]->setDamage( dmg ); items[ i ]->setSpeed( speed ); items[ i ]->setSapLoad( sapLoad ); items[ i ]->setRange( range ); items[ i ]->setProtection( DMGTYPE::BLUNT,maxBluntProtection,bluntProtectionFactor ); items[ i ]->setProtection( DMGTYPE::PIERCING,maxSlashingProtection,slashingProtectionFactor ); items[ i ]->setProtection( DMGTYPE::SLASHING,maxPiercingProtection,piercingProtectionFactor ); /* items[ i ]->setSlashingProtection( maxSlashingProtection ); items[ i ]->setBluntProtection( maxBluntProtection ); items[ i ]->setPiercingProtection( maxPiercingProtection ); items[ i ]->setSlashingProtectionFactor( slashingProtectionFactor ); items[ i ]->setBluntProtectionFactor( bluntProtectionFactor ); items[ i ]->setPiercingProtectionFactor( piercingProtectionFactor ); */ items[ i ]->setDodgeModifier( DodgeBonus ); items[ i ]->setParryModifier( ParryBonus ); items[ i ]->Color = color; } else realNb--; } if ( itemEvent != NULL ) { CMissionEventCraft event(itemEvent->getSheetId(),realNb); if( c ) c->processMissionEvent(event); } } else { item->setHp( durability ); item->setWeight( weight ); item->setDamage( dmg ); item->setSpeed( speed ); item->setSapLoad( sapLoad ); item->setRange( range ); item->setProtection( DMGTYPE::BLUNT,maxBluntProtection,bluntProtectionFactor ); item->setProtection( DMGTYPE::PIERCING,maxSlashingProtection,slashingProtectionFactor ); item->setProtection( DMGTYPE::SLASHING,maxPiercingProtection,piercingProtectionFactor ); /* item->setSlashingProtection( maxSlashingProtection ); item->setBluntProtection( maxBluntProtection ); item->setPiercingProtection( maxPiercingProtection ); item->setSlashingProtectionFactor( slashingProtectionFactor ); item->setBluntProtectionFactor( bluntProtectionFactor ); item->setPiercingProtectionFactor( piercingProtectionFactor ); */ item->setDodgeModifier( DodgeBonus ); item->setParryModifier( ParryBonus ); item->Color = color; CMissionEventCraft event(sheet,1); if( c ) c->processMissionEvent(event); } if( c != 0) { //Consume Mps c->consumeMp(); // action report for xp gain c->actionReport( 0, deltaLvl, ACTNATURE::NEUTRAL, SKILLS::toString( skill ) ); } phrase->setCraftedItem( item ); } }
//----------------------------------------------- // CFaberPhrase validate //----------------------------------------------- bool CFaberPhrase::validate() { H_AUTO(CFaberPhrase_validate); if ( !CraftSystemEnabled ) return false; CCharacter * c = (CCharacter *) CEntityBaseManager::getEntityBasePtr( _ActorRowId ); if( c == 0 ) { nlwarning("<CFaberPhrase::validate> Player character not found but his crafting action still running!!!"); return false; } // test entity can use action if (c->canEntityUseAction() == false) { return false; } // check right hand item is a crafting tool CGameItemPtr rightHandItem = c->getRightHandItem(); if (rightHandItem == NULL || rightHandItem->getStaticForm() == NULL || rightHandItem->getStaticForm()->Family != ITEMFAMILY::CRAFTING_TOOL) { PHRASE_UTILITIES::sendDynamicSystemMessage(_ActorRowId, "CRAFT_NEED_CRAFTING_TOOL"); return false; } // check tool is not worned if( rightHandItem->getItemWornState() == ITEM_WORN_STATE::Worned ) { PHRASE_UTILITIES::sendDynamicSystemMessage(_ActorRowId, "CRAFT_NEED_CRAFTING_TOOL"); return false; } // check quality of right hand item (need be >= Recommended (level of item)) if (rightHandItem->recommended()+49 < _Recommended) { PHRASE_UTILITIES::sendDynamicSystemMessage(_ActorRowId, "CRAFT_NEED_RECOMMENDED_CRAFTING_TOOL"); return false; } // entities cant craft if in combat /* commented as test of right hand item is now made... TDataSetRow entityRowId = CPhraseManager::getInstance().getEntityEngagedMeleeBy( _ActorRowId ); if (TheDataset.isAccessible(entityRowId)) { PHRASE_UTILITIES::sendDynamicSystemMessage(_ActorRowId, "CANT_CRAFT_ENGAGED_IN_MELEE"); return false; } */ const sint32 focus = c->getScores()._PhysicalScores[ SCORES::focus ].Current; if ( focus < _FocusCost ) { PHRASE_UTILITIES::sendDynamicSystemMessage(_ActorRowId, "CANT_CRAFT_NOT_ENOUGHT_FOCUS"); c->unlockFaberRms(); return false; } const sint32 hp = c->currentHp(); if (hp <= 0 || c->isDead()) { PHRASE_UTILITIES::sendDynamicSystemMessage(_ActorRowId, "CANT_CRAFT_WHEN_DEAD"); c->unlockFaberRms(); return false; } /// todo alain : test if on mount // store vector of pointer on raw material item if( state() == Evaluated ) { if( c->lockFaberRms() ) { _Mps.clear(); _MpsFormula.clear(); if( c->getFillFaberRms( _Mps, _MpsFormula, _LowerRmQuality ) == false ) //TODO check exec step { c->unlockFaberRms(); PHRASE_UTILITIES::sendDynamicSystemMessage(_ActorRowId, "CANT_FOUND_RM"); return false; } } else { c->unlockFaberRms(); PHRASE_UTILITIES::sendDynamicSystemMessage(_ActorRowId, "CANT_LOCK_RM"); return false; } } return true; }// CFaberPhrase validate
//----------------------------------------------- // CTimedActionPhrase build //----------------------------------------------- bool CTimedActionPhrase::build( const TDataSetRow & actorRowId, const std::vector< const CStaticBrick* >& bricks, bool buildToExecute ) { _ActorRowId = actorRowId; for (uint i = 0 ; i < bricks.size() ; ++i) { const CStaticBrick *brick = bricks[i]; nlassert(brick != NULL); if (i==0) _RootSheetId = brick->SheetId; // process params for ( uint j = 0 ; j < brick->Params.size() ; ++j) { TBrickParam::IId *param = brick->Params[j]; if (!param) continue; switch(param->id()) { case TBrickParam::TA_TELEPORT: { _TimedAction = new CTPTimedAction(); if (_TimedAction == NULL) { nlwarning("Error allocating new CTPTimedAction object"); return false; } _ExecutionDuration = DelayBeforeItemTP; _ActionType = CLIENT_ACTION_TYPE::Teleport; } break; case TBrickParam::TA_DISCONNECT: { _TimedAction = new CDisconnectTimedAction(); if (_TimedAction == NULL) { nlwarning("Error allocating new CTPTimedAction object"); return false; } _ExecutionDuration = TimeBeforeDisconnection; if (IsRingShard) { // Find out how much time to wait depending on the role of the character CCharacter* player = PlayerManager.getChar(_ActorRowId); if (player) { // In Ring edition and animation mode, take a short cut when Far Teleporting R2::TUserRole role = player->sessionUserRole(); if ((role == R2::TUserRole::ur_editor) || (role == R2::TUserRole::ur_animator)) _ExecutionDuration = 1; } } _ActionType = CLIENT_ACTION_TYPE::Disconnect; } break; case TBrickParam::TA_MOUNT: { _TimedAction = new CMountTimedAction(); if (_TimedAction == NULL) { nlwarning("Error allocating new CTPTimedAction object"); return false; } _ExecutionDuration = MountDuration; _ActionType = CLIENT_ACTION_TYPE::Mount; } break; case TBrickParam::TA_UNMOUNT: { _TimedAction = new CUnmountTimedAction(); if (_TimedAction == NULL) { nlwarning("Error allocating new CTPTimedAction object"); return false; } _ExecutionDuration = UnmountDuration; _ActionType = CLIENT_ACTION_TYPE::Unmount; } break; case TBrickParam::TA_CONSUME: { _TimedAction = new CConsumeItemTimedAction(); if (_TimedAction == NULL) { nlwarning("Error allocating new CConsumeItemTimedAction object"); return false; } // get item to consume to init consumption time CCharacter *player = PlayerManager.getChar(actorRowId); if (player) { CGameItemPtr item =player->getConsumedItem(); if (item != NULL) { const CStaticItem *form = item->getStaticForm(); if (form && form->ConsumableItem) { _ExecutionDuration = TGameCycle(form->ConsumableItem->ConsumptionTime / CTickEventHandler::getGameTimeStep()); } } } _ActionType = CLIENT_ACTION_TYPE::ConsumeItem; } break; default: ; }; } } return true; }// CTimedActionPhrase build
//----------------------------------------------------------------------------- void CNamedItems::loadNamedItemsFromFile(const std::string & fileName) { CHashMap<std::string, CGameItemPtr>::iterator it; for (it = _NamedItems.begin(); it != _NamedItems.end(); ++it) { GameItemManager.destroyItem((*it).second); } _NamedItems.clear(); string path; try { path = CPath::lookup(fileName); } catch (Exception &) { nlwarning("<NAMED_ITEMS> file '%s' was not found", fileName.c_str()); return; } static CPersistentDataRecord pdr; pdr.clear(); pdr.readFromTxtFile(path.c_str()); CInventoryPtr inv = loadFromPdr(pdr); if (inv == NULL) { nlwarning("<NAMED_ITEMS> error while loading items from the PDR"); return; } const uint size = inv->getSlotCount(); nlinfo("loading '%u' named items", size); for (uint i = 0; inv->getFreeSlotCount() != inv->getSlotCount() && i < size; ++i) { if (inv->getItem(i) == NULL) continue; CGameItemPtr item = inv->removeItem(i); if (item != NULL) { if (item->getSheetId() == CSheetId::Unknown) { nlwarning("<NAMED_ITEMS> item '%u' has invalid sheet id", i); GameItemManager.destroyItem(item); continue; } if (item->getPhraseId().empty()) { nlwarning("<NAMED_ITEMS> item '%u' has no name", i); GameItemManager.destroyItem(item); continue; } if (_NamedItems.find(item->getPhraseId()) != _NamedItems.end()) { nlwarning("<NAMED_ITEMS> item '%u', name '%s' exists more than once", i, item->getPhraseId().c_str()); GameItemManager.destroyItem(item); continue; } // Yoyo: force this item to work with the new form requirement system. // BUT: do it only if _UseNewSystemRequirement==false (if LDs put true, we suppose that the named item has special req value) if(item->getUseNewSystemRequirement()==false) item->computeRequirementFromForm(); nldebug("<NAMED_ITEMS> creating named item '%s'",item->getPhraseId().c_str()); _NamedItems.insert(make_pair(item->getPhraseId(), item)); } } }
//----------------------------------------------- // createInGameItem //----------------------------------------------- CGameItemPtr CGameItemManager::createInGameItem( uint16 quality, uint32 quantity, const NLMISC::CSheetId &sheet, const CEntityId &creatorId , const std::string * phraseId) { H_AUTO(GIM_createInGameItem); static const CSheetId preorderSheetId("pre_order.sitem"); if ( quantity == 0 || quality ==0 ) return NULL; // static const CSheetId idSheetStack("stack.sitem"); const CStaticItem* form = CSheets::getForm( sheet ); if (!form) { nlwarning("<CCharacter::createInGameItem> Cannot find form of item %s", sheet.toString().c_str()); return NULL; } CGameItemPtr item; CGameItemPtr sellingItem; // if item can be sold, get it in the sold items list if ( form->Family != ITEMFAMILY::RAW_MATERIAL && form->Family != ITEMFAMILY::HARVEST_TOOL && form->Family != ITEMFAMILY::CRAFTING_TOOL && form->Family != ITEMFAMILY::CRYSTALLIZED_SPELL && form->Family != ITEMFAMILY::ITEM_SAP_RECHARGE && form->Family != ITEMFAMILY::FOOD ) { vector< CGameItemPtr >::const_iterator it; const vector< CGameItemPtr >::const_iterator itEnd = CStaticItems::getStaticItems().end(); for( it = CStaticItems::getStaticItems().begin(); it != itEnd; ++it ) { if( (*it)->getSheetId() == sheet ) { sellingItem = *it; break; } } } switch( form->Family ) { case ITEMFAMILY::CRAFTING_TOOL: case ITEMFAMILY::HARVEST_TOOL: case ITEMFAMILY::RAW_MATERIAL: case ITEMFAMILY::TELEPORT: case ITEMFAMILY::CRYSTALLIZED_SPELL: case ITEMFAMILY::ITEM_SAP_RECHARGE: case ITEMFAMILY::MISSION_ITEM: case ITEMFAMILY::PET_ANIMAL_TICKET: case ITEMFAMILY::HANDLED_ITEM: case ITEMFAMILY::CONSUMABLE: case ITEMFAMILY::XP_CATALYSER: case ITEMFAMILY::SCROLL: case ITEMFAMILY::FOOD: case ITEMFAMILY::SCROLL_R2: case ITEMFAMILY::GENERIC_ITEM: { item = GameItemManager.createItem( const_cast< CSheetId& > ( sheet ), quality, true, true, creatorId); } break; default: { if( sellingItem != NULL ) { item = sellingItem->getItemCopy(); item->quality( quality ); if ( phraseId ) item->setPhraseId(*phraseId); } else if (sheet == preorderSheetId) { item = GameItemManager.createItem(sheet, quality, true, form->DropOrSell, creatorId); } } if( item == NULL) { nlwarning("<CCharacter::createInGameItem> Error while creating item : NULL pointer"); return NULL; } } quantity = min(quantity, item->getMaxStackSize()); item->setStackSize(quantity); return item; } // createInGameItem //