bool Monster::canWalkTo(Position pos, Direction dir) { if(getNoMove()) return false; switch(dir) { case NORTH: pos.y += -1; break; case WEST: pos.x += -1; break; case EAST: pos.x += 1; break; case SOUTH: pos.y += 1; break; default: break; } if(!isInSpawnRange(pos) || !getWalkCache(pos)) return false; Tile* tile = g_game.getTile(pos); if(!tile || g_game.isSwimmingPool(NULL, getTile(), false) != g_game.isSwimmingPool(NULL, tile, false)) // prevent monsters entering/exiting to swimming pool return false; return !tile->getTopVisibleCreature(this) && tile->__queryAdd( 0, this, 1, FLAG_PATHFINDING) == RET_NOERROR; }
bool Monster::canMoveTo(const Tile& tile) const { if (!Creature::canMoveTo(tile)) { return false; } if (!isInSpawnRange(tile.getPosition())) { return false; } return true; }
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 Monster::canWalkTo(Position pos, Direction direction) const { pos = getNextPosition(direction, pos); if (isInSpawnRange(pos)) { if (getWalkCache(pos) == 0) { return false; } Tile* tile = g_game.map.getTile(pos); if (tile && tile->getTopVisibleCreature(this) == nullptr && tile->queryAdd(0, *this, 1, FLAG_PATHFINDING) == RETURNVALUE_NOERROR) { return true; } } return false; }
bool Monster::canWalkTo(Position pos, Direction dir) { if(getNoMove()) return false; switch(dir) { case NORTH: pos.y += -1; break; case WEST: pos.x += -1; break; case EAST: pos.x += 1; break; case SOUTH: pos.y += 1; break; default: break; } if(!isInSpawnRange(pos) || !getWalkCache(pos)) return false; Tile* tile = g_game.getTile(pos); if(!tile || g_game.isSwimmingPool(NULL, getTile(), false) != g_game.isSwimmingPool(NULL, tile, false)) // prevent monsters entering/exiting to swimming pool return false; /* // Check here // If we don't follow, or attack, and we can't handle the damage, then we can't move on this field MagicField* field = NULL; if(!followCreature && !attackedCreature && (field = tile->getFieldItem()) && !isImmune(field->getCombatType())) return false; */ return !tile->getTopVisibleCreature(this) && tile->__queryAdd( 0, this, 1, FLAG_PATHFINDING) == RET_NOERROR; }
bool Monster::canWalkTo(Position pos, Direction dir) { switch(dir) { case NORTH: pos.y += -1; break; case WEST: pos.x += -1; break; case EAST: pos.x += 1; break; case SOUTH: pos.y += 1; break; default: break; } if(isInSpawnRange(pos)) { if(getWalkCache(pos) == 0) return false; Tile* tile = g_game.getTile(pos.x, pos.y, pos.z); if(tile && tile->getTopVisibleCreature(this) == NULL && tile->__queryAdd(0, this, 1, FLAG_PATHFINDING) == RET_NOERROR) return true; } return false; }
bool Actor::canWalkTo(Position pos, Direction dir) { switch(dir.value()){ case enums::NORTH: pos.y += -1; break; case enums::WEST: pos.x += -1; break; case enums::EAST: pos.x += 1; break; case enums::SOUTH: pos.y += 1; break; default: break; } if(isInSpawnRange(pos)){ if(getWalkCache(pos) == 0){ return false; } Tile* tile = g_game.getParentTile(pos.x, pos.y, pos.z); if(tile && tile->getTopVisibleCreature(this) == NULL && tile->__queryAdd(0, this, 1, FLAG_PATHFINDING) == RET_NOERROR){ return true; } } return false; }
bool Spawn::addMonster(std::string name, Direction dir, int x, int y, int spawntime) { Position tmpPos(centerPos.x + x, centerPos.y, centerPos.z); if(!isInSpawnRange(tmpPos)) { // #ifdef __DEBUG__ std::cout << "Monster is outside the spawn-area!" << std::endl; // #endif return false; } struct spawninfo si; si.name = name; si.dir = dir; si.pos.x = centerPos.x + x; si.pos.y = centerPos.y + y; si.pos.z = centerPos.z; si.spawntime = spawntime; si.lastspawn = 0; unsigned long spawnid = (int)spawnmap.size() + 1; spawnmap[spawnid] = si; return true; }
void Monster::onThink(uint32_t interval) { Creature::onThink(interval); if (mType->info.thinkEvent != -1) { // onThink(self, interval) LuaScriptInterface* scriptInterface = mType->info.scriptInterface; if (!scriptInterface->reserveScriptEnv()) { std::cout << "[Error - Monster::onThink] Call stack overflow" << std::endl; return; } ScriptEnvironment* env = scriptInterface->getScriptEnv(); env->setScriptId(mType->info.thinkEvent, scriptInterface); lua_State* L = scriptInterface->getLuaState(); scriptInterface->pushFunction(mType->info.thinkEvent); LuaScriptInterface::pushUserdata<Monster>(L, this); LuaScriptInterface::setMetatable(L, -1, "Monster"); lua_pushnumber(L, interval); if (scriptInterface->callFunction(2)) { return; } } if (!isInSpawnRange(position)) { g_game.internalTeleport(this, masterPos); setIdle(true); } else { updateIdleStatus(); if (!isIdle) { addEventWalk(); if (isSummon()) { if (!attackedCreature) { if (getMaster() && getMaster()->getAttackedCreature()) { //This happens if the monster is summoned during combat selectTarget(getMaster()->getAttackedCreature()); } else if (getMaster() != followCreature) { //Our master has not ordered us to attack anything, lets follow him around instead. setFollowCreature(getMaster()); } } else if (attackedCreature == this) { setFollowCreature(nullptr); } else if (followCreature != attackedCreature) { //This happens just after a master orders an attack, so lets follow it aswell. setFollowCreature(attackedCreature); } } else if (!targetList.empty()) { if (!followCreature || !hasFollowPath) { searchTarget(); } else if (isFleeing()) { if (attackedCreature && !canUseAttack(getPosition(), attackedCreature)) { searchTarget(TARGETSEARCH_ATTACKRANGE); } } } onThinkTarget(interval); onThinkYell(interval); onThinkDefense(interval); } } }