int SaberInventoryContainerComponent::canAddObject(SceneObject* sceneObject, SceneObject* object, int containmentType, String& errorDescription) { ManagedReference<SceneObject*> p = sceneObject->getParent(); if (p != NULL){ int containment = p->getContainmentType(); if (containment == 4){ errorDescription = "@jedi_spam:saber_not_while_equpped"; return TransferErrorCode::INVALIDTYPE; } } if (!object->isLightsaberCrystalObject()) { errorDescription = "@jedi_spam:saber_not_crystal"; return TransferErrorCode::INVALIDTYPE; } LightsaberCrystalComponent* crystal = cast<LightsaberCrystalComponent*> (object); if (crystal->getOwner() == ""){ errorDescription = "@jedi_spam:saber_crystal_not_tuned"; return TransferErrorCode::INVALIDTYPE; } ManagedReference<CreatureObject*> creature = cast<CreatureObject*>(object->getParent().get().get()); if (creature != NULL && crystal->getOwner() != creature->getDisplayedName()){ errorDescription = "@jedi_spam:saber_crystal_not_owner"; return TransferErrorCode::INVALIDTYPE; } if (crystal->isDestroyed()) { errorDescription = "You cannot add a broken crystal to your lightsaber."; return TransferErrorCode::INVALIDTYPE; } VectorMap<uint64, ManagedReference<SceneObject*> >* containerObjects = sceneObject->getContainerObjects(); if (containerObjects->size() >= sceneObject->getContainerVolumeLimit()) { errorDescription = "@container_error_message:container03"; //This container is full. return TransferErrorCode::CONTAINERFULL; } for (int i = 0; i < containerObjects->size(); i++){ Reference<LightsaberCrystalComponent*> crystalInside = sceneObject->getContainerObject(i).castTo<LightsaberCrystalComponent*>(); if (crystal->getColor() != 31 && crystalInside->getColor() != 31){ errorDescription = "@jedi_spam:saber_already_has_color"; return TransferErrorCode::INVALIDTYPE; } } return 0; }
void CraftingSessionImplementation::addSkillMods() { ManagedReference<ManufactureSchematic*> manufactureSchematic = this->manufactureSchematic.get(); ManagedReference<TangibleObject*> prototype = this->prototype.get(); ManagedReference<DraftSchematic*> draftSchematic = manufactureSchematic->getDraftSchematic(); VectorMap<String, int>* skillMods = draftSchematic->getDraftSchematicTemplate()->getSkillMods(); for (int i = 0; i < skillMods->size(); i++) { VectorMapEntry<String, int> mod = skillMods->elementAt(i); if (prototype->isWearableObject()) { WearableObject* wearable = prototype.castTo<WearableObject*>(); VectorMap<String, int>* wearableMods = wearable->getWearableSkillMods(); if (wearableMods->contains(mod.getKey())) { int oldValue = wearableMods->get(mod.getKey()); int newValue = mod.getValue() + oldValue; if (newValue > 25) newValue = 25; wearableMods->put(mod.getKey(), newValue); continue; } } prototype->addSkillMod(SkillModManager::WEARABLE, mod.getKey(), mod.getValue(), false); } }
bool ImageDesignManager::validateCustomizationString(CustomizationVariables* data, const String& appearanceFilename, int skillLevel) { VectorMap<String, Reference<CustomizationVariable*> > variables; variables.setNullValue(NULL); AssetCustomizationManagerTemplate::instance()->getCustomizationVariables(appearanceFilename.hashCode(), variables, false); if (variables.size() == 0) { instance()->error("no customization data found for " + appearanceFilename); return false; } for (int i = 0; i < data->size(); ++i) { uint8 id = data->elementAt(i).getKey(); int16 val = data->elementAt(i).getValue(); String name = CustomizationIdManager::instance()->getCustomizationVariable(id); //instance()->info("validating " + name + " with value " + String::valueOf(val), true); CustomizationVariable* customizationVariable = variables.get(name).get(); if (customizationVariable == NULL) { instance()->error("customization variable id " + String::valueOf(id) + " not found in the appearance file " + appearanceFilename + " with value " + String::valueOf(val)); continue; } PaletteColorCustomizationVariable* palette = dynamic_cast<PaletteColorCustomizationVariable*>(customizationVariable); if (palette != NULL) { if (!validatePalette(palette, val, skillLevel)) return false; } else { BasicRangedIntCustomizationVariable* range = dynamic_cast<BasicRangedIntCustomizationVariable*>(customizationVariable); if (range == NULL) { instance()->error("unkown customization variable type " + name); return false; } else { int maxExcl = range->getMaxValueExclusive(); int minIncl = range->getMinValueInclusive(); if (val >= maxExcl || val < minIncl) { instance()->error("variable outside bounds " + name + " value " + val + " outside bounds [" + String::valueOf(minIncl) + "," + String::valueOf(maxExcl) + ")"); return false; } else { //instance()->info("variable " + name + " value " + String::valueOf(val) + " inside bounds [" + String::valueOf(minIncl) + "," + String::valueOf(maxExcl) + ")", true); } } } //info("setting variable:" + name + " to " + String::valueOf(val), true); } return true; }
void SceneObjectImplementation::sendSlottedObjectsTo(SceneObject* player) { //sending all slotted objects by default VectorMap<String, ManagedReference<SceneObject* > > slotted; getSlottedObjects(slotted); SortedVector<SceneObject*> objects(slotted.size(), slotted.size()); objects.setNoDuplicateInsertPlan(); for (int i = 0; i < slotted.size(); ++i) { SceneObject* object = slotted.get(i); if (objects.put(object) != -1) { if (object->isInQuadTree()) { notifyInsert(object); } else { object->sendTo(player, true); } } } }
float EventInterpreter::getMean(const VectorMap& items){ float sum = 0; for(VectorMap::const_iterator i=items.begin();i != items.end(); ++i){ sum += *i; } return (sum/items.size()); }
void CraftingSessionImplementation::addSkillMods() { ManagedReference<ManufactureSchematic*> manufactureSchematic = this->manufactureSchematic.get(); ManagedReference<TangibleObject*> prototype = this->prototype.get(); ManagedReference<DraftSchematic*> draftSchematic = manufactureSchematic->getDraftSchematic(); VectorMap<String, int>* skillMods = draftSchematic->getDraftSchematicTemplate()->getSkillMods(); for (int i = 0; i < skillMods->size(); i++) { VectorMapEntry<String, int> mod = skillMods->elementAt(i); prototype->addSkillMod(SkillModManager::WEARABLE, mod.getKey(), mod.getValue(), false); } }
float EventInterpreter::getSTDDev(const VectorMap& items, float mean){ float stddev = 0; for(VectorMap::const_iterator i=items.begin(); i != items.end(); ++i){ stddev += pow((*i-mean),2); } return sqrt(stddev/items.size()); }
void DroidMaintenanceModuleDataComponent::payStructures(CreatureObject* player, VectorMap<unsigned long long, int> assignments) { // we know each struct to pay and any fees applied. ManagedReference<DroidObject*> droid = getDroidObject(); for(int i=0;i< assignments.size();i++) { uint64 objectID = assignments.elementAt(i).getKey(); int maintToPay = assignments.elementAt(i).getValue(); ManagedReference<SceneObject*> obj = player->getZoneServer()->getObject(objectID); StructureObject* structureObject = cast<StructureObject*>(obj.get()); if (structureObject != NULL) Locker sLock(obj,player); structureObject->payMaintenance(maintToPay,player,true); } }
void TangibleObjectImplementation::removeTemplateSkillMods(TangibleObject* targetObject) { SharedTangibleObjectTemplate* tano = dynamic_cast<SharedTangibleObjectTemplate*>(templateObject.get()); if (tano == NULL) return; VectorMap<String, int>* mods = tano->getSkillMods(); for (int i = 0; i < mods->size(); ++i) { VectorMapEntry<String, int> entry = mods->elementAt(i); targetObject->removeSkillMod(SkillModManager::TEMPLATE, entry.getKey(), entry.getValue()); } }
void SkillManager::surrenderAllSkills(CreatureObject* creature, bool notifyClient) { ManagedReference<PlayerObject*> ghost = creature->getPlayerObject(); SkillList* skillList = creature->getSkillList(); Vector<String> listOfNames; skillList->getStringList(listOfNames); SkillList copyOfList; copyOfList.loadFromNames(listOfNames); for (int i = 0; i < copyOfList.size(); i++) { Skill* skill = copyOfList.get(i); if (skill->getSkillPointsRequired() > 0) { creature->removeSkill(skill, notifyClient); //Remove skill modifiers VectorMap<String, int>* skillModifiers = skill->getSkillModifiers(); for (int i = 0; i < skillModifiers->size(); ++i) { VectorMapEntry<String, int>* entry = &skillModifiers->elementAt(i); creature->removeSkillMod(SkillModManager::SKILLBOX, entry->getKey(), entry->getValue(), notifyClient); } SkillModManager::instance()->verifySkillBoxSkillMods(creature); if (ghost != NULL) { //Give the player the used skill points back. ghost->addSkillPoints(skill->getSkillPointsRequired()); //Remove abilities Vector<String>* abilityNames = skill->getAbilities(); removeAbilities(ghost, *abilityNames, notifyClient); //Remove draft schematic groups Vector<String>* schematicsGranted = skill->getSchematicsGranted(); SchematicMap::instance()->removeSchematics(ghost, *schematicsGranted, notifyClient); /// update force ghost->setForcePowerMax(creature->getSkillMod("jedi_force_power_max"), true); } } } }
void ImageDesignManager::updateColorVariable(const Vector<String>& fullVariables, uint32 value, TangibleObject* tano, int skillLevel) { String appearanceFilename = tano->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(); //info("checking customization variable " + fullVariableNameLimit + " for " + var, true); if (fullVariableNameLimit.contains(var)) { BasicRangedIntCustomizationVariable* ranged = dynamic_cast<BasicRangedIntCustomizationVariable*>(variableLimits.elementAt(j).getValue().get()); PaletteColorCustomizationVariable* palette = NULL; uint32 currentVal = value; if (ranged != NULL) { int min = ranged->getMinValueInclusive(); int max = ranged->getMaxValueExclusive(); if (value < min) currentVal = min; if (value >= max) currentVal = max - 1; } else { palette = dynamic_cast<PaletteColorCustomizationVariable*>(variableLimits.elementAt(j).getValue().get()); if (palette != NULL) { if (!validatePalette(palette, currentVal, skillLevel)) currentVal = palette->getDefaultValue(); } } Locker locker(tano); tano->setCustomizationVariable(fullVariableNameLimit, currentVal, true); //info("setting " + fullVariableNameLimit + " to " + String::valueOf(currentVal), true); } } } }
int ContainerComponent::canAddObject(SceneObject* sceneObject, SceneObject* object, int containmentType, String& errorDescription) { if (sceneObject == object) { errorDescription = "@container_error_message:container02"; //You cannot add something to itself. return TransferErrorCode::CANTADDTOITSELF; } Locker contLocker(sceneObject->getContainerLock()); VectorMap<String, ManagedReference<SceneObject*> >* slottedObjects = sceneObject->getSlottedObjects(); VectorMap<uint64, ManagedReference<SceneObject*> >* containerObjects = sceneObject->getContainerObjects(); if (containmentType >= 4) { Locker contLocker(sceneObject->getContainerLock()); int arrangementGroup = containmentType - 4; if (object->getArrangementDescriptorSize() > arrangementGroup) { Vector<String> descriptors = object->getArrangementDescriptor(arrangementGroup); for (int i = 0; i < descriptors.size(); ++i){ String childArrangement = descriptors.get(i); if (slottedObjects->contains(childArrangement)) { errorDescription = "@container_error_message:container04"; //This slot is already occupied. return TransferErrorCode::SLOTOCCUPIED; } } } } else if (containmentType == -1) { if (containerObjects->size() >= sceneObject->getContainerVolumeLimit()) { errorDescription = "@container_error_message:container03"; //This container is full. return TransferErrorCode::CONTAINERFULL; } } else { sceneObject->error("unkown containmentType in canAddObject type " + String::valueOf(containmentType)); errorDescription = "DEBUG: cant move item unkown containmentType type"; return TransferErrorCode::UNKNOWNCONTAIMENTTYPE; } return 0; }
void SceneObjectImplementation::sendContainerObjectsTo(SceneObject* player) { //sending all objects by default VectorMap<uint64, ManagedReference<SceneObject* > > objects; getContainerObjects(objects); for (int j = 0; j < objects.size(); ++j) { SceneObject* containerObject = objects.get(j); if (containerObject == NULL) continue; if (containerObject->isInQuadTree()) { notifyInsert(containerObject); } else { containerObject->sendTo(player, true); } } }
void VehicleObjectImplementation::notifyInsertToZone(Zone* zone) { SceneObjectImplementation::notifyInsertToZone(zone); if( this->linkedCreature == NULL ) return; ManagedReference<CreatureObject* > linkedCreature = this->linkedCreature.get(); if( linkedCreature == NULL ) return; // Decay customized paint (if any) if (paintCount > 0){ // Paint starts to fade when there are 4 calls left if (paintCount <= 4){ // Send player notification of decay if( paintCount == 1 ){ linkedCreature->sendSystemMessage("@pet/pet_menu:customization_gone_veh"); // "Your vehicle's customization has completely faded away." } else{ linkedCreature->sendSystemMessage("@pet/pet_menu:customization_fading_veh"); // "Your vehicle's customization is fading away." } // Fade color to white String appearanceFilename = getObjectTemplate()->getAppearanceFilename(); VectorMap<String, Reference<CustomizationVariable*> > variables; AssetCustomizationManagerTemplate::instance()->getCustomizationVariables(appearanceFilename.hashCode(), variables, false); for(int i = 0; i< variables.size(); ++i){ String varkey = variables.elementAt(i).getKey(); if (varkey.contains("color")){ setCustomizationVariable(varkey, paintCount-1, true); // Palette values 3,2,1,0 are grey->white } } } --paintCount; } }
long DroidMaintenanceModuleDataComponent::calculateRunTime(VectorMap<unsigned long long, int> assignments) { long duration = 0; ManagedReference<DroidObject*> droid = getDroidObject(); String localPlanet = droid->getZone()->getZoneName(); ManagedReference<SceneObject*> primeStructure; for(int i=0;i< assignments.size();i++) { uint64 objectID = assignments.elementAt(i).getKey(); if(isValidStructure(objectID)) { ManagedReference<SceneObject*> obj = droid->getZoneServer()->getObject(objectID); if (obj->getZone()->getZoneName() != localPlanet) { duration += 6033000; // 1 hr 40 minutes and 33 seconds }else { // same planet if (primeStructure == NULL) { primeStructure = obj; } if (obj == primeStructure) { if (droid->getDistanceTo(obj) > 432) { duration += 2900000; // 48 minutes and 20 seconds } else { duration += 900000; // 15 minutes } } else { float distance = primeStructure->getDistanceTo(obj); if (distance > 432) { duration += 2900000; // 48 minutes and 20 seconds primeStructure = obj; // new prime structure } else { // this struct is within 432 of prime float timeAdded = (distance/3) * 1000; // add 1 sec for every 3 meters apart duration += (timeAdded + 900000); primeStructure = obj; // we now grab this structure as our prime going down the list. } } } } } return duration; }
// TODO: can this be simplified by doing the building check in the ticker? void EntertainingSessionImplementation::addEntertainerFlourishBuff() { // Watchers that are in our group for passive buff VectorMap<ManagedReference<CreatureObject*>, EntertainingData>* patrons = NULL; if (dancing) { patrons = &watchers; } else if (playingMusic) { patrons = &listeners; } if (patrons != NULL) { for (int i = 0; i < patrons->size(); ++i) { ManagedReference<CreatureObject*> patron = patrons->elementAt(i).getKey(); try { increaseEntertainerBuff(patron); } catch (Exception& e) { error("Unreported exception caught in EntertainingSessionImplementation::addEntertainerFlourishBuff()"); } } } /*else System::out << "no patrons";*/ }
void CraftingSessionImplementation::addWeaponDots() { ManagedReference<TangibleObject*> prototype = this->prototype.get(); if (!(prototype->isWeaponObject())) return; ManagedReference<WeaponObject*> weapon = cast<WeaponObject*>(prototype.get()); ManagedReference<ManufactureSchematic*> manufactureSchematic = this->manufactureSchematic.get(); ManagedReference<DraftSchematic*> draftSchematic = manufactureSchematic->getDraftSchematic(); Vector<VectorMap<String, int> >* weaponDots = draftSchematic->getDraftSchematicTemplate()->getWeaponDots(); for (int i = 0; i < weaponDots->size(); i++) { VectorMap<String, int> dot = weaponDots->elementAt(i); for (int j = 0; j < dot.size(); j++) { String property = dot.elementAt(j).getKey(); int value = dot.elementAt(j).getValue(); if (property == "type") weapon->addDotType(value); else if (property == "attribute") weapon->addDotAttribute(value); else if (property == "strength") weapon->addDotStrength(value); else if (property == "duration") weapon->addDotDuration(value); else if (property == "potency") weapon->addDotPotency(value); else if (property == "uses") weapon->addDotUses(value); } } }
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); } } } }
void LootManagerImplementation::setSkillMods(TangibleObject* object, LootItemTemplate* templateObject, int level, float excMod) { if (!object->isWeaponObject() && !object->isWearableObject()) return; VectorMap<String, int>* skillMods = templateObject->getSkillMods(); VectorMap<String, int> additionalMods; bool yellow = false; if (System::random(skillModChance / excMod) == 0) { // if it has a skillmod the name will be yellow yellow = true; int modCount = 1; int roll = System::random(100); if(roll > (100 - excMod)) modCount += 2; if(roll < (5 * excMod)) modCount += 1; for(int i = 0; i < modCount; ++i) { //Mods can't be lower than -1 or greater than 25 int max = MAX(-1, MIN(25, round(0.1f * level + 3))); int min = MAX(-1, MIN(25, round(0.075f * level - 1))); int mod = System::random(max - min) + min; if(mod == 0) mod = 1; String modName = getRandomLootableMod( object->getGameObjectType() ); if( !modName.isEmpty() ) additionalMods.put(modName, mod); } } if (yellow) { uint32 bitmask = object->getOptionsBitmask() | OptionBitmask::YELLOW; object->setOptionsBitmask(bitmask, false); } if (object->isWearableObject()) { ManagedReference<WearableObject*> wearableObject = cast<WearableObject*>(object); for (int i = 0; i < additionalMods.size(); i++) { wearableObject->addSkillMod(SkillModManager::WEARABLE, additionalMods.elementAt(i).getKey(), additionalMods.elementAt(i).getValue()); } for (int i = 0; i < skillMods->size(); i++) { wearableObject->addSkillMod(SkillModManager::WEARABLE, skillMods->elementAt(i).getKey(), skillMods->elementAt(i).getValue()); } } else if (object->isWeaponObject()) { ManagedReference<WeaponObject*> weaponObject = cast<WeaponObject*>(object); for (int i = 0; i < additionalMods.size(); i++) { weaponObject->addSkillMod(SkillModManager::WEARABLE, additionalMods.elementAt(i).getKey(), additionalMods.elementAt(i).getValue()); } for (int i = 0; i < skillMods->size(); i++) { weaponObject->addSkillMod(SkillModManager::WEARABLE, skillMods->elementAt(i).getKey(), skillMods->elementAt(i).getValue()); } } }
bool ZoneContainerComponent::removeObject(SceneObject* sceneObject, SceneObject* object, SceneObject* destination, bool notifyClient) { Zone* zone = dynamic_cast<Zone*>(sceneObject); if (object->isActiveArea()) return removeActiveArea(zone, dynamic_cast<ActiveArea*>(object)); ManagedReference<SceneObject*> parent = object->getParent(); //SortedVector<ManagedReference<SceneObject*> >* notifiedSentObjects = sceneObject->getNotifiedSentObjects(); try { Locker locker(object); if (zone == NULL) return false; object->info("removing from zone"); Locker zoneLocker(zone); if (parent != NULL) { parent->removeObject(object, NULL, false); } else zone->remove(object); Zone* oldZone = zone; // oldZone->dropSceneObject(object); // zoneLocker.release(); SortedVector<ManagedReference<QuadTreeEntry*> >* closeObjects = object->getCloseObjects(); if (closeObjects != NULL) { try { while (closeObjects->size() > 0) { ManagedReference<QuadTreeEntry*> obj = closeObjects->get(0); if (obj != NULL && obj != object && obj->getCloseObjects() != NULL) obj->removeInRangeObject(object); object->removeInRangeObject((int) 0); } } catch (...) { } } else { object->info("Null closeobjects vector in ZoneContainerComponent::removeObject", true); SortedVector<ManagedReference<QuadTreeEntry*> > closeSceneObjects; zone->getInRangeObjects(object->getPositionX(), object->getPositionY(), 512, &closeSceneObjects, false); for (int i = 0; i < closeSceneObjects.size(); ++i) { QuadTreeEntry* obj = closeSceneObjects.get(i); if (obj != NULL && obj != object && obj->getCloseObjects() != NULL) obj->removeInRangeObject(object); } } // Zone* oldZone = zone; zone = NULL; oldZone->dropSceneObject(object); SharedBuildingObjectTemplate* objtemplate = dynamic_cast<SharedBuildingObjectTemplate*>(object->getObjectTemplate()); if (objtemplate != NULL) { String modFile = objtemplate->getTerrainModificationFile(); if (!modFile.isEmpty()) { oldZone->getPlanetManager()->getTerrainManager()->removeTerrainModification(object->getObjectID()); } } zoneLocker.release(); if (object->isTangibleObject()) { TangibleObject* tano = cast<TangibleObject*>(object); Vector<ManagedReference<ActiveArea*> >* activeAreas = tano->getActiveAreas(); while (activeAreas->size() > 0) { Locker _alocker(object->getContainerLock()); ManagedReference<ActiveArea*> area = activeAreas->get(0); activeAreas->remove(0); _alocker.release(); area->enqueueExitEvent(object); } } SortedVector<ManagedReference<SceneObject*> >* childObjects = object->getChildObjects(); //Remove all outdoor child objects from zone for (int i = 0; i < childObjects->size(); ++i) { ManagedReference<SceneObject*> outdoorChild = childObjects->get(i); if (outdoorChild == NULL) continue; if (outdoorChild->isInQuadTree()) { Locker locker(outdoorChild); outdoorChild->destroyObjectFromWorld(true); } } } catch (Exception& e) { } object->notifyObservers(ObserverEventType::OBJECTREMOVEDFROMZONE, NULL, 0); VectorMap<uint32, ManagedReference<Facade*> >* objectActiveSessions = object->getObjectActiveSessions(); while (objectActiveSessions->size()) { ManagedReference<Facade*> facade = objectActiveSessions->remove(0).getValue(); if (facade == NULL) continue; facade->cancelSession(); } //activeAreas.removeAll(); object->info("removed from zone"); object->notifyRemoveFromZone(); object->setZone(NULL); return true; }
SceneObject* ObjectManager::cloneObject(SceneObject* object, bool makeTransient) { ObjectOutputStream objectData(500); (cast<ManagedObject*>(object))->writeObject(&objectData); objectData.reset(); ObjectInputStream objectInput; objectData.copy(&objectInput, 0); objectInput.reset(); uint32 serverCRC = object->getServerObjectCRC(); SceneObject* clonedObject = NULL; ObjectDatabase* database = getTable(object->getObjectID()); String databaseName; uint64 oid; if (database != NULL) { database->getDatabaseName(databaseName); oid = getNextObjectID(databaseName); } else oid = getNextFreeObjectID(); clonedObject = instantiateSceneObject(serverCRC, oid, false); if (makeTransient || !object->isPersistent()) { //clonedObject = createObject(serverCRC, 0, databaseName); clonedObject->setPersistent(0); } else if (object->isPersistent()) { //clonedObject = createObject(serverCRC, object->getPersistenceLevel(), databaseName); clonedObject->setPersistent(object->getPersistenceLevel()); } Locker locker(clonedObject); clonedObject->readObject(&objectInput); clonedObject->createComponents(); clonedObject->setParent(NULL); VectorMap<String, ManagedReference<SceneObject*> > slottedObjects; clonedObject->getSlottedObjects(slottedObjects); for (int i=slottedObjects.size()-1; i>=0; i--) { String key = slottedObjects.elementAt(i).getKey(); Reference<SceneObject*> obj = slottedObjects.elementAt(i).getValue(); clonedObject->removeSlottedObject(i); Reference<SceneObject*> clonedChild = cloneObject(obj, makeTransient); clonedChild->setParent(object); slottedObjects.put(key, clonedChild); } VectorMap<uint64, ManagedReference<SceneObject*> > objects; clonedObject->getContainerObjects(objects); for (int i=objects.size()-1; i>=0; i--) { uint64 key = objects.elementAt(i).getKey(); Reference<SceneObject*> obj = objects.elementAt(i).getValue(); objects.remove(i); Reference<SceneObject*> clonedChild = cloneObject(obj, makeTransient); clonedChild->setParent(object); objects.put(key, clonedChild); } clonedObject->onCloneObject(object); if (clonedObject->isPersistent()) updatePersistentObject(clonedObject); return clonedObject; }
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 ContainerComponent::transferObject(SceneObject* sceneObject, SceneObject* object, int containmentType, bool notifyClient, bool allowOverflow) { if (sceneObject == object) { return false; } ManagedReference<SceneObject*> objParent = object->getParent(); ManagedReference<Zone*> objZone = object->getLocalZone(); if (object->containsActiveSession(SessionFacadeType::SLICING)) { ManagedReference<Facade*> facade = object->getActiveSession(SessionFacadeType::SLICING); ManagedReference<SlicingSession*> session = dynamic_cast<SlicingSession*>(facade.get()); if (session != NULL) { session->cancelSession(); } } if (objParent != NULL || objZone != NULL) { if (objParent != NULL) objParent->removeObject(object, sceneObject, notifyClient); if (object->getParent() != NULL) { object->error("error removing from parent"); return false; } if (objZone != NULL) objZone->remove(object); object->setZone(NULL); if (objParent == NULL) objParent = objZone; } bool update = true; VectorMap<String, ManagedReference<SceneObject*> >* slottedObjects = sceneObject->getSlottedObjects(); VectorMap<uint64, ManagedReference<SceneObject*> >* containerObjects = sceneObject->getContainerObjects(); //if (containerType == 1 || containerType == 5) { if (containmentType >= 4) { Locker contLocker(sceneObject->getContainerLock()); int arrangementGroup = containmentType - 4; if (object->getArrangementDescriptorSize() > arrangementGroup) { const Vector<String>* descriptors = object->getArrangementDescriptor(arrangementGroup); for (int i = 0; i < descriptors->size(); ++i){ const String& childArrangement = descriptors->get(i); if (slottedObjects->contains(childArrangement)) { return false; } } for (int i = 0; i < descriptors->size(); ++i) { slottedObjects->put(descriptors->get(i), object); } } else { return false; } object->setParent(sceneObject); object->setContainmentType(containmentType); } else if (containmentType == -1) { /* else if (containerType == 2 || containerType == 3) {*/ Locker contLocker(sceneObject->getContainerLock()); if (!allowOverflow && containerObjects->size() >= sceneObject->getContainerVolumeLimit()){ return false; } /*if (containerObjects.contains(object->getObjectID())) return false*/ if (containerObjects->put(object->getObjectID(), object) == -1) update = false; object->setParent(sceneObject); object->setContainmentType(containmentType); } else { sceneObject->error("unknown containment type " + String::valueOf(containmentType)); StackTrace::printStackTrace(); return false; } if ((containmentType >= 4) && objZone == NULL) sceneObject->broadcastObject(object, true); else if (notifyClient) sceneObject->broadcastMessage(object->link(sceneObject->getObjectID(), containmentType), true); notifyObjectInserted(sceneObject, object); if (update) { sceneObject->updateToDatabase(); //object->updateToDatabaseWithoutChildren()(); } ManagedReference<SceneObject*> rootParent = object->getRootParent(); if (rootParent != NULL) rootParent->notifyObjectInsertedToChild(object, sceneObject, objParent); object->notifyObservers(ObserverEventType::PARENTCHANGED, sceneObject); return true; }
bool LairObserverImplementation::checkForNewSpawns(TangibleObject* lair, TangibleObject* attacker, bool forceSpawn) { if (lair->getZone() == NULL) return false; if (spawnedCreatures.size() >= lairTemplate->getSpawnLimit() && !lairTemplate->hasBossMobs()) return false; if (forceSpawn) { spawnNumber++; } else if (getMobType() == LairTemplate::NPC) { return false; } else { int conditionDamage = lair->getConditionDamage(); int maxCondition = lair->getMaxCondition(); switch (spawnNumber) { case 0: spawnNumber++; break; case 1: if (conditionDamage > (maxCondition / 10)) { spawnNumber++; } else { return false; } break; case 2: if (conditionDamage > (maxCondition / 2)) { spawnNumber++; } else { return false; } break; case 3: if (lairTemplate->hasBossMobs() && conditionDamage > ((maxCondition * 9) / 10)) { spawnNumber++; } else { return false; } break; default: return false; break; } } VectorMap<String, int> objectsToSpawn; // String mobileTemplate, int number to spawn if (spawnNumber == 4) { if (System::random(100) > 9) return false; VectorMap<String, int>* mobs = lairTemplate->getBossMobiles(); for (int i = 0; i < mobs->size(); i++) { objectsToSpawn.put(mobs->elementAt(i).getKey(), mobs->elementAt(i).getValue()); } } else { Vector<String>* mobiles = lairTemplate->getWeightedMobiles(); int amountToSpawn = 0; if (getMobType() == LairTemplate::CREATURE) { amountToSpawn = System::random(3) + ((lairTemplate->getSpawnLimit() / 3) - 2); } else { amountToSpawn = System::random(lairTemplate->getSpawnLimit() / 2) + (lairTemplate->getSpawnLimit() / 2); } if (amountToSpawn < 1) amountToSpawn = 1; for (int i = 0; i < amountToSpawn; i++) { int num = System::random(mobiles->size() - 1); String mob = mobiles->get(num); if (objectsToSpawn.contains(mob)) { int value = objectsToSpawn.get(mob); objectsToSpawn.drop(mob); objectsToSpawn.put(mob, value + 1); } else { objectsToSpawn.put(mob, 1); } } } for(int i = 0; i < objectsToSpawn.size(); ++i) { if (spawnNumber != 4 && spawnedCreatures.size() >= lairTemplate->getSpawnLimit()) return true; String templateToSpawn = objectsToSpawn.elementAt(i).getKey(); int numberToSpawn = objectsToSpawn.get(templateToSpawn); CreatureTemplate* creatureTemplate = CreatureTemplateManager::instance()->getTemplate(templateToSpawn); if (creatureTemplate == NULL) continue; float tamingChance = creatureTemplate->getTame(); CreatureManager* creatureManager = lair->getZone()->getCreatureManager(); for (int j = 0; j < numberToSpawn; j++) { float x = lair->getPositionX() + (size - System::random(size * 20) / 10.0f); float y = lair->getPositionY() + (size - System::random(size * 20) / 10.0f); float z = lair->getZone()->getHeight(x, y); ManagedReference<CreatureObject*> creo = NULL; if (creatureManager->checkSpawnAsBaby(tamingChance, babiesSpawned, 500)) { creo = creatureManager->spawnCreatureAsBaby(templateToSpawn.hashCode(), x, z, y); babiesSpawned++; } if (creo == NULL) creo = creatureManager->spawnCreatureWithAi(templateToSpawn.hashCode(), x, z, y); if (creo == NULL) continue; if (!creo->isAiAgent()) { error("spawned non player creature with template " + templateToSpawn); } else { AiAgent* ai = cast<AiAgent*>( creo.get()); //Locker clocker(npc, lair); ai->setDespawnOnNoPlayerInRange(false); ai->setHomeLocation(x, z, y); ai->setRespawnTimer(0); ai->setHomeObject(lair); spawnedCreatures.add(creo); } } } if (spawnNumber == 4) { Reference<LairAggroTask*> task = new LairAggroTask(lair, attacker, _this.get(), true); task->schedule(1000); } return objectsToSpawn.size() > 0; }
bool 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 ContainerComponent::canAddObject(SceneObject* sceneObject, SceneObject* object, int containmentType, String& errorDescription) { if (sceneObject == object) { errorDescription = "@container_error_message:container02"; //You cannot add something to itself. return TransferErrorCode::CANTADDTOITSELF; } if ((object->isNoTrade() || object->containsNoTradeObjectRecursive()) && !object->isVendor()) { ManagedReference<SceneObject*> containerPlayerParent = sceneObject->getParentRecursively(SceneObjectType::PLAYERCREATURE); ManagedReference<SceneObject*> containerBuildingParent = sceneObject->getParentRecursively(SceneObjectType::BUILDING); ManagedReference<SceneObject*> containerFactoryParent = sceneObject->getParentRecursively(SceneObjectType::FACTORY); ManagedReference<SceneObject*> objPlayerParent = object->getParentRecursively(SceneObjectType::PLAYERCREATURE); ManagedReference<SceneObject*> objBuildingParent = object->getParentRecursively(SceneObjectType::BUILDING); if (containerFactoryParent != NULL) { errorDescription = "@container_error_message:container28"; return TransferErrorCode::CANTADD; } else if (objPlayerParent == NULL && objBuildingParent != NULL) { ManagedReference<BuildingObject*> buio = cast<BuildingObject*>( objBuildingParent.get()); if (buio != NULL ) { uint64 bid = buio->getOwnerObjectID(); if ((containerPlayerParent != NULL && bid != containerPlayerParent->getObjectID()) || (sceneObject->isPlayerCreature() && bid != sceneObject->getObjectID())) { errorDescription = "@container_error_message:container27"; return TransferErrorCode::CANTREMOVE; } } } else if (objPlayerParent != NULL && containerPlayerParent == NULL && containerBuildingParent != NULL && !sceneObject->isPlayerCreature()) { ManagedReference<BuildingObject*> buio = cast<BuildingObject*>( containerBuildingParent.get()); if (buio != NULL && buio->getOwnerObjectID() != objPlayerParent->getObjectID()) { errorDescription = "@container_error_message:container28"; return TransferErrorCode::CANTADD; } } } else if (object->isVendor()) { ManagedReference<SceneObject*> containerPlayerParent = sceneObject->getParentRecursively(SceneObjectType::PLAYERCREATURE); if (!sceneObject->isCellObject() && (!sceneObject->hasArrangementDescriptor("inventory") || containerPlayerParent == NULL)) { return TransferErrorCode::CANTADD; } } Locker contLocker(sceneObject->getContainerLock()); VectorMap<String, ManagedReference<SceneObject*> >* slottedObjects = sceneObject->getSlottedObjects(); VectorMap<uint64, ManagedReference<SceneObject*> >* containerObjects = sceneObject->getContainerObjects(); if (containmentType >= 4) { Locker contLocker(sceneObject->getContainerLock()); int arrangementGroup = containmentType - 4; if (object->getArrangementDescriptorSize() > arrangementGroup) { const Vector<String>* descriptors = object->getArrangementDescriptor(arrangementGroup); for (int i = 0; i < descriptors->size(); ++i){ const String& childArrangement = descriptors->get(i); if (slottedObjects->contains(childArrangement)) { errorDescription = "@container_error_message:container04"; //This slot is already occupied. return TransferErrorCode::SLOTOCCUPIED; } } } } else if (containmentType == -1) { if (containerObjects->size() >= sceneObject->getContainerVolumeLimit()) { errorDescription = "@container_error_message:container03"; //This container is full. return TransferErrorCode::CONTAINERFULL; } } else { sceneObject->error("unknown containmentType in canAddObject type " + String::valueOf(containmentType)); errorDescription = "DEBUG: cant move item unknown containmentType type"; return TransferErrorCode::UNKNOWNCONTAIMENTTYPE; } return 0; }
void EntertainingSessionImplementation::doEntertainerPatronEffects() { ManagedReference<CreatureObject*> creo = entertainer.get(); if (creo == NULL) return; if (performanceName == "") return; Locker locker(creo); //**DECLARATIONS** VectorMap<ManagedReference<CreatureObject*>, EntertainingData>* patrons = NULL; SkillManager* skillManager = creo->getZoneServer()->getSkillManager(); PerformanceManager* performanceManager = skillManager->getPerformanceManager(); Performance* performance = NULL; ManagedReference<Instrument*> instrument = getInstrument(creo); float woundHealingSkill = 0.0f; float playerShockHealingSkill = 0.0f; float buildingShockHealingSkill = creo->getSkillMod("private_med_battle_fatigue"); float factionPerkSkill = creo->getSkillMod("private_faction_mind_heal"); //**LOAD PATRONS, GET THE PERFORMANCE AND ENT'S HEALING SKILL.** if (dancing) { patrons = &watchers; performance = performanceManager->getDance(performanceName); woundHealingSkill = (float) creo->getSkillMod("healing_dance_wound"); playerShockHealingSkill = (float) creo->getSkillMod("healing_dance_shock"); } else if (playingMusic && instrument != NULL) { patrons = &listeners; performance = performanceManager->getSong(performanceName, instrument->getInstrumentType()); woundHealingSkill = (float) creo->getSkillMod("healing_music_wound"); playerShockHealingSkill = (float) creo->getSkillMod("healing_music_shock"); } else { cancelSession(); return; } if (performance == NULL) { return; } ManagedReference<BuildingObject*> building = creo->getRootParent().get().castTo<BuildingObject*>(); if (building != NULL && factionPerkSkill > 0 && building->isPlayerRegisteredWithin(creo->getObjectID())) { unsigned int buildingFaction = building->getFaction(); unsigned int healerFaction = creo->getFaction(); PlayerObject* ghost = creo->getPlayerObject(); if (ghost != NULL && healerFaction != 0 && healerFaction == buildingFaction && ghost->getFactionStatus() == FactionStatus::OVERT) { woundHealingSkill += factionPerkSkill; playerShockHealingSkill += factionPerkSkill; } } //**DETERMINE WOUND HEAL AMOUNTS.** int woundHeal = ceil(performance->getHealMindWound() * (woundHealingSkill / 100.0f)); int shockHeal = ceil(performance->getHealShockWound() * ((playerShockHealingSkill + buildingShockHealingSkill) / 100.0f)); //**ENTERTAINER HEALS THEIR OWN MIND.** healWounds(creo, woundHeal*(flourishCount+1), shockHeal*(flourishCount+1)); //**APPLY EFFECTS TO PATRONS.** if (patrons != NULL && patrons->size() > 0) { for (int i = 0; i < patrons->size(); ++i) { ManagedReference<CreatureObject*> patron = patrons->elementAt(i).getKey(); try { //**VERIFY THE PATRON IS NOT ON THE DENY SERVICE LIST if (creo->isInRange(patron, 10.0f)) { healWounds(patron, woundHeal*(flourishCount+1), shockHeal*(flourishCount+1)); increaseEntertainerBuff(patron); } else { //patron is not in range, force to stop listening ManagedReference<PlayerManager*> playerManager = patron->getZoneServer()->getPlayerManager(); Locker locker(patron, entertainer.get()); if (dancing) { if (playerManager != NULL) playerManager->stopWatch(patron, creo->getObjectID(), true, false, false, true); if (!patron->isListening()) sendEntertainmentUpdate(patron, 0, "", true); } else if (playingMusic) { if (playerManager != NULL) playerManager->stopListen(patron, creo->getObjectID(), true, false, false, true); if (!patron->isWatching()) sendEntertainmentUpdate(patron, 0, "", true); } } } catch (Exception& e) { error("Unreported exception caught in EntertainingSessionImplementation::doEntertainerPatronEffects()"); } } } //else //System::out << "There are no patrons.\n"; info("EntertainingSessionImplementation::doEntertainerPatronEffects() end"); }
int DroidCustomKitObjectMenuComponent::handleObjectMenuSelect(SceneObject* sceneObject, CreatureObject* player, byte selectedID) { 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->isDroidObject()) { player->sendSystemMessage("You can only use this tool to customize droids"); return 0; } //permission check CreatureObject* droid = cast<CreatureObject*>(target.get()); uint64 ownerID = droid->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 droid"); return 0; } } //end permission check Locker clocker(droid, 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 droid"); // protocol droids return 0; } DroidObject* painted = cast<DroidObject*>(droid); if (painted != NULL){ painted->refreshPaint(); } ManagedReference<SuiListBox*> frameTrimSelector = new SuiListBox(player, SuiWindowType::CUSTOMIZE_KIT); frameTrimSelector->setUsingObject(player); frameTrimSelector->setCallback(new CustomDroidSuiCallback(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"); if (numPalette > 1 ) { 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; }
void LootManagerImplementation::addStaticDots(TangibleObject* object, LootItemTemplate* templateObject, int level) { if (object == NULL) return; if (!object->isWeaponObject()) return; ManagedReference<WeaponObject*> weapon = cast<WeaponObject*>(object); bool shouldGenerateDots = false; float dotChance = templateObject->getStaticDotChance(); if (dotChance < 0) return; // Apply the Dot if the chance roll equals the number or is zero. if (dotChance == 0 || System::random(dotChance) == 0) { // Defined in loot item script. shouldGenerateDots = true; } if (shouldGenerateDots) { int dotType = templateObject->getStaticDotType(); if (dotType < 1 || dotType > 4) return; VectorMap<String, SortedVector<int> >* dotValues = templateObject->getStaticDotValues(); int size = dotValues->size(); // Check if they specified correct vals. if (size > 0) { weapon->addDotType(dotType); for (int i = 0; i < size; i++) { String property = dotValues->elementAt(i).getKey(); SortedVector<int> theseValues = dotValues->elementAt(i).getValue(); int min = theseValues.elementAt(0); int max = theseValues.elementAt(1); float value = 0; if (max != min) { value = calculateDotValue(min, max, level); } else { value = max; } if(property == "attribute") { if (min != max) value = System::random(max - min) + min; if (dotType != 2 && (value != 0 && value != 3 && value != 6)) { int numbers[] = { 0, 3, 6 }; // The main pool attributes. int choose = System::random(2); value = numbers[choose]; } weapon->addDotAttribute(value); } else if (property == "strength") { weapon->addDotStrength(value); } else if (property == "duration") { weapon->addDotDuration(value); } else if (property == "potency") { weapon->addDotPotency(value); } else if (property == "uses") { weapon->addDotUses(value); } } } } }
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."; } } }