コード例 #1
0
ファイル: tile.cpp プロジェクト: anzmx/forgottenserver
void Tile::postAddNotification(Thing* thing, const Cylinder* oldParent, int32_t index, cylinderlink_t link /*= LINK_OWNER*/)
{
	SpectatorVec list;
	g_game.map.getSpectators(list, getPosition(), true, true);
	for (Creature* spectator : list) {
		spectator->getPlayer()->postAddNotification(thing, oldParent, index, LINK_NEAR);
	}

	//add a reference to this item, it may be deleted after being added (mailbox for example)
	Creature* creature = thing->getCreature();
	Item* item;
	if (creature) {
		creature->incrementReferenceCounter();
		item = nullptr;
	} else {
		item = thing->getItem();
		if (item) {
			item->incrementReferenceCounter();
		}
	}

	if (link == LINK_OWNER) {
		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);
			}
		}

		//calling movement scripts
		Creature* creature = thing->getCreature();
		if (creature) {
			g_moveEvents->onCreatureMove(creature, this, oldParent ? oldParent->getPosition() : getPosition(), MOVE_EVENT_STEP_IN);
		} else if (item) {
			g_moveEvents->onItemMove(item, this, true);
		}
	}

	//release the reference to this item onces we are finished
	if (creature) {
		g_game.ReleaseCreature(creature);
	} else if (item) {
		g_game.ReleaseItem(item);
	}
}
コード例 #2
0
ファイル: tile.cpp プロジェクト: 081421/otxserver
void Tile::postAddNotification(Creature* actor, Thing* thing, const Cylinder* oldParent,
	int32_t index, CylinderLink_t link/* = LINK_OWNER*/)
{
	const SpectatorVec& list = g_game.getSpectators(pos);
	SpectatorVec::const_iterator it;

	Player* tmpPlayer = NULL;
	for(it = list.begin(); it != list.end(); ++it)
	{
		if((tmpPlayer = (*it)->getPlayer()))
			tmpPlayer->postAddNotification(actor, thing, oldParent, index, LINK_NEAR);
	}

	//add a reference to this item, it may be deleted after being added (mailbox for example)
	thing->addRef();
	if(link == LINK_OWNER)
	{
		//calling movement scripts
		if(Creature* creature = thing->getCreature())
		{
			const Tile* fromTile = NULL;
			if(oldParent)
				fromTile = oldParent->getTile();

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

		if(hasFlag(TILESTATE_TELEPORT))
		{
			if(Teleport* teleport = getTeleportItem())
				teleport->__addThing(actor, thing);
		}
		else if(hasFlag(TILESTATE_TRASHHOLDER))
		{
			if(TrashHolder* trashHolder = getTrashHolder())
				trashHolder->__addThing(actor, thing);
		}
		else if(hasFlag(TILESTATE_MAILBOX))
		{
			if(Mailbox* mailbox = getMailbox())
				mailbox->__addThing(actor, thing);
		}
	}

	//release the reference to this item onces we are finished
	g_game.freeThing(thing);
}
コード例 #3
0
ファイル: tile.cpp プロジェクト: nclx/forgottenserver
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);
}
コード例 #4
0
ファイル: tile.cpp プロジェクト: divinity76/server
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);
	}
}
コード例 #5
0
ファイル: tile.cpp プロジェクト: divinity76/YurOTS
ReturnValue Tile::isBlocking(int objectstate, bool ignoreCreature /* = false*/, bool ignoreMoveableBlocking /*=false*/) const
{
	if(isPz() && ((objectstate & BLOCK_PZ) == BLOCK_PZ)) {
		return RET_PROTECTIONZONE;
	}

	if(((objectstate & BLOCK_PATHFIND) == BLOCK_PATHFIND) && (floorChange() || getTeleportItem())) {
		return RET_THEREISNOWAY;
	}
		
	if(ground) {
		const ItemType& groundType = Item::items[ground->getID()];

		if(((objectstate & BLOCK_PROJECTILE) == BLOCK_PROJECTILE) &&
			groundType.blockProjectile)
			return RET_CANNOTTHROW;

		/*
		if((groundType.blockPathFind || groundType.blockSolid) && ((objectstate & BLOCK_PATHFIND) == BLOCK_PATHFIND))
			return RET_THEREISNOWAY;
		*/

		if(((objectstate & BLOCK_PICKUPABLE) == BLOCK_PICKUPABLE)) {			
			if(groundType.blockSolid && (!groundType.hasHeight || groundType.pickupable))
				return RET_NOTENOUGHROOM;
		}

		if(((objectstate & BLOCK_SOLID) == BLOCK_SOLID) && groundType.blockSolid)
			return RET_NOTENOUGHROOM;
	}
	else if( !((objectstate & BLOCK_PROJECTILE) == BLOCK_PROJECTILE)) {
		return RET_NOTILE;
	}

	if(!ignoreCreature && !creatures.empty() && ((objectstate & BLOCK_SOLID) == BLOCK_SOLID))
		return RET_CREATUREBLOCK;

	ItemVector::const_iterator iit;
	for (iit = topItems.begin(); iit != topItems.end(); ++iit) {
		const ItemType& iiType = Item::items[(*iit)->getID()];

		if(((objectstate & BLOCK_PROJECTILE) == BLOCK_PROJECTILE)) {
			if(iiType.blockProjectile)
				return RET_CANNOTTHROW;
			/*else
				continue;*/
		}

		/*
		if((iiType.blockPathFind || iiType.blockSolid) && ((objectstate & BLOCK_PATHFIND) == BLOCK_PATHFIND) &&
			!(ignoreMoveableBlocking && iiType.moveable))
			return RET_THEREISNOWAY;
			*/

		if(((objectstate & BLOCK_PICKUPABLE) == BLOCK_PICKUPABLE)) {			
			if(iiType.blockSolid && (!iiType.hasHeight || iiType.pickupable))
				return RET_NOTENOUGHROOM;
		}

		if(((objectstate & BLOCK_SOLID) == BLOCK_SOLID) && iiType.blockSolid &&
			!(ignoreMoveableBlocking && iiType.moveable))
			return RET_NOTENOUGHROOM;
	}
	
	for (iit = downItems.begin(); iit != downItems.end(); ++iit) {
		const ItemType& iiType = Item::items[(*iit)->getID()];

		if(((objectstate & BLOCK_PROJECTILE) == BLOCK_PROJECTILE)) {
			if(iiType.blockProjectile)
				return RET_CANNOTTHROW;
			/*else
				continue;*/
		}

		/*
		if((iiType.blockPathFind || iiType.blockSolid) && ((objectstate & BLOCK_PATHFIND) == BLOCK_PATHFIND) &&
			!(ignoreMoveableBlocking && iiType.moveable))
			return RET_THEREISNOWAY;
		*/

		if(((objectstate & BLOCK_PICKUPABLE) == BLOCK_PICKUPABLE)) {
			if(iiType.blockSolid && (!iiType.hasHeight || iiType.pickupable))
				return RET_NOTENOUGHROOM;
		}

		if(((objectstate & BLOCK_SOLID) == BLOCK_SOLID) && iiType.blockSolid &&
			!(ignoreMoveableBlocking && iiType.moveable))
			return RET_NOTENOUGHROOM;
	}

	//return false;
	return RET_NOERROR;
}
コード例 #6
0
ファイル: tile.cpp プロジェクト: divinity76/server
ReturnValue Tile::__queryAdd(int32_t index, const Thing* thing, uint32_t count,
	bool childIsOwner /*= false*/) const
{
	Thing* iithing = NULL;

	if(const Creature* creature = thing->getCreature()){
		if(!creatures.empty())
			return RET_NOTPOSSIBLE;

		if(ground == NULL)
			return RET_NOTPOSSIBLE;
		
		if(const Monster* monster = creature->getMonster()){
			if(hasFlag(TILESTATE_PROTECTIONZONE))
				return RET_NOTPOSSIBLE;

			if(const MagicEffectItem* fieldItem = getFieldItem()){
				const MagicEffectTargetCreatureCondition* magicTargetCondition = fieldItem->getCondition();

				if(magicTargetCondition){
					if((monster->getImmunities() & magicTargetCondition->attackType) != magicTargetCondition->attackType){
						return RET_NOTPOSSIBLE;
					}
				}
			}

			if(floorChange() || getTeleportItem()){
				return RET_NOTPOSSIBLE;
			}

			for(uint32_t i = 0; i < getThingCount(); ++i){
				iithing = __getThing(i);

				if(const Item* iitem = iithing->getItem()){
					const ItemType& iiType = Item::items[iitem->getID()];

					if(iiType.blockSolid){
						if(!monster->canPushItems() || !iiType.moveable){
							return RET_NOTPOSSIBLE;
						}
					}
				}
			}

			return RET_NOERROR;
		}
		else if(const Player* player = creature->getPlayer()){
			if(hasFlag(TILESTATE_PROTECTIONZONE) && player->pzLocked){
				return RET_PLAYERISPZLOCKED;
			}
		}

		for(uint32_t i = 0; i < getThingCount(); ++i){
			iithing = __getThing(i);

			if(const Item* iitem = iithing->getItem()){
				const ItemType& iiType = Item::items[iitem->getID()];

				if(iiType.blockSolid){
					//check if this a creature that just is about to login/spawn
					//those can be placed here if the blocking item is moveable
					if(!creature->getParent()){
						if(!iiType.moveable)
							return RET_NOTPOSSIBLE;
					}
					else
						return RET_NOTPOSSIBLE;
				}
			}
		}
	}
	else if(const Item* item = thing->getItem()){
		//If its a new (summoned item) always accept it
		if(thing->getParent() == NULL){
			return RET_NOERROR;
		}

		if(ground == NULL)
			return RET_NOTPOSSIBLE;

		if(!creatures.empty() && item->isBlocking())
			return RET_NOTENOUGHROOM;

		for(uint32_t i = 0; i < getThingCount(); ++i){
			iithing = __getThing(i);

			if(const Item* iitem = iithing->getItem()){
				const ItemType& iiType = Item::items[iitem->getID()];

				if(iiType.blockSolid){
					if(item->isPickupable()){
						//experimental
						//if((iiType.isVertical || iiType.isHorizontal) && item->isHangable()){
						//	ItemVector::const_iterator iit;
						//	for(iit = downItems.begin(); iit != downItems.end(); ++iit){
						//		if((*iit)->isHangable())
						//			return RET_NOTENOUGHROOM;
						//	}
						//}
						//else
						if(!iiType.hasHeight /*|| !iiType.moveable*/)
							return RET_NOTENOUGHROOM;
						else if(iiType.pickupable)
							return RET_NOTENOUGHROOM;
					}
					else
						return RET_NOTENOUGHROOM;
				}
			}
		}
	}

	return RET_NOERROR;
}