//--------------------------------------------------- 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()); } } } } } }
//--------------------------------------------------- // 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 //
// **************************************************************************** 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(); }
// **************************************************************************** void CCharacterInvView::updateClientSlot(uint32 slot, const CGameItemPtr item) { // do nothing if client is not ready if (!getCharacter()->getEnterFlag()) return; if (item != NULL) { uint32 price; RM_FABER_STAT_TYPE::TRMStatType itemBestStat; getCharacter()->queryItemPrice( item, price ); itemBestStat = item->getCraftParameters() == 0 ? RM_FABER_STAT_TYPE::Unknown : item->getCraftParameters()->getBestItemStat(); BOTCHATTYPE::TBotChatResaleFlag resaleFlag = (item->durability() == item->maxDurability() ? BOTCHATTYPE::ResaleOk : BOTCHATTYPE::ResaleKOBroken); if (item->getLockedByOwner()) { resaleFlag = BOTCHATTYPE::ResaleKOLockedByOwner; } INVENTORIES::CItemSlot itemSlot( slot ); itemSlot.setItemProp( INVENTORIES::Sheet, item->getSheetId().asInt() ); itemSlot.setItemProp( INVENTORIES::Quality, item->quality() ); itemSlot.setItemProp( INVENTORIES::Quantity, item->getStackSize() ); itemSlot.setItemProp( INVENTORIES::UserColor, item->color() ); itemSlot.setItemProp( INVENTORIES::Locked, item->getLockCount() ); itemSlot.setItemProp( INVENTORIES::Weight, item->weight() / 10 ); itemSlot.setItemProp( INVENTORIES::NameId, item->sendNameId(getCharacter()) ); itemSlot.setItemProp( INVENTORIES::Enchant, item->getClientEnchantValue() ); itemSlot.setItemProp( INVENTORIES::Price, price ); itemSlot.setItemProp( INVENTORIES::ResaleFlag, resaleFlag ); itemSlot.setItemProp( INVENTORIES::ItemClass, item->getItemClass() ); itemSlot.setItemProp( INVENTORIES::ItemBestStat, itemBestStat ); itemSlot.setItemProp( INVENTORIES::PrerequisitValid, getCharacter()->checkPreRequired( item ) ); itemSlot.setItemProp( INVENTORIES::Worned, (item->getItemWornState()==ITEM_WORN_STATE::Worned)); getCharacter()->_InventoryUpdater.setItemProps( getInventory()->getInventoryId(), itemSlot ); } else { // empty slot getCharacter()->_InventoryUpdater.resetItem( getInventory()->getInventoryId(), slot ); } // send slot update to the client getCharacter()->_InventoryUpdater.incInfoVersion(getInventory()->getInventoryId(), slot); }
/// 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; }
//----------------------------------------------------------------------------- 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)); } } }
/* * 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); }
//-------------------------------------------------------------- // 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 ); } }