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); } }
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); }
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); }
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); } }
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; }
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; }