bool Spawn::spawnMonster(uint32_t spawnId, MonsterType* mType, const Position& pos, Direction dir, bool startup /*= false*/) { Monster* monster = Monster::createMonster(mType); if(!monster) return false; if(startup) { //No need to send out events to the surrounding since there is no one out there to listen! if(!g_game.internalPlaceCreature(monster, pos, false, true)) { delete monster; return false; } } else { if(!g_game.placeCreature(monster, pos, false, true)) { delete monster; return false; } } monster->setSpawn(this); monster->useThing2(); monster->setMasterPos(pos, radius); monster->setDirection(dir); spawnedMap.insert(SpawnedPair(spawnId, monster)); spawnMap[spawnId].lastSpawn = OTSYS_TIME(); return true; }
bool Spawn::spawnMonster(uint32_t spawnId, MonsterType* mType, const Position& pos, Direction dir, bool startup /*= false*/) { int32_t nHealth = mType->health,nMaxHealth = mType->healthMax, nExp = mType->experience, nDef = mType->defense, nArm = mType->armor; int32_t monsterLevel = random_range(mType->minLevel, mType->maxLevel); if (monsterLevel != 0) { monsterLevel = monsterLevel; } else { monsterLevel = random_range(5,15); } mType->health = (uint64_t)std::ceil(mType->health * monsterLevel / 8); mType->healthMax = (uint64_t)std::ceil(mType->healthMax * monsterLevel / 8); mType->experience = (uint64_t)std::ceil(mType->experience * monsterLevel / 8); mType->defense = (uint64_t)std::ceil(mType->defense * monsterLevel / 8); mType->armor = (uint64_t)std::ceil(mType->armor * monsterLevel / 8); Monster* monster = Monster::createMonster(mType); monster->doMonsterSetCombatValues(monsterLevel); monster->doMonsterSetLevel(monsterLevel); mType->health = nHealth; mType->healthMax = nMaxHealth; mType->experience = nExp; mType->defense = nDef; mType->armor = nArm; if(!monster) return false; if(startup) { //No need to send out events to the surrounding since there is no one out there to listen! if(!g_game.internalPlaceCreature(monster, pos, false, true)) { delete monster; return false; } } else if(!g_game.placeCreature(monster, pos, false, true)) { delete monster; return false; } monster->setSpawn(this); monster->setMasterPosition(pos, radius); monster->setDirection(dir); monster->addRef(); spawnedMap.insert(SpawnedPair(spawnId, monster)); spawnMap[spawnId].lastSpawn = OTSYS_TIME(); return true; }
void Spawn::checkSpawn() { #ifdef __DEBUG_SPAWN__ std::cout << "[Notice] Spawn::checkSpawn " << this << std::endl; #endif checkSpawnEvent = 0; Monster* monster; uint32_t spawnId; for(SpawnedMap::iterator it = spawnedMap.begin(); it != spawnedMap.end();) { spawnId = it->first; monster = it->second; if(monster->isRemoved()) { if(spawnId != 0) spawnMap[spawnId].lastSpawn = OTSYS_TIME(); monster->releaseThing2(); spawnedMap.erase(it++); } else if(!isInSpawnZone(monster->getPosition()) && spawnId != 0) { spawnedMap.insert(SpawnedPair(0, monster)); spawnedMap.erase(it++); } else ++it; } uint32_t spawnCount = 0; for(SpawnMap::iterator it = spawnMap.begin(); it != spawnMap.end(); ++it) { spawnId = it->first; spawnBlock_t& sb = it->second; if(spawnedMap.count(spawnId) == 0) { if(OTSYS_TIME() >= sb.lastSpawn + sb.interval) { if(findPlayer(sb.pos)) { sb.lastSpawn = OTSYS_TIME(); continue; } spawnMonster(spawnId, sb.mType, sb.pos, sb.direction); ++spawnCount; if(spawnCount >= (uint32_t)g_config.getNumber(ConfigManager::RATE_SPAWN)) break; } } } if(spawnedMap.size() < spawnMap.size()) checkSpawnEvent = Scheduler::getScheduler().addEvent(createSchedulerTask(getInterval(), boost::bind(&Spawn::checkSpawn, this))); #ifdef __DEBUG_SPAWN__ else std::cout << "[Notice] Spawn::checkSpawn stopped " << this << std::endl; #endif }