示例#1
0
//---------------------------------------------------
// 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 //
示例#2
0
//----------------------------------------------------------------------------
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;
}
示例#3
0
// ****************************************************************************
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;
}
示例#4
0
//----------------------------------------------------------------------------
// 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 //
示例#5
0
// ****************************************************************************
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;
}
示例#6
0
// ****************************************************************************
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;
}
示例#7
0
	//////////////////////////////////////////////////////////////////////////////////////////////////////////
	// 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 //
示例#8
0
//-----------------------------------------------------------------------------
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;
}
示例#9
0
//---------------------------------------------------
// 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 //
示例#10
0
/// 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());
					}
				}
			}
		}
	}
}
示例#12
0
// ****************************************************************************
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);
	}
}
示例#13
0
// ****************************************************************************
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());
		}
	}
}
示例#14
0
// ****************************************************************************
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;
}
示例#15
0
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
示例#16
0
/// 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;
}
示例#18
0
// ****************************************************************************
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 );
		}
	}
}
示例#19
0
// ****************************************************************************
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();
		}
示例#21
0
//---------------------------------------------------
// 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);
}
示例#23
0
//--------------------------------------------------------------
//				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 //
示例#24
0
//--------------------------------------------------------------
//				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);
//	}
}
示例#26
0
	//////////////////////////////////////////////////////////////////////////////////////////////////////////
	// 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 );
		}
	}
示例#27
0
//-----------------------------------------------
// 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
示例#28
0
//-----------------------------------------------
// 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
示例#29
0
//-----------------------------------------------------------------------------
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));
		}
	}
}
示例#30
0
//-----------------------------------------------
// 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 //