void BountyMissionObjectiveImplementation::spawnTarget(const String& zoneName) { Locker locker(&syncMutex); ManagedReference<MissionObject* > mission = this->mission.get(); if ((npcTarget != NULL && npcTarget->isInQuadTree()) || isPlayerTarget()) { return; } ZoneServer* zoneServer = getPlayerOwner().get()->getZoneServer(); Zone* zone = zoneServer->getZone(zoneName); CreatureManager* cmng = zone->getCreatureManager(); if (npcTarget == NULL) { Vector3 position = getTargetPosition(); try { npcTarget = cast<AiAgent*>(zone->getCreatureManager()->spawnCreatureWithAi(mission->getTargetOptionalTemplate().hashCode(), position.getX(), zone->getHeight(position.getX(), position.getY()), position.getY(), 0)); } catch (Exception& e) { fail(); ManagedReference<CreatureObject*> player = getPlayerOwner(); if (player != NULL) { player->sendSystemMessage("ERROR: could not find template for target. Please report this on Mantis to help us track down the root cause."); } error("Template error: " + e.getMessage() + " Template = '" + mission->getTargetOptionalTemplate() +"'"); } if (npcTarget != NULL) { npcTarget->setCustomObjectName(mission->getTargetName(), true); //TODO add observer to catch player kill and fail mission in that case. addObserverToCreature(ObserverEventType::OBJECTDESTRUCTION, npcTarget); addObserverToCreature(ObserverEventType::DAMAGERECEIVED, npcTarget); } else { fail(); ManagedReference<CreatureObject*> player = getPlayerOwner(); if (player != NULL) { player->sendSystemMessage("ERROR: could not find template for target. Please report this on Mantis to help us track down the root cause."); } error("Could not spawn template: '" + mission->getTargetOptionalTemplate() + "'"); } } }
bool DeliverMissionObjectiveImplementation::activateWithResult() { ManagedReference<CreatureObject*> owner = getPlayerOwner(); ManagedReference<MissionObject* > mission = this->mission.get(); if (owner == NULL || mission == NULL) { return false; } Zone* zone = owner->getZone(); if (zone == NULL) { return false; } CreatureManager* creatureManager = zone->getCreatureManager(); PlanetManager* planetManager = zone->getPlanetManager(); if (planetManager == NULL) { return false; } TerrainManager* terrainManager = planetManager->getTerrainManager(); if (terrainManager == NULL) { return false; } ZoneServer* zoneServer = owner->getZoneServer(); if (zoneServer == NULL) { return false; } MissionManager* missionManager = zoneServer->getMissionManager(); if (missionManager == NULL) { return false; } //Select spawn type. int spawnType = NpcSpawnPoint::NEUTRALSPAWN; switch (mission->getFaction()) { case FactionManager::FACTIONIMPERIAL: spawnType = NpcSpawnPoint::IMPERIALSPAWN; break; case FactionManager::FACTIONREBEL: spawnType = NpcSpawnPoint::REBELSPAWN; break; default: spawnType = NpcSpawnPoint::NEUTRALSPAWN; break; } //Spawn target and destination NPC's. //Target NPC //Find a free spawn point. targetSpawnPoint = missionManager->getFreeNpcSpawnPoint(mission->getStartPlanetCRC(), mission->getStartPositionX(), mission->getStartPositionY(), spawnType); if (targetSpawnPoint == NULL) { return false; } Vector3* targetPosition = targetSpawnPoint->getPosition(); if (targetPosition == NULL) { return false; } //Destination NPC. //Find a free spawn point. int retries = 10; destinationSpawnPoint = NULL; while (retries > 0 && (destinationSpawnPoint == NULL || destinationSpawnPoint == targetSpawnPoint)) { destinationSpawnPoint = missionManager->getFreeNpcSpawnPoint(mission->getEndPlanet().hashCode(), mission->getEndPositionX(), mission->getEndPositionY(), spawnType); retries--; } if (destinationSpawnPoint == NULL || destinationSpawnPoint == targetSpawnPoint) { return false; } missionManager->allocateMissionNpcs(targetSpawnPoint, destinationSpawnPoint, terrainManager, creatureManager); //Create waypoint and activate it. if (objectiveStatus == 0) { WaypointObject* waypoint = mission->getWaypointToMission(); Locker locker(waypoint); waypoint->setPlanetCRC(mission->getStartPlanetCRC()); waypoint->setPosition(targetPosition->getX(), 0, targetPosition->getY()); waypoint->setActive(true); mission->updateMissionLocation(); } else { updateMissionTarget(getPlayerOwner().get()); } return true; }
bool DestroyMissionLairObserverImplementation::checkForNewSpawns(TangibleObject* lair, TangibleObject* attacker, bool forceSpawn) { Zone* zone = lair->getZone(); if (zone == NULL) return false; int spawnLimitAdjustment = 0; if (difficulty == 0) { spawnLimitAdjustment = -3; } else if (difficulty == 4) { spawnLimitAdjustment = 3; } int spawnLimit = lairTemplate->getSpawnLimit() + spawnLimitAdjustment; if (forceSpawn) { spawnNumber.increment(); } else if (getMobType() == LairTemplate::NPC) { return false; } else { if (spawnedCreatures.size() >= spawnLimit && !lairTemplate->hasBossMobs()) return true; int conditionDamage = lair->getConditionDamage(); int maxCondition = lair->getMaxCondition(); switch (spawnNumber) { case 0: spawnNumber.increment(); break; case 1: if (conditionDamage > (maxCondition / 10)) { spawnNumber.increment(); } else { return false; } break; case 2: if (conditionDamage > (maxCondition / 2)) { spawnNumber.increment(); } else { return false; } break; case 3: if (lairTemplate->hasBossMobs() && conditionDamage > ((maxCondition * 9) / 10)) { spawnNumber.increment(); } 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) > 4) 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 = spawnLimit / 3; } else { amountToSpawn = System::random(2) + (spawnLimit / 3); } 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() >= spawnLimit) 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 = zone->getCreatureManager(); for (int j = 0; j < numberToSpawn; j++) { if (lair->getZone() == NULL) break; float x = lair->getPositionX() + (size - System::random(size * 20) / 10.0f); float y = lair->getPositionY() + (size - System::random(size * 20) / 10.0f); float z = zone->getHeight(x, y); ManagedReference<CreatureObject*> creo = NULL; if (creatureManager->checkSpawnAsBaby(tamingChance, babiesSpawned, 1000)) { 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(ai, 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.getReferenceUnsafeStaticCast(), true); task->schedule(1000); } return objectsToSpawn.size() > 0; }