Example #1
0
Item* Creature::dropCorpse()
{
	Item* splash = NULL;
	if(getRace() == RACE_VENOM)
		splash = Item::CreateItem(ITEM_FULLSPLASH, FLUID_SLIME);
	else if(getRace() == RACE_BLOOD)
		splash = Item::CreateItem(ITEM_FULLSPLASH, FLUID_BLOOD);

	Tile* tile = getParentTile();
	if(splash){
		if(g_game.internalAddItem(NULL, tile, splash, INDEX_WHEREEVER, FLAG_IGNOREBLOCKITEM | FLAG_IGNOREBLOCKCREATURE) == RET_NOERROR){
			g_game.startDecay(splash);
		}
		else{
			g_game.FreeThing(splash);
		}
	}

	Item* corpse = createCorpse();
	if(corpse){
		if(g_game.internalAddItem(NULL, tile, corpse, INDEX_WHEREEVER, FLAG_IGNOREBLOCKITEM | FLAG_IGNOREBLOCKCREATURE) == RET_NOERROR){
			dropLoot(corpse->getContainer());
			g_game.startDecay(corpse);
			return corpse;
		}
		else{
			g_game.FreeThing(corpse);
		}
	}

	return NULL;
}
Example #2
0
void House::resetTransferItem()
{
	if(transferItem){
		Item* tmpItem = transferItem;
		transferItem = NULL;
		transfer_container.setParent(NULL);

		transfer_container.__removeThing(tmpItem, tmpItem->getItemCount());
		g_game.FreeThing(tmpItem);
	}
}
Example #3
0
void Tile::postAddNotification(Thing* thing, const Cylinder* oldParent, int32_t index, cylinderlink_t link /*= LINK_OWNER*/)
{
	const Position& cylinderMapPos = getPosition();

	SpectatorVec list;
	g_game.getSpectators(list, cylinderMapPos, true, true);

	for (SpectatorVec::const_iterator it = list.begin(), end = list.end(); it != end; ++it) {
		(*it)->getPlayer()->postAddNotification(thing, oldParent, index, LINK_NEAR);
	}

	//add a reference to this item, it may be deleted after being added (mailbox for example)
	thing->useThing2();

	if (link == LINK_OWNER) {
		//calling movement scripts
		Creature* creature = thing->getCreature();

		if (creature) {
			g_moveEvents->onCreatureMove(creature, this, true);
		} else {
			Item* item = thing->getItem();
			if (item) {
				g_moveEvents->onItemMove(item, this, true);
			}
		}

		if (hasFlag(TILESTATE_TELEPORT)) {
			Teleport* teleport = getTeleportItem();

			if (teleport) {
				teleport->__addThing(thing);
			}
		} else if (hasFlag(TILESTATE_TRASHHOLDER)) {
			TrashHolder* trashholder = getTrashHolder();

			if (trashholder) {
				trashholder->__addThing(thing);
			}
		} else if (hasFlag(TILESTATE_MAILBOX)) {
			Mailbox* mailbox = getMailbox();

			if (mailbox) {
				mailbox->__addThing(thing);
			}
		}
	}

	//release the reference to this item onces we are finished
	g_game.FreeThing(thing);
}
Example #4
0
Spawn::~Spawn()
{
	stopEvent();
	Monster* monster = NULL;
	for(SpawnedMap::iterator it = spawnedMap.begin(); it != spawnedMap.end(); ++it)
	{
		if(!(monster = it->second))
			continue;

		monster->setSpawn(NULL);
		if(!monster->isRemoved())
			g_game.FreeThing(monster);
	}

	spawnedMap.clear();
	spawnMap.clear();
}
Example #5
0
void Tile::__addThing(int32_t index, Thing* thing)
{
	Creature* creature = thing->getCreature();

	if (creature)
	{
		g_game.clearSpectatorCache();
		creature->setParent(this);
		CreatureVector* creatures = makeCreatures();
		creatures->insert(creatures->begin(), creature);
		++thingCount;
	}
	else
	{
		Item* item = thing->getItem();

		if (!item)
		{
#ifdef __DEBUG__MOVESYS__
			std::cout << "Failure: [Tile::__addThing] item == NULL" << std::endl;
			DEBUG_REPORT
#endif
			return /*RET_NOTPOSSIBLE*/;
		}

		TileItemVector* items = getItemList();

		if (items && items->size() > 0xFFFF)
		{
			return /*RET_NOTPOSSIBLE*/;
		}

		item->setParent(this);

		if (item->isGroundTile())
		{
			if (!ground)
			{
				ground = item;
				++thingCount;
				onAddTileItem(item);
			}
			else
			{
				const ItemType& oldType = Item::items[ground->getID()];
				const ItemType& newType = Item::items[item->getID()];
				int32_t oldGroundIndex = __getIndexOfThing(ground);
				Item* oldGround = ground;
				ground->setParent(NULL);
				g_game.FreeThing(ground);
				ground = item;
				updateTileFlags(oldGround, true);
				updateTileFlags(item, false);
				onUpdateTileItem(oldGround, oldType, item, newType);
				postRemoveNotification(oldGround, NULL, oldGroundIndex, true);
			}
		}
		else if (item->isAlwaysOnTop())
		{
			if (item->isSplash())
			{
				//remove old splash if exists
				if (items)
				{
					for (ItemVector::iterator it = items->getBeginTopItem(); it != items->getEndTopItem(); ++it)
					{
						if ((*it)->isSplash())
						{
							int32_t oldSplashIndex = __getIndexOfThing(*it);
							Item* oldSplash = *it;
							__removeThing(oldSplash, 1);
							oldSplash->setParent(NULL);
							g_game.FreeThing(oldSplash);
							postRemoveNotification(oldSplash, NULL, oldSplashIndex, true);
							break;
						}
					}
				}
			}

			bool isInserted = false;

			if (items)
			{
				for (ItemVector::iterator it = items->getBeginTopItem(); it != items->getEndTopItem(); ++it)
				{
					//Note: this is different from internalAddThing
					if (Item::items[item->getID()].alwaysOnTopOrder <= Item::items[(*it)->getID()].alwaysOnTopOrder)
					{
						items->insert(it, item);
						++thingCount;
						isInserted = true;
						break;
					}
				}
			}
			else
			{
				items = makeItemList();
			}

			if (!isInserted)
			{
				items->push_back(item);
				++thingCount;
			}

			onAddTileItem(item);
		}
		else
		{
			if (item->isMagicField())
			{
				//remove old field item if exists
				if (items)
				{
					MagicField* oldField = NULL;

					for (ItemVector::iterator it = items->getBeginDownItem(); it != items->getEndDownItem(); ++it)
					{
						if ((oldField = (*it)->getMagicField()))
						{
							if (oldField->isReplaceable())
							{
								int32_t oldFieldIndex = __getIndexOfThing(*it);
								__removeThing(oldField, 1);
								oldField->setParent(NULL);
								g_game.FreeThing(oldField);
								postRemoveNotification(oldField, NULL, oldFieldIndex, true);
								break;
							}
							else
							{
								//This magic field cannot be replaced.
								item->setParent(NULL);
								g_game.FreeThing(item);
								return;
							}
						}
					}
				}
			}

			items = makeItemList();
			items->insert(items->getBeginDownItem(), item);
			++items->downItemCount;
			++thingCount;
			onAddTileItem(item);
		}
	}
Example #6
0
void Tile::__addThing(int32_t index, Thing* thing)
{
	Creature* creature = thing->getCreature();
	if(creature){
		creature->setParent(this);
		creatures.insert(creatures.begin(), creature);
	}
	else{
		Item* item = thing->getItem();
		if(item == NULL){
#ifdef __DEBUG__MOVESYS__
			std::cout << "Failure: [Tile::__addThing] item == NULL" << std::endl;
			int *a = NULL; *a = 1;
#endif
			return /*RET_NOTPOSSIBLE*/;
		}
		
		item->setParent(this);

		if(item->isGroundTile()){
			if(ground == NULL){
				onAddTileItem(item);
			}
			else{
				uint32_t index = __getIndexOfThing(ground);				
				onUpdateTileItem(index, ground, item);

				ground->setParent(NULL);
				g_game.FreeThing(ground);
				ground = NULL;
			}

			ground = item;
		}
		else if(item->isAlwaysOnTop()){
			if(item->isSplash()){
				//remove old splash if exists
				ItemVector::iterator iit;
				for(iit = topItems.begin(); iit != topItems.end(); ++iit){
					if((*iit)->isSplash()){
						Item* oldSplash = *iit;
						__removeThing(oldSplash, 1);

						oldSplash->setParent(NULL);
						g_game.FreeThing(oldSplash);
						break;
					}
				}
			}

			bool isInserted = false;
			ItemVector::iterator iit;
			for(iit = topItems.begin(); iit != topItems.end(); ++iit){
				//Note: this is different from internalAddThing
				if(Item::items[item->getID()].alwaysOnTopOrder <= Item::items[(*iit)->getID()].alwaysOnTopOrder){
					topItems.insert(iit, item);
					isInserted = true;
					break;
				}
			}

			if(!isInserted){
				topItems.push_back(item);
			}

			onAddTileItem(item);
		}
		else{
			if(item->isMagicField()){
				//remove old field item if exists
				ItemVector::iterator iit;
				for(iit = downItems.begin(); iit != downItems.end(); ++iit){
					if((*iit)->isMagicField()){
						Item* oldField = *iit;
						__removeThing(oldField, 1);

						oldField->setParent(NULL);
						g_game.FreeThing(oldField);
						break;
					}
				}
			}

			downItems.insert(downItems.begin(), item);
			onAddTileItem(item);
		}
	}
}