bool ResourceLabratory::applyComponentStats(TangibleObject* prototype, ManufactureSchematic* manufactureSchematic) { if(manufactureSchematic == NULL || manufactureSchematic->getDraftSchematic() == NULL) return false; float max, min, currentvalue, propertyvalue; int precision; bool modified = false; bool hidden; String experimentalTitle, property; CraftingValues* craftingValues = manufactureSchematic->getCraftingValues(); ManagedReference<DraftSchematic* > draftSchematic = manufactureSchematic->getDraftSchematic(); for (int i = 0; i < manufactureSchematic->getSlotCount(); ++i) { Reference<IngredientSlot* > ingredientSlot = manufactureSchematic->getSlot(i); Reference<DraftSlot* > draftSlot = draftSchematic->getDraftSlot(i); if(ingredientSlot == NULL || !ingredientSlot->isComponentSlot() || !ingredientSlot->isFull()) continue; ComponentSlot* compSlot = cast<ComponentSlot*>(ingredientSlot.get()); if(compSlot == NULL) continue; ManagedReference<TangibleObject*> tano = compSlot->getPrototype(); if (tano == NULL || !tano->isComponent()) continue; ManagedReference<Component*> component = cast<Component*>( tano.get()); if (prototype->isWearableObject() && !prototype->isArmorObject()) { if (component->getObjectTemplate()->getObjectName() == "@craft_clothing_ingredients_n:reinforced_fiber_panels" || component->getObjectTemplate()->getObjectName() == "@craft_clothing_ingredients_n:synthetic_cloth"){ for (int k = 0; k < component->getPropertyCount(); ++k) { const String property = component->getProperty(k); if (property == "" || property == "null") { continue; } String key = checkBioSkillMods(property); if (key == "") { continue; } else { currentvalue = component->getAttributeValue(property); precision = component->getAttributePrecision(property); int preciseValue = Math::getPrecision(currentvalue, precision); WearableObject* clothing = cast<WearableObject*>(prototype); VectorMap<String, int>* clothingMods = clothing->getWearableSkillMods(); int existingValue = 0; if(clothingMods->contains(key)) { existingValue = clothingMods->get(key); } preciseValue += existingValue; if (preciseValue > 25) preciseValue = 25; clothing->addSkillMod(SkillModManager::WEARABLE, key, preciseValue); } } } } else { for (int j = 0; j < component->getPropertyCount(); ++j) { property = component->getProperty(j); // charges modified = true; if (craftingValues->hasProperty(property)) { max = craftingValues->getMaxValue(property); min = craftingValues->getMinValue(property); hidden = craftingValues->isHidden(property); currentvalue = craftingValues->getCurrentValue(property); propertyvalue = component->getAttributeValue(property) * draftSlot->getContribution(); short combineType = craftingValues->getCombineType(property); switch(combineType) { case CraftingManager::LINEARCOMBINE: currentvalue += propertyvalue; min += propertyvalue; max += propertyvalue; craftingValues->setMinValue(property, min); craftingValues->setMaxValue(property, max); craftingValues->setCurrentValue(property, currentvalue); break; case CraftingManager::PERCENTAGECOMBINE: currentvalue += propertyvalue; min += propertyvalue; max += propertyvalue; craftingValues->setMinValue(property, min); craftingValues->setMaxValue(property, max); craftingValues->setCurrentPercentage(property, currentvalue); break; case CraftingManager::BITSETCOMBINE: currentvalue = (int)currentvalue | (int)propertyvalue; craftingValues->setCurrentValue(property , currentvalue); break; case CraftingManager::OVERRIDECOMBINE: // Do nothing because the values should override whatever is // on the component break; default: break; } } else { currentvalue = component->getAttributeValue(property); precision = component->getAttributePrecision(property); experimentalTitle = component->getAttributeTitle(property); craftingValues->addExperimentalProperty(experimentalTitle, property, currentvalue, currentvalue, precision, component->getAttributeHidden(property), CraftingManager::LINEARCOMBINE); craftingValues->setCurrentPercentage(property, 0); craftingValues->setMaxPercentage(property, 0); craftingValues->setCurrentValue(property, currentvalue); } } } } return modified; }
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; }