void StringIdManager::populateDatabase() {
	int count = 0;

	TemplateManager::instance();
	TreeArchive* treeArchive = DataArchiveStore::instance()->getTreeArchive();

	Vector<String>* files = treeArchive->getFilesAndSubDirectoryFiles("string/en");

	if (files == NULL) {
		error("string/en directory missing");

		ObjectDatabaseManager::instance()->commitLocalTransaction();
		return;
	}

	for (int i = 0; i < files->size(); ++i) {
		String file = files->get(i);

		ObjectInputStream* stream = TemplateManager::instance()->openTreFile(files->get(i));

		if (stream == NULL) {
			//error("could not open file " + files->get(i));

			continue;
		} else {
			if (stream->size() > 4) {
				//info("opening " + files->get(i), true);

				StringFile stringFile;
				if (!stringFile.load(stream)) {
					delete stream;

					error("could not parse " + files->get(i));
					continue;
				}

				file = file.replaceFirst("string/en/","");
				file = file.replaceFirst(".stf","");

				HashTable<String, UnicodeString>* hashTable = stringFile.getStringMap();

				HashTableIterator<String, UnicodeString> iterator = hashTable->iterator();

				while (iterator.hasNext()) {
					String name;
					UnicodeString value;

					iterator.getNextKeyAndValue(name, value);

					String full = "@" + file + ":" + name;

					//info("key = " + full + " value = " + value.toString(), true);

					ObjectOutputStream* data = new ObjectOutputStream();
					value.toBinaryStream(data);

					uint64 longKey = (uint64)full.hashCode();

					ObjectOutputStream* key = new ObjectOutputStream();
					TypeInfo<uint64>::toBinaryStream(&longKey, key);

					stringsDatabase->putData(key, data);
					++count;
				}

			}

			delete stream;
		}
	}

	delete files;

	info("writing to the db " + String::valueOf(count) + " strings", true);
}
void CraftingSessionImplementation::addIngredient(TangibleObject* tano, int slot, int clientCounter) {
	ManagedReference<CraftingTool*> craftingTool = this->craftingTool.get();
	ManagedReference<CreatureObject*> crafter = this->crafter.get();
	ManagedReference<PlayerObject*> crafterGhost = this->crafterGhost.get();
	ManagedReference<CraftingStation*> craftingStation = this->craftingStation.get();
	ManagedReference<ManufactureSchematic*> manufactureSchematic = this->manufactureSchematic.get();
	ManagedReference<TangibleObject*> prototype = this->prototype.get();

	if (crafter == NULL) {
		sendSlotMessage(clientCounter, IngredientSlot::INVALID);
		return;
	}

	if (manufactureSchematic == NULL) {
		sendSlotMessage(clientCounter, IngredientSlot::NOSCHEMATIC);
		return;
	}

	if (prototype == NULL) {
		sendSlotMessage(clientCounter, IngredientSlot::PROTOTYPENOTFOUND);
		return;
	}

	if (tano == NULL) {
		sendSlotMessage(clientCounter, IngredientSlot::INVALIDINGREDIENT);
		return;
	}

	SceneObject* inventory = crafter->getSlottedObject("inventory");
	if (inventory == NULL) {
		sendSlotMessage(clientCounter, IngredientSlot::NOINVENTORY);
		return;
	}

	Locker locker(_this.get());

	Locker locker2(tano);

	/// Check if item is on the player, but not in a crafting tool
	/// Or if the item is in a crafting station to prevent some duping
	if(!tano->isASubChildOf(crafter) && (craftingStation == NULL || !tano->isASubChildOf(craftingStation))) {
		sendSlotMessage(clientCounter, IngredientSlot::INVALIDINGREDIENT);
		return;
	}

	ManagedReference<SceneObject*> craftingComponents = craftingTool->getSlottedObject("crafted_components");
	ManagedReference<SceneObject*> craftingComponentsSatchel = NULL;

	if(craftingComponents == NULL) {

		/// Add Components to crafted object
		String craftingComponentsPath = "object/tangible/crafting/crafting_components_container.iff";
		craftingComponents = crafter->getZoneServer()->createObject(craftingComponentsPath.hashCode(), 1);
		craftingComponents->setSendToClient(false);
		craftingTool->transferObject(craftingComponents, 4, false);

		craftingComponents->setContainerDefaultDenyPermission(ContainerPermissions::OPEN + ContainerPermissions::MOVEIN + ContainerPermissions::MOVEOUT + ContainerPermissions::MOVECONTAINER);
		craftingComponents->setContainerDefaultAllowPermission(0);
		craftingComponents->setContainerDenyPermission("owner", ContainerPermissions::OPEN + ContainerPermissions::MOVEIN + ContainerPermissions::MOVEOUT + ContainerPermissions::MOVECONTAINER);
		craftingComponents->setContainerDenyPermission("admin", ContainerPermissions::OPEN + ContainerPermissions::MOVEIN + ContainerPermissions::MOVEOUT + ContainerPermissions::MOVECONTAINER);
		craftingComponents->setContainerAllowPermission("owner", 0);
		craftingComponents->setContainerAllowPermission("admin", 0);
		craftingComponents->setContainerInheritPermissionsFromParent(false);

		//String craftingComponentsSatchelPath = "object/tangible/container/base/base_container_volume.iff";
		String craftingComponentsSatchelPath = "object/tangible/hopper/crafting_station_hopper/crafting_station_ingredient_hopper_large.iff";
		craftingComponentsSatchel = crafter->getZoneServer()->createObject(craftingComponentsSatchelPath.hashCode(), 1);

		craftingComponentsSatchel->setContainerInheritPermissionsFromParent(false);
		craftingComponentsSatchel->setContainerDefaultDenyPermission(ContainerPermissions::OPEN + ContainerPermissions::MOVEIN + ContainerPermissions::MOVEOUT + ContainerPermissions::MOVECONTAINER);
		craftingComponentsSatchel->setContainerDefaultAllowPermission(0);
		craftingComponentsSatchel->setContainerAllowPermission("admin", ContainerPermissions::OPEN);
		craftingComponentsSatchel->setContainerDenyPermission("admin", ContainerPermissions::MOVEIN + ContainerPermissions::MOVEOUT + ContainerPermissions::MOVECONTAINER);
		craftingComponentsSatchel->setContainerAllowPermission("owner", 0);
		craftingComponentsSatchel->setContainerDenyPermission("owner", ContainerPermissions::OPEN + ContainerPermissions::MOVEIN + ContainerPermissions::MOVEOUT + ContainerPermissions::MOVECONTAINER);

		craftingComponentsSatchel->sendTo(crafter, true);
		craftingComponents->transferObject(craftingComponentsSatchel, -1, false);

	} else {
		craftingComponentsSatchel = craftingComponents->getContainerObject(0);
	}
	// Lock the craft and satchel as well
	//Locker crossSatcheLock(craftingComponentsSatchel,crafter);
	// crafter is pre-locked before entering this method, satchel::trasnferObject is thread safe

	int result = manufactureSchematic->addIngredientToSlot(crafter, craftingComponentsSatchel, tano, slot);

	sendSlotMessage(clientCounter, result);

	if(crafterGhost != NULL && crafterGhost->getDebug()) {
		crafter->sendSystemMessage("Adding ingredient: " + tano->getDisplayedName());
	}

}
Reference<FactoryCrate*> TangibleObjectImplementation::createFactoryCrate(bool insertSelf) {
	String file;
	uint32 type = getGameObjectType();

	if(type & SceneObjectType::ARMOR)
		file = "object/factory/factory_crate_armor.iff";
	else if(type == SceneObjectType::CHEMICAL || type == SceneObjectType::PHARMACEUTICAL || type == SceneObjectType::PETMEDECINE)
		file = "object/factory/factory_crate_chemicals.iff";
	else if(type & SceneObjectType::CLOTHING)
		file = "object/factory/factory_crate_clothing.iff";
	else if(type == SceneObjectType::ELECTRONICS)
		file = "object/factory/factory_crate_electronics.iff";
	else if(type == SceneObjectType::FOOD || type == SceneObjectType::DRINK)
		file = "object/factory/factory_crate_food.iff";
	else if(type == SceneObjectType::FURNITURE)
		file = "object/factory/factory_crate_furniture.iff";
	else if(type & SceneObjectType::INSTALLATION)
		file = "object/factory/factory_crate_installation.iff";
	else if(type & SceneObjectType::WEAPON)
		file = "object/factory/factory_crate_weapon.iff";
	else
		file = "object/factory/factory_crate_generic_items.iff";

	SharedTangibleObjectTemplate* tanoData = dynamic_cast<SharedTangibleObjectTemplate*>(templateObject.get());

	if (tanoData == NULL)
		return NULL;

	ObjectManager* objectManager = ObjectManager::instance();

	Reference<FactoryCrate*> crate = (getZoneServer()->createObject(file.hashCode(), 2)).castTo<FactoryCrate*>();

	if (crate == NULL)
		return NULL;

	Locker locker(crate);

	crate->setMaxCapacity(tanoData->getFactoryCrateSize());

	if (insertSelf) {
		if (!crate->transferObject(asTangibleObject(), -1, false)) {
			crate->destroyObjectFromDatabase(true);
			return NULL;
		}
	} else {

		ManagedReference<TangibleObject*> protoclone = cast<TangibleObject*>( objectManager->cloneObject(asTangibleObject()));

		if (protoclone == NULL) {
			crate->destroyObjectFromDatabase(true);
			return NULL;
		}

		protoclone->setParent(NULL);
		if (!crate->transferObject(protoclone, -1, false)) {
			protoclone->destroyObjectFromDatabase(true);
			crate->destroyObjectFromDatabase(true);
			return NULL;
		}
	}

	crate->setCustomObjectName(getCustomObjectName(), false);

	crate->setUseCount(1);

	return crate;
}
Example #4
0
void ImageDesignManager::updateCustomization(CreatureObject* imageDesigner, const String& customizationName, float value, CreatureObject* creo) {
	if (creo == NULL)
		return;

	if (value < 0 || value > 1)
		return;

	String speciesGender = getSpeciesGenderString(creo);

	ManagedReference<CreatureObject*> creatureObject = creo;

	CustomizationData* customData = getCustomizationData(speciesGender, customizationName);

	if (customData == NULL) {
		//System::out << "Unable to get CustomizationData for " + speciesGender + "_" + customizationName << endl;
		return;
	}

	String variables = customData->getVariables();
	String type = customData->getType();

	String skillMod = customData->getImageDesignSkillMod();

	if (imageDesigner->getSkillMod(skillMod) < customData->getSkillModValue())
		return;

	if (customData->getIsScale()) {
		float minScale = customData->getMinScale();
		float maxScale = customData->getMaxScale();

		float height = minScale + value * (maxScale - minScale);

		creatureObject->setHeight(MAX(MIN(height, maxScale), minScale));

		return;
	}

	Vector<String> fullVariables;
	StringTokenizer tokenizer(variables);
	tokenizer.setDelimeter(",");

	while (tokenizer.hasMoreTokens()) {
		String var;
		tokenizer.getStringToken(var);

		fullVariables.add(var);
	}

	String appearanceFilename = creo->getObjectTemplate()->getAppearanceFilename();

	VectorMap<String, Reference<CustomizationVariable*> > variableLimits;

	AssetCustomizationManagerTemplate::instance()->getCustomizationVariables(appearanceFilename.hashCode(), variableLimits, false);

	for (int i = 0; i < fullVariables.size(); ++i) {
		String var = fullVariables.get(i);

		for (int j = 0; j < variableLimits.size(); ++j) {
			String fullVariableNameLimit = variableLimits.elementAt(j).getKey();

			if (fullVariableNameLimit.contains(var)) {
				BasicRangedIntCustomizationVariable* ranged = dynamic_cast<BasicRangedIntCustomizationVariable*>(variableLimits.elementAt(j).getValue().get());

				if (ranged == NULL) {
					error("variable " + fullVariableNameLimit + " is not ranged");

					continue;
				}

				int min = ranged->getMinValueInclusive();
				int max = ranged->getMaxValueExclusive();

				int count = max - min;

				int setVal;

				float currentValue = value;

				if (fullVariables.size() > 1) {
					// examples for var count = 2
					// ex: received value 0 is for i == 0 -> 1.0, i == 1 -> 0.0
					// ex: received value 0.5 is for i == 0 -> 0.0, i == 1 -> 0.0
					// ex: received value 1 is for i == 0 -> 0.0, i == 1 -> 1.0

					// pre: i � [0, 1] && value � [0, 1]
					// post f � [0, 1]
					currentValue = MAX(0, ((value - 0.5) * 2) * (-1 + (i * 2)));
				}

				if (customData->getReverse()) {
					setVal = float(max - 1) - currentValue * (float(count) - 1);
				} else {
					setVal = float(min) + currentValue * (float(count) - 1);
				}

				creatureObject->setCustomizationVariable(fullVariableNameLimit, setVal, true);

				//info("setting " + fullVariableNameLimit + " to " + String::valueOf(setVal), true);
			}
		}
	}

}
Example #5
0
void DropShadower::updateShadows()
{
    if (reentrant || owner == nullptr)
        return;

    ComponentPeer* const peer = owner->getPeer();
    const bool isOwnerVisible = owner->isVisible() && (peer == nullptr || ! peer->isMinimised());

    const bool createShadowWindows  = shadowWindows.size() == 0
                                         && owner->getWidth() > 0
                                         && owner->getHeight() > 0
                                         && isOwnerVisible
                                         && (Desktop::canUseSemiTransparentWindows()
                                              || owner->getParentComponent() != nullptr);

    {
        const ScopedValueSetter<bool> setter (reentrant, true, false);

        const int shadowEdge = jmax (xOffset, yOffset) + (int) blurRadius;

        if (createShadowWindows)
        {
            // keep a cached version of the image to save doing the gaussian too often
            String imageId;
            imageId << shadowEdge << ',' << xOffset << ',' << yOffset << ',' << alpha;

            const int hash = imageId.hashCode();

            Image bigIm (ImageCache::getFromHashCode (hash));

            if (bigIm.isNull())
            {
                bigIm = Image (Image::ARGB, shadowEdge * 5, shadowEdge * 5, true, Image::NativeImage);

                Graphics bigG (bigIm);
                bigG.setColour (Colours::black.withAlpha (alpha));
                bigG.fillRect (shadowEdge + xOffset,
                               shadowEdge + yOffset,
                               bigIm.getWidth() - (shadowEdge * 2),
                               bigIm.getHeight() - (shadowEdge * 2));

                ImageConvolutionKernel blurKernel (roundToInt (blurRadius * 2.0f));
                blurKernel.createGaussianBlur (blurRadius);

                blurKernel.applyToImage (bigIm, bigIm,
                                         Rectangle<int> (xOffset, yOffset,
                                                         bigIm.getWidth(), bigIm.getHeight()));

                ImageCache::addImageToCache (bigIm, hash);
            }

            const int iw = bigIm.getWidth();
            const int ih = bigIm.getHeight();
            const int shadowEdge2 = shadowEdge * 2;

            setShadowImage (bigIm, 0, shadowEdge, shadowEdge2, 0, 0);
            setShadowImage (bigIm, 1, shadowEdge, shadowEdge2, 0, ih - shadowEdge2);
            setShadowImage (bigIm, 2, shadowEdge, shadowEdge, 0, shadowEdge2);
            setShadowImage (bigIm, 3, shadowEdge, shadowEdge2, iw - shadowEdge, 0);
            setShadowImage (bigIm, 4, shadowEdge, shadowEdge2, iw - shadowEdge, ih - shadowEdge2);
            setShadowImage (bigIm, 5, shadowEdge, shadowEdge, iw - shadowEdge, shadowEdge2);
            setShadowImage (bigIm, 6, shadowEdge, shadowEdge, shadowEdge, 0);
            setShadowImage (bigIm, 7, shadowEdge, shadowEdge, iw - shadowEdge2, 0);
            setShadowImage (bigIm, 8, shadowEdge, shadowEdge, shadowEdge2, 0);
            setShadowImage (bigIm, 9, shadowEdge, shadowEdge, shadowEdge, ih - shadowEdge);
            setShadowImage (bigIm, 10, shadowEdge, shadowEdge, iw - shadowEdge2, ih - shadowEdge);
            setShadowImage (bigIm, 11, shadowEdge, shadowEdge, shadowEdge2, ih - shadowEdge);

            for (int i = 0; i < 4; ++i)
                shadowWindows.add (new ShadowWindow (*owner, i, shadowImageSections));
        }

        if (shadowWindows.size() >= 4)
        {
            const int x = owner->getX();
            const int y = owner->getY() - shadowEdge;
            const int w = owner->getWidth();
            const int h = owner->getHeight() + shadowEdge + shadowEdge;

            for (int i = shadowWindows.size(); --i >= 0;)
            {
                // there seem to be rare situations where the dropshadower may be deleted by
                // callbacks during this loop, so use a weak ref to watch out for this..
                WeakReference<Component> sw (shadowWindows[i]);

                if (sw != nullptr)
                    sw->setAlwaysOnTop (owner->isAlwaysOnTop());

                if (sw != nullptr)
                    sw->setVisible (isOwnerVisible);

                if (sw != nullptr)
                {
                    switch (i)
                    {
                        case 0: sw->setBounds (x - shadowEdge, y, shadowEdge, h); break;
                        case 1: sw->setBounds (x + w, y, shadowEdge, h); break;
                        case 2: sw->setBounds (x, y, w, shadowEdge); break;
                        case 3: sw->setBounds (x, owner->getBottom(), w, shadowEdge); break;
                        default: break;
                    }
                }

                if (sw == nullptr)
                    return;
            }
        }
    }

    if (createShadowWindows)
        bringShadowWindowsToFront();
}
Example #6
0
int CampKitMenuComponent::handleObjectMenuSelect(SceneObject* sceneObject,
		CreatureObject* player, byte selectedID) const {
	if (!sceneObject->isTangibleObject())
		return 0;

	TangibleObject* tano = cast<TangibleObject*>(sceneObject);

	if (tano == NULL || !player->isPlayerCreature())
		return 0;

	if (player->getZone() == NULL)
		return 0;

	if (!sceneObject->isASubChildOf(player))
		return 0;

	if (selectedID == 20) {

		/// Get Camp Kit Template
		CampKitTemplate* campKitData = cast<CampKitTemplate*> (sceneObject->getObjectTemplate());
		if (campKitData == NULL) {
			error("No CampKitTemplate for: " + String::valueOf(sceneObject->getServerObjectCRC()));
			return 0;
		}

		/// Get Camp Template
		SharedObjectTemplate* templateData = TemplateManager::instance()->getTemplate(campKitData->getSpawnObjectTemplate().hashCode());
		CampStructureTemplate* campStructureData = cast<CampStructureTemplate*> (templateData);
		if (campStructureData == NULL) {
			error("No CampStructureTemplate for: " + campKitData->getSpawnObjectTemplate());
			return 0;
		}

		ManagedReference<ZoneServer*> zoneServer = player->getZoneServer();
		if (zoneServer == NULL) {
			error("ZoneServer is null when trying to create camp");
			return 0;
		}

		ManagedReference<Zone*> zone = player->getZone();
		if (zone == NULL) {
			error("Zone is null when trying to create camp");
			return 0;
		}

		ManagedReference<PlanetManager*> planetManager = zone->getPlanetManager();
		if (planetManager == NULL) {
			error("Unable to get PlanetManager when placing camp");
			return 0;
		}


		/// Get Ghost
		Reference<PlayerObject*> ghost = player->getSlottedObject("ghost").castTo<PlayerObject*>();
		if (ghost == NULL) {
			error("PlayerCreature has no ghost: " + String::valueOf(player->getObjectID()));
			return 0;
		}

		int playerSkill = player->getSkillMod("camp");

		if(playerSkill < campStructureData->getSkillRequired()) {
			player->sendSystemMessage("@camp:sys_nsf_skill");
			return 0;
		}

		if(player->isInCombat()) {
			player->sendSystemMessage("@camp:sys_not_in_combat");
			return 0;
		}

		if(player->getParent() != NULL && player->getParent().get()->isCellObject()) {
			player->sendSystemMessage("@camp:error_inside");
			return 0;
		}

		if(!sceneObject->isASubChildOf(player)) {
			player->sendSystemMessage("@camp:sys_not_in_inventory");
			return 0;
		}

		if(!player->isStanding() || player->isRidingMount()) {
			player->sendSystemMessage("@camp:error_cmd_fail");
			return 0;
		}

		ManagedReference<CityRegion*> region = player->getCityRegion();
		if(region != NULL) {
			player->sendSystemMessage("@camp:error_muni_true");
			return 0;
		}

		/// Check for water
		if(player->isSwimming() || player->isInWater()) {
			player->sendSystemMessage("@camp:error_in_water");
			return 0;
		}

		/// Make sure player doesn't already have a camp setup somewhere else
		for (int i = 0; i < ghost->getTotalOwnedStructureCount(); ++i) {
			uint64 oid = ghost->getOwnedStructure(i);

			ManagedReference<StructureObject*> structure = ghost->getZoneServer()->getObject(oid).castTo<StructureObject*>();

			if (structure != NULL && structure->isCampStructure()) {
				player->sendSystemMessage("@camp:sys_already_camping");
				return 0;
			}
		}

		/// Check if player is in another camp
		if(player->getCurrentCamp() != NULL) {
			player->sendSystemMessage("@camp:error_camp_exists");
			return 0;
		}

		/// Check if player is elevated, on a building or porch

		/// Check camps/lairs nearby
		SortedVector<ManagedReference<QuadTreeEntry* > > nearbyObjects;
		zone->getInRangeObjects(player->getPositionX(), player->getPositionY(),
				512, &nearbyObjects, true);

		for(int i = 0; i < nearbyObjects.size(); ++i) {
			SceneObject* scno = cast<SceneObject*>(nearbyObjects.get(i).get());
			if (scno != NULL && scno->isCampStructure() && scno->getDistanceTo(
					player) <= scno->getObjectTemplate()->getNoBuildRadius() + campStructureData->getRadius()) {
				player->sendSystemMessage("@camp:error_camp_too_close");
				return 0;
			}

			if (scno != NULL && !scno->isCampStructure() && scno->isStructureObject() &&
					scno->getDistanceTo(player) <= 100) {
				player->sendSystemMessage("@camp:error_building_too_close");
				return 0;
			}

			if(scno != NULL && scno->getDistanceTo(player) <= scno->getObjectTemplate()->getNoBuildRadius() + campStructureData->getRadius()) {

				if (scno->getObserverCount(ObserverEventType::OBJECTDESTRUCTION) > 0) {
					SortedVector<ManagedReference<Observer* > > observers = scno->getObservers(ObserverEventType::OBJECTDESTRUCTION);
					for(int j = 0; j < observers.size(); ++j) {
						if(observers.get(j)->isObserverType(ObserverType::LAIR)) {
							player->sendSystemMessage("@camp:error_lair_too_close");
							return 0;
						}
					}
				}

				if (scno->getObserverCount(ObserverEventType::CREATUREDESPAWNED) > 0) {
					SortedVector<ManagedReference<Observer* > > observers2 = scno->getObservers(ObserverEventType::CREATUREDESPAWNED);
					for(int j = 0; j < observers2.size(); ++j) {
						if(observers2.get(j)->isObserverType(ObserverType::LAIR)) {
							player->sendSystemMessage("@camp:error_lair_too_close");
							return 0;
						}
					}
				}
			}
		}

		/// Check to see if you can camp here (Allows building in city no-build zone but not within city limits which are checked above)
		if (!planetManager->isCampingPermittedAt(player->getPositionX(), player->getPositionY(), campStructureData->getRadius())) {
			player->sendSystemMessage("@camp:error_nobuild");
			return 0;
		}

		player->sendSystemMessage("@camp:starting_camp");

		/// Create Structure
		StructureObject* structureObject = StructureManager::instance()->placeStructure(
				player, campKitData->getSpawnObjectTemplate(),
				player->getPositionX(), player->getPositionY(),
				(int) player->getDirectionAngle());

		if (structureObject == NULL) {
			error("Unable to create camp: " + campKitData->getSpawnObjectTemplate());
			return 1;
		}

		/// Identify terminal for Active area
		Terminal* campTerminal = NULL;
		SortedVector < ManagedReference<SceneObject*> > *childObjects
				= structureObject->getChildObjects();

		for (int i = 0; i < childObjects->size(); ++i) {
			if (childObjects->get(i)->isTerminal()) {
				campTerminal = cast<Terminal*> (childObjects->get(i).get());
				break;
			}
		}

		if (campTerminal == NULL) {
			structureObject->destroyObjectFromDatabase(true);
			error("Camp does not have terminal: " + campStructureData->getTemplateFileName());
			return 1;
		}

		String campName = player->getFirstName();
		if(!player->getLastName().isEmpty())
			campName += " " + player->getLastName();
		campName += "'s Camp";
		campTerminal->setCustomObjectName(campName, true);

		/// Create active area
		String areaPath = "object/camp_area.iff";
		ManagedReference<CampSiteActiveArea*> campArea =
			(zoneServer->createObject( areaPath.hashCode(), 1)).castTo< CampSiteActiveArea*>();

		if (campArea == NULL) {
			structureObject->destroyObjectFromDatabase(true);
			return 1;
		}

		Locker areaLocker(campArea, player);

		campArea->init(campStructureData);
		campArea->setTerminal(campTerminal);
		campArea->setCamp(structureObject);
		campArea->setOwner(player);
		campArea->setNoBuildArea(true);
		campArea->initializePosition(player->getPositionX(), 0, player->getPositionY());

		if (!zone->transferObject(campArea, -1, false)) {
			structureObject->destroyObjectFromDatabase(true);
			campArea->destroyObjectFromDatabase(true);
			return 1;
		}

		structureObject->addActiveArea(campArea);

		player->sendSystemMessage("@camp:camp_complete");

		/// Remove Camp
		TangibleObject* tano = cast<TangibleObject*>(sceneObject);
		if(tano != NULL)
			tano->decreaseUseCount();


		return 0;
	} else
		return TangibleObjectMenuComponent::handleObjectMenuSelect(sceneObject,
				player, selectedID);

	return 0;
}
TangibleObject* LootManagerImplementation::createLootObject(LootItemTemplate* templateObject, int level, bool maxCondition) {

	if(level < 1)
		level = 1;

	if(level > 300)
		level = 300;

	String directTemplateObject = templateObject->getDirectObjectTemplate();

	ManagedReference<TangibleObject*> prototype = zoneServer->createObject(directTemplateObject.hashCode(), 2).castTo<TangibleObject*>();

	if (prototype == NULL) {
		error("could not create loot object: " + directTemplateObject);
		return NULL;
	}

	prototype->createChildObjects();

	String serial = craftingManager->generateSerial();
	prototype->setSerialNumber(serial);
	prototype->setJunkDealerNeeded(templateObject->getJunkDealerTypeNeeded());
	float junkMinValue = templateObject->getJunkMinValue() * junkValueModifier;
	float junkMaxValue = templateObject->getJunkMaxValue() * junkValueModifier;
	float fJunkValue = junkMinValue+System::random(junkMaxValue-junkMinValue);

	if (level>0 && templateObject->getJunkDealerTypeNeeded()>1){
		fJunkValue=fJunkValue + (fJunkValue * ((float)level / 100)); // This is the loot value calculation if the item has a level
	}
	CraftingValues craftingValues = templateObject->getCraftingValuesCopy();

	setInitialObjectStats(templateObject, &craftingValues, prototype);

	setCustomObjectName(prototype, templateObject);

	float excMod = 1.0;

	if (System::random(legendaryChance) == legendaryChance) {
			uint32 bitmask = prototype->getOptionsBitmask() | OptionBitmask::YELLOW;

			UnicodeString newName = prototype->getDisplayedName() + " (Legendary)";
			prototype->setCustomObjectName(newName, false);

			excMod = legendaryModifier;

			prototype->setOptionsBitmask(bitmask, false);
	} else if (System::random(exceptionalChance) == exceptionalChance) {
		uint32 bitmask = prototype->getOptionsBitmask() | OptionBitmask::YELLOW;

		UnicodeString newName = prototype->getDisplayedName() + " (Exceptional)";
		prototype->setCustomObjectName(newName, false);

		excMod = exceptionalModifier;

		prototype->setOptionsBitmask(bitmask, false);
	}
	String subtitle;
	bool yellow = false;

	for (int i = 0; i < craftingValues.getExperimentalPropertySubtitleSize(); ++i) {
		subtitle = craftingValues.getExperimentalPropertySubtitle(i);

		if (subtitle == "hitpoints" || subtitle == "maxrange") {
			if(!(prototype->isComponent())) {
				continue;
			}
		}

		float min = craftingValues.getMinValue(subtitle);
		float max = craftingValues.getMaxValue(subtitle);

		if (min == max)
			continue;

		if (subtitle != "useCount" &&
				subtitle != "quantity" &&
				subtitle != "charges" &&
				subtitle != "uses" &&
				subtitle != "charge") {

			float minMod = (max > min) ? 2000.f : -2000.f;
			float maxMod = (max > min) ? 500.f : -500.f;

			if (max > min && min >= 0) { // Both max and min non-negative, max is higher
				min = ((min * level / minMod) + min) * excMod;
				max = ((max * level / maxMod) + max) * excMod;

			} else if (max > min && max <= 0) { // Both max and min are non-positive, max is higher
				minMod *= -1;
				maxMod *= -1;
				min = ((min * level / minMod) + min) / excMod;
				max = ((max * level / maxMod) + max) / excMod;

			} else if (max > min) { // max is positive, min is negative
				minMod *= -1;
				min = ((min * level / minMod) + min) / excMod;
				max = ((max * level / maxMod) + max) * excMod;

			} else if (max < min && max >= 0) { // Both max and min are non-negative, min is higher
				min = ((min * level / minMod) + min) / excMod;
				max = ((max * level / maxMod) + max) / excMod;

			} else if (max < min && min <= 0) { // Both max and min are non-positive, min is higher
				minMod *= -1;
				maxMod *= -1;
				min = ((min * level / minMod) + min) * excMod;
				max = ((max * level / maxMod) + max) * excMod;

			} else { // max is negative, min is positive
				maxMod *= -1;
				min = ((min * level / minMod) + min) / excMod;
				max = ((max * level / maxMod) + max) * excMod;
			}
		} else {
			if (excMod != 1.0) {
				min *= yellowModifier;
				max *= yellowModifier;
			}
		}

		if (excMod == 1.0 && (yellowChance == 0 || System::random(yellowChance) == 0)) {
			if (max > min && min >= 0) {
				min *= yellowModifier;
				max *= yellowModifier;
			} else if (max > min && max <= 0) {
				min /= yellowModifier;
				max /= yellowModifier;
			} else if (max > min) {
				min /= yellowModifier;
				max *= yellowModifier;
			} else if (max < min && max >= 0) {
				min /= yellowModifier;
				max /= yellowModifier;
			} else if (max < min && min <= 0) {
				min *= yellowModifier;
				max *= yellowModifier;
			} else {
				min /= yellowModifier;
				max *= yellowModifier;
			}

			yellow = true;
		}

		craftingValues.setMinValue(subtitle, min);
		craftingValues.setMaxValue(subtitle, max);

		float percentage = System::random(10000) / 10000.f;

		craftingValues.setCurrentPercentage(subtitle, percentage);
	}

	if (yellow) {
		uint32 bitmask = prototype->getOptionsBitmask() | OptionBitmask::YELLOW;
		prototype->setOptionsBitmask(bitmask, false);
		prototype->setJunkValue((int)(fJunkValue * 1.25));
	}else{
		if (excMod==1){
			prototype->setJunkValue((int)(fJunkValue));
		}else{
			prototype->setJunkValue((int)(fJunkValue * (excMod/2)));
		}
	}

	// Use percentages to recalculate the values
	craftingValues.recalculateValues(false);

	craftingValues.addExperimentalProperty("creatureLevel", "creatureLevel", level, level, 0, false, CraftingManager::LINEARCOMBINE);
	craftingValues.setHidden("creatureLevel");

	//check weapons and weapon components for min damage > max damage
	if (prototype->isComponent() || prototype->isWeaponObject()) {
		if (craftingValues.hasProperty("mindamage") && craftingValues.hasProperty("maxdamage")) {
			float oldMin = craftingValues.getCurrentValue("mindamage");
			float oldMax = craftingValues.getCurrentValue("maxdamage");

			if (oldMin > oldMax) {
				craftingValues.setCurrentValue("mindamage", oldMax);
				craftingValues.setCurrentValue("maxdamage", oldMin);
			}
		}
	}

	// Add Dots to weapon objects.
	addStaticDots(prototype, templateObject, level);
	addRandomDots(prototype, templateObject, level, excMod);

	setSkillMods(prototype, templateObject, level, excMod);

	setSockets(prototype, &craftingValues);

	// Update the Tano with new values
	prototype->updateCraftingValues(&craftingValues, true);

	//add some condition damage where appropriate
	if (!maxCondition)
		addConditionDamage(prototype, &craftingValues);

	return prototype;
}
TEST_F(LuaMobileTest, LuaSpawnManagerTest) {
	Vector<String> zoneNames;
	zoneNames.add("corellia");
	zoneNames.add("dantooine");
	zoneNames.add("dathomir");
	zoneNames.add("endor");
	zoneNames.add("lok");
	zoneNames.add("naboo");
	zoneNames.add("rori");
	zoneNames.add("talus");
	zoneNames.add("tatooine");
	zoneNames.add("yavin4");

	Lua* lua = new Lua();
	lua->init();

	for (int i = 0; i < zoneNames.size(); i++) {
		lua->runFile("scripts/managers/spawn_manager/" + zoneNames.get(i) + ".lua");

		// Verify regions
		LuaObject regions = lua->getGlobalObject(zoneNames.get(i) + "_regions");

		ASSERT_TRUE( regions.isValidTable() ) << "Regions table in " << zoneNames.get(i).toCharArray() << " spawn manager is invalid.";

		for (int j = 1; j <= regions.getTableSize(); ++j) {
			lua_rawgeti(regions.getLuaState(), -1, j);
			LuaObject region(regions.getLuaState());

			ASSERT_TRUE( region.isValidTable() ) << "Invalid region table #" << String::valueOf(j).toCharArray() << " in " << zoneNames.get(i).toCharArray() << "_regions.";

			String area = region.getStringAt(1);
			int tier = region.getIntAt(5);

			if (tier & SpawnAreaMap::WORLDSPAWNAREA) {
				EXPECT_TRUE( tier & SpawnAreaMap::SPAWNAREA ) << "World spawn area " << std::string(area.toCharArray()) << " on planet " << std::string(zoneNames.get(i).toCharArray()) << " is not a spawn area.";
			}

			if (tier & SpawnAreaMap::SPAWNAREA) {
				String group = region.getStringAt(7);
				EXPECT_TRUE( CreatureTemplateManager::instance()->getSpawnGroup(group.hashCode()) != NULL ) << "Spawn group " << std::string(group.toCharArray()) << " for spawn area " << std::string(area.toCharArray()) << " on planet " << std::string(zoneNames.get(i).toCharArray()) << " does not exist.";
			}

			region.pop();
		}

		regions.pop();

		// Verify static spawns
		LuaObject spawns = lua->getGlobalObject(zoneNames.get(i) + "_static_spawns");

		ASSERT_TRUE( spawns.isValidTable() ) << "Static spawns table in " << zoneNames.get(i).toCharArray() << " spawn manager is invalid.";

		for (int j = 1; j <= spawns.getTableSize(); ++j) {
			lua_rawgeti(spawns.getLuaState(), -1, j);
			LuaObject spawn(spawns.getLuaState());

			ASSERT_TRUE( spawn.isValidTable() ) << "Invalid spawn table #" << String::valueOf(j).toCharArray() << " in " << zoneNames.get(i).toCharArray() << "_static_spawns.";

			String name = spawn.getStringAt(1);

			EXPECT_TRUE( CreatureTemplateManager::instance()->getTemplate(name) != NULL ) << "Static spawn " << std::string(name.toCharArray()) << " on planet " << std::string(zoneNames.get(i).toCharArray()) << " is not valid";

			spawn.pop();
		}

		spawns.pop();

		// Verify badges
		LuaObject badges = lua->getGlobalObject(zoneNames.get(i) + "_badges");

		ASSERT_TRUE( badges.isValidTable() ) << "Badges table in " << zoneNames.get(i).toCharArray() << " spawn manager is invalid.";

		for (int j = 1; j <= badges.getTableSize(); ++j) {
			lua_rawgeti(badges.getLuaState(), -1, j);
			LuaObject badge(badges.getLuaState());

			ASSERT_TRUE( badge.isValidTable() ) << "Invalid badge table #" << String::valueOf(j).toCharArray() << " in " << zoneNames.get(i).toCharArray() << "_badges.";

			uint8 id = badge.getIntAt(5);

			EXPECT_TRUE( Badge::exists(id) ) << "Badge id #" << String::valueOf(id).toCharArray() << " does not exist.";

			badge.pop();
		}

		badges.pop();
	}
}
bool CreatureManagerImplementation::addWearableItem(CreatureObject* creature, TangibleObject* clothing) {
	if (!clothing->isWearableObject() && !clothing->isWeaponObject())
		return false;

	ChatManager* chatMan = zoneServer->getChatManager();

	SharedTangibleObjectTemplate* tanoData = dynamic_cast<SharedTangibleObjectTemplate*>(clothing->getObjectTemplate());

	if (tanoData == NULL || chatMan == NULL)
		return false;

	Vector<uint32>* races = tanoData->getPlayerRaces();
	String race = creature->getObjectTemplate()->getFullTemplateString();

	if (clothing->isWearableObject()) {
		if (!races->contains(race.hashCode())) {
			UnicodeString message;

			if(creature->getObjectTemplate()->getFullTemplateString().contains("ithorian"))
				message = "@player_structure:wear_not_ithorian";
			else
				message = "@player_structure:wear_no";

			chatMan->broadcastChatMessage(creature, message, clothing->getObjectID(), 0, creature->getMoodID());

			return false;
		}
	}

	ManagedReference<SceneObject*> clothingParent = clothing->getParent().get();

	if (clothingParent == NULL)
		return false;

	for (int i = 0; i < clothing->getArrangementDescriptorSize(); ++i) {
		const Vector<String>* descriptors = clothing->getArrangementDescriptor(i);

		for (int j = 0; j < descriptors->size(); ++j) {
			ManagedReference<SceneObject*> slot = creature->getSlottedObject(descriptors->get(j));

			if (slot != NULL) {
				Locker locker(slot);
				slot->destroyObjectFromWorld(true);
				slot->destroyObjectFromDatabase(true);
			}
		}
	}

	creature->transferObject(clothing, 4, false);
	creature->doAnimation("pose_proudly");
	creature->broadcastObject(clothing, true);

	UnicodeString message;
	if (clothing->isWeaponObject())
		message = "@player_structure:wear_yes_weapon";
	else
		message = "@player_structure:wear_yes";

	chatMan->broadcastChatMessage(creature, message, clothing->getObjectID(), 0, creature->getMoodID());

	return true;
}
Example #10
0
void ContainerPermissions::clearDenyPermission(const String& group, uint16 permission) {
	clearDenyPermission(group.hashCode(), permission);
}
int PlantObjectImplementation::handleObjectMenuSelect(CreatureObject* player, byte selectedID) {
	ManagedReference<SceneObject*> rootParent = getRootParent();
	ManagedReference<SceneObject*> parent = getParent();

	if (rootParent == NULL || parent == NULL) {
		return 0;
	}

	ManagedReference<BuildingObject*> building = cast<BuildingObject*>( rootParent.get());

	if ((building == NULL || !building->isOnAdminList(player) || !parent->isCellObject()) && selectedID >= 69 && selectedID <= 74) {
		player->sendSystemMessage("@plant_grow:must_be_in_building"); // The plant must be in a building which you administrate.
		return 0;
	}

	if (selectedID == 69) { // Add Nutrients
		sendResourceSUI(player, 1);
	} else if (selectedID == 72) { // Add Water
		sendResourceSUI(player, 2);
	} else if (selectedID == 70) { // Remove Nutrients
		nutrientLevel -= 5;

		if (nutrientLevel < 0)
			nutrientLevel = 0;

		player->sendSystemMessage("@plant_grow:remove_nutrients");
	} else if (selectedID == 73) { // Remove Water
		waterLevel -= 5;

		if (waterLevel < 0)
			waterLevel = 0;

		player->sendSystemMessage("@plant_grow:remove_water");
	} else if (selectedID == 74) { // Pick Fruit
		if (fruitCount < 1)
			return 0;

		ManagedReference<SceneObject*> inventory = player->getSlottedObject("inventory");

		if(inventory->isContainerFullRecursive()){
			player->sendSystemMessage("@plant_grow:no_inventory"); // You do not have any inventory space.
			return 0;
		}

		ZoneServer* zserv = player->getZoneServer();

		fruitCount--;

		String fruitTemplate = "object/tangible/item/plant/force_melon.iff";
		Reference<SceneObject*> fruit = zserv->createObject(fruitTemplate.hashCode(), 1);

		if(fruit == NULL) {
			return 0;
		}

		if (!inventory->transferObject(fruit, -1, false, false) ) {
			fruit->destroyObjectFromDatabase(true);
			return 0;
		}

		inventory->broadcastObject(fruit, true);
		player->sendSystemMessage("@plant_grow:pick_fruit"); // You pick a piece of fruit from the plant.

	}

	return 1;
}
Example #12
0
void ContainerPermissions::setAllowPermission(const String& group, uint16 permission) {
	setAllowPermission(group.hashCode(), permission);
}
Example #13
0
uint16 ContainerPermissions::getDenyPermissions(const String& group) {
	return getDenyPermissions(group.hashCode());
}
Example #14
0
bool ContainerPermissions::hasPermission(const String& group, uint16 permission) {
	return hasPermission(group.hashCode(), permission);
}
Example #15
0
int StructureManager::placeStructureFromDeed(CreatureObject* creature, StructureDeed* deed, float x, float y, int angle) {
	ManagedReference<Zone*> zone = creature->getZone();

	//Already placing a structure?
	if (zone == NULL || creature->containsActiveSession(SessionFacadeType::PLACESTRUCTURE))
		return 1;

	ManagedReference<PlanetManager*> planetManager = zone->getPlanetManager();

	String serverTemplatePath = deed->getGeneratedObjectTemplate();

	if (deed->getFaction() != 0 && creature->getFaction() != deed->getFaction()) {
		creature->sendSystemMessage("You are not the correct faction");
		return 1;
	}

	Reference<SharedStructureObjectTemplate*> serverTemplate =
			dynamic_cast<SharedStructureObjectTemplate*>(templateManager->getTemplate(serverTemplatePath.hashCode()));

	//Check to see if this zone allows this structure.
	if (serverTemplate == NULL || !serverTemplate->isAllowedZone(zone->getZoneName())) {
		creature->sendSystemMessage("@player_structure:wrong_planet"); //That deed cannot be used on this planet.
		return 1;
	}

	if (!planetManager->isBuildingPermittedAt(x, y, creature)) {
		creature->sendSystemMessage("@player_structure:not_permitted"); //Building is not permitted here.
		return 1;
	}

	SortedVector<ManagedReference<ActiveArea*> > objects;
	zone->getInRangeActiveAreas(x, y, &objects, true);

	ManagedReference<CityRegion*> city;

	for (int i = 0; i < objects.size(); ++i) {
		ActiveArea* area = objects.get(i).get();

		if (!area->isRegion())
			continue;

		city = dynamic_cast<Region*>(area)->getCityRegion();

		if (city != NULL)
			break;
	}

	SortedVector<ManagedReference<QuadTreeEntry*> > inRangeObjects;
	zone->getInRangeObjects(x, y, 128, &inRangeObjects, true);

	float placingFootprintLength0, placingFootprintWidth0, placingFootprintLength1, placingFootprintWidth1;

	if (!getStructureFootprint(serverTemplate, angle, placingFootprintLength0, placingFootprintWidth0, placingFootprintLength1, placingFootprintWidth1)) {
		float x0 = x + placingFootprintWidth0;
		float y0 = y + placingFootprintLength0;
		float x1 = x + placingFootprintWidth1;
		float y1 = y + placingFootprintLength1;

		BoundaryRectangle placingFootprint(x0, y0, x1, y1);

		//info("placing center x:" + String::valueOf(x) + " y:" + String::valueOf(y), true);
		//info("placingFootprint x0:" + String::valueOf(x0) + " y0:" + String::valueOf(y0) + " x1:" + String::valueOf(x1) + " y1:" + String::valueOf(y1), true);

		for (int i = 0; i < inRangeObjects.size(); ++i) {
			SceneObject* scene = inRangeObjects.get(i).castTo<SceneObject*>();

			if (scene == NULL)
				continue;

			float l0 = -5; //Along the x axis.
			float w0 = -5; //Along the y axis.
			float l1 = 5;
			float w1 = 5;

			if (getStructureFootprint(scene->getObjectTemplate(), scene->getDirectionAngle(), l0, w0, l1, w1))
				continue;

			float xx0 = scene->getPositionX() + (w0 + 0.1);
			float yy0 = scene->getPositionY() + (l0 + 0.1);
			float xx1 = scene->getPositionX() + (w1 - 0.1);
			float yy1 = scene->getPositionY() + (l1 - 0.1);

			BoundaryRectangle rect(xx0, yy0, xx1, yy1);

			//info("existing footprint xx0:" + String::valueOf(xx0) + " yy0:" + String::valueOf(yy0) + " xx1:" + String::valueOf(xx1) + " yy1:" + String::valueOf(yy1), true);

			// check 4 points of the current rect
			if (rect.containsPoint(x0, y0)
					|| rect.containsPoint(x0, y1)
					|| rect.containsPoint(x1, y0)
					|| rect.containsPoint(x1, y1) ) {

				//info("existing footprint contains placing point", true);

				creature->sendSystemMessage("@player_structure:no_room"); //there is no room to place the structure here..

				return 1;
			}

			if (placingFootprint.containsPoint(xx0, yy0)
					|| placingFootprint.containsPoint(xx0, yy1)
					|| placingFootprint.containsPoint(xx1, yy0)
					|| placingFootprint.containsPoint(xx1, yy1)
					|| (xx0 == x0 && yy0 == y0 && xx1 == x1 && yy1 == y1)) {
				//info("placing footprint contains existing point", true);

				creature->sendSystemMessage("@player_structure:no_room"); //there is no room to place the structure here.

				return 1;
			}
		}
	}

	int rankRequired = serverTemplate->getCityRankRequired();

	if (city == NULL && rankRequired > 0) {
		creature->sendSystemMessage("@city/city:build_no_city"); // You must be in a city to place that structure.
		return 1;
	}

	if (city != NULL) {
		if (city->isZoningEnabled() && !city->hasZoningRights(creature->getObjectID())) {
			creature->sendSystemMessage("@player_structure:no_rights"); //You don't have the right to place that structure in this city. The mayor or one of the city milita must grant you zoning rights first.
			return 1;
		}

		if (rankRequired != 0 && city->getCityRank() < rankRequired) {
			StringIdChatParameter param("city/city", "rank_req"); // The city must be at least rank %DI (%TO) in order for you to place this structure.
			param.setDI(rankRequired);
			param.setTO("city/city", "rank" + String::valueOf(rankRequired));

			creature->sendSystemMessage(param);
			return 1;
		}

		if (serverTemplate->isCivicStructure() && !city->isMayor(creature->getObjectID()) ) {
				creature->sendSystemMessage("@player_structure:cant_place_civic");//"This structure must be placed within the borders of the city in which you are mayor."
				return 1;
		}

		if (serverTemplate->isUniqueStructure() && city->hasUniqueStructure(serverTemplate->getServerObjectCRC())) {
			creature->sendSystemMessage("@player_structure:cant_place_unique"); //This city can only support a single structure of this type.
			return 1;
		}
	}

	Locker _lock(deed, creature);


	if(serverTemplate->isDerivedFrom("object/building/faction_perk/base/shared_factional_building_base.iff")){
		Zone* zone = creature->getZone();
		if(zone == NULL)
			return 1;

		GCWManager* gcwMan = zone->getGCWManager();
		if(gcwMan == NULL)
			return 1;

		if(!gcwMan->canPlaceMoreBases(creature))
			return 1;
	}

	//Ensure that it is the correct deed, and that it is in a container in the creature's inventory.
	if (!deed->isASubChildOf(creature)) {
		creature->sendSystemMessage("@player_structure:no_possession"); //You no longer are in possession of the deed for this structure. Aborting construction.
		return 1;
	}

	TemplateManager* templateManager = TemplateManager::instance();

	ManagedReference<PlayerObject*> ghost = creature->getPlayerObject();

	if (ghost != NULL) {
		String abilityRequired = serverTemplate->getAbilityRequired();

		if (!abilityRequired.isEmpty() && !ghost->hasAbility(abilityRequired)) {
			creature->sendSystemMessage("@player_structure:" + abilityRequired);
			return 1;
		}

		int lots = serverTemplate->getLotSize();

		if (!ghost->hasLotsRemaining(lots)) {
			StringIdChatParameter param("@player_structure:not_enough_lots");
			param.setDI(lots);
			creature->sendSystemMessage(param);
			return 1;
		}
	}

	//Validate that the structure can be placed at the given coordinates:
	//Ensure that no other objects impede on this structures footprint, or overlap any city regions or no build areas.
	//Make sure that the player has zoning rights in the area.

	ManagedReference<PlaceStructureSession*> session = new PlaceStructureSession(creature, deed);
	creature->addActiveSession(SessionFacadeType::PLACESTRUCTURE, session);

	//Construct the structure.
	session->constructStructure(x, y, angle);

	//Remove the deed from it's container.
	deed->destroyObjectFromWorld(true);

	return 0;
}
int VehicleCustomKitObjectMenuComponent::handleObjectMenuSelect(SceneObject* sceneObject, CreatureObject* player, byte selectedID) const {

	if (player == NULL)
		return 0;

	if (!sceneObject->isASubChildOf(player))
		return 0;

	if (selectedID != 20)
		return TangibleObjectMenuComponent::handleObjectMenuSelect(sceneObject, player, selectedID);

	if(!sceneObject->isTangibleObject())
		return 0;

	ManagedReference<TangibleObject*> kitTano = cast<TangibleObject*>(sceneObject);
	if(kitTano == NULL)
		return 0;

	uint64 targetID = player->getTargetID();
	ZoneServer* server = player->getZoneServer();
	if (server == NULL)
		return 0;

	ManagedReference<TangibleObject*> target = server->getObject(targetID, true).castTo<TangibleObject*>();
	if (target == NULL || !target->isVehicleObject()) {
		player->sendSystemMessage("You can only use this tool to customize vehicle");
		return 0;
	}

	//permission check
	CreatureObject* vehicle = cast<CreatureObject*>(target.get());
	uint64 ownerID = vehicle->getCreatureLinkID();
	if ( ownerID != player->getObjectID()){
		bool hasConsent = false;

		ManagedReference<CreatureObject*> targetOwner = server->getObject(ownerID, true).castTo<CreatureObject*>();
		if (targetOwner != NULL)
		{
			Locker crossLock(targetOwner, player);
			ManagedReference<PlayerObject*> ghostOwner = targetOwner->getPlayerObject();
			for (int i = 0; i < ghostOwner->getConsentListSize(); ++i) {
				String entryName = ghostOwner->getConsentName(i);
				if (!entryName.isEmpty()){
					if (entryName == player->getFirstName().toLowerCase()){
						hasConsent = true;
					}
				}
			}
		}
		if (!hasConsent){
			player->sendSystemMessage("You require consent to customize another player's vehicle");
			return 0;
		}
	}
	//end permission check

	Locker clocker(vehicle, player);

	String appearanceFilename = target->getObjectTemplate()->getAppearanceFilename();
	VectorMap<String, Reference<CustomizationVariable*> > variables;
	AssetCustomizationManagerTemplate::instance()->getCustomizationVariables(appearanceFilename.hashCode(), variables, false);
	int numPalette = 0;
	for(int i = 0; i< variables.size(); ++i)
	{
		String varkey = variables.elementAt(i).getKey();
		if (varkey.contains("color"))
		{
			++numPalette;
		}
	}

	if (numPalette == 0) {
		player->sendSystemMessage("No customization options available on this vehicle");//jetpack
		return 0;
	}

	VehicleObject* painted = cast<VehicleObject*>(vehicle);
	if (painted != NULL){
		painted->refreshPaint();
	}

	ManagedReference<SuiListBox*> frameTrimSelector = new SuiListBox(player, SuiWindowType::CUSTOMIZE_KIT);
	frameTrimSelector->setUsingObject(player);
	frameTrimSelector->setCallback(new CustomVehicleSuiCallback(server, numPalette, kitTano ));
	frameTrimSelector->setUsingObject(target);
	frameTrimSelector->setPromptTitle("Customize");
	frameTrimSelector->setPromptText("Please select the customization action you would like to take");

	frameTrimSelector->addMenuItem("Color Frame");
	frameTrimSelector->addMenuItem("Color Trim");
	if (numPalette > 2 ) {
		frameTrimSelector->addMenuItem("Color Extra Trim");
	}

	frameTrimSelector->setCancelButton(true, "");
	frameTrimSelector->setOkButton(true, "@ok");

	ManagedReference<PlayerObject*> ghost = player->getPlayerObject();
	ghost->addSuiBox(frameTrimSelector);
	player->sendMessage(frameTrimSelector->generateMessage());

	return 0;
}
Example #17
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)
}
Example #18
0
bool SkillManager::awardSkill(const String& skillName, CreatureObject* creature, bool notifyClient, bool awardRequiredSkills, bool noXpRequired) {
	Skill* skill = skillMap.get(skillName.hashCode());

	if (skill == NULL)
		return false;

	Locker locker(creature);

	//Check for required skills.
	Vector<String>* requiredSkills = skill->getSkillsRequired();
	for (int i = 0; i < requiredSkills->size(); ++i) {
		String requiredSkillName = requiredSkills->get(i);
		Skill* requiredSkill = skillMap.get(requiredSkillName.hashCode());

		if (requiredSkill == NULL)
			continue;

		if (awardRequiredSkills)
			awardSkill(requiredSkillName, creature, notifyClient, awardRequiredSkills, noXpRequired);

		if (!creature->hasSkill(requiredSkillName))
			return false;
	}

	if (!canLearnSkill(skillName, creature, noXpRequired)) {
		return false;
	}

	//If they already have the skill, then return true.
	if (creature->hasSkill(skill->getSkillName()))
		return true;

	ManagedReference<PlayerObject*> ghost = creature->getPlayerObject();

	if (ghost != NULL) {
		//Withdraw skill points.
		ghost->addSkillPoints(-skill->getSkillPointsRequired());

		//Witdraw experience.
		if (!noXpRequired) {
			ghost->addExperience(skill->getXpType(), -skill->getXpCost(), true);
		}

		creature->addSkill(skill, notifyClient);

		//Add skill modifiers
		VectorMap<String, int>* skillModifiers = skill->getSkillModifiers();

		for (int i = 0; i < skillModifiers->size(); ++i) {
			VectorMapEntry<String, int>* entry = &skillModifiers->elementAt(i);
			creature->addSkillMod(SkillModManager::SKILLBOX, entry->getKey(), entry->getValue(), notifyClient);

		}

		//Add abilities
		Vector<String>* abilityNames = skill->getAbilities();
		addAbilities(ghost, *abilityNames, notifyClient);
		if (skill->isGodOnly()) {
			for (int i = 0; i < abilityNames->size(); ++i) {
				String ability = abilityNames->get(i);
				StringIdChatParameter params;
				params.setTU(ability);
				params.setStringId("ui", "skill_command_acquired_prose");

				creature->sendSystemMessage(params);
			}
		}

		//Add draft schematic groups
		Vector<String>* schematicsGranted = skill->getSchematicsGranted();
		SchematicMap::instance()->addSchematics(ghost, *schematicsGranted, notifyClient);

		//Update maximum experience.
		updateXpLimits(ghost);


		// Update Force Power Max.
		ghost->setForcePowerMax(creature->getSkillMod("jedi_force_power_max"), true);

		if (skillName.contains("master")) {
			ManagedReference<PlayerManager*> playerManager = creature->getZoneServer()->getPlayerManager();
			if (playerManager != NULL) {
				const Badge* badge = BadgeList::instance()->get(skillName);

				if (badge == NULL && skillName == "crafting_shipwright_master") {
					badge = BadgeList::instance()->get("crafting_shipwright");
				}

				if (badge != NULL) {
					playerManager->awardBadge(ghost, badge);
				}
			}
		}

		SkillList* list = creature->getSkillList();

		int totalSkillPointsWasted = 250;

		for (int i = 0; i < list->size(); ++i) {
			Skill* skill = list->get(i);

			totalSkillPointsWasted -= skill->getSkillPointsRequired();
		}

		if (ghost->getSkillPoints() != totalSkillPointsWasted) {
			creature->error("skill points mismatch calculated: " + String::valueOf(totalSkillPointsWasted) + " found: " + String::valueOf(ghost->getSkillPoints()));
			ghost->setSkillPoints(totalSkillPointsWasted);
		}

		ManagedReference<PlayerManager*> playerManager = creature->getZoneServer()->getPlayerManager();
		if (playerManager != NULL) {
			creature->setLevel(playerManager->calculatePlayerLevel(creature));
		}
	}

	/// Update client with new values for things like Terrain Negotiation
	CreatureObjectDeltaMessage4* msg4 = new CreatureObjectDeltaMessage4(creature);
	msg4->updateAccelerationMultiplierBase();
	msg4->updateAccelerationMultiplierMod();
	msg4->updateSpeedMultiplierBase();
	msg4->updateSpeedMultiplierMod();
	msg4->updateRunSpeed();
	msg4->updateTerrainNegotiation();
	msg4->close();
	creature->sendMessage(msg4);

	SkillModManager::instance()->verifySkillBoxSkillMods(creature);

	return true;
}
int ForceShrineMenuComponent::handleObjectMenuSelect(SceneObject* sceneObject, CreatureObject* creature, byte selectedID) {
	if (selectedID != 213)
		return 0;

	if (creature->getPosture() != CreaturePosture::CROUCHED){
		creature->sendSystemMessage("@jedi_trials:show_respect"); // Must show respect
		return 0;
	}

	ManagedReference<PlayerObject*> ghost = creature->getPlayerObject();

	if (ghost == NULL)
		return 0;

	if (creature->getScreenPlayState("VillageJediProgression") && !creature->hasSkill("force_title_jedi_rank_02")){
		ManagedReference<SuiMessageBox*> box = new SuiMessageBox(creature, SuiWindowType::NONE);
		box->setPromptTitle("@jedi_trials:padawan_trials_title"); // Jedi Trials
		box->setPromptText("@jedi_trials:padawan_trials_completed");

		ghost->addSuiBox(box);
		creature->sendMessage(box->generateMessage());

		SkillManager::instance()->awardSkill("force_title_jedi_rank_02", creature, true, true, true);

		creature->playEffect("clienteffect/entertainer_dazzle_level_3.cef", ""); // Not sure if it's the right one for this.

		PlayMusicMessage* pmm = new PlayMusicMessage("sound/intro.snd");
		creature->sendMessage(pmm);

		ghost->setJediState(2);

		// Trainer number. Pick a random trainer, there are at least 600 in the galaxy.

		ZoneServer* zoneServer = ghost->getZoneServer();
		int randomZone = System::random(zoneServer->getZoneCount() - 1);

		ManagedReference<Zone*> zone = zoneServer->getZone(randomZone);
		Vector3 randomTrainer = zone->getCreatureManager()->getRandomJediTrainer();

		if ((randomTrainer.getX() == 0) && (randomTrainer.getY() == 0)) { // No trainers on the zone.
			ManagedReference<Zone*> zone = zoneServer->getZone(0);
			Vector3 randomTrainer = zone->getCreatureManager()->getRandomJediTrainer();
		}

		Vector3 trainerPositionFinal(randomTrainer.getX(), randomTrainer.getY(), 0);

		String zoneName = zone->getZoneName();

		ghost->setTrainerCoordinates(trainerPositionFinal);
		ghost->setTrainerZoneName(zoneName); // For the Waypoint.


		ManagedReference<SceneObject*> inventory = creature->getSlottedObject("inventory");

		//Check if inventory is full.
		if (inventory->hasFullContainerObjects()) {
			creature->sendSystemMessage("@jedi_spam:inventory_full_jedi_robe"); //	You have too many items in your inventory. In order to get your Padawan Robe you must clear out at least one free slot.
			return 0;
		}

		ZoneServer* zserv = creature->getZoneServer();

		String PadawanRobe = "object/tangible/wearables/robe/robe_jedi_padawan.iff";
		ManagedReference<SceneObject*> padawanRobe = zserv->createObject(PadawanRobe.hashCode(), 1);
		if (inventory->transferObject(padawanRobe, -1)) {
			inventory->broadcastObject(padawanRobe, true);
		} else {
			padawanRobe->destroyObjectFromDatabase(true);
		}
	}

	else if (!creature->hasSkill("force_title_jedi_novice")){

		int rand = System::random(14) + 1;

		StringBuffer sysmsg;

		sysmsg << "@jedi_trials:force_shrine_wisdom_" << rand;

		creature->sendSystemMessage(sysmsg.toString());

	}

	else if (creature->hasSkill("force_title_jedi_rank_02")){

		ManagedReference<SceneObject*> inventory = creature->getSlottedObject("inventory");

		//Check if inventory is full.
		if (inventory->hasFullContainerObjects()) {
			creature->sendSystemMessage("@jedi_spam:inventory_full_jedi_robe"); //	You have too many items in your inventory. In order to get your Padawan Robe you must clear out at least one free slot.
			return 0;
		}

		ZoneServer* zserv = creature->getZoneServer();

		String PadawanRobe = "object/tangible/wearables/robe/robe_jedi_padawan.iff";
		ManagedReference<SceneObject*> padawanRobe = zserv->createObject(PadawanRobe.hashCode(), 1);
		if (inventory->transferObject(padawanRobe, -1)) {
			inventory->broadcastObject(padawanRobe, true);
		} else {
			padawanRobe->destroyObjectFromDatabase(true);
		}

	}

	return 0;


}
Example #20
0
bool SkillManager::surrenderSkill(const String& skillName, CreatureObject* creature, bool notifyClient) {
	Skill* skill = skillMap.get(skillName.hashCode());

	if (skill == NULL)
		return false;

	Locker locker(creature);

	SkillList* skillList = creature->getSkillList();

	if(skillName == "force_title_jedi_novice" && getForceSensitiveSkillCount(creature, true) > 0) {
		return false;
	}

	if(skillName.beginsWith("force_sensitive_") &&
		getForceSensitiveSkillCount(creature, false) <= 24 &&
		creature->hasSkill("force_title_jedi_rank_01"))
		return false;

	for (int i = 0; i < skillList->size(); ++i) {
		Skill* checkSkill = skillList->get(i);

		if (checkSkill->isRequiredSkillOf(skill))
			return false;
	}

	if(creature->hasSkill("force_title_jedi_rank_03") && skillName.contains("force_discipline_") && !knightPrereqsMet(creature, skillName)) {
		return false;
	}

	//If they have already surrendered the skill, then return true.
	if (!creature->hasSkill(skill->getSkillName()))
		return true;

	creature->removeSkill(skill, notifyClient);

	//Remove skill modifiers
	VectorMap<String, int>* skillModifiers = skill->getSkillModifiers();

	ManagedReference<PlayerObject*> ghost = creature->getPlayerObject();

	for (int i = 0; i < skillModifiers->size(); ++i) {
		VectorMapEntry<String, int>* entry = &skillModifiers->elementAt(i);
		creature->removeSkillMod(SkillModManager::SKILLBOX, entry->getKey(), entry->getValue(), notifyClient);

	}

	if (ghost != NULL) {
		//Give the player the used skill points back.
		ghost->addSkillPoints(skill->getSkillPointsRequired());

		//Remove abilities but only if the creature doesn't still have a skill that grants the
		//ability.  Some abilities are granted by multiple skills. For example Dazzle for dancers
		//and musicians.
		Vector<String>* skillAbilities = skill->getAbilities();
		if (skillAbilities->size() > 0) {
			SortedVector<String> abilitiesLost;
			for (int i = 0; i < skillAbilities->size(); i++) {
				abilitiesLost.put(skillAbilities->get(i));
			}
			for (int i = 0; i < skillList->size(); i++) {
				Skill* remainingSkill = skillList->get(i);
				Vector<String>* remainingAbilities = remainingSkill->getAbilities();
				for(int j = 0; j < remainingAbilities->size(); j++) {
					if (abilitiesLost.contains(remainingAbilities->get(j))) {
						abilitiesLost.drop(remainingAbilities->get(j));
						if (abilitiesLost.size() == 0) {
							break;
						}
					}
				}
			}
			if (abilitiesLost.size() > 0) {
				removeAbilities(ghost, abilitiesLost, notifyClient);
			}
		}

		//Remove draft schematic groups
		Vector<String>* schematicsGranted = skill->getSchematicsGranted();
		SchematicMap::instance()->removeSchematics(ghost, *schematicsGranted, notifyClient);

		//Update maximum experience.
		updateXpLimits(ghost);

		/// Update Force Power Max
		ghost->setForcePowerMax(creature->getSkillMod("jedi_force_power_max"), true);

		SkillList* list = creature->getSkillList();

		int totalSkillPointsWasted = 250;

		for (int i = 0; i < list->size(); ++i) {
			Skill* skill = list->get(i);

			totalSkillPointsWasted -= skill->getSkillPointsRequired();
		}

		if (ghost->getSkillPoints() != totalSkillPointsWasted) {
			creature->error("skill points mismatch calculated: " + String::valueOf(totalSkillPointsWasted) + " found: " + String::valueOf(ghost->getSkillPoints()));
			ghost->setSkillPoints(totalSkillPointsWasted);
		}

		ManagedReference<PlayerManager*> playerManager = creature->getZoneServer()->getPlayerManager();
		if (playerManager != NULL) {
			creature->setLevel(playerManager->calculatePlayerLevel(creature));
		}
	}

	/// Update client with new values for things like Terrain Negotiation
	CreatureObjectDeltaMessage4* msg4 = new CreatureObjectDeltaMessage4(creature);
	msg4->updateAccelerationMultiplierBase();
	msg4->updateAccelerationMultiplierMod();
	msg4->updateSpeedMultiplierBase();
	msg4->updateSpeedMultiplierMod();
	msg4->updateRunSpeed();
	msg4->updateTerrainNegotiation();
	msg4->close();
	creature->sendMessage(msg4);

	SkillModManager::instance()->verifySkillBoxSkillMods(creature);

	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;
}
Example #22
0
bool SkillManager::fullfillsSkillPrerequisites(const String& skillName, CreatureObject* creature) {
	Skill* skill = skillMap.get(skillName.hashCode());

	if (skill == NULL) {
		return false;
	}

	Vector<String>* requiredSpecies = skill->getSpeciesRequired();
	if (requiredSpecies->size() > 0) {
		bool foundSpecies = false;
		for (int i = 0; i < requiredSpecies->size(); i++) {
			if (creature->getSpeciesName() == requiredSpecies->get(i)) {
				foundSpecies = true;
				break;
			}
		}
		if (!foundSpecies) {
			return false;
		}
	}

	//Check for required skills.
	Vector<String>* requiredSkills = skill->getSkillsRequired();
	for (int i = 0; i < requiredSkills->size(); ++i) {
		String requiredSkillName = requiredSkills->get(i);
		Skill* requiredSkill = skillMap.get(requiredSkillName.hashCode());

		if (requiredSkill == NULL) {
			continue;
		}

		if (!creature->hasSkill(requiredSkillName)) {
			return false;
		}
	}

	PlayerObject* ghost = creature->getPlayerObject();
	if(ghost == NULL || ghost->getJediState() < skill->getJediStateRequired()) {
		return false;
	}

	if (ghost->isPrivileged())
		return true;

	if (skillName.beginsWith("force_sensitive")) { // Check for Force Sensitive boxes.
		int index = skillName.indexOf("0");
		if (index != -1) {
			String skillNameFinal = skillName.subString(0, skillName.length() - 3);
			if (creature->getScreenPlayState("VillageUnlockScreenPlay:" + skillNameFinal) < 2) {
				return false;
			}
		}
	}

	if(skillName == "force_title_jedi_rank_01" && getForceSensitiveSkillCount(creature, false) < 24) {
		return false;
	}

	if(skillName == "force_title_jedi_rank_03" && !knightPrereqsMet(creature, "")) {
		return false;
	}

	return true;
}
void CreatureAttackData::setVariable(const String& var, const String& val) {
	uint32 crc = var.hashCode();
	switch(crc) {
	case 0x9E64852D: // String("damage").hashCode():
		damage = Float::valueOf(val);
		break;
	case 0xA82FB287: // String("damageMultiplier").hashCode():
		damageMultiplier = Float::valueOf(val);
		break;
	case 0xC60F1652: // String("healthDamageMultiplier").hashCode():
		healthDamageMultiplier = Float::valueOf(val);
		break;
	case 0x77139783: // String("actionDamageMultiplier").hashCode():
		actionDamageMultiplier = Float::valueOf(val);
		break;
	case 0xD7D06F99: // String("mindDamageMultiplier").hashCode():
		mindDamageMultiplier = Float::valueOf(val);
		break;
	case 0xC33D0A1B: // String("accuracyBonus").hashcode()
		accuracyBonus = Integer::valueOf(val);
		break;
	case 0x7CA69F2E: // String("speedMultiplier").hashCode()
		speedMultiplier = Float::valueOf(val);
		break;
	case 0x3A1C0159: // String("healthCostMultiplier").hashCode()
		healthCostMultiplier = Float::valueOf(val);
		break;
	case 0x5FFD87F5: // String("actionCostMultiplier").hashCode()
		actionCostMultiplier = Float::valueOf(val);
		break;
	case 0xDF28A3E4: // String("mindCostMultiplier").hashCode()
		mindCostMultiplier = Float::valueOf(val);
		break;
	case 0xA3CB47C4: // String("forceCostMultiplier").hashCode()
		forceCostMultiplier = Float::valueOf(val);
		break;
	case 0xBF4C6ADB: // String("poolsToDamage").hashCode()
		poolsToDamage = Integer::valueOf(val);
		break;
	case 0xB8BC4726: // String("nextAttackDelayChance").hashCode()
		nextAttackDelayChance = Integer::valueOf(val);
		break;
	case 0x91E2CE2E: // String("durationStateTime").hashCode()
		durationStateTime = Integer::valueOf(val);
		break;
	case 0x3B3CF0ED: // String("dotDuration").hashCode()
		dotDuration = (uint32)Long::valueOf(val);
		break;
	case 0x5292F0A8: // String("dotType").hashCode()
		dotType = UnsignedLong::valueOf(val);
		break;
	case 0xB821C9FB: // String("dotPool").hashCode()
		dotPool = (uint8)Integer::valueOf(val);
		break;
	case 0x35656F0F: // String("dotStrength").hashCode()
		dotStrength = (uint32)Long::valueOf(val);
		break;
	case 0x509E1FC0: // String("dotPotency").hashCode()
		dotPotency = Float::valueOf(val);
		break;
	case 0xD2C29953: // String("coneAngle").hashCode()
		coneAngle = Integer::valueOf(val);
		break;
	case 0xE17D7C71: // String("range").hashCode()
		range = Integer::valueOf(val);
		break;
	case 0xFEC2FA79: // String("areaRange").hashCode()
		areaRange = Integer::valueOf(val);
		break;
	case 0x244FB60D: // String("animationCRC").hashCode()
		animationCRC = Integer::valueOf(val);
		break;
	case 0x708615B8: // String("attackType").hashCode()
		attackType = Integer::valueOf(val);
		break;
	case 0x550ED3F5: // String("trails").hashCode()
		trails = Integer::valueOf(val);
		break;
	case 0xFAFA1475: // String("combatSpam").hashCode()
		combatSpam = val;
		break;
	default:
		break;
	}
}
Reference<SceneObject*> PlanetManagerImplementation::loadSnapshotObject(WorldSnapshotNode* node, WorldSnapshotIff* wsiff, int& totalObjects) {
	uint64 objectID = node->getObjectID();
	String templateName = wsiff->getObjectTemplateName(node->getNameID());

	ZoneServer* zoneServer = server->getZoneServer();

	Reference<SceneObject*> object = zoneServer->getObject(objectID);

	++totalObjects;

	if (ConfigManager::instance()->isProgressMonitorActivated())
		printf("\r\tLoading snapshot objects: [%d] / [?]\t", totalObjects);

	//Object already exists, exit.
	if (object != NULL)
		return NULL;

	Reference<SceneObject*> parentObject = zoneServer->getObject(node->getParentID());

	String serverTemplate = templateName.replaceFirst("shared_", "");
	Vector3 position = node->getPosition();

	object = zoneServer->createClientObject(serverTemplate.hashCode(), objectID);

	Locker locker(object);

	object->initializePosition(position.getX(), position.getZ(), position.getY());
	object->setDirection(node->getDirection());

	if (parentObject != NULL && parentObject->isBuildingObject() && object->isCellObject()) {
		CellObject* cell = cast<CellObject*>(object.get());
		BuildingObject* building = cast<BuildingObject*>(parentObject.get());

		Locker clocker(building, object);

		building->addCell(cell, node->getCellID());
	}

	if (parentObject != NULL)
		parentObject->transferObject(object, -1);
	else if (node->getParentID() != 0)
		error("parent id " + String::valueOf(node->getParentID()));

	if (parentObject == NULL) {
		//object->insertToZone(zone);
		Locker clocker(object);

		zone->transferObject(object, -1, true);
	}

	//Load child nodes
	for (int i = 0; i < node->getNodeCount(); ++i) {
		WorldSnapshotNode* childNode = node->getNode(i);

		if (childNode == NULL)
			continue;

		loadSnapshotObject(childNode, wsiff, totalObjects);
	}

	//object->createChildObjects();

	return object;
}
int PlayerContainerComponent::canAddObject(SceneObject* sceneObject, SceneObject* object, int containmentType, String& errorDescription) const {
	CreatureObject* creo = dynamic_cast<CreatureObject*>(sceneObject);

	if (creo == NULL) {
		return TransferErrorCode::PLAYERUSEMASKERROR;
	}

	if (object->isTangibleObject() && containmentType == 4) {
		TangibleObject* wearable = cast<TangibleObject*>(object);

		SharedTangibleObjectTemplate* tanoData = dynamic_cast<SharedTangibleObjectTemplate*>(wearable->getObjectTemplate());

		if (tanoData != NULL) {
			Vector<uint32>* races = tanoData->getPlayerRaces();
			String race = creo->getObjectTemplate()->getFullTemplateString();

			if (!races->contains(race.hashCode())) {
				errorDescription = "You lack the necessary requirements to wear this object";

				return TransferErrorCode::PLAYERUSEMASKERROR;
			}
		}

		if (creo->isPlayerCreature()) {
			if (!wearable->isNeutral()) {
				if (wearable->isImperial() && (creo->getFactionStatus() == FactionStatus::ONLEAVE || !creo->isImperial())) {
					errorDescription = "You lack the necessary requirements to wear this object";

					return TransferErrorCode::PLAYERUSEMASKERROR;
				}

				if (wearable->isRebel() && (creo->getFactionStatus() == FactionStatus::ONLEAVE || !creo->isRebel())) {
					errorDescription = "You lack the necessary requirements to wear this object";

					return TransferErrorCode::PLAYERUSEMASKERROR;
				}
			}
		}

		if (object->isArmorObject()) {
			PlayerManager* playerManager = sceneObject->getZoneServer()->getPlayerManager();

			if (!playerManager->checkEncumbrancies(creo, cast<ArmorObject*>(object))) {
				errorDescription = "You lack the necessary secondary stats to equip this item";

				return TransferErrorCode::NOTENOUGHENCUMBRANCE;
			}
		}

		if (object->isWearableObject()) {
			if (tanoData != NULL) {
				const Vector<String>& skillsRequired = tanoData->getCertificationsRequired();

				if (skillsRequired.size() > 0) {
					bool hasSkill = false;

					for (int i = 0; i < skillsRequired.size(); i++) {
						const String& skill = skillsRequired.get(i);

						if (!skill.isEmpty() && creo->hasSkill(skill)) {
							hasSkill = true;
							break;
						}
					}

					if (!hasSkill) {
						errorDescription = "@error_message:insufficient_skill"; // You lack the skill to use this item.

						return TransferErrorCode::PLAYERUSEMASKERROR;
					}
				}
			}
		}

		if (object->isWeaponObject()) {
			WeaponObject* weapon = cast<WeaponObject*>(object);
			int bladeColor = weapon->getBladeColor();
			PlayerObject* ghost = creo->getPlayerObject();

			if (weapon->isJediWeapon()) {
				if (bladeColor == 31) {
					errorDescription = "@jedi_spam:lightsaber_no_color";
					return TransferErrorCode::PLAYERUSEMASKERROR;
				}

				if (weapon->getCraftersName() != creo->getFirstName() && !ghost->isPrivileged()) {
					errorDescription = "@jedi_spam:not_your_lightsaber";
					return TransferErrorCode::PLAYERUSEMASKERROR;
				}
			}
		}
	}

	return ContainerComponent::canAddObject(sceneObject, object, containmentType, errorDescription);
}
void SharedTangibleObjectTemplate::parseVariableData(const String& varName, LuaObject* data) {
	lua_State* state = data->getLuaState();
	TemplateManager* templateManager = TemplateManager::instance();

	if (varName == "certificationsRequired") {
		LuaObject certifications(state);
		certificationsRequired.removeAll();
		for (int i = 1; i <= certifications.getTableSize(); ++i) {
			certificationsRequired.add(certifications.getStringAt(i));
		}

		certifications.pop();
	} else if (varName == "structureFootprintFileName") {
		structureFootprint = templateManager->loadStructureFootprint(Lua::getStringParameter(state));
	} else if (varName == "targetable") {
		targetable = Lua::getByteParameter(state);
	} else if (varName == "playerUseMask") {
		playerUseMask = Lua::getShortParameter(state);
	} else if (varName == "useCount") {
		useCount = Lua::getIntParameter(state);
	} else if (varName == "factoryCrateSize") {
		factoryCrateSize = Lua::getIntParameter(state);
	} else if (varName == "maxCondition") {
		maxCondition = Lua::getIntParameter(state);
	} else if (varName == "level") {
		level = Lua::getIntParameter(state);
	} else if (varName == "optionsBitmask") {
		optionsBitmask = Lua::getIntParameter(state);
	} else if (varName == "pvpStatusBitmask") {
		pvpStatusBitmask = Lua::getIntParameter(state);
	} else if (varName == "sliceable") {
		sliceable = Lua::getIntParameter(state);
	} else if (varName == "faction") {
		String factionString = Lua::getStringParameter(state);
		faction = factionString.toLowerCase().hashCode();
	} else if (varName == "playerRaces") {
		LuaObject races(state);

		// Inherited lists need to be tossed if a new list is about to be created
		if (playerRaces->size() != 0) {
			playerRaces->removeAll();
		}

		for (int i = 1; i <= races.getTableSize(); ++i) {
			String race = races.getStringAt(i);

			if (!playerRaces->contains(race.hashCode())) {
				playerRaces->add(race.hashCode());
			}


		}

		races.pop();
	} else if (varName == "skillMods") {
		skillMods.removeAll();

		LuaObject smods(state);
		for (int i = 1; i <= smods.getTableSize(); ++i) {
			lua_rawgeti(state, -1, i);
			LuaObject mod(state);

			String modName = mod.getStringAt(1);
			int modValue = mod.getIntAt(2);

			skillMods.put(modName, modValue);

			mod.pop();
		}
		smods.pop();
	} else if (varName == "numberExperimentalProperties") {
		LuaObject numberExperimentalPropertiesList(state);
		numberExperimentalProperties->removeAll();
		for (int i = 1; i <= numberExperimentalPropertiesList.getTableSize(); ++i) {
			numberExperimentalProperties->add(numberExperimentalPropertiesList.getIntAt(i));
		}

		numberExperimentalPropertiesList.pop();
	} else if (varName == "experimentalProperties") {
		LuaObject experimentalPropertiesList(state);
		experimentalProperties->removeAll();
		for (int i = 1; i <= experimentalPropertiesList.getTableSize(); ++i) {
			experimentalProperties->add(experimentalPropertiesList.getStringAt(i));
		}

		experimentalPropertiesList.pop();
	} else if (varName == "experimentalWeights") {
		LuaObject experimentalWeightsList(state);
		experimentalWeights->removeAll();
		for (int i = 1; i <= experimentalWeightsList.getTableSize(); ++i) {
			experimentalWeights->add(experimentalWeightsList.getIntAt(i));
		}

		experimentalWeightsList.pop();
	} else if (varName == "experimentalGroupTitles") {
		LuaObject experimentalGroupTitlesList(state);
		experimentalGroupTitles->removeAll();
		for (int i = 1; i <= experimentalGroupTitlesList.getTableSize(); ++i) {
			experimentalGroupTitles->add(experimentalGroupTitlesList.getStringAt(i));
		}

		experimentalGroupTitlesList.pop();
	} else if (varName == "experimentalSubGroupTitles") {
		LuaObject experimentalSubGroupTitlesList(state);
		experimentalSubGroupTitles->removeAll();
		for (int i = 1; i <= experimentalSubGroupTitlesList.getTableSize(); ++i) {
			experimentalSubGroupTitles->add(experimentalSubGroupTitlesList.getStringAt(i));
		}

		experimentalSubGroupTitlesList.pop();
	} else if (varName == "experimentalMin") {
		LuaObject experimentalMinList(state);
		experimentalMin->removeAll();
		for (int i = 1; i <= experimentalMinList.getTableSize(); ++i) {
			experimentalMin->add(experimentalMinList.getFloatAt(i));
		}

		experimentalMinList.pop();
	} else if (varName == "experimentalMax") {
		LuaObject experimentalMaxList(state);
		experimentalMax->removeAll();
		for (int i = 1; i <= experimentalMaxList.getTableSize(); ++i) {
			experimentalMax->add(experimentalMaxList.getFloatAt(i));
		}

		experimentalMaxList.pop();
	} else if (varName == "experimentalPrecision") {
		LuaObject experimentalPrecisionList(state);
		experimentalPrecision->removeAll();
		for (int i = 1; i <= experimentalPrecisionList.getTableSize(); ++i) {
			experimentalPrecision->add(experimentalPrecisionList.getIntAt(i));
		}
		experimentalPrecisionList.pop();
	} else if (varName == "experimentalCombineType") {
		LuaObject experimentalCombineList(state);
		experimentalCombineType->removeAll();
		for (int i = 1; i <= experimentalCombineList.getTableSize(); ++i) {
			experimentalCombineType->add(experimentalCombineList.getIntAt(i));
		}
		experimentalCombineList.pop();
	} else {
		data->pop();
	}

}
void CraftingSessionImplementation::customization(const String& name, byte templateChoice, int schematicCount, const String& customizationString) {
	ManagedReference<CraftingTool*> craftingTool = this->craftingTool.get();
	ManagedReference<CreatureObject*> crafter = this->crafter.get();
	ManagedReference<PlayerObject*> crafterGhost = this->crafterGhost.get();
	ManagedReference<CraftingStation*> craftingStation = this->craftingStation.get();
	ManagedReference<ManufactureSchematic*> manufactureSchematic = this->manufactureSchematic.get();
	ManagedReference<TangibleObject*> prototype = this->prototype.get();
	ManagedReference<CraftingManager*> craftingManager = this->craftingManager.get();

	if (manufactureSchematic == NULL) {
		sendSlotMessage(0, IngredientSlot::NOSCHEMATIC);
		return;
	}

	if (prototype == NULL) {
		sendSlotMessage(0, IngredientSlot::PROTOTYPENOTFOUND);
		return;
	}

	//if(NameManager::instance()->isProfane(name)) {
	//	player->sendSystemMessage("Your selected name has been declined because it may contain inappropriate language.  Close the 'customizing' window and try again");
	//	return;
	//}

	Locker locker(craftingTool);
	Locker locker2(manufactureSchematic);
	Locker locker3(_this.get());

	if (templateChoice != 0xFF) {

		Reference<DraftSchematic*> draftSchematic =
				manufactureSchematic->getDraftSchematic();

		if (draftSchematic != NULL) {
			if (draftSchematic->getTemplateListSize() >= (int) templateChoice) {
				String chosenTemplate = draftSchematic->getTemplate((int) templateChoice);
				uint32 clientCRC = chosenTemplate.hashCode();
				prototype->setClientObjectCRC(clientCRC);

				String minusShared = chosenTemplate.replaceAll("shared_","");
				SharedObjectTemplate* newTemplate = TemplateManager::instance()->getTemplate(minusShared.hashCode());

				prototype->loadTemplateData(newTemplate);
				prototype->updateCraftingValues(manufactureSchematic->getCraftingValues(), false);

				prototype->sendDestroyTo(crafter);
				prototype->sendTo(crafter, true);
			}
		}
	}

	if(schematicCount < 0 || schematicCount > 1000)
		schematicCount = 1000;

	manufactureSchematic->setManufactureLimit(schematicCount);

	StringTokenizer tokenizer(customizationString);
	byte customizationindex, customizationvalue;
	String customizationname = "";

	//Database::escapeString(name);

	//Remove color codes
	String newName = name;
	while (newName.contains("\\#")) {
		int index = newName.indexOf("\\#");
		String sub = "\\" + newName.subString(index, index + 2);
		newName = newName.replaceFirst(sub,"");
	}

	UnicodeString customName(newName);
	prototype->setCustomObjectName(customName, false);

	/// Set Name
	manufactureSchematic->getObjectName()->setStringId(
			prototype->getObjectNameStringIdFile(),
			prototype->getObjectNameStringIdName());

	/// Set Manufacture Schematic Custom name
	if (!newName.isEmpty())
		manufactureSchematic->setCustomObjectName(customName, false);

	while (tokenizer.hasMoreTokens()) {

		customizationindex = (byte) tokenizer.getIntToken();

		customizationname = variables.elementAt(customizationindex).getKey();

		customizationvalue = (byte) tokenizer.getIntToken();

		prototype->setCustomizationVariable(customizationname,
				customizationvalue);
	}

	TangibleObjectDeltaMessage3* dtano3 =
			new TangibleObjectDeltaMessage3(prototype);
	dtano3->updateName(newName);
	dtano3->updateCustomizationString();
	dtano3->close();

	crafter->sendMessage(dtano3);

	ManufactureSchematicObjectDeltaMessage3 * dMsco3 =
			new ManufactureSchematicObjectDeltaMessage3(
					manufactureSchematic);
	dMsco3->updateName(newName);
	dMsco3->updateCondition(schematicCount);
	dMsco3->close();

	crafter->sendMessage(dMsco3);

	//Object Controller
	ObjectControllerMessage* objMsg = new ObjectControllerMessage(
			crafter->getObjectID(), 0x1B, 0x010C);
	objMsg->insertInt(0x15A);
	objMsg->insertInt(0);
	objMsg->insertByte(0);

	crafter->sendMessage(objMsg);

	state = 5;
}
Example #28
0
void StructureManager::promptPayUncondemnMaintenance(CreatureObject* creature,
		StructureObject* structure) {
	ManagedReference<PlayerObject*> ghost = creature->getPlayerObject();

	if (ghost == NULL) {
		return;
	}

	int uncondemnCost = -structure->getSurplusMaintenance();

	ManagedReference<SuiMessageBox*> sui;
	String text;

	if (creature->getCashCredits() + creature->getBankCredits()
			>= uncondemnCost) {
		//Owner can un-condemn the structure.
		sui = new SuiMessageBox(creature,
				SuiWindowType::STRUCTURE_UNCONDEMN_CONFIRM);
		if (sui == NULL) {
			//TODO: what message should be shown here?
			return;
		}

		//TODO: investigate sui packets to see if it is possible to send StringIdChatParameter directly.
		String textStringId =
				"@player_structure:structure_condemned_owner_has_credits";
		text =
				StringIdManager::instance()->getStringId(
						textStringId.hashCode()).toString();
		text = text.replaceFirst("%DI", String::valueOf(uncondemnCost));

		sui->setCancelButton(true, "@cancel");
		sui->setCallback(
				new StructurePayUncondemnMaintenanceSuiCallback(server));
	} else {
		//Owner cannot un-condemn the structure.
		sui = new SuiMessageBox(creature, SuiWindowType::NONE);
		if (sui == NULL) {
			//TODO: what message should be shown here?
			return;
		}

		//TODO: investigate sui packets to see if it is possible to send StringIdChatParameter directly.
		String textStringId =
				"@player_structure:structure_condemned_owner_no_credits";
		text =
				StringIdManager::instance()->getStringId(
						textStringId.hashCode()).toString();
		text = text.replaceFirst("%DI", String::valueOf(uncondemnCost));

		sui->setCancelButton(false, "@cancel");
	}

	sui->setPromptText(text);
	sui->setOkButton(true, "@ok");
	sui->setPromptTitle("@player_structure:fix_condemned_title");
	sui->setUsingObject(structure);

	ghost->addSuiBox(sui);
	creature->sendMessage(sui->generateMessage());
}
Example #29
0
TEST_F(LuaMobileTest, LuaMobileTemplatesTest) {
	CreatureTemplateManager::DEBUG_MODE = 1;

	// Verify that all mobiles load
	ASSERT_EQ(CreatureTemplateManager::instance()->loadTemplates(), 0);

	// Verify loot group map loaded
	ASSERT_EQ(LootGroupMap::ERROR_CODE, 0);

	// Verify factions load
	FactionManager::instance()->loadData();
	ASSERT_FALSE(FactionManager::instance()->getFactionMap()->isEmpty());

	// Load Templates
	ASSERT_TRUE( TemplateManager::instance() != NULL );
	if( TemplateManager::instance()->loadedTemplatesCount == 0 ){
		TemplateManager::instance()->loadLuaTemplates();
		ASSERT_EQ(TemplateManager::ERROR_CODE, 0);
	}
	// verify DNA manager loads
	DnaManager::instance()->loadSampleData();
	ASSERT_TRUE( DnaManager::instance() != NULL);


	// Test Creature Templates
	HashTableIterator<uint32, Reference<CreatureTemplate*> > creatureIterator = CreatureTemplateManager::instance()->iterator();
	while (creatureIterator.hasNext()) {
		CreatureTemplate* creature = creatureIterator.next();
		std::string templateName( creature->getTemplateName().toCharArray() );
		//Verify non-empty objectName is a valid string
		String objName = creature->getObjectName();
		if (!objName.isEmpty()) {
			std::string name = objName.toCharArray();
			EXPECT_TRUE( mobNames.contains(objName) ) << "Mobile " << templateName << " has invalid objectName: "  << name;
		}

		// Check configured templates
		Vector<String> objTemps = creature->getTemplates();
		EXPECT_FALSE( objTemps.isEmpty() ) << "Mobile " << templateName << " does not have any templates configured";
		int objectType = 0;
		for( int j=0; j< objTemps.size(); j++ ){
			SharedObjectTemplate* templateData = templateManager->getTemplate(objTemps.get(j).hashCode());
			std::string objName = objTemps.get(j).toCharArray();
			EXPECT_TRUE( templateData != NULL ) << "Mobile " << templateName << " has invalid template configured: " << objName;

			// Check Template Genetics math to find invalid mobs
			if (templateData != NULL) {
				SharedCreatureObjectTemplate* creoData = dynamic_cast<SharedCreatureObjectTemplate*> (templateData);
				if (creoData != NULL) {
				}
			}

			if (objectType == 0) {
				objectType = templateData->getGameObjectType();
			}
		}
		// Verify that control device template is valid
		String controlDeviceTemplate = creature->getControlDeviceTemplate();
		if (!controlDeviceTemplate.isEmpty()) {
			SharedObjectTemplate* controlDeviceTemplateData = templateManager->getTemplate(controlDeviceTemplate.hashCode());
			EXPECT_TRUE( controlDeviceTemplateData != NULL ) << "Control device template " << controlDeviceTemplate.toCharArray() << " from " << templateName << " does not exist.";
			EXPECT_TRUE( controlDeviceTemplate.beginsWith("object/intangible/pet/") ) << "Control device template " << controlDeviceTemplate.toCharArray() << " from " << templateName << " is not a pet/droid control device template.";
		}

		// Verify that faction is valid
		String faction = creature->getFaction();
		if (!faction.isEmpty()) {
			EXPECT_TRUE( FactionManager::instance()->isFaction(faction) ) << "Faction, " << faction.toCharArray() << ", from mobile template " << templateName << " does not exist.";
		}

		// Verify level
		int level = creature->getLevel();
		EXPECT_TRUE( level > 0 ) << "Level is not a positive value on mobile: " << templateName;

		// Verify hit chance
		float hitChance = creature->getChanceHit();
		EXPECT_TRUE( hitChance > 0 ) << "ChanceHit is not a positive value on mobile: " << templateName;

		// Verify xp
		int xp = creature->getBaseXp();
		EXPECT_TRUE( xp >= 0 ) << "Xp has a negative value on mobile: " << templateName;

		// Verify damage
		int minDamage = creature->getDamageMin();
		int maxDamage = creature->getDamageMax();
		EXPECT_TRUE( minDamage > 0 ) << "Min damage is not a positive value on mobile: " << templateName;
		EXPECT_TRUE( maxDamage >= minDamage ) << "Max damage is lower than min damage on mobile: " << templateName;

		// Verify HAM
		int minHam = creature->getBaseHAM();
		int maxHam = creature->getBaseHAMmax();
		EXPECT_TRUE( minHam > 0 ) << "Base ham is not a positive value on mobile: " << templateName;
		EXPECT_TRUE( maxHam >= minHam ) << "Base ham max is lower than base ham on mobile: " << templateName;

		// Verify armor
		int armor = creature->getArmor();
		EXPECT_TRUE( armor >= 0 && armor <= 3 ) << "Armor is not a valid value on mobile: " << templateName;

		// Verify resists
		float kinetic = creature->getKinetic();
		EXPECT_TRUE( kinetic >= -1 && kinetic <= 200 ) << "Kinetic resist is not a valid value on mobile: " << templateName;
		float energy = creature->getEnergy();
		EXPECT_TRUE( energy >= -1 && energy <= 200 ) << "Energy resist is not a valid value on mobile: " << templateName;
		float electricity = creature->getElectricity();
		EXPECT_TRUE( electricity >= -1 && electricity <= 200 ) << "Electricity resist is not a valid value on mobile: " << templateName;
		float stun = creature->getStun();
		EXPECT_TRUE( stun >= -1 && stun <= 200 ) << "Stun resist is not a valid value on mobile: " << templateName;
		float blast = creature->getBlast();
		EXPECT_TRUE( blast >= -1 && blast <= 200 ) << "Blast resist is not a valid value on mobile: " << templateName;
		float heat = creature->getHeat();
		EXPECT_TRUE( heat >= -1 && heat <= 200 ) << "Heat resist is not a valid value on mobile: " << templateName;
		float cold = creature->getCold();
		EXPECT_TRUE( cold >= -1 && cold <= 200 ) << "Cold resist is not a valid value on mobile: " << templateName;
		float acid = creature->getAcid();
		EXPECT_TRUE( acid >= -1 && acid <= 200 ) << "Acid resist is not a valid value on mobile: " << templateName;
		float lightSaber = creature->getLightSaber();
		EXPECT_TRUE( lightSaber >= -1 && lightSaber <= 200 ) << "LightSaber resist is not a valid value on mobile: " << templateName;

		// Verify creature resources
		String meat = creature->getMeatType();
		float meatMax = creature->getMeatMax();
		if (!meat.isEmpty()) {
			String meatResources = "meat_domesticated,meat_wild,meat_herbivore,meat_carnivore,meat_reptilian,meat_avian,meat_insect";
			StringTokenizer tokenizer(meatResources);
			tokenizer.setDelimeter(",");
			bool match = false;
			String token;
			while (tokenizer.hasMoreTokens()) {
				tokenizer.getStringToken(token);
				if (meat == token)
					match = true;
			}
			EXPECT_TRUE( match ) << "Meat type on mobile " << templateName << " is not a valid meat resource";
			EXPECT_TRUE( meatMax > 0 ) << "Meat amount on mobile " << templateName << " is zero.";
		} else {
			EXPECT_TRUE( meatMax == 0 ) << "MeatAmount is not zero yet has no type defined on mobile " << templateName;
		}

		String hide = creature->getHideType();
		float hideMax = creature->getHideMax();
		if (!hide.isEmpty()) {
			String hideResources = "hide_bristley,hide_leathery,hide_scaley,hide_wooly";
			StringTokenizer tokenizer(hideResources);
			tokenizer.setDelimeter(",");
			bool match = false;
			String token;
			while (tokenizer.hasMoreTokens()) {
				tokenizer.getStringToken(token);
				if (hide == token)
					match = true;
			}
			EXPECT_TRUE( match ) << "Hide type on mobile " << templateName << " is not a valid hide resource";
			EXPECT_TRUE( hideMax > 0 ) << "Hide amount on mobile " << templateName << " is zero.";
		} else {
			EXPECT_TRUE( hideMax == 0 ) << "HideAmount is not zero yet has no type defined on mobile " << templateName;
		}

		String bone = creature->getBoneType();
		float boneMax = creature->getBoneMax();
		if (!bone.isEmpty()) {
			String boneResources = "bone_avian,bone_mammal";
			StringTokenizer tokenizer(boneResources);
			tokenizer.setDelimeter(",");
			bool match = false;
			String token;
			while (tokenizer.hasMoreTokens()) {
				tokenizer.getStringToken(token);
				if (bone == token)
					match = true;
			}
			EXPECT_TRUE( match ) << "Bone type on mobile " << templateName << " is not a valid bone resource";
			EXPECT_TRUE( boneMax > 0 ) << "Bone amount on mobile " << templateName << " is zero.";
		} else {
			EXPECT_TRUE( boneMax == 0 ) << "BoneAmount is not zero yet has no type defined on mobile " << templateName;
		}

		String milk = creature->getMilkType();
		float milkMax = creature->getMilk();
		if (!milk.isEmpty()) {
			String milkResources = "milk_domesticated,milk_wild";
			StringTokenizer tokenizer(milkResources);
			tokenizer.setDelimeter(",");
			bool match = false;
			String token;
			while (tokenizer.hasMoreTokens()) {
				tokenizer.getStringToken(token);
				if (milk == token)
					match = true;
			}
			EXPECT_TRUE( match ) << "Milk type on mobile " << templateName << " is not a valid milk resource";
			EXPECT_TRUE( milkMax > 0 ) << "Milk amount on mobile " << templateName << " is zero.";
		} else {
			EXPECT_TRUE( milkMax == 0 ) << "Milk is not zero yet has no type defined on mobile " << templateName;
		}

		// Verify taming chance
		float tamingChance = creature->getTame();
		EXPECT_TRUE( tamingChance >= 0 && tamingChance <= 1 ) << "Taming chance is not a valid value on mobile: " << templateName;

		// Verify diet on creatures
		if (boneMax > 0 || hideMax > 0 || meatMax > 0 || milkMax > 0 || tamingChance > 0) {
			uint32 diet = creature->getDiet();
			EXPECT_TRUE( diet != 0 ) << "Diet is NONE on creature type mobile " << templateName;
		}

		// Verify scale
		float scale = creature->getScale();
		EXPECT_TRUE( scale > 0 ) << "Scale is not a positive value on mobile: " << templateName;

		// Verify PACK mobs have a social group
		uint32 creatureBitmask = creature->getCreatureBitmask();
		String socialGroup = creature->getSocialGroup();
		if (creatureBitmask & CreatureFlag::PACK) {
			EXPECT_FALSE( socialGroup.isEmpty() ) << "Social group is empty on pack mobile: " << templateName;
		}

		// Verify loot group percentages
		LootGroupCollection* groupCollection = creature->getLootGroups();
		if( groupCollection->count() > 0 ){


			for( int i = 0; i < groupCollection->count(); i++ ){

				LootGroupCollectionEntry* collectionEntry = groupCollection->get(i);
				LootGroups* groups = collectionEntry->getLootGroups();
				if( groups->count() > 0){

					int totalChance = 0;
					for( int j = 0; j < groups->count(); j++ ){

						LootGroupEntry* lootGroup = groups->get(j);
						totalChance += lootGroup->getLootChance();

						// Verify loot group is configured correctly
						LootGroupTemplate* foundGroup = lootGroupMap->getLootGroupTemplate( lootGroup->getLootGroupName() );
						std::string groupName( lootGroup->getLootGroupName().toCharArray() );
						EXPECT_TRUE( foundGroup != NULL ) << "Loot group " << groupName << " from " << templateName << " was not found in LootGroupMap";

					}

					EXPECT_EQ( 10000000, totalChance ) << "Loot groups total chance is incorrect " << templateName;
				}
			}
		}

		// Verify weapon groups exist
		Vector<String> weapons = creature->getWeapons();
		for (int i = 0; i < weapons.size(); i++) {
			String weaponGroup = weapons.get(i);
			std::string groupName( weaponGroup.toCharArray() );
			Vector<String> group = CreatureTemplateManager::instance()->getWeapons(weaponGroup);
			EXPECT_TRUE( group.size() > 0 ) << "Weapon group " << groupName << " from " << templateName << " was not found in weaponMap";
		}

		// Verify conversation template exist, and the mob has converse option bit
		uint32 convoTemplate = creature->getConversationTemplate();
		uint32 optionsBitmask = creature->getOptionsBitmask();
		if (convoTemplate != 0) {
			ConversationTemplate* convoTemp = CreatureTemplateManager::instance()->getConversationTemplate(convoTemplate);
			EXPECT_TRUE( convoTemp != NULL ) << "Conversation template from " << templateName << " was not found.";
			EXPECT_TRUE( optionsBitmask & OptionBitmask::CONVERSE ) << templateName << " has a convo template but not the CONVERSE options bit.";
		}
		// Verify that mobs with converse option bit have a convo template
		if (optionsBitmask & OptionBitmask::CONVERSE) {
			EXPECT_TRUE( convoTemplate != 0 ) << templateName << " has the CONVERSE options bit but not a convo template.";
		}

		// Verify that outfits exist
		String outfit = creature->getOutfit();
		if (!outfit.isEmpty()) {
			MobileOutfitGroup* outfitGroup = CreatureTemplateManager::instance()->getMobileOutfitGroup(outfit);
			EXPECT_TRUE( outfitGroup != NULL ) << "Outfit group " << outfit.toCharArray() << " from " << templateName << " was not found.";
		}

		// Verify attacks are valid commands
		CreatureAttackMap* cam = creature->getAttacks();
		for (int i = 0; i < cam->size(); i++) {
			String commandName = cam->getCommand(i);

			EXPECT_TRUE( commandName.isEmpty() || commandConfigManager->contains(commandName) ) << "Attack: " << commandName.toCharArray() << " is not a valid command in mobile template: " << templateName;
		}

		// Very attackable npcs
		uint32 pvpBitmask = creature->getPvpBitmask();
		if ((pvpBitmask & CreatureFlag::ATTACKABLE) && objectType == 1025) {
			// Verify attackable npcs have attacks
			EXPECT_TRUE( cam->size() > 0 ) << "Attackable npc " << templateName << " does not have attacks.";
		}
	}

	// Test Lair Templates
	HashTableIterator<uint32, Reference<LairTemplate*> > lairIterator = CreatureTemplateManager::instance()->lairTemplateIterator();
	while (lairIterator.hasNext()) {
		LairTemplate* lair = lairIterator.next();
		std::string templateName( lair->getName().toCharArray() );

		// Verify that mobiles exist and that their weighting is positive
		VectorMap<String, int>* mobiles = lair->getMobiles();
		for (int i = 0; i < mobiles->size(); i++) {
			int weighting = mobiles->elementAt(i).getValue();
			String mobile = mobiles->elementAt(i).getKey();
			std::string mobName = mobile.toCharArray();
			EXPECT_TRUE( CreatureTemplateManager::instance()->getTemplate(mobile) != NULL ) << "Mobile " << mobName << " in lair template " << templateName << " does not exist";
			EXPECT_TRUE( weighting > 0 ) << "Mobile " << mobName << " in lair template " << templateName << " has a non positive weighting";
		}

		// Verify that boss mobiles exist and that their count is positive
		VectorMap<String, int>* bossMobiles = lair->getBossMobiles();
		for (int i = 0; i < bossMobiles->size(); i++) {
			int count = bossMobiles->elementAt(i).getValue();
			String bossMob = bossMobiles->elementAt(i).getKey();
			std::string bossName = bossMob.toCharArray();
			EXPECT_TRUE( CreatureTemplateManager::instance()->getTemplate(bossMob) != NULL ) << "Boss mobile " << bossName << " in lair template " << templateName << " does not exist";
			EXPECT_TRUE( count > 0 ) << "Boss mobile " << bossName << " in lair template " << templateName << " has a non positive spawn count";
		}

		// Verify spawn limit is positive
		int limit = lair->getSpawnLimit();
		EXPECT_TRUE( limit > 0 ) << "Spawn limit in lair template " << templateName << " is not positive";

		// Verify any configured buildings exist
		int buildingCount = 0;
		for(int i=0; i<=4; i++){

			Vector<String>* buildings = lair->getBuildings( i );
			if( buildings == NULL )
				continue;

			buildingCount += buildings->size();

			for( int j=0; j < buildings->size(); j++ ){
				String buildingTemplate = buildings->get(j);
				std::string buildingStr = buildingTemplate.toCharArray();
				SharedObjectTemplate* templateObject = templateManager->getTemplate(buildingTemplate.hashCode());
				EXPECT_TRUE( templateObject != NULL && templateObject->isSharedTangibleObjectTemplate() ) << "Building template " << buildingStr << " in lair template " << templateName << " does not exist";
				if( lair->getBuildingType() == LairTemplate::LAIR ){
					EXPECT_TRUE( buildingTemplate.beginsWith( "object/tangible/lair/") ) << "Building template " << buildingStr << " in lair template " << templateName << " is not a child of object/tangible/lair/";
				}
				if( lair->getBuildingType() == LairTemplate::THEATER ){
					EXPECT_TRUE( buildingTemplate.beginsWith( "object/building/poi/") ) << "Building template " << buildingStr << " in lair template " << templateName << " is not a child of object/building/poi/";
				}
			}
		}

		// Verify mission buildings exist and are lairs
		String missionBuilding = lair->getMissionBuilding(10);
		if (!missionBuilding.isEmpty()) {
			std::string buildingStr = missionBuilding.toCharArray();
			SharedObjectTemplate* templateObject = templateManager->getTemplate(missionBuilding.hashCode());
			EXPECT_TRUE( templateObject != NULL && templateObject->isSharedTangibleObjectTemplate() ) << "Mission building template " << buildingStr << " in lair template " << templateName << " does not exist";
			EXPECT_TRUE( missionBuilding.beginsWith( "object/tangible/lair/") ) << "Mission building template " << buildingStr << " in lair template " << templateName << " is not a child of object/tangible/lair/";
		}

		if( lair->getBuildingType() == LairTemplate::THEATER ){
			EXPECT_TRUE( buildingCount > 0 ) << "There are no buildings configured in theater type lair template " << templateName;
		}
		if( lair->getBuildingType() == LairTemplate::NONE ){
			EXPECT_TRUE( buildingCount == 0 ) << "There are buildings configured in 'none' type lair template " << templateName;
		}
		if( lair->getBuildingType() == LairTemplate::LAIR ){
			EXPECT_TRUE( buildingCount > 0 ) << "There are no buildings configured in lair type lair template " << templateName;
		}

	}

	// Test Spawn Groups
	HashTableIterator<uint32, Reference<SpawnGroup*> > spawnIterator = CreatureTemplateManager::instance()->spawnGroupIterator();
	while (spawnIterator.hasNext()) {
		SpawnGroup* group = spawnIterator.next();
		std::string templateName( group->getTemplateName().toCharArray() );

		Vector<String> lairTemplates;

		// Verify spawn list
		Vector<Reference<LairSpawn*> >* spawnList = group->getSpawnList();
		for (int i = 0; i < spawnList->size(); i++) {
			LairSpawn* spawn = spawnList->get(i);
			std::string lairName( spawn->getLairTemplateName().toCharArray() );

			// Verify lair template exists and isn't duplicated in the group
			String lairTemplateName = spawn->getLairTemplateName();
			Reference<LairTemplate*> lairTemplate = CreatureTemplateManager::instance()->getLairTemplate(lairTemplateName.hashCode());
			EXPECT_TRUE( lairTemplate != NULL ) << "Lair template " << lairName << " in spawn group " << templateName << " does not exist.";
			EXPECT_FALSE( lairTemplates.contains(lairTemplateName) ) << "Lair template " << lairName << " is duplicated in spawn group " << templateName;
			lairTemplates.add(lairTemplateName);

			// Verify spawn limit is at least -1
			float spawnLimit = spawn->getSpawnLimit();
			EXPECT_TRUE( spawnLimit >= -1 ) << "SpawnLimit for lairTemplate " << lairName << " in spawn group " << templateName << " is less than -1.";

			// Verify difficulties
			int minDiff = spawn->getMinDifficulty();
			int maxDiff = spawn->getMaxDifficulty();
			EXPECT_TRUE( minDiff > 0 ) << "MinDifficulty for lairTemplate " << lairName << " in spawn group " << templateName << " is not positive.";
			EXPECT_TRUE( maxDiff >= minDiff ) << "MaxDifficulty for lairTemplate " << lairName << " in spawn group " << templateName << " is less than min difficulty.";

			// Verify number to spawn is not negative
			int numberToSpawn = spawn->getNumberToSpawn();
			EXPECT_TRUE( numberToSpawn >= 0 ) << "NumberToSpawn for lairTemplate " << lairName << " in spawn group " << templateName << " is negative.";

			// Verify weighting is positive
			int weighting = spawn->getWeighting();
			EXPECT_TRUE( weighting > 0 ) << "Weighting for lairTemplate " << lairName << " in spawn group " << templateName << " is not positive.";

			// Verify size is at least 1
			float size = spawn->getSize();
			EXPECT_TRUE( size >= 1 ) << "Size for lairTemplate " << lairName << " in spawn group " << templateName << " is less than 1.";
		}
	}

	// Test Destroy Mission Spawn Groups
	HashTableIterator<uint32, Reference<SpawnGroup*> > missionIterator = CreatureTemplateManager::instance()->destroyMissionGroupIterator();
	while (missionIterator.hasNext()) {
		SpawnGroup* group = missionIterator.next();
		std::string templateName( group->getTemplateName().toCharArray() );

		Vector<String> lairTemplates;

		// Verify spawn list
		Vector<Reference<LairSpawn*> >* spawnList = group->getSpawnList();
		for (int i = 0; i < spawnList->size(); i++) {
			LairSpawn* spawn = spawnList->get(i);
			std::string lairName( spawn->getLairTemplateName().toCharArray() );

			// Verify lair template exists
			String lairTemplateName = spawn->getLairTemplateName();
			Reference<LairTemplate*> lairTemplate = CreatureTemplateManager::instance()->getLairTemplate(lairTemplateName.hashCode());
			EXPECT_TRUE( lairTemplate != NULL ) << "Lair template " << lairName << " in destroy mission spawn group " << templateName << " does not exist.";
			EXPECT_FALSE( lairTemplates.contains(lairTemplateName) ) << "Lair template " << lairName << " is duplicated in destroy mission spawn group " << templateName;
			lairTemplates.add(lairTemplateName);

			if (lairTemplate != NULL) {
				// Verify that lair template has a valid mission building or is of type LAIR
				String missionBuilding = lairTemplate->getMissionBuilding(10);
				if (!missionBuilding.isEmpty()) {
					std::string buildingStr = missionBuilding.toCharArray();
					SharedObjectTemplate* templateObject = templateManager->getTemplate(missionBuilding.hashCode());
					EXPECT_TRUE( templateObject != NULL && templateObject->isSharedTangibleObjectTemplate() ) << "Mission building template " << buildingStr << " in lair template " << lairName << ", part of destroy mission group " << templateName << " does not exist";
					EXPECT_TRUE( missionBuilding.beginsWith( "object/tangible/lair/") ) << "Mission building template " << buildingStr << " in lair template " << lairName << ", part of destroy mission group " << templateName << " is not a child of object/tangible/lair/";
				} else {
					EXPECT_TRUE( lairTemplate->getBuildingType() == LairTemplate::LAIR ) << "Lair template " << lairName << ", part of destroy mission group " << templateName << " is not of type LAIR";
				}
			}

			// Verify difficulties
			int minDiff = spawn->getMinDifficulty();
			int maxDiff = spawn->getMaxDifficulty();
			EXPECT_TRUE( minDiff > 0 ) << "MinDifficulty for lairTemplate " << lairName << " in destroy mission spawn group " << templateName << " is not positive.";
			EXPECT_TRUE( maxDiff >= minDiff ) << "MaxDifficulty for lairTemplate " << lairName << " in destroy mission spawn group " << templateName << " is less than min difficulty.";

			// Verify size is at least 1
			float size = spawn->getSize();
			EXPECT_TRUE( size >= 1 ) << "Size for lairTemplate " << lairName << " in destroy mission spawn group " << templateName << " is less than 1.";
		}
	}
}
void DestroyMissionObjectiveImplementation::spawnLair() {
	ManagedReference<MissionObject* > mission = this->mission.get();

	ManagedReference<MissionSpawnActiveArea* > spawnActiveArea = this->spawnActiveArea;

	if (spawnActiveArea == NULL)
		return;

	if (lairObject != NULL && lairObject->getZone() != NULL)
		return;

	Zone* zone = spawnActiveArea->getZone();

	Locker locker(spawnActiveArea);

	spawnActiveArea->destroyObjectFromWorld(true);

	Vector3 pos = findValidSpawnPosition(zone);

	ManagedReference<WaypointObject*> waypoint = mission->getWaypointToMission();

	if (waypoint == NULL) {
		waypoint = mission->createWaypoint();
	}

	waypoint->setPosition(pos.getX(), 0, pos.getY());
	mission->updateMissionLocation();

	mission->setStartPosition(pos.getX(), pos.getY());

	//TODO: find correct string id
	ManagedReference<CreatureObject*> player = getPlayerOwner();

	if (player != NULL) {
		player->sendSystemMessage("Transmission Received: Mission Target has been located.  Mission waypoint has been updated to exact location");
	}

	LairTemplate* lair = CreatureTemplateManager::instance()->getLairTemplate(lairTemplate.hashCode());

	if (lair == NULL) {
		error("incorrect lair template in destroy mission objective " + lairTemplate);
		abort();
		return;
	}

	if (lairObject == NULL) {
		String buildingToSpawn = lair->getMissionBuilding(difficulty);

	 	if (buildingToSpawn.isEmpty()) {
	 		error("error spawning " + buildingToSpawn);
	 		abort();
	 		return;
	 	}

		lairObject = zone->getZoneServer()->createObject(buildingToSpawn.hashCode(), 0).castTo<LairObject*>();

	 	if (lairObject == NULL) {
	 		error("error spawning " + buildingToSpawn);
	 		abort();
	 		return;
	 	}

	 	Locker locker(lairObject);

	 	lairObject->setFaction(lair->getFaction());
	 	lairObject->setPvpStatusBitmask(CreatureFlag::ATTACKABLE);
	 	lairObject->setOptionsBitmask(0, false);
	 	lairObject->setMaxCondition(difficultyLevel * (900 + System::random(200)));
	 	lairObject->setConditionDamage(0, false);
	 	lairObject->initializePosition(pos.getX(), pos.getZ(), pos.getY());
	 	lairObject->setDespawnOnNoPlayersInRange(false);

		ManagedReference<MissionObserver*> observer = new MissionObserver(_this.get());
		addObserver(observer, true);

		lairObject->registerObserver(ObserverEventType::OBJECTDESTRUCTION, observer);

	 	ManagedReference<DestroyMissionLairObserver*> lairObserver = new DestroyMissionLairObserver();
	 	lairObserver->deploy();
	 	lairObserver->setLairTemplate(lair);
	 	lairObserver->setDifficulty(difficulty);
	 	lairObserver->setObserverType(ObserverType::LAIR);
	 	lairObserver->setSize(mission->getSize());

	 	lairObject->registerObserver(ObserverEventType::OBJECTDESTRUCTION, lairObserver);
	 	lairObject->registerObserver(ObserverEventType::DAMAGERECEIVED, lairObserver);
	 	lairObject->registerObserver(ObserverEventType::AIMESSAGE, lairObserver);
	 	lairObject->registerObserver(ObserverEventType::OBJECTREMOVEDFROMZONE, lairObserver);

		zone->transferObject(lairObject, -1, true);

		lairObserver->checkForNewSpawns(lairObject, NULL, true);
	}

	if (lairObject != NULL && lairObject->getZone() == NULL) {
		zone->transferObject(lairObject, -1, true);
	}
}