Esempio n. 1
0
void Tile::onUpdateTile()
{
	const Position& cylinderMapPos = getPosition();

	SpectatorVec list;
	SpectatorVec::iterator it;
	g_game.getSpectators(Range(cylinderMapPos, true), list);

	//send to client
	Player* player = NULL;
	for(it = list.begin(); it != list.end(); ++it){
		if(player = (*it)->getPlayer()){
			player->sendUpdateTile(cylinderMapPos);
		}
	}

	g_game.isExecutingEvents = true;

	//event methods
	for(it = list.begin(); it != list.end(); ++it){
		(*it)->onUpdateTile(cylinderMapPos);
	}

	g_game.isExecutingEvents = false;
}
Esempio n. 2
0
void Tile::onRemoveTileItem(const SpectatorVec& list, std::vector<uint32_t>& oldStackPosVector, Item* item)
{
	if (item->hasProperty(MOVEABLE) || item->getContainer()) {
		Game::BrowseFieldMap::const_iterator it = g_game.browseFields.find(this);
		if (it != g_game.browseFields.end()) {
			it->second->__removeThing(item, item->getItemCount());
		}
	}

	updateTileFlags(item, true);

	const Position& cylinderMapPos = getPosition();
	const ItemType& iType = Item::items[item->getID()];

	SpectatorVec::const_iterator end = list.end();

	//send to client
	int32_t i = 0;

	for (SpectatorVec::const_iterator it = list.begin(); it != end; ++it) {
		if (Player* tmpPlayer = (*it)->getPlayer()) {
			tmpPlayer->sendRemoveTileItem(this, cylinderMapPos, oldStackPosVector[i], item);
			++i;
		}
	}

	//event methods
	for (SpectatorVec::const_iterator it = list.begin(); it != end; ++it) {
		(*it)->onRemoveTileItem(this, cylinderMapPos, iType, item);
	}
}
Esempio n. 3
0
int ActionScript::luaActionDoSendAnimatedText(lua_State *L)
{
	//doSendAnimatedText(position,text,color)
	int color = (int)internalGetNumber(L);
	const char * text = internalGetString(L);
	PositionEx pos;
	internalGetPositionEx(L,pos);

	ActionScript *action = getActionScript(L);

	Position realpos = internalGetRealPosition(action, action->_player,(Position&)pos);
	SpectatorVec list;
	SpectatorVec::iterator it;

	action->game->getSpectators(Range(realpos, true), list);

	for(it = list.begin(); it != list.end(); ++it) {
		Player *p = dynamic_cast<Player*>(*it);
		if(p)
			p->sendAnimatedText(realpos, color, text);
	}

	lua_pushnumber(L, 0);
	return 1;
}
Esempio n. 4
0
void Tile::postRemoveNotification(Thing* thing, const Cylinder* newParent, int32_t index, bool isCompleteRemoval, cylinderlink_t link /*= LINK_OWNER*/)
{
	const Position& cylinderMapPos = getPosition();

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

	if (/*isCompleteRemoval &&*/ getThingCount() > 8) {
		onUpdateTile(list);
	}

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

	//calling movement scripts
	Creature* creature = thing->getCreature();

	if (creature) {
		g_moveEvents->onCreatureMove(creature, this, false);
	} else {
		Item* item = thing->getItem();
		if (item) {
			g_moveEvents->onItemMove(item, this, false);
		}
	}
}
Esempio n. 5
0
void Tile::onRemoveTileItem(const SpectatorVec& list, std::vector<uint32_t>& oldStackPosVector, Item* item)
{
	updateTileFlags(item, true);
	const Position& cylinderMapPos = getPosition();
	const ItemType& iType = Item::items[item->getID()];
	SpectatorVec::const_iterator it;
	//send to client
	Player* tmpPlayer = NULL;
	uint32_t i = 0;

	for (it = list.begin(); it != list.end(); ++it)
	{
		if ((tmpPlayer = (*it)->getPlayer()))
		{
			tmpPlayer->sendRemoveTileItem(this, cylinderMapPos, oldStackPosVector[i], item);
			++i;
		}
	}

	//event methods
	for (it = list.begin(); it != list.end(); ++it)
	{
		(*it)->onRemoveTileItem(this, cylinderMapPos, iType, item);
	}
}
Esempio n. 6
0
void Tile::onUpdateTile(const SpectatorVec& list)
{
	const Position& cylinderMapPos = getPosition();

	//send to clients
	for (SpectatorVec::const_iterator it = list.begin(), end = list.end(); it != end; ++it) {
		(*it)->getPlayer()->sendUpdateTile(this, cylinderMapPos);
	}
}
Esempio n. 7
0
bool Spawn::findPlayer(const Position& pos)
{
	SpectatorVec list;
	g_game.getSpectators(list, pos, false, true);

	for (SpectatorVec::const_iterator it = list.begin(), end = list.end(); it != end; ++it) {
		if (!(*it)->getPlayer()->hasFlag(PlayerFlag_IgnoredByMonsters)) {
			return true;
		}
	}

	return false;
}
Esempio n. 8
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);
}
Esempio n. 9
0
void Spawn::idle(int t)
{
	SpawnedMap::iterator it;
	for(it = spawnedmap.begin(); it != spawnedmap.end();) {
		if (it->second->isRemoved == true /*it->second->health <= 0*/) {
			if(it->first != 0) {
				spawnmap[it->first].lastspawn = OTSYS_TIME();
			}
			it->second->releaseThing();
			//delete it->second;
			spawnedmap.erase(it++);
		}
		else if(!isInSpawnRange(it->second->pos) && it->first != 0) {
			spawnedmap.insert(spawned_pair(0, it->second));
			spawnedmap.erase(it++);
		}
		else
			++it;
	}
	
	for(SpawnMap::iterator sit = spawnmap.begin(); sit != spawnmap.end(); ++sit) {

		if(spawnedmap.count(sit->first) == 0) {
			if((OTSYS_TIME() - sit->second.lastspawn) >= sit->second.spawntime) {

				SpectatorVec list;
				SpectatorVec::iterator it;

				game->getSpectators(Range(sit->second.pos, true), list);

				bool playerFound = false;
				for(it = list.begin(); it != list.end(); ++it) {
					Player *player = dynamic_cast<Player*>(*it);

					if(player && player->access < g_config.ACCESS_PROTECT) {
						playerFound = true;
						break;
					}
				}
				
				if(playerFound) {
					sit->second.lastspawn = OTSYS_TIME();
					continue;
				}

				respawn(sit->first, sit->second.pos, sit->second.name, sit->second.dir);
			}
		}
	}
}
Esempio n. 10
0
bool Spawn::findPlayer(const Position& pos)
{
	SpectatorVec list;
	g_game.getSpectators(list, pos);

	Player* tmpPlayer = NULL;
	for(SpectatorVec::iterator it = list.begin(); it != list.end(); ++it)
	{
		if((tmpPlayer = (*it)->getPlayer()) && !tmpPlayer->hasFlag(PlayerFlag_IgnoredByMonsters))
			return true;
	}

	return false;
}
Esempio n. 11
0
bool Monster::convinceCreature(Creature* creature)
{
	Player* player = creature->getPlayer();
	if(player && !player->hasFlag(PlayerFlag_CanConvinceAll) && !mType->isConvinceable)
		return false;

	Creature* oldMaster = NULL;
	if(isSummon())
		oldMaster = master;

	if(oldMaster)
	{
		if(oldMaster->getPlayer() || oldMaster == creature)
			return false;

		oldMaster->removeSummon(this);
	}

	setFollowCreature(NULL);
	setAttackedCreature(NULL);
	destroySummons();

	creature->addSummon(this);
	updateTargetList();
	updateIdleStatus();

	//Notify surrounding about the change
	SpectatorVec list;
	g_game.getSpectators(list, getPosition(), false, true);
	g_game.getSpectators(list, creature->getPosition(), true, true);

	isMasterInRange = true;
	for(SpectatorVec::iterator it = list.begin(); it != list.end(); ++it)
		(*it)->onCreatureConvinced(creature, this);

	if(spawn)
	{
		spawn->removeMonster(this);
		spawn = NULL;
		masterRadius = -1;
	}

	if(raid)
	{
		raid->unRef();
		raid = NULL;
	}

	return true;
}
Esempio n. 12
0
void Tile::moveCreature(Creature* creature, Cylinder* toCylinder, bool teleport /* = false*/)
{
	int32_t oldStackPos = __getIndexOfThing(creature);

	//remove the creature
	__removeThing(creature, 0);

	//add the creature
	toCylinder->__addThing(creature);

	Position fromPos = getPosition();
	Position toPos = toCylinder->getPosition();

	if(!teleport){
		if(fromPos.y > toPos.y)
			creature->setDirection(NORTH);
		else if(fromPos.y < toPos.y)
			creature->setDirection(SOUTH);
		if(fromPos.x < toPos.x)
			creature->setDirection(EAST);
		else if(fromPos.x > toPos.x)
			creature->setDirection(WEST);
	}

	SpectatorVec list;
	SpectatorVec::iterator it;
	g_game.getSpectators(Range(fromPos, true), list);
	g_game.getSpectators(Range(toPos, true), list);

	//send to client
	Player* player = NULL;
	for(it = list.begin(); it != list.end(); ++it) {
		if(player = (*it)->getPlayer()){
			player->sendCreatureMove(creature, fromPos, oldStackPos, teleport);
		}
	}

	g_game.isExecutingEvents = true;

	//event method
	for(it = list.begin(); it != list.end(); ++it) {
		(*it)->onCreatureMove(creature, fromPos, oldStackPos, teleport);
	}

	g_game.isExecutingEvents = false;

	toCylinder->postAddNotification(creature);
	postRemoveNotification(creature);
}
Esempio n. 13
0
void Container::onAddContainerItem(Item* item)
{
	const Position& cylinderMapPos = getPosition();

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

	SpectatorVec::const_iterator end = list.end();

	//send to client
	for(SpectatorVec::const_iterator it = list.begin(); it != end; ++it)
		(*it)->getPlayer()->sendAddContainerItem(this, item);

	//event methods
	for(SpectatorVec::const_iterator it = list.begin(); it != end; ++it)
		(*it)->getPlayer()->onAddContainerItem(this, item);
}
Esempio n. 14
0
bool ConditionRegeneration::executeCondition(Creature* creature, int32_t interval)
{
	internalHealthTicks += interval;
	internalManaTicks += interval;

	if (creature->getZone() != ZONE_PROTECTION) {
		if (internalHealthTicks >= healthTicks) {
			internalHealthTicks = 0;

			int32_t realHealthGain = creature->getHealth();
			creature->changeHealth(healthGain);
			realHealthGain = creature->getHealth() - realHealthGain;

			if (isBuff && realHealthGain > 0) {
				Player* player = creature->getPlayer();
				if (player) {
					std::string healString = std::to_string(realHealthGain) + (realHealthGain != 1 ? " hitpoints." : " hitpoint.");

					TextMessage message(MESSAGE_HEALED, "You were healed for " + healString);
					message.position = player->getPosition();
					message.primary.value = realHealthGain;
					message.primary.color = TEXTCOLOR_MAYABLUE;
					player->sendTextMessage(message);

					SpectatorVec list;
					g_game.map.getSpectators(list, player->getPosition(), false, true);
					list.erase(player);
					if (!list.empty()) {
						message.type = MESSAGE_HEALED_OTHERS;
						message.text = player->getName() + " was healed for " + healString;
						for (Creature* spectator : list) {
							spectator->getPlayer()->sendTextMessage(message);
						}
					}
				}
			}
		}

		if (internalManaTicks >= manaTicks) {
			internalManaTicks = 0;
			creature->changeMana(manaGain);
		}
	}

	return ConditionGeneric::executeCondition(creature, interval);
}
Esempio n. 15
0
void Container::onRemoveContainerItem(uint32_t index, Item* item)
{
	const Position& cylinderMapPos = getPosition();

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

	SpectatorVec::const_iterator end = list.end();

	//send change to client
	Item* lastItem = getItem(maxSize);
	for(SpectatorVec::const_iterator it = list.begin(); it != end; ++it)
		(*it)->getPlayer()->sendRemoveContainerItem(this, index, lastItem);

	//event methods
	for(SpectatorVec::const_iterator it = list.begin(); it != end; ++it)
		(*it)->getPlayer()->onRemoveContainerItem(this, index, item);
}
Esempio n. 16
0
void Container::onUpdateContainerItem(uint32_t index, Item* oldItem, const ItemType& oldType,
	Item* newItem, const ItemType& newType)
{
	const Position& cylinderMapPos = getPosition();

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

	SpectatorVec::const_iterator end = list.end();

	//send to client
	for(SpectatorVec::const_iterator it = list.begin(); it != end; ++it)
		(*it)->getPlayer()->sendUpdateContainerItem(this, index, oldItem, newItem);

	//event methods
	for(SpectatorVec::const_iterator it = list.begin(); it != end; ++it)
		(*it)->getPlayer()->onUpdateContainerItem(this, index, oldItem, oldType, newItem, newType);
}
Esempio n. 17
0
void Tile::postAddNotification(Thing* thing, bool hasOwnership /*= true*/)
{
	const Position& cylinderMapPos = getPosition();

	SpectatorVec list;
	SpectatorVec::iterator it;
	g_game.getSpectators(Range(cylinderMapPos, true), list);

	for(it = list.begin(); it != list.end(); ++it){
		if(Player* player = (*it)->getPlayer()){
			player->postAddNotification(thing, false);
		}
	}

	//do action(s)
	if(Creature* creature = thing->getCreature()){
		MagicEffectItem* fieldItem = getFieldItem();
		if(fieldItem){
			//remove magic walls/wild growth
			if(fieldItem->isBlocking()){
				g_game.internalRemoveItem(fieldItem, 1);
			}

			const MagicEffectTargetCreatureCondition* magicTargetCondition = fieldItem->getCondition();

			if(!(g_game.getWorldType() == WORLD_TYPE_NO_PVP && creature && magicTargetCondition && magicTargetCondition->getOwnerID() != 0)){
				fieldItem->getDamage(creature);
			}
			
			if(magicTargetCondition && ((magicTargetCondition->attackType == ATTACK_FIRE) || 
					(magicTargetCondition->attackType == ATTACK_POISON) ||
					(magicTargetCondition->attackType == ATTACK_ENERGY))){	
				Creature* attacker = g_game.getCreatureByID(magicTargetCondition->getOwnerID());
				g_game.creatureMakeMagic(attacker, creature->getPosition(), magicTargetCondition);
			}
		}
	}
	
	Teleport* teleport = getTeleportItem();
	if(teleport){
		teleport->__addThing(thing);
	}
}
Esempio n. 18
0
int ActionScript::luaActionDoPlayerAddHealth(lua_State *L)
{
	//doPlayerAddHealth(uid,health)
	int addhealth = (int)internalGetNumber(L);
	unsigned int cid = (unsigned int)internalGetNumber(L);

	ActionScript *action = getActionScript(L);

	const KnownThing* tmp = action->GetPlayerByUID(cid);
	if(tmp){
		Player *player = (Player*)(tmp->thing);
		int tmp = player->health + addhealth;
		if(tmp <= 0){
			player->health = 1;
		}
		else if(tmp > player->healthmax){
			player->health = player->healthmax;
		}
		else{
			player->health = tmp;
		}
		player->sendStats();

		SpectatorVec list;
		SpectatorVec::iterator it;

		action->game->getSpectators(Range(player->pos,true), list);
		for(it = list.begin(); it != list.end(); ++it) {
			Player* p = dynamic_cast<Player*>(*it);
			if(p)
				p->sendCreatureHealth(player);
		}
	}
	else{
		lua_pushnumber(L, -1);
		std::cout << "luaDoPlayerAddHealth: player not found" << std::endl;
		return 1;
	}

	lua_pushnumber(L, 0);
	return 1;
}
Esempio n. 19
0
void Creature::onGainExperience(uint64_t gainExp, Creature* target)
{
	if (gainExp != 0 && getMaster()) {
		gainExp = gainExp / 2;
		getMaster()->onGainExperience(gainExp, target);

		const Position& targetPos = getPosition();

		std::ostringstream ssExp;
		ssExp << ucfirst(getNameDescription()) << " gained " << gainExp << " experience points.";
		std::string strExp = ssExp.str();

		SpectatorVec list;
		g_game.getSpectators(list, targetPos, false, true);

		for (SpectatorVec::const_iterator it = list.begin(), end = list.end(); it != end; ++it) {
			(*it)->getPlayer()->sendExperienceMessage(MSG_EXPERIENCE_OTHERS, strExp, targetPos, gainExp, TEXTCOLOR_WHITE_EXP);
		}
	}
}
Esempio n. 20
0
void Container::onRemoveContainerItem(uint32_t index, Item* item)
{
    const Position& cylinderMapPos = getPosition();
    SpectatorVec list;

    SpectatorVec::iterator it;
    g_game.getSpectators(list, cylinderMapPos, false, false, 2, 2, 2, 2);

    //send change to client
    Player* player = NULL;
    for(it = list.begin(); it != list.end(); ++it)
    {
        if((player = (*it)->getPlayer()))
            player->sendRemoveContainerItem(this, index, item);
    }

    //event methods
    for(it = list.begin(); it != list.end(); ++it)
    {
        if((player = (*it)->getPlayer()))
            player->onRemoveContainerItem(this, index, item);
    }
}
Esempio n. 21
0
void Creature::onGainExperience(uint64_t gainExp, Creature* target)
{
	if (gainExp == 0 || !master) {
		return;
	}

	gainExp /= 2;
	master->onGainExperience(gainExp, target);

	SpectatorVec list;
	g_game.map.getSpectators(list, position, false, true);
	if (list.empty()) {
		return;
	}

	TextMessage message(MESSAGE_EXPERIENCE_OTHERS, ucfirst(getNameDescription()) + " gained " + std::to_string(gainExp) + (gainExp != 1 ? " experience points." : " experience point."));
	message.position = position;
	message.primary.color = TEXTCOLOR_WHITE_EXP;
	message.primary.value = gainExp;

	for (Creature* spectator : list) {
		spectator->getPlayer()->sendTextMessage(message);
	}
}
Esempio n. 22
0
void Container::onUpdateContainerItem(uint32_t index, Item* oldItem, const ItemType& oldType,
                                      Item* newItem, const ItemType& newType)
{
    const Position& cylinderMapPos = getPosition();
    SpectatorVec list;

    SpectatorVec::iterator it;
    g_game.getSpectators(list, cylinderMapPos, false, false, 2, 2, 2, 2);

    //send to client
    Player* player = NULL;
    for(it = list.begin(); it != list.end(); ++it)
    {
        if((player = (*it)->getPlayer()))
            player->sendUpdateContainerItem(this, index, oldItem, newItem);
    }

    //event methods
    for(it = list.begin(); it != list.end(); ++it)
    {
        if((player = (*it)->getPlayer()))
            player->onUpdateContainerItem(this, index, oldItem, oldType, newItem, newType);
    }
}
Esempio n. 23
0
void Tile::postRemoveNotification(Thing* thing, bool hadOwnership /*= true*/)
{
	const Position& cylinderMapPos = getPosition();

	SpectatorVec list;
	SpectatorVec::iterator it;
	g_game.getSpectators(Range(cylinderMapPos, true), list);

	if(getThingCount() > 8){
		onUpdateTile();

		/*//send to client
		for(it = list.begin(); it != list.end(); ++it){
			(*it)->onUpdateTile(cylinderMapPos);
		}
		*/
	}

	for(it = list.begin(); it != list.end(); ++it){
		if(Player* player = (*it)->getPlayer()){
			player->postRemoveNotification(thing, false);
		}
	}
}
Esempio n. 24
0
void Tile::moveCreature(Creature* actor, Creature* creature, Cylinder* toCylinder, bool forceTeleport/* = false*/)
{
	Tile* newTile = toCylinder->getTile();
	SpectatorVec list;
	SpectatorVec::iterator it;

	g_game.getSpectators(list, pos, false, true);
	Position newPos = newTile->getPosition();
	g_game.getSpectators(list, newPos, true, true);

	bool teleport = false;
	if(forceTeleport || !newTile->ground || !Position::areInRange<1,1,0>(pos, newPos))
		teleport = true;

	std::vector<uint32_t> oldStackposVector;
	Player* tmpPlayer = NULL;
	for(it = list.begin(); it != list.end(); ++it)
	{
		if((tmpPlayer = (*it)->getPlayer()))
			oldStackposVector.push_back(getClientIndexOfThing(tmpPlayer, creature));
	}

	int32_t oldStackpos = __getIndexOfThing(creature);
	//remove the creature
	__removeThing(creature, 0);
	//switch the node ownership
	if(qt_node != newTile->qt_node)
	{
		qt_node->removeCreature(creature);
		newTile->qt_node->addCreature(creature);
	}

	//add the creature
	newTile->__addThing(actor, creature);
	int32_t newStackpos = newTile->__getIndexOfThing(creature);
	if(!teleport)
	{
		if(pos.y > newPos.y)
			creature->setDirection(NORTH);
		else if(pos.y < newPos.y)
			creature->setDirection(SOUTH);
		if(pos.x < newPos.x)
			creature->setDirection(EAST);
		else if(pos.x > newPos.x)
			creature->setDirection(WEST);
	}

	//send to client
	int32_t i = 0;
	for(it = list.begin(); it != list.end(); ++it)
	{
		if((tmpPlayer = (*it)->getPlayer()) && tmpPlayer->canSeeCreature(creature))
			tmpPlayer->sendCreatureMove(creature, newTile, newPos, this, pos, oldStackposVector[i++], teleport);
	}

	//event method
	for(it = list.begin(); it != list.end(); ++it)
		(*it)->onCreatureMove(creature, newTile, newPos, this, pos, teleport);

	postRemoveNotification(actor, creature, toCylinder, oldStackpos, true);
	newTile->postAddNotification(actor, creature, this, newStackpos);
}
Esempio n. 25
0
void Tile::removeThing(Thing* thing, uint32_t count)
{
	Creature* creature = thing->getCreature();
	if (creature) {
		CreatureVector* creatures = getCreatures();
		if (creatures) {
			CreatureVector::iterator it = std::find(creatures->begin(), creatures->end(), thing);
			if (it != creatures->end()) {
				g_game.map.clearSpectatorCache();
				creatures->erase(it);
			}
		}
		return;
	}

	Item* item = thing->getItem();
	if (!item) {
		return;
	}

	int32_t index = getThingIndex(item);
	if (index == -1) {
		return;
	}

	if (item == ground) {
		ground->setParent(nullptr);
		ground = nullptr;

		SpectatorVec list;
		g_game.map.getSpectators(list, getPosition(), true);
		onRemoveTileItem(list, std::vector<int32_t>(list.size(), 0), item);
		return;
	}

	TileItemVector* items = getItemList();
	if (!items) {
		return;
	}

	const ItemType& itemType = Item::items[item->getID()];
	if (itemType.alwaysOnTop) {
		auto it = std::find(items->getBeginTopItem(), items->getEndTopItem(), item);
		if (it == items->getEndTopItem()) {
			return;
		}

		std::vector<int32_t> oldStackPosVector;

		SpectatorVec list;
		g_game.map.getSpectators(list, getPosition(), true);
		for (Creature* spectator : list) {
			if (Player* tmpPlayer = spectator->getPlayer()) {
				oldStackPosVector.push_back(getStackposOfItem(tmpPlayer, item));
			}
		}

		item->setParent(nullptr);
		items->erase(it);
		onRemoveTileItem(list, oldStackPosVector, item);
	} else {
		auto it = std::find(items->getBeginDownItem(), items->getEndDownItem(), item);
		if (it == items->getEndDownItem()) {
			return;
		}

		if (itemType.stackable && count != item->getItemCount()) {
			uint8_t newCount = static_cast<uint8_t>(std::max<int32_t>(0, static_cast<int32_t>(item->getItemCount() - count)));
			item->setItemCount(newCount);
			onUpdateTileItem(item, itemType, item, itemType);
		} else {
			std::vector<int32_t> oldStackPosVector;

			SpectatorVec list;
			g_game.map.getSpectators(list, getPosition(), true);
			for (Creature* spectator : list) {
				if (Player* tmpPlayer = spectator->getPlayer()) {
					oldStackPosVector.push_back(getStackposOfItem(tmpPlayer, item));
				}
			}

			item->setParent(nullptr);
			items->erase(it);
			items->addDownItemCount(-1);
			onRemoveTileItem(list, oldStackPosVector, item);
		}
	}
}
Esempio n. 26
0
void Tile::moveCreature(Creature* creature, Cylinder* toCylinder, bool teleport /* = false*/)
{
	Tile* newTile = toCylinder->getTile();
	int32_t oldStackPos = __getIndexOfThing(creature);
	Position oldPos = getPosition();
	Position newPos = newTile->getPosition();
	Player* tmpPlayer = NULL;
	SpectatorVec list;
	SpectatorVec::iterator it;
	g_game.getSpectators(list, oldPos, false, true);
	g_game.getSpectators(list, newPos, true, true);
	std::vector<uint32_t> oldStackPosVector;

	for (it = list.begin(); it != list.end(); ++it)
	{
		if ((tmpPlayer = (*it)->getPlayer()))
		{
			oldStackPosVector.push_back(getClientIndexOfThing(tmpPlayer, creature));
		}
	}

	//remove the creature
	__removeThing(creature, 0);

	// Switch the node ownership
	if (qt_node != newTile->qt_node)
	{
		qt_node->removeCreature(creature);
		newTile->qt_node->addCreature(creature);
	}

	//add the creature
	newTile->__addThing(creature);
	int32_t newStackPos = newTile->__getIndexOfThing(creature);

	if (!teleport)
	{
		if (oldPos.y > newPos.y)
		{
			creature->setDirection(NORTH);
		}
		else if (oldPos.y < newPos.y)
		{
			creature->setDirection(SOUTH);
		}

		if (oldPos.x < newPos.x)
		{
			creature->setDirection(EAST);
		}
		else if (oldPos.x > newPos.x)
		{
			creature->setDirection(WEST);
		}
	}

	//send to client
	uint32_t i = 0;

	for (it = list.begin(); it != list.end(); ++it)
	{
		if ((tmpPlayer = (*it)->getPlayer()))
		{
			tmpPlayer->sendCreatureMove(creature, newTile, newPos, this, oldPos, oldStackPosVector[i], teleport);
			++i;
		}
	}

	//event method
	for (it = list.begin(); it != list.end(); ++it)
	{
		(*it)->onCreatureMove(creature, newTile, newPos, this, oldPos, teleport);
	}

	postRemoveNotification(creature, toCylinder, oldStackPos, true);
	newTile->postAddNotification(creature, this, newStackPos);
}
Esempio n. 27
0
void Tile::moveCreature(Creature* creature, Cylinder* toCylinder, bool forceTeleport/* = false*/)
{
	Tile* newTile = toCylinder->getTile();
	int32_t oldStackPos = __getIndexOfThing(creature);

	Position oldPos = getPosition();
	Position newPos = newTile->getPosition();

	bool teleport = false;

	if (forceTeleport || !newTile->ground || !Position::areInRange<1, 1, 0>(oldPos, newPos)) {
		teleport = true;
	}

	SpectatorVec list;
	g_game.getSpectators(list, oldPos, true);
	g_game.getSpectators(list, newPos, true);

	SpectatorVec::const_iterator end = list.end();

	std::vector<uint32_t> oldStackPosVector;

	for (SpectatorVec::const_iterator it = list.begin(); it != end; ++it) {
		if (Player* tmpPlayer = (*it)->getPlayer()) {
			oldStackPosVector.push_back(getClientIndexOfThing(tmpPlayer, creature));
		}
	}

	//remove the creature
	__removeThing(creature, 0);

	// Switch the node ownership
	if (qt_node != newTile->qt_node) {
		qt_node->removeCreature(creature);
		newTile->qt_node->addCreature(creature);
	}

	//add the creature
	newTile->__addThing(creature);
	int32_t newStackPos = newTile->__getIndexOfThing(creature);

	if (!teleport) {
		if (oldPos.y > newPos.y) {
			creature->setDirection(NORTH);
		} else if (oldPos.y < newPos.y) {
			creature->setDirection(SOUTH);
		}

		if (oldPos.x < newPos.x) {
			creature->setDirection(EAST);
		} else if (oldPos.x > newPos.x) {
			creature->setDirection(WEST);
		}
	}

	//send to client
	uint32_t i = 0;

	for (SpectatorVec::const_iterator it = list.begin(); it != end; ++it) {
		if (Player* tmpPlayer = (*it)->getPlayer()) {
			//Use the correct stackpos
			if (!creature->isInGhostMode() || tmpPlayer->isAccessPlayer()) {
				tmpPlayer->sendCreatureMove(creature, newTile, newPos, this, oldPos, oldStackPosVector[i], teleport);
			}

			++i;
		}
	}

	//event method
	for (SpectatorVec::const_iterator it = list.begin(); it != end; ++it) {
		(*it)->onCreatureMove(creature, newTile, newPos, this, oldPos, teleport);
	}

	postRemoveNotification(creature, toCylinder, oldStackPos, true);
	newTile->postAddNotification(creature, this, newStackPos);
}
Esempio n. 28
0
bool Actor::convinceCreature(Creature* creature)
{
  Player* player = creature->getPlayer();
  if(player && !player->hasFlag(PlayerFlag_CanConvinceAll)){
    if(!cType.isConvinceable()){
      return false;
    }
  }

  if(isPlayerSummon()){
    return false;
  }
  else if(isSummon()){
    if(getMaster() != creature){
      Creature* oldMaster = getMaster();
      oldMaster->removeSummon(this);
      creature->addSummon(this);

      setFollowCreature(NULL);
      setAttackedCreature(NULL);

      //destroy summons
      destroySummons();

      isMasterInRange = true;
      updateTargetList();
      updateIdleStatus();

      //Notify surrounding about the change
      SpectatorVec list;
      g_game.getSpectators(list, getPosition(), false, true);
      g_game.getSpectators(list, creature->getPosition(), true, true);

      for(SpectatorVec::iterator it = list.begin(); it != list.end(); ++it){
        (*it)->onCreatureConvinced(creature, this);
      }

      if(spawn){
        spawn->removeMonster(this);
        spawn = NULL;
        masterRadius = -1;
      }

      return true;
    }
  }
  else{
    creature->addSummon(this);
    setFollowCreature(NULL);
    setAttackedCreature(NULL);

    destroySummons();

    isMasterInRange = true;
    updateTargetList();
    updateIdleStatus();

    //Notify surrounding about the change
    SpectatorVec list;
    g_game.getSpectators(list, getPosition(), false, true);
    g_game.getSpectators(list, creature->getPosition(), true, true);

    for(SpectatorVec::iterator it = list.begin(); it != list.end(); ++it){
      (*it)->onCreatureConvinced(creature, this);
    }

    if(spawn){
      spawn->removeMonster(this);
      spawn = NULL;
      masterRadius = -1;
    }

    return true;
  }

  return false;
}
Esempio n. 29
0
bool Monster::convinceCreature(Creature* creature)
{
	Player* player = creature->getPlayer();
	if(player && !player->hasFlag(PlayerFlag_CanConvinceAll))
	{
		if(!mType->isConvinceable)
			return false;
	}

	if(isSummon())
	{
		if(getMaster()->getPlayer())
			return false;
		else if(getMaster() != creature)
		{
			Creature* oldMaster = getMaster();
			oldMaster->removeSummon(this);
			creature->addSummon(this);

			setFollowCreature(NULL);
			setAttackedCreature(NULL);

			//destroy summons
			for(std::list<Creature*>::iterator cit = summons.begin(); cit != summons.end(); ++cit)
			{
				(*cit)->changeHealth(-(*cit)->getHealth());
				(*cit)->setMaster(NULL);
				(*cit)->releaseThing2();
			}
			summons.clear();

			isMasterInRange = true;
			updateTargetList();
			updateIdleStatus();

			//Notify surrounding about the change
			SpectatorVec list;
			g_game.getSpectators(list, getPosition(), false, true);
			g_game.getSpectators(list, creature->getPosition(), true, true);

			for(SpectatorVec::iterator it = list.begin(); it != list.end(); ++it)
				(*it)->onCreatureConvinced(creature, this);

			if(spawn)
			{
				spawn->removeMonster(this);
				spawn = NULL;
				masterRadius = -1;
			}
			return true;
		}
	}
	else
	{
		creature->addSummon(this);
		setFollowCreature(NULL);
		setAttackedCreature(NULL);

		for(std::list<Creature*>::iterator cit = summons.begin(); cit != summons.end(); ++cit)
		{
			(*cit)->changeHealth(-(*cit)->getHealth());
			(*cit)->setMaster(NULL);
			(*cit)->releaseThing2();
		}
		summons.clear();

		isMasterInRange = true;
		updateTargetList();
		updateIdleStatus();

		//Notify surrounding about the change
		SpectatorVec list;
		g_game.getSpectators(list, getPosition(), false, true);
		g_game.getSpectators(list, creature->getPosition(), true, true);

		for(SpectatorVec::iterator it = list.begin(); it != list.end(); ++it)
			(*it)->onCreatureConvinced(creature, this);

		if(spawn)
		{
			spawn->removeMonster(this);
			spawn = NULL;
			masterRadius = -1;
		}
		return true;
	}
	return false;
}