bool LairObserverImplementation::checkForNewSpawns(TangibleObject* lair, TangibleObject* attacker, bool forceSpawn) { if (lair->getZone() == NULL) return false; if (spawnedCreatures.size() >= lairTemplate->getSpawnLimit() && !lairTemplate->hasBossMobs()) return false; if (forceSpawn) { spawnNumber++; } else if (getMobType() == LairTemplate::NPC) { return false; } else { int conditionDamage = lair->getConditionDamage(); int maxCondition = lair->getMaxCondition(); switch (spawnNumber) { case 0: spawnNumber++; break; case 1: if (conditionDamage > (maxCondition / 10)) { spawnNumber++; } else { return false; } break; case 2: if (conditionDamage > (maxCondition / 2)) { spawnNumber++; } else { return false; } break; case 3: if (lairTemplate->hasBossMobs() && conditionDamage > ((maxCondition * 9) / 10)) { spawnNumber++; } else { return false; } break; default: return false; break; } } VectorMap<String, int> objectsToSpawn; // String mobileTemplate, int number to spawn if (spawnNumber == 4) { if (System::random(100) > 9) return false; VectorMap<String, int>* mobs = lairTemplate->getBossMobiles(); for (int i = 0; i < mobs->size(); i++) { objectsToSpawn.put(mobs->elementAt(i).getKey(), mobs->elementAt(i).getValue()); } } else { Vector<String>* mobiles = lairTemplate->getWeightedMobiles(); int amountToSpawn = 0; if (getMobType() == LairTemplate::CREATURE) { amountToSpawn = System::random(3) + ((lairTemplate->getSpawnLimit() / 3) - 2); } else { amountToSpawn = System::random(lairTemplate->getSpawnLimit() / 2) + (lairTemplate->getSpawnLimit() / 2); } if (amountToSpawn < 1) amountToSpawn = 1; for (int i = 0; i < amountToSpawn; i++) { int num = System::random(mobiles->size() - 1); String mob = mobiles->get(num); if (objectsToSpawn.contains(mob)) { int value = objectsToSpawn.get(mob); objectsToSpawn.drop(mob); objectsToSpawn.put(mob, value + 1); } else { objectsToSpawn.put(mob, 1); } } } for(int i = 0; i < objectsToSpawn.size(); ++i) { if (spawnNumber != 4 && spawnedCreatures.size() >= lairTemplate->getSpawnLimit()) return true; String templateToSpawn = objectsToSpawn.elementAt(i).getKey(); int numberToSpawn = objectsToSpawn.get(templateToSpawn); CreatureTemplate* creatureTemplate = CreatureTemplateManager::instance()->getTemplate(templateToSpawn); if (creatureTemplate == NULL) continue; float tamingChance = creatureTemplate->getTame(); CreatureManager* creatureManager = lair->getZone()->getCreatureManager(); for (int j = 0; j < numberToSpawn; j++) { float x = lair->getPositionX() + (size - System::random(size * 20) / 10.0f); float y = lair->getPositionY() + (size - System::random(size * 20) / 10.0f); float z = lair->getZone()->getHeight(x, y); ManagedReference<CreatureObject*> creo = NULL; if (creatureManager->checkSpawnAsBaby(tamingChance, babiesSpawned, 500)) { creo = creatureManager->spawnCreatureAsBaby(templateToSpawn.hashCode(), x, z, y); babiesSpawned++; } if (creo == NULL) creo = creatureManager->spawnCreatureWithAi(templateToSpawn.hashCode(), x, z, y); if (creo == NULL) continue; if (!creo->isAiAgent()) { error("spawned non player creature with template " + templateToSpawn); } else { AiAgent* ai = cast<AiAgent*>( creo.get()); //Locker clocker(npc, lair); ai->setDespawnOnNoPlayerInRange(false); ai->setHomeLocation(x, z, y); ai->setRespawnTimer(0); ai->setHomeObject(lair); spawnedCreatures.add(creo); } } } if (spawnNumber == 4) { Reference<LairAggroTask*> task = new LairAggroTask(lair, attacker, _this.get(), true); task->schedule(1000); } return objectsToSpawn.size() > 0; }
void SpawnAreaMap::loadStaticSpawns() { String planetName = zone->getZoneName(); LuaObject obj = lua->getGlobalObject(planetName + "_static_spawns"); if (!obj.isValidTable()) { obj.pop(); return; } int count = 0; int max = obj.getTableSize(); for (int i = 1; i <= obj.getTableSize(); ++i) { lua_rawgeti(obj.getLuaState(), -1, i); LuaObject spawn(obj.getLuaState()); if (spawn.isValidTable()) { CreatureManager* creatureManager = zone->getCreatureManager(); String name = obj.getStringAt(1); uint32 respawn = obj.getIntAt(2); float x = obj.getFloatAt(3); float z = obj.getFloatAt(4); float y = obj.getFloatAt(5); float heading = obj.getFloatAt(6); uint64 parentID = obj.getLongAt(7); String moodString; UnicodeString customName; int junkDealerBuyingType =0; int junkDealerConversationType =0; if (obj.getTableSize() > 7) moodString = obj.getStringAt(8); if (obj.getTableSize() > 8) customName = obj.getStringAt(9); if (obj.getTableSize() > 9) junkDealerBuyingType = obj.getIntAt(10); if (obj.getTableSize() > 10) junkDealerConversationType = obj.getIntAt(11); if (parentID == 0) z = zone->getHeight(x, y); ManagedReference<CreatureObject*> creatureObject = creatureManager->spawnCreature(name.hashCode(), 0, x, z, y, parentID); if (creatureObject != NULL) { creatureObject->setDirection(Math::deg2rad(heading)); if (creatureObject->isJunkDealer()){ cast<JunkdealerCreature*>(creatureObject.get())->setJunkDealerConversationType(junkDealerConversationType); cast<JunkdealerCreature*>(creatureObject.get())->setJunkDealerBuyerType(junkDealerBuyingType); } if (!moodString.isEmpty()) { creatureObject->setMoodString(moodString); //TODO: remove after fixing commoners if (moodString == "conversation" || moodString == "calm") { creatureObject->setPvpStatusBitmask(0); creatureObject->setCloseObjects(NULL); } } if (!customName.isEmpty()) creatureObject->setCustomObjectName(customName, true); if (creatureObject->isAiAgent()) { AiAgent* ai = cast<AiAgent*>( creatureObject.get()); ai->setRespawnTimer(respawn); } if (name.contains("trainer_")) { Vector3 coords(creatureObject.get()->getWorldPositionX(), creatureObject.get()->getWorldPositionY(), 0); trainerObjects.add(coords); } } else { StringBuffer msg; msg << "could not spawn mobile: " + name; error(msg.toString()); } } spawn.pop(); if (ConfigManager::instance()->isProgressMonitorActivated()) printf("\r\tLoading static spawns: [%d] / [%d]\t", ++count, max); } obj.pop(); //--{"mobile", x, z, y, degrees heading, parentID} //spawnCreature(uint32 templateCRC, uint32 objectCRC, float x, float z, float y, uint64 parentID) }