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