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; }
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 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(); }
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; }
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; }
void ContainerPermissions::setAllowPermission(const String& group, uint16 permission) { setAllowPermission(group.hashCode(), permission); }
uint16 ContainerPermissions::getDenyPermissions(const String& group) { return getDenyPermissions(group.hashCode()); }
bool ContainerPermissions::hasPermission(const String& group, uint16 permission) { return hasPermission(group.hashCode(), permission); }
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; }
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) }
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; }
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; }
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; }
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()); }
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); } }