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; }
bool ContainerComponent::removeObject(SceneObject* sceneObject, SceneObject* object, SceneObject* destination, bool notifyClient) { VectorMap<String, ManagedReference<SceneObject*> >* slottedObjects = sceneObject->getSlottedObjects(); VectorMap<uint64, ManagedReference<SceneObject*> >* containerObjects = sceneObject->getContainerObjects(); ManagedReference<SceneObject*> objectKeeper = object; if (object->getParent() != sceneObject && object->getParent() != NULL) { ManagedReference<SceneObject*> objParent = object->getParent(); Locker contLocker(sceneObject->getContainerLock()); containerObjects->drop(object->getObjectID()); if (objParent->hasObjectInContainer(object->getObjectID()) || objParent->hasObjectInSlottedContainer(object)) { sceneObject->error("trying to remove an object that is in a different object"); objParent->info("i am the parent", true); return false; } else object->setParent(NULL); } int containedType = object->getContainmentType(); //info("trying to remove object with containedType " + String::valueOf(containedType), true); // if (containedType == 4 || containedType == 5) { Locker contLocker(sceneObject->getContainerLock()); int arrangementSize = object->getArrangementDescriptorSize(); int arrangementGroup = MAX(0, containedType - 4); if (object->getArrangementDescriptorSize() > arrangementGroup) { bool removeFromSlot = false; const Vector<String>* descriptors = object->getArrangementDescriptor(arrangementGroup); for (int i = 0; i < descriptors->size(); ++i){ const String& childArrangement = descriptors->get(i); ManagedReference<SceneObject*> obj = slottedObjects->get(childArrangement); if (slottedObjects->get(childArrangement) == object) { removeFromSlot = true; break; } } if (removeFromSlot) { for (int i = 0; i < descriptors->size(); ++i) slottedObjects->drop(descriptors->get(i)); } } // } else if (containedType == -1) { //Locker contLocker(sceneObject->getContainerLock()); if (containerObjects->contains(object->getObjectID())) { //info("containerObjects doesnt contain specified object", true); //object->setParent(NULL); // return false; containerObjects->drop(object->getObjectID()); } object->setParent(NULL); contLocker.release(); /* } else { sceneObject->error("unknown contained type " + String::valueOf(containedType)); StackTrace::printStackTrace(); return false; } */ if (notifyClient) sceneObject->broadcastMessage(object->link((uint64) 0, 0xFFFFFFFF), true); notifyObjectRemoved(sceneObject, object, destination); sceneObject->updateToDatabase(); object->updateToDatabase(); if (sceneObject->getParent() == NULL) { sceneObject->notifyObjectRemovedFromChild(object, sceneObject); } else { ManagedReference<SceneObject*> rootParent = sceneObject->getRootParent(); if (rootParent != NULL) rootParent->notifyObjectRemovedFromChild(object, sceneObject); else sceneObject->notifyObjectRemovedFromChild(object, sceneObject); } return true; }