mirror of
https://github.com/SWG-Source/dsrc.git
synced 2026-01-17 00:05:07 -05:00
2013 lines
104 KiB
Java
Executable File
2013 lines
104 KiB
Java
Executable File
package script.library;
|
|
|
|
import script.*;
|
|
|
|
import java.util.Vector;
|
|
|
|
public class craftinglib extends script.base_script
|
|
{
|
|
public craftinglib()
|
|
{
|
|
}
|
|
public static final String VERSION = "v0.00.00";
|
|
public static final float COMPLEXITY_INCREMENT_MOD = 3.0f;
|
|
public static final float RESOURCE_NOT_USED = -9999;
|
|
public static final String COMPONENT_ATTRIBUTE_OBJVAR_NAME = "crafting_components";
|
|
public static final String COMPONENT_ATTRIBUTE_INTERNAL_OBJVAR_NAME = "crafting_components_internal";
|
|
public static final String OBJVAR_COMPONENT_ATTRIB_BONUSES = "attrib_bonuses";
|
|
public static final String RESOURCE_AVERAGE_DICTIONARY_NAME = "itemTotalResourceAverage";
|
|
public static final String SLOT_RESOURCE_DICTIONARY_NAME = "slotResourceAverage";
|
|
public static final String RESOURCE_MALLEABILITY_SKILL_MOD = "resourceMalleabilitySkillMod";
|
|
public static final float NUMERIC_RANGE_EXPRESSION = 10000.0f;
|
|
public static final float BASE_RANGE = 100.0f;
|
|
public static final float EXPERIENCE_GRANTED_MULTIPLIER = 3.0f;
|
|
public static final int socketThreshold = 60;
|
|
public static final int socketDelta = 10;
|
|
public static final int maxSockets = 1;
|
|
public static final int socketChance = 50;
|
|
public static final float STATION_AREA = 20.0f;
|
|
public static final String OBJVAR_STATION = "crafting.station";
|
|
public static final String OBJVAR_PRIVATE_STATION = "crafting.private";
|
|
public static final String OBJVAR_CRAFTER = "crafting.crafter";
|
|
public static final String OBJVAR_CRAFTING_TYPE = "crafting.type";
|
|
public static final String OBJVAR_PROTOTYPE_START = "crafting.prototypeStartTime";
|
|
public static final String OBJVAR_PROTOTYPE_TIME = "crafting.prototypeTime";
|
|
public static final String OBJVAR_CRAFTING_PROTOTYPE_OBJECT = "crafting.prototypeObject";
|
|
public static final String OBJVAR_CRAFTING_PROTOTYPE_CRAFTER = "crafting.prototypeCrafter";
|
|
public static final String OBJVAR_PACKED_CRAFTING_VALUES_DICTIONARY = "crafting.valuesDictionary";
|
|
public static final String OBJVAR_CRAFTING_STATION_BONUS = "crafting.stationMod";
|
|
public static final String OBJVAR_SKILLMOD_BONUS = "skillmod.bonus";
|
|
public static final String OBJVAR_REFACTOR = "crafting.refactor";
|
|
public static final String OBJVAR_FORCE_CRITICAL_ASSEMBLY = "crafting.force_critical_assembly";
|
|
public static final String OBJVAR_FORCE_CRITICAL_EXPERIMENT = "crafting.force_critical_experiment";
|
|
public static final String OBJVAR_FORCE_CRITICAL_SUCCESS = "crafting.force_critical_success";
|
|
public static final String OBJVAR_FORCE_CRITICAL_SUCCESS_RESULT = "crafting.force_critical_success_result";
|
|
public static final String OBJVAR_NO_CRIT_FAIL = "crafting.no_critical_fail";
|
|
public static final String OBJVAR_IN_CRAFTING_SESSION = "crafting.inCraftingSession";
|
|
public static final float EXPERIMENTATION_EFFECTIVENESS_MULTIPLIER = 1.0f;
|
|
public static final String EXPERIENCE_NAME_RESOURCE_ORGANIC = "resource_harvesting_organic";
|
|
public static final String EXPERIENCE_NAME_RESOURCE_INORGANIC = "resource_harvesting_inorganic";
|
|
public static final float EXPERIENCE_PER_RESOURCE = 1.0f;
|
|
public static final int STATE_UNSET = -1;
|
|
public static final int STATE_CRITICAL_SUCCESS = 0;
|
|
public static final int STATE_GREAT_SUCCESS = 1;
|
|
public static final int STATE_GOOD_SUCCESS = 2;
|
|
public static final int STATE_MODERATE_SUCCESS = 3;
|
|
public static final int STATE_SUCCESS = 4;
|
|
public static final int STATE_FAILURE = 5;
|
|
public static final int STATE_MODERATE_FAILURE = 6;
|
|
public static final int STATE_BIG_FAILURE = 7;
|
|
public static final int STATE_CRITICAL_FAILURE = 8;
|
|
public static final int STATE_CRITICAL_FAILURE_NODESTROY = 9;
|
|
public static final int MAX_SUCCESS_STATE = 9;
|
|
|
|
public static final String[] STATE_NAMES =
|
|
{
|
|
"crit success",
|
|
"great success",
|
|
"good success",
|
|
"mod success",
|
|
"success",
|
|
"fail",
|
|
"mod fail",
|
|
"big fail",
|
|
"crit fail",
|
|
"crit fail (nodestroy)"
|
|
};
|
|
|
|
public static final int RESOURCE_BULK = 0;
|
|
public static final int RESOURCE_COLD_RESIST = 1;
|
|
public static final int RESOURCE_CONDUCTIVITY = 2;
|
|
public static final int RESOURCE_DECAY_RESIST = 3;
|
|
public static final int RESOURCE_HEAT_RESIST = 4;
|
|
public static final int RESOURCE_FLAVOR = 5;
|
|
public static final int RESOURCE_MALLEABILITY = 6;
|
|
public static final int RESOURCE_POTENTIAL_ENERGY = 7;
|
|
public static final int RESOURCE_QUALITY = 8;
|
|
public static final int RESOURCE_SHOCK_RESIST = 9;
|
|
public static final int RESOURCE_TOUGHNESS = 10;
|
|
public static final int RESOURCE_VOLUME = 11;
|
|
public static final int NUM_RESOURCE_ATTRIBS = 12;
|
|
public static final int SLOT_WEIGHT_SLOT_01 = 100;
|
|
public static final int SLOT_WEIGHT_SLOT_02 = 101;
|
|
public static final int SLOT_WEIGHT_SLOT_03 = 102;
|
|
public static final int SLOT_WEIGHT_SLOT_04 = 103;
|
|
public static final int SLOT_WEIGHT_SLOT_05 = 104;
|
|
public static final int SLOT_WEIGHT_SLOT_06 = 105;
|
|
public static final int SLOT_WEIGHT_SLOT_07 = 106;
|
|
public static final int SLOT_WEIGHT_SLOT_08 = 107;
|
|
public static final String[] RESOURCE_OBJVAR_NAMES =
|
|
{
|
|
"res_bulk",
|
|
"res_cold_resist",
|
|
"res_conductivity",
|
|
"res_decay_resist",
|
|
"res_heat_resist",
|
|
"res_flavor",
|
|
"res_malleability",
|
|
"res_potential_energy",
|
|
"res_quality",
|
|
"res_shock_resistance",
|
|
"res_toughness",
|
|
"res_volume"
|
|
};
|
|
public static final String TISSUE_SKILL_MODS = "tissue_skill_mods";
|
|
public static final String TISSUE_SKILL_INDEX = "tissue_skill_index";
|
|
public static final String TISSUE_SKILL_VALUE = "tissue_skill_value";
|
|
public static final string_id SID_INSPIRE_BONUS = new string_id("performance", "perform_inspire_crafting_bonus");
|
|
public static final String TABLE_SCHEMATIC_GROUPS = "datatables/crafting/schematic_group.iff";
|
|
public static final String SKILL_MOD_2_BONUS = "skillmod2.bonus.";
|
|
public static final float RE_POWER_MODIFIER = 0.40f;
|
|
public static final String OBJVAR_RE_STAT_MODIFIED = "crafting.re_stat_modified";
|
|
public static final String OBJVAR_RE_RATIO = "crafting.re_ratio";
|
|
public static final String OBJVAR_RE_VALUE = "crafting.re_value";
|
|
public static final String SCRIPTVAR_CELL_STATIONS = "crafting.stations";
|
|
public static final int OBJVAR_SCHEM_VERSION = 1;
|
|
public static final int STATION_TYPE_FOOD = 8644;
|
|
public static final int STATION_TYPE_FOOD_AND_STRUCTURE = 10180;
|
|
public static final int STATION_TYPE_ARMOR = 10;
|
|
public static final int STATION_TYPE_STRUCTURE = 1536;
|
|
public static final int STATION_TYPE_WEAPON = 526369;
|
|
public static final int STATION_TYPE_WEAPON_TOOL = 524321;
|
|
public static final int STATION_TYPE_SPACE = 393216;
|
|
public static final string_id RESEARCH_CENTER_MESSAGE = new string_id("city/city", "research_center_message");
|
|
public static final string_id MANUFACTURING_CENTER_MESSAGE = new string_id("city/city", "manufacturing_center_message");
|
|
public static float calcResourceQualitySkillMod(dictionary craftingValuesDictionary) throws InterruptedException
|
|
{
|
|
if (craftingValuesDictionary == null)
|
|
{
|
|
return 0;
|
|
}
|
|
float[] resources = craftingValuesDictionary.getFloatArray(RESOURCE_AVERAGE_DICTIONARY_NAME);
|
|
if (resources == null || resources.length != NUM_RESOURCE_ATTRIBS)
|
|
{
|
|
LOG("crafting", "Java craftinglib.scriptlib::calcResourceQualitySkillMod - no resource average array!");
|
|
return 0;
|
|
}
|
|
float averageResourceQuality = resources[RESOURCE_QUALITY];
|
|
float objectQualityMultiMod = (averageResourceQuality - 500) / 200;
|
|
float resourceQualitySkillMod = objectQualityMultiMod * 5;
|
|
debugServerConsoleMsg(null, "The resourceQualitySkillMod is " + resourceQualitySkillMod);
|
|
float itemDefaultComplexity = craftingValuesDictionary.getFloat("itemDefaultComplexity");
|
|
debugServerConsoleMsg(null, "object complexity value by default is " + itemDefaultComplexity);
|
|
if (averageResourceQuality >= 900)
|
|
{
|
|
float itemCurrentComplexity = craftingValuesDictionary.getFloat("itemCurrentComplexity");
|
|
itemCurrentComplexity = itemCurrentComplexity - 1;
|
|
craftingValuesDictionary.put("itemCurrentComplexity", itemCurrentComplexity);
|
|
debugServerConsoleMsg(null, "object complexity reduced by 1 thanks to high average quality of resources used");
|
|
debugServerConsoleMsg(null, "object complexity value is now " + itemCurrentComplexity);
|
|
}
|
|
return resourceQualitySkillMod;
|
|
}
|
|
public static float calcItemComplexitySkillMod(dictionary craftingValuesDictionary) throws InterruptedException
|
|
{
|
|
if (craftingValuesDictionary == null)
|
|
{
|
|
return 0;
|
|
}
|
|
float itemDefaultComplexity = craftingValuesDictionary.getFloat("itemDefaultComplexity");
|
|
float itemCurrentComplexity = craftingValuesDictionary.getFloat("itemCurrentComplexity");
|
|
float itemComplexitySubMod = itemCurrentComplexity - itemDefaultComplexity;
|
|
float itemComplexitySkillMod = 0;
|
|
if (itemComplexitySubMod > 0)
|
|
{
|
|
itemComplexitySkillMod = itemComplexitySubMod * COMPLEXITY_INCREMENT_MOD;
|
|
}
|
|
debugServerConsoleMsg(null, "The itemComplexitySkillMod is " + itemComplexitySkillMod);
|
|
return itemComplexitySkillMod;
|
|
}
|
|
public static float calcResourceMalleabilitySkillMod(dictionary craftingValuesDictionary) throws InterruptedException
|
|
{
|
|
if (craftingValuesDictionary == null)
|
|
{
|
|
return 0;
|
|
}
|
|
float[] resources = craftingValuesDictionary.getFloatArray(RESOURCE_AVERAGE_DICTIONARY_NAME);
|
|
if (resources == null || resources.length != NUM_RESOURCE_ATTRIBS)
|
|
{
|
|
LOG("crafting", "Java craftinglib.scriptlib::calcResourceMalleabilitySkillMod - no resource average array!");
|
|
return 0;
|
|
}
|
|
float averageResourceMalleability = resources[RESOURCE_MALLEABILITY];
|
|
float objectMalleabilityMultiMod = (averageResourceMalleability - 500) / 200;
|
|
float resourceMalleabilitySkillMod = objectMalleabilityMultiMod * 5;
|
|
debugServerConsoleMsg(null, "The resourceMalleabilitySkillMod is " + resourceMalleabilitySkillMod);
|
|
craftingValuesDictionary.put(RESOURCE_MALLEABILITY_SKILL_MOD, resourceMalleabilitySkillMod);
|
|
return resourceMalleabilitySkillMod;
|
|
}
|
|
public static float getAttributeResourceMod(float averagedAttributeSum) throws InterruptedException
|
|
{
|
|
float resourceAverageMod;
|
|
if (averagedAttributeSum == 500)
|
|
{
|
|
resourceAverageMod = 1;
|
|
}
|
|
else
|
|
{
|
|
resourceAverageMod = (averagedAttributeSum - 500) / 200;
|
|
}
|
|
float attributeResourceMod = resourceAverageMod * 5;
|
|
return attributeResourceMod;
|
|
}
|
|
public static float computeWeightedAverage(float[] resourceValues, resource_weight.weight[] weights) throws InterruptedException
|
|
{
|
|
float total = 0;
|
|
int count = 0;
|
|
for (int i = 0; i < weights.length; ++i)
|
|
{
|
|
debugServerConsoleMsg(null, "@@@@@craftinglib.scriptlib computeWeightedAverage, resource = " + weights[i].resource + ", value = " + resourceValues[weights[i].resource] + ", weight = " + weights[i].weight);
|
|
total += resourceValues[weights[i].resource] * weights[i].weight;
|
|
count += weights[i].weight;
|
|
debugServerConsoleMsg(null, "\t@@@@@craftinglib.scriptlib computeWeightedAverage, total = " + total + ", count = " + count);
|
|
}
|
|
if (count != 0)
|
|
{
|
|
return total / count;
|
|
}
|
|
return 0;
|
|
}
|
|
public static int calcSkillDesignAssemblyCheck(obj_id player, dictionary craftingValuesDictionary, String[] skills) throws InterruptedException
|
|
{
|
|
boolean isPlayerQA = false;
|
|
boolean isPlayerTester = false;
|
|
if (hasObjVar(player, "crafting_qa"))
|
|
{
|
|
isPlayerQA = true;
|
|
}
|
|
if (hasObjVar(player, "crafting_tester"))
|
|
{
|
|
isPlayerTester = true;
|
|
}
|
|
float deltaMod = NUMERIC_RANGE_EXPRESSION / BASE_RANGE;
|
|
if (!isIdValid(player) || craftingValuesDictionary == null)
|
|
{
|
|
CustomerServiceLog("Crafting", "VALIDATION FAILED -- Assembly returned a critical failure because player object ID or crafting dictionary was null");
|
|
return STATE_CRITICAL_FAILURE;
|
|
}
|
|
int successState = STATE_UNSET;
|
|
float dieRoll = rand(1, (int)NUMERIC_RANGE_EXPRESSION);
|
|
float dieRollMod = 0f;
|
|
float itemComplexitySkillMod = calcItemComplexitySkillMod(craftingValuesDictionary);
|
|
float resourceMalleabilitySkillMod = calcResourceMalleabilitySkillMod(craftingValuesDictionary);
|
|
float resourceQualitySkillMod = calcResourceQualitySkillMod(craftingValuesDictionary);
|
|
if (craftingValuesDictionary.containsKey(OBJVAR_REFACTOR))
|
|
{
|
|
itemComplexitySkillMod = 0;
|
|
}
|
|
float craftingStationMod = 0;
|
|
obj_id stationId = getCraftingStation(player);
|
|
if (!isIdValid(stationId))
|
|
{
|
|
stationId = getSelf();
|
|
}
|
|
if (isIdValid(stationId) && exists(stationId) && hasObjVar(stationId, OBJVAR_CRAFTING_STATION_BONUS))
|
|
{
|
|
craftingStationMod = getFloatObjVar(stationId, OBJVAR_CRAFTING_STATION_BONUS) / 10;
|
|
}
|
|
float playerSkillMod = 0;
|
|
if (skills != null)
|
|
{
|
|
int[] mods = getEnhancedSkillStatisticModifiers(player, skills);
|
|
for (int i = 0; i < mods.length; ++i)
|
|
{
|
|
playerSkillMod += mods[i];
|
|
}
|
|
}
|
|
float forceSkillMod = getSkillStatisticModifier(player, "force_assembly");
|
|
debugServerConsoleMsg(null, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
|
|
debugServerConsoleMsg(null, "@@@@");
|
|
debugServerConsoleMsg(null, "@@@@ calcSkillDesignAssemblyCheck: Base Roll = " + dieRoll);
|
|
debugServerConsoleMsg(null, "@@@@ calcSkillDesignAssemblyCheck: Complexity Mod = " + itemComplexitySkillMod);
|
|
debugServerConsoleMsg(null, "@@@@ calcSkillDesignAssemblyCheck: Malleability Mod = " + resourceMalleabilitySkillMod);
|
|
debugServerConsoleMsg(null, "@@@@ calcSkillDesignAssemblyCheck: Quality Mod = " + resourceQualitySkillMod);
|
|
debugServerConsoleMsg(null, "@@@@ calcSkillDesignAssemblyCheck: Station Mod = " + craftingStationMod);
|
|
debugServerConsoleMsg(null, "@@@@ calcSkillDesignAssemblyCheck: Skill Mod = " + playerSkillMod);
|
|
debugServerConsoleMsg(null, "@@@@ calcSkillDesignAssemblyCheck: Force Mod = " + forceSkillMod);
|
|
if (isPlayerQA)
|
|
{
|
|
sendSystemMessageTestingOnly(player, "CRAFTING ---------------------------------");
|
|
}
|
|
int city_id = city.checkCity(player, false);
|
|
if (city_id > 0 && (city.cityHasSpec(city_id, city.SF_SPEC_INDUSTRY) || city.cityHasSpec(city_id, city.SF_SPEC_MASTER_MANUFACTURING)))
|
|
{
|
|
dieRollMod += dieRoll * 1.1f;
|
|
sendSystemMessage(player, new string_id("city/city", "manufacturing_center_message"));
|
|
if (isPlayerQA)
|
|
{
|
|
sendSystemMessageTestingOnly(player, "CRAFTING -- 10% raw random bonus for industry city");
|
|
}
|
|
}
|
|
dieRollMod += getCraftingInspirationBonus(player, craftingValuesDictionary, dieRoll, 5f);
|
|
if (utils.hasScriptVar(player, "buff.dessert_pyollian_cake.value"))
|
|
{
|
|
int eff = (int)utils.getFloatScriptVar(player, "buff.dessert_pyollian_cake.value");
|
|
buff.removeBuff(player, "dessert_pyollian_cake");
|
|
dieRollMod += (eff * deltaMod);
|
|
if (isPlayerQA)
|
|
{
|
|
sendSystemMessageTestingOnly(player, "CRAFTING -- Food buff effect applied to raw random roll");
|
|
}
|
|
}
|
|
if (isPlayerQA)
|
|
{
|
|
sendSystemMessageTestingOnly(player, "CRAFTING -- Raw Random Roll = " + dieRoll);
|
|
sendSystemMessageTestingOnly(player, "CRAFTING --");
|
|
sendSystemMessageTestingOnly(player, "CRAFTING -- Item Complexity Mod = " + itemComplexitySkillMod);
|
|
sendSystemMessageTestingOnly(player, "CRAFTING -- Resource Malleability Mod = " + resourceMalleabilitySkillMod);
|
|
sendSystemMessageTestingOnly(player, "CRAFTING -- Resource Quality Mod = " + resourceQualitySkillMod);
|
|
sendSystemMessageTestingOnly(player, "CRAFTING -- Assembly Skill Mod = " + playerSkillMod);
|
|
sendSystemMessageTestingOnly(player, "CRAFTING -- Force Skill Mod = " + forceSkillMod);
|
|
sendSystemMessageTestingOnly(player, "CRAFTING -- Crafting Station Mod = " + craftingStationMod);
|
|
}
|
|
debugServerConsoleMsg(null, "@@@@");
|
|
float totalSkillMod = resourceMalleabilitySkillMod + resourceQualitySkillMod + playerSkillMod + forceSkillMod + craftingStationMod - itemComplexitySkillMod;
|
|
debugServerConsoleMsg(null, "@@@@ calcSkillDesignAssemblyCheck: Total Skill Mod = " + totalSkillMod);
|
|
debugServerConsoleMsg(null, "@@@@ calcSkillDesignAssemblyCheck: Delta = " + deltaMod);
|
|
if (isPlayerQA)
|
|
{
|
|
sendSystemMessageTestingOnly(player, "CRAFTING -- Sum of Roll Modifiers = " + totalSkillMod);
|
|
sendSystemMessageTestingOnly(player, "CRAFTING --");
|
|
sendSystemMessageTestingOnly(player, "CRAFTING -- Modifier Balance Multiplier = " + deltaMod);
|
|
sendSystemMessageTestingOnly(player, "CRAFTING --");
|
|
}
|
|
totalSkillMod *= deltaMod;
|
|
debugServerConsoleMsg(null, "@@@@ calcSkillDesignAssemblyCheck: Adjusted Skill Mod = " + totalSkillMod);
|
|
if (isPlayerQA)
|
|
{
|
|
sendSystemMessageTestingOnly(player, "CRAFTING -- Balanced Roll Modifiers = " + totalSkillMod);
|
|
}
|
|
float modifiedDieRoll = dieRoll + totalSkillMod + dieRollMod;
|
|
debugServerConsoleMsg(null, "@@@@ calcSkillDesignAssemblyCheck: Total Roll = " + modifiedDieRoll);
|
|
if (isPlayerQA)
|
|
{
|
|
sendSystemMessageTestingOnly(player, "CRAFTING -- FINAL MODIFIED ROLL = " + modifiedDieRoll);
|
|
}
|
|
float criticalAdjust = playerSkillMod / 4000.0f;
|
|
if (criticalAdjust > 0.05f)
|
|
{
|
|
criticalAdjust = 0.05f;
|
|
}
|
|
float criticalSuccess = NUMERIC_RANGE_EXPRESSION * (0.95f - criticalAdjust);
|
|
float criticalFailure = NUMERIC_RANGE_EXPRESSION * (0.05f - criticalAdjust);
|
|
float skillMod = getEnhancedSkillStatisticModifier(player, "force_failure_reduction");
|
|
skillMod *= 0.005f;
|
|
criticalFailure -= skillMod;
|
|
if (craftingValuesDictionary.containsKey(OBJVAR_REFACTOR))
|
|
{
|
|
criticalSuccess = NUMERIC_RANGE_EXPRESSION + 1;
|
|
criticalFailure = dieRoll - 1;
|
|
}
|
|
else if (hasObjVar(getSelf(), OBJVAR_NO_CRIT_FAIL))
|
|
{
|
|
debugServerConsoleMsg(null, "Schematic is no crit fail, ain't that nice?");
|
|
criticalFailure = dieRoll - 1;
|
|
}
|
|
final float BASE_DIFFICULTY_ADJUSTMENT = 0.25f;
|
|
float defaultSkillCheckDifficulty = NUMERIC_RANGE_EXPRESSION * BASE_DIFFICULTY_ADJUSTMENT;
|
|
float greatSuccess = defaultSkillCheckDifficulty + NUMERIC_RANGE_EXPRESSION * 0.45f;
|
|
float goodSuccess = defaultSkillCheckDifficulty + NUMERIC_RANGE_EXPRESSION * 0.30f;
|
|
float moderateSuccess = defaultSkillCheckDifficulty + NUMERIC_RANGE_EXPRESSION * 0.15f;
|
|
float moderateFailure = defaultSkillCheckDifficulty - NUMERIC_RANGE_EXPRESSION * 0.15f;
|
|
float bigFailure = defaultSkillCheckDifficulty - NUMERIC_RANGE_EXPRESSION * 0.30f;
|
|
debugServerConsoleMsg(null, "@@@@");
|
|
debugServerConsoleMsg(null, "@@@@");
|
|
debugServerConsoleMsg(null, "@@@@ calcSkillDesignAssemblyCheck: Critical Success = " + criticalSuccess);
|
|
debugServerConsoleMsg(null, "@@@@ calcSkillDesignAssemblyCheck: Critical Failure = " + criticalFailure);
|
|
debugServerConsoleMsg(null, "@@@@");
|
|
debugServerConsoleMsg(null, "@@@@ calcSkillDesignAssemblyCheck: Great Success = " + greatSuccess);
|
|
debugServerConsoleMsg(null, "@@@@ calcSkillDesignAssemblyCheck: Good Success = " + goodSuccess);
|
|
debugServerConsoleMsg(null, "@@@@ calcSkillDesignAssemblyCheck: Moderate Success = " + moderateSuccess);
|
|
debugServerConsoleMsg(null, "@@@@ calcSkillDesignAssemblyCheck: Success = " + defaultSkillCheckDifficulty);
|
|
debugServerConsoleMsg(null, "@@@@ calcSkillDesignAssemblyCheck: Failure = " + moderateFailure);
|
|
debugServerConsoleMsg(null, "@@@@ calcSkillDesignAssemblyCheck: Big Failure = " + bigFailure);
|
|
debugServerConsoleMsg(null, "@@@@");
|
|
debugServerConsoleMsg(null, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
|
|
if (isPlayerQA)
|
|
{
|
|
sendSystemMessageTestingOnly(player, "CRAFTING --");
|
|
sendSystemMessageTestingOnly(player, "CRAFTING -- Critical Success: raw roll above " + criticalSuccess);
|
|
sendSystemMessageTestingOnly(player, "CRAFTING -- Critical Failure: raw roll below " + criticalFailure);
|
|
sendSystemMessageTestingOnly(player, "CRAFTING --");
|
|
sendSystemMessageTestingOnly(player, "CRAFTING -- Great Success: mod roll above " + greatSuccess);
|
|
sendSystemMessageTestingOnly(player, "CRAFTING -- Good Success: mod roll above " + goodSuccess);
|
|
sendSystemMessageTestingOnly(player, "CRAFTING -- Moderate Success: mod roll above " + moderateSuccess);
|
|
sendSystemMessageTestingOnly(player, "CRAFTING -- Success: mod roll above " + defaultSkillCheckDifficulty);
|
|
sendSystemMessageTestingOnly(player, "CRAFTING -- Failure: mod roll above " + moderateFailure);
|
|
sendSystemMessageTestingOnly(player, "CRAFTING -- Moderate Failure: mod roll above " + bigFailure);
|
|
sendSystemMessageTestingOnly(player, "CRAFTING -- Big Failure: mod roll below " + bigFailure);
|
|
}
|
|
if (isPlayerTester)
|
|
{
|
|
CustomerServiceLog("crit_fail", "== ASSEMBLY_BEGIN == " + getName(player) + " (" + player + ") is starting to assemble an item -- Base Roll: " + dieRoll + ", Mod Roll: " + modifiedDieRoll);
|
|
}
|
|
if (luck.isLucky(player, 0.01f))
|
|
{
|
|
successState = STATE_CRITICAL_SUCCESS;
|
|
}
|
|
else if (dieRoll >= criticalSuccess)
|
|
{
|
|
successState = STATE_CRITICAL_SUCCESS;
|
|
}
|
|
else if (modifiedDieRoll > greatSuccess)
|
|
{
|
|
successState = STATE_GREAT_SUCCESS;
|
|
}
|
|
else if (modifiedDieRoll > goodSuccess)
|
|
{
|
|
successState = STATE_GOOD_SUCCESS;
|
|
}
|
|
else if (modifiedDieRoll > moderateSuccess)
|
|
{
|
|
successState = STATE_MODERATE_SUCCESS;
|
|
}
|
|
else if (modifiedDieRoll > defaultSkillCheckDifficulty)
|
|
{
|
|
successState = STATE_SUCCESS;
|
|
}
|
|
else if (modifiedDieRoll > moderateFailure)
|
|
{
|
|
successState = STATE_FAILURE;
|
|
}
|
|
else if (modifiedDieRoll > bigFailure)
|
|
{
|
|
successState = STATE_MODERATE_FAILURE;
|
|
}
|
|
else
|
|
{
|
|
successState = STATE_BIG_FAILURE;
|
|
}
|
|
if (successState != STATE_CRITICAL_SUCCESS && craftingValuesDictionary.containsKey(OBJVAR_FORCE_CRITICAL_SUCCESS))
|
|
{
|
|
if (!craftingValuesDictionary.containsKey(OBJVAR_REFACTOR))
|
|
{
|
|
successState = STATE_CRITICAL_SUCCESS;
|
|
craftingValuesDictionary.put(OBJVAR_FORCE_CRITICAL_SUCCESS_RESULT, true);
|
|
}
|
|
}
|
|
craftingValuesDictionary.put("assemblySuccessState", successState);
|
|
if (isPlayerQA)
|
|
{
|
|
if (successState >= 0 && successState < STATE_NAMES.length)
|
|
{
|
|
sendSystemMessageTestingOnly(player, "CRAFTING --");
|
|
sendSystemMessageTestingOnly(player, "CRAFTING -- Success State: " + STATE_NAMES[successState]);
|
|
sendSystemMessageTestingOnly(player, "CRAFTING ---------------------------------");
|
|
}
|
|
}
|
|
if (successState >= 0 && successState < STATE_NAMES.length)
|
|
{
|
|
debugServerConsoleMsg(null, "calcSkillDesignAssemblyCheck: success state = " + successState + " (" + STATE_NAMES[successState] + ")");
|
|
}
|
|
else
|
|
{
|
|
debugServerConsoleMsg(null, "calcSkillDesignAssemblyCheck: success state = " + successState);
|
|
}
|
|
return successState;
|
|
}
|
|
public static float calcAssemblySuccessAttributeMultiplier(int assemblySuccessState, dictionary craftingValuesDictionary) throws InterruptedException
|
|
{
|
|
if (craftingValuesDictionary == null)
|
|
{
|
|
return 0;
|
|
}
|
|
float attributeMultiplier = 0;
|
|
switch (assemblySuccessState)
|
|
{
|
|
case craftinglib.STATE_CRITICAL_SUCCESS:
|
|
attributeMultiplier = 15;
|
|
float currentComplexityTemp = craftingValuesDictionary.getFloat("itemCurrentComplexity");
|
|
currentComplexityTemp -= 1.0f;
|
|
craftingValuesDictionary.put("itemCurrentComplexity", currentComplexityTemp);
|
|
break;
|
|
case craftinglib.STATE_CRITICAL_FAILURE:
|
|
case craftinglib.STATE_CRITICAL_FAILURE_NODESTROY:
|
|
attributeMultiplier = -4;
|
|
break;
|
|
case craftinglib.STATE_GREAT_SUCCESS:
|
|
attributeMultiplier = 15;
|
|
break;
|
|
case craftinglib.STATE_GOOD_SUCCESS:
|
|
attributeMultiplier = 10;
|
|
break;
|
|
case craftinglib.STATE_MODERATE_SUCCESS:
|
|
attributeMultiplier = 5;
|
|
break;
|
|
case craftinglib.STATE_SUCCESS:
|
|
attributeMultiplier = 1;
|
|
break;
|
|
case craftinglib.STATE_FAILURE:
|
|
attributeMultiplier = -1;
|
|
break;
|
|
case craftinglib.STATE_MODERATE_FAILURE:
|
|
attributeMultiplier = -2;
|
|
break;
|
|
case craftinglib.STATE_BIG_FAILURE:
|
|
attributeMultiplier = -3;
|
|
break;
|
|
default:
|
|
debugServerConsoleMsg(null, "Wacky assembly skill success-state detected. No attribute multiplier set");
|
|
attributeMultiplier = -5;
|
|
break;
|
|
}
|
|
debugServerConsoleMsg(null, "Crafting assembly skill check gave a " + assemblySuccessState + " result, for a " + attributeMultiplier + " success multiplier");
|
|
craftingValuesDictionary.put("assemblySuccessMultiplier", attributeMultiplier);
|
|
return attributeMultiplier;
|
|
}
|
|
public static void calcCraftingDesignStageIngredientAttribAverageValues(dictionary craftingValuesDictionary, draft_schematic.slot[] ingredientSlots) throws InterruptedException
|
|
{
|
|
if (craftingValuesDictionary == null || ingredientSlots == null)
|
|
{
|
|
return;
|
|
}
|
|
dictionary componentDictionary = new dictionary();
|
|
float[][] slotResourceAverage = new float[ingredientSlots.length][NUM_RESOURCE_ATTRIBS];
|
|
float[] totalResourceSum = new float[NUM_RESOURCE_ATTRIBS];
|
|
float[] resourceUnits = new float[NUM_RESOURCE_ATTRIBS];
|
|
for (int i = 0; i < ingredientSlots.length; i++)
|
|
{
|
|
if (ingredientSlots[i] == null)
|
|
{
|
|
continue;
|
|
}
|
|
obj_id ingredient = ingredientSlots[i].ingredients[0].ingredient;
|
|
int ingredientCount = ingredientSlots[i].ingredients[0].count;
|
|
switch (ingredientSlots[i].ingredientType)
|
|
{
|
|
case draft_schematic.IT_item:
|
|
case draft_schematic.IT_template:
|
|
case draft_schematic.IT_templateGeneric:
|
|
case draft_schematic.IT_schematic:
|
|
case draft_schematic.IT_schematicGeneric:
|
|
debugServerConsoleMsg(null, "getting components for object " + ingredient);
|
|
int itemGOT = getGameObjectType(ingredient);
|
|
if (itemGOT == GOT_resource_container_pseudo)
|
|
{
|
|
debugServerConsoleMsg(null, "got pseudo resource for slot " + ingredientSlots[i].name);
|
|
for (int j = 0; j < ingredientSlots[i].ingredients.length; ++j)
|
|
{
|
|
ingredient = ingredientSlots[i].ingredients[j].ingredient;
|
|
ingredientCount = ingredientSlots[i].ingredients[j].count;
|
|
for (int k = 0; k < NUM_RESOURCE_ATTRIBS; ++k)
|
|
{
|
|
String ovname = COMPONENT_ATTRIBUTE_OBJVAR_NAME + "." + RESOURCE_OBJVAR_NAMES[k];
|
|
if (hasObjVar(ingredient, ovname))
|
|
{
|
|
float resourceAttrib = getIntObjVar(ingredient, ovname);
|
|
totalResourceSum[k] += resourceAttrib * ingredientCount;
|
|
resourceUnits[k] += ingredientCount;
|
|
}
|
|
}
|
|
}
|
|
continue;
|
|
}
|
|
obj_var_list component_data = getObjVarList(getSelf(), COMPONENT_ATTRIBUTE_OBJVAR_NAME + "." + (ingredientSlots[i].name).getAsciiId());
|
|
if (component_data != null)
|
|
{
|
|
int dataCount = component_data.getNumItems();
|
|
debugServerConsoleMsg(null, "got component for slot " + ingredientSlots[i].name + ", count = " + dataCount);
|
|
for (int j = 0; j < dataCount; ++j)
|
|
{
|
|
obj_var ov = component_data.getObjVar(j);
|
|
if (ov != null)
|
|
{
|
|
Object data = ov.getData();
|
|
if (data instanceof Integer)
|
|
{
|
|
debugServerConsoleMsg(null, "\tsetting component attrib " + ov.getName() + " = " + ov.getIntData());
|
|
componentDictionary.put(ov.getName(), ov.getIntData());
|
|
}
|
|
else if (data instanceof Float)
|
|
{
|
|
debugServerConsoleMsg(null, "\tadding component attrib " + ov.getName() + " = " + ov.getFloatData());
|
|
componentDictionary.addFloat(ov.getName(), ov.getFloatData());
|
|
}
|
|
else if (data instanceof int[])
|
|
{
|
|
debugServerConsoleMsg(null, "\tsetting component attrib " + ov.getName() + " = " + ov.getIntArrayData());
|
|
componentDictionary.put(ov.getName(), ov.getIntArrayData());
|
|
}
|
|
else if (data instanceof float[])
|
|
{
|
|
debugServerConsoleMsg(null, "\tadding component attrib " + ov.getName() + " = " + ov.getFloatArrayData());
|
|
componentDictionary.addFloatArray(ov.getName(), ov.getFloatArrayData());
|
|
}
|
|
else if (data instanceof String)
|
|
{
|
|
debugServerConsoleMsg(null, "\tadding component attrib " + ov.getName() + " = " + ov.getStringData());
|
|
componentDictionary.put(ov.getName(), ov.getStringData());
|
|
}
|
|
else if (ov instanceof obj_var_list && (ov.getName()).equals(TISSUE_SKILL_MODS))
|
|
{
|
|
obj_var_list specialObjvars = (obj_var_list)ov;
|
|
int[] mod_idx = specialObjvars.getIntArrayObjVar(TISSUE_SKILL_INDEX);
|
|
int[] mod_val = specialObjvars.getIntArrayObjVar(TISSUE_SKILL_VALUE);
|
|
int[] dict_mod_idx = null;
|
|
int[] dict_mod_val = null;
|
|
dictionary specialDictionary = (dictionary)(componentDictionary.get(TISSUE_SKILL_MODS));
|
|
if (specialDictionary == null)
|
|
{
|
|
specialDictionary = new dictionary();
|
|
dict_mod_idx = new int[6];
|
|
dict_mod_val = new int[6];
|
|
}
|
|
else
|
|
{
|
|
dict_mod_idx = specialDictionary.getIntArray(TISSUE_SKILL_INDEX);
|
|
dict_mod_val = specialDictionary.getIntArray(TISSUE_SKILL_VALUE);
|
|
}
|
|
int count = mod_idx.length;
|
|
for (int k = 0; k < count; ++k)
|
|
{
|
|
for (int l = 0; l < dict_mod_idx.length; ++l)
|
|
{
|
|
if (dict_mod_idx[l] == mod_idx[k])
|
|
{
|
|
dict_mod_val[l] += mod_val[k];
|
|
debugServerConsoleMsg(null, "\tadding to existing skill mod: idx " + dict_mod_idx[l] + " = " + dict_mod_val[l]);
|
|
break;
|
|
}
|
|
else if (dict_mod_idx[l] == 0)
|
|
{
|
|
dict_mod_idx[l] = mod_idx[k];
|
|
dict_mod_val[l] = mod_val[k];
|
|
debugServerConsoleMsg(null, "\tadding new skill mod: idx " + dict_mod_idx[l] + " = " + dict_mod_val[l]);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
specialDictionary.put(TISSUE_SKILL_INDEX, dict_mod_idx);
|
|
specialDictionary.put(TISSUE_SKILL_VALUE, dict_mod_val);
|
|
componentDictionary.put(TISSUE_SKILL_MODS, specialDictionary);
|
|
}
|
|
else
|
|
{
|
|
debugServerConsoleMsg(null, "\tcomponent attrib " + ov.getName() + " has unknown data type " + data.getClass());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
LOG("crafting", "In Java craftinglib.scriptlib.calcCraftingDesignStageIngredientAttribAverageValues:" + " component object " + ingredient + " does not have the " + COMPONENT_ATTRIBUTE_OBJVAR_NAME + " objvar list attached to it");
|
|
}
|
|
break;
|
|
case draft_schematic.IT_resourceType:
|
|
case draft_schematic.IT_resourceClass:
|
|
if (ingredientSlots[i].ingredients.length > 1)
|
|
{
|
|
debugServerConsoleMsg(null, "ERROR! An amalgam/alloy was detected! Support for amalgams/alloys was ripped out!");
|
|
}
|
|
else
|
|
{
|
|
resource_attribute[] resourceAttribs = getScaledResourceAttributes(ingredient, ingredientSlots[i].ingredientName);
|
|
if (resourceAttribs != null)
|
|
{
|
|
for (int j = 0; j < resourceAttribs.length; ++j)
|
|
{
|
|
if (resourceAttribs[j] != null && resourceAttribs[j].getValue() != RESOURCE_NOT_USED)
|
|
{
|
|
for (int k = 0; k < RESOURCE_OBJVAR_NAMES.length; ++k)
|
|
{
|
|
if (RESOURCE_OBJVAR_NAMES[k].equals(resourceAttribs[j].getName()))
|
|
{
|
|
totalResourceSum[k] += resourceAttribs[j].getValue() * ingredientCount;
|
|
resourceUnits[k] += ingredientCount;
|
|
slotResourceAverage[i][k] = resourceAttribs[j].getValue();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
float[] itemTotalResourceAverage = new float[NUM_RESOURCE_ATTRIBS];
|
|
for (int i = 0; i < NUM_RESOURCE_ATTRIBS; ++i)
|
|
{
|
|
if (resourceUnits[i] != 0)
|
|
{
|
|
itemTotalResourceAverage[i] = totalResourceSum[i] / resourceUnits[i];
|
|
}
|
|
else
|
|
{
|
|
itemTotalResourceAverage[i] = 0;
|
|
}
|
|
debugServerConsoleMsg(null, "\t@@@@@craftinglib.scriptlib calcCraftingDesignStageIngredientAttribAverageValues, itemTotalResourceAverage unit [i]# " + i + ", value = " + itemTotalResourceAverage[i]);
|
|
}
|
|
craftingValuesDictionary.put(RESOURCE_AVERAGE_DICTIONARY_NAME, itemTotalResourceAverage);
|
|
craftingValuesDictionary.put(SLOT_RESOURCE_DICTIONARY_NAME, slotResourceAverage);
|
|
utils.saveDictionaryAsObjVar(getSelf(), COMPONENT_ATTRIBUTE_INTERNAL_OBJVAR_NAME, componentDictionary);
|
|
}
|
|
public static float getCraftingInspirationBonus(obj_id player, dictionary craftingValuesDictionary, float currentValue, float multiplier) throws InterruptedException
|
|
{
|
|
if (!isIdValid(player))
|
|
{
|
|
return 0f;
|
|
}
|
|
if (!utils.hasScriptVar(player, "buff.craftBonus.types"))
|
|
{
|
|
return 0f;
|
|
}
|
|
int flags = utils.getIntScriptVar(player, "buff.craftBonus.types");
|
|
int type = craftingValuesDictionary.getInt("craftingType");
|
|
if ((flags & type) > 0)
|
|
{
|
|
float mod = utils.getFloatScriptVar(player, "buff.craftBonus.value");
|
|
float bonus = currentValue * (multiplier * mod);
|
|
return bonus;
|
|
}
|
|
return 0f;
|
|
}
|
|
public static void calcResourceMaxItemAttributes(dictionary craftingValuesDictionary, draft_schematic.attribute[] itemAttributes, resource_weight[] weights) throws InterruptedException
|
|
{
|
|
calcResourceMaxItemAttributes(null, craftingValuesDictionary, itemAttributes, weights);
|
|
}
|
|
public static void calcResourceMaxItemAttributes(obj_id player, dictionary craftingValuesDictionary, draft_schematic.attribute[] itemAttributes, resource_weight[] weights) throws InterruptedException
|
|
{
|
|
float[] averageResourceValues = craftingValuesDictionary.getFloatArray(RESOURCE_AVERAGE_DICTIONARY_NAME);
|
|
float[][] slotResourceValues = (float[][])(craftingValuesDictionary.get(SLOT_RESOURCE_DICTIONARY_NAME));
|
|
for (int i = 0; i < itemAttributes.length; ++i)
|
|
{
|
|
if (itemAttributes[i] == null || itemAttributes[i].minValue == itemAttributes[i].maxValue)
|
|
{
|
|
continue;
|
|
}
|
|
if ((itemAttributes[i].name).equals("complexity"))
|
|
{
|
|
itemAttributes[i].currentValue = craftingValuesDictionary.getFloat("itemCurrentComplexity");
|
|
}
|
|
else if (weights != null)
|
|
{
|
|
float lowAttributeRangeValue = itemAttributes[i].minValue;
|
|
float highAttributeRangeValue = itemAttributes[i].maxValue;
|
|
float attributeValueRangeSize = highAttributeRangeValue - lowAttributeRangeValue;
|
|
float onePercentOfAttributeRange = attributeValueRangeSize / 100;
|
|
for (int j = 0; j < weights.length; ++j)
|
|
{
|
|
if ((itemAttributes[i].name).equals(weights[j].attribName))
|
|
{
|
|
debugServerConsoleMsg(null, "**** craftinglib.scriptlib attrib " + itemAttributes[i].name);
|
|
String onePercentName = (itemAttributes[i].name).getAsciiId() + "OnePercent";
|
|
float itemAttributeApplicableResourceValueAverage = 0;
|
|
if (weights[j].slot >= 0 && weights[j].slot < slotResourceValues.length)
|
|
{
|
|
itemAttributeApplicableResourceValueAverage = computeWeightedAverage(slotResourceValues[weights[j].slot], weights[j].weights) / 10.0f;
|
|
}
|
|
else
|
|
{
|
|
itemAttributeApplicableResourceValueAverage = computeWeightedAverage(averageResourceValues, weights[j].weights) / 10.0f;
|
|
}
|
|
if (isIdValid(player))
|
|
{
|
|
itemAttributeApplicableResourceValueAverage += getCraftingInspirationBonus(player, craftingValuesDictionary, itemAttributeApplicableResourceValueAverage, 1f);
|
|
itemAttributeApplicableResourceValueAverage += (int)getEnhancedSkillStatisticModifierUncapped(player, "expertise_resource_quality_increase");
|
|
if (itemAttributeApplicableResourceValueAverage > 100.0f)
|
|
{
|
|
itemAttributeApplicableResourceValueAverage = 100.0f;
|
|
}
|
|
}
|
|
if (itemAttributeApplicableResourceValueAverage < 1.0f)
|
|
{
|
|
itemAttributeApplicableResourceValueAverage = 1.0f;
|
|
}
|
|
float resourceMaxRange = onePercentOfAttributeRange * itemAttributeApplicableResourceValueAverage;
|
|
itemAttributes[i].resourceMaxValue = lowAttributeRangeValue + resourceMaxRange;
|
|
itemAttributes[i].currentValue = lowAttributeRangeValue;
|
|
craftingValuesDictionary.put(onePercentName, resourceMaxRange / 100.0f);
|
|
debugServerConsoleMsg(null, "**** craftinglib.scriptlib calcResourceMaxItemAttributes 1% = " + onePercentOfAttributeRange + ", average = " + itemAttributeApplicableResourceValueAverage + ", resourceMaxRange = " + resourceMaxRange + ", resourceMaxValue = " + itemAttributes[i].resourceMaxValue);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
itemAttributes[i].resourceMaxValue = itemAttributes[i].maxValue;
|
|
itemAttributes[i].currentValue = itemAttributes[i].minValue;
|
|
String onePercentName = (itemAttributes[i].name).getAsciiId() + "OnePercent";
|
|
float resourceMaxRange = itemAttributes[i].maxValue - itemAttributes[i].minValue;
|
|
craftingValuesDictionary.put(onePercentName, resourceMaxRange / 100.0f);
|
|
debugServerConsoleMsg(null, "**** craftinglib.scriptlib calcResourceMaxItemAttributes 1% (non-resource item) = " + (resourceMaxRange / 100.0f) + ", resourceMaxRange = " + resourceMaxRange + ", resourceMaxValue = " + itemAttributes[i].resourceMaxValue);
|
|
}
|
|
}
|
|
}
|
|
public static void calcPostAssemblyResourceSetAttribValues(dictionary craftingValuesDictionary, draft_schematic.attribute[] itemAttributes, resource_weight[] weights) throws InterruptedException
|
|
{
|
|
float[] averageResourceValues = craftingValuesDictionary.getFloatArray(RESOURCE_AVERAGE_DICTIONARY_NAME);
|
|
float[][] slotResourceValues = (float[][])(craftingValuesDictionary.get(SLOT_RESOURCE_DICTIONARY_NAME));
|
|
debugServerConsoleMsg(null, "Setting attribs for resources:");
|
|
for (int i = 0; i < itemAttributes.length; ++i)
|
|
{
|
|
if (itemAttributes[i] == null || itemAttributes[i].minValue == itemAttributes[i].maxValue)
|
|
{
|
|
continue;
|
|
}
|
|
if (!(itemAttributes[i].name).equals("complexity") && weights != null)
|
|
{
|
|
for (int j = 0; j < weights.length; ++j)
|
|
{
|
|
if ((itemAttributes[i].name).equals(weights[j].attribName))
|
|
{
|
|
float onePercentOfPossibleAttribute = craftingValuesDictionary.getFloat(weights[j].attribName + "OnePercent");
|
|
float averagedAttributeSum = 0;
|
|
if (weights[j].slot >= 0 && weights[j].slot < slotResourceValues.length)
|
|
{
|
|
averagedAttributeSum = computeWeightedAverage(slotResourceValues[weights[j].slot], weights[j].weights);
|
|
}
|
|
else
|
|
{
|
|
averagedAttributeSum = computeWeightedAverage(averageResourceValues, weights[j].weights);
|
|
}
|
|
float resourceContribution = averagedAttributeSum * (15.0f / 1000.0f);
|
|
if (resourceContribution < 1.0f)
|
|
{
|
|
resourceContribution = 1.0f;
|
|
}
|
|
float attributeResourceValue = onePercentOfPossibleAttribute * resourceContribution;
|
|
itemAttributes[i].currentValue += attributeResourceValue;
|
|
debugServerConsoleMsg(null, "\t" + itemAttributes[i].name + " += " + attributeResourceValue);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
public static void calcPostSkillAssemblyCheckSetAttribValues(dictionary craftingValuesDictionary, draft_schematic.attribute[] itemAttributes) throws InterruptedException
|
|
{
|
|
if (craftingValuesDictionary == null || itemAttributes == null)
|
|
{
|
|
return;
|
|
}
|
|
int assemblySuccessState = craftingValuesDictionary.getInt("assemblySuccessState");
|
|
float assemblySuccessStateMultiplier = calcAssemblySuccessAttributeMultiplier(assemblySuccessState, craftingValuesDictionary);
|
|
if (assemblySuccessStateMultiplier < 0)
|
|
{
|
|
return;
|
|
}
|
|
debugServerConsoleMsg(null, "Setting attribs for assembly success:");
|
|
for (int i = 0; i < itemAttributes.length; ++i)
|
|
{
|
|
if (itemAttributes[i] == null || itemAttributes[i].minValue == itemAttributes[i].maxValue)
|
|
{
|
|
continue;
|
|
}
|
|
if ((itemAttributes[i].name).equals("complexity"))
|
|
{
|
|
itemAttributes[i].currentValue = craftingValuesDictionary.getFloat("itemCurrentComplexity");
|
|
debugServerConsoleMsg(null, "\t" + itemAttributes[i].name + " = " + itemAttributes[i].currentValue);
|
|
}
|
|
else if (!(itemAttributes[i].name).equals("armorSpecialType"))
|
|
{
|
|
float onePercentOfPossibleAttribute = craftingValuesDictionary.getFloat((itemAttributes[i].name).getAsciiId() + "OnePercent");
|
|
float attributePostSkillAssemblyValue = onePercentOfPossibleAttribute * assemblySuccessStateMultiplier;
|
|
itemAttributes[i].currentValue += attributePostSkillAssemblyValue;
|
|
debugServerConsoleMsg(null, "\t" + itemAttributes[i].name + " += " + attributePostSkillAssemblyValue);
|
|
}
|
|
}
|
|
}
|
|
public static int calcAssemblyPhaseAttributes(obj_id player, draft_schematic.slot[] itemIngredients, draft_schematic.attribute[] itemAttributes, dictionary craftingValuesDictionary, String[] playerSkillMods, resource_weight[] maxResourceAttribWeights, resource_weight[] resourceAttribWeights) throws InterruptedException
|
|
{
|
|
debugServerConsoleMsg(null, "Beginning assembly-phase attribute resolution");
|
|
calcCraftingDesignStageIngredientAttribAverageValues(craftingValuesDictionary, itemIngredients);
|
|
int success = calcSkillDesignAssemblyCheck(player, craftingValuesDictionary, playerSkillMods);
|
|
if (success == STATE_CRITICAL_FAILURE || success == STATE_CRITICAL_FAILURE_NODESTROY)
|
|
{
|
|
return success;
|
|
}
|
|
calcResourceMaxItemAttributes(player, craftingValuesDictionary, itemAttributes, maxResourceAttribWeights);
|
|
calcPostAssemblyResourceSetAttribValues(craftingValuesDictionary, itemAttributes, resourceAttribWeights);
|
|
calcPostSkillAssemblyCheckSetAttribValues(craftingValuesDictionary, itemAttributes);
|
|
float complexity = 0;
|
|
draft_schematic.attribute xpAttrib = null;
|
|
for (int i = 0; i < itemAttributes.length; ++i)
|
|
{
|
|
if (itemAttributes[i] == null)
|
|
{
|
|
continue;
|
|
}
|
|
if ((itemAttributes[i].name).equals("complexity"))
|
|
{
|
|
complexity = itemAttributes[i].currentValue;
|
|
}
|
|
else if ((itemAttributes[i].name).equals("xp"))
|
|
{
|
|
xpAttrib = itemAttributes[i];
|
|
}
|
|
}
|
|
if (xpAttrib != null)
|
|
{
|
|
float numSlotsFilled = 0;
|
|
if (itemIngredients != null)
|
|
{
|
|
numSlotsFilled = itemIngredients.length;
|
|
}
|
|
xpAttrib.currentValue = xpAttrib.minValue;
|
|
debugServerConsoleMsg(null, "craftinglib.scriptlib calcAssemblyPhaseAttributes complexity = " + complexity + ", slots filled = " + numSlotsFilled + ", xp = " + xpAttrib.currentValue);
|
|
}
|
|
else
|
|
{
|
|
debugServerConsoleMsg(null, "craftinglib.scriptlib calcAssemblyPhaseAttributes no xp attrib defined!");
|
|
}
|
|
return success;
|
|
}
|
|
public static void calcExperimentalAttribs(draft_schematic schematic) throws InterruptedException
|
|
{
|
|
debugServerConsoleMsg(null, "craftinglib.scriptlib calcExperimentalAttribs enter");
|
|
if (schematic == null)
|
|
{
|
|
debugServerConsoleMsg(null, "craftinglib.scriptlib calcExperimentalAttribs error - no schematic");
|
|
return;
|
|
}
|
|
draft_schematic.attribute[] objectAttribs = schematic.getAttribs();
|
|
draft_schematic.attribute[] experimentalAttribs = schematic.getExperimentalAttribs();
|
|
if (objectAttribs == null || experimentalAttribs == null)
|
|
{
|
|
debugServerConsoleMsg(null, "craftinglib.scriptlib calcExperimentalAttribs error - no attribs");
|
|
return;
|
|
}
|
|
for (int i = 0; i < experimentalAttribs.length; ++i)
|
|
{
|
|
experimentalAttribs[i].minValue = 0;
|
|
experimentalAttribs[i].maxValue = 1.0f;
|
|
experimentalAttribs[i].resourceMaxValue = 0;
|
|
experimentalAttribs[i].currentValue = 0;
|
|
experimentalAttribs[i].scratch = 0;
|
|
}
|
|
for (int i = 0; i < objectAttribs.length; ++i)
|
|
{
|
|
if (objectAttribs[i] == null)
|
|
{
|
|
continue;
|
|
}
|
|
debugServerConsoleMsg(null, "object attrib " + objectAttribs[i].name + ", min = " + objectAttribs[i].minValue + ", resourceMax = " + objectAttribs[i].resourceMaxValue + ", max = " + objectAttribs[i].maxValue + ", current = " + objectAttribs[i].currentValue);
|
|
draft_schematic.attribute expAttr = schematic.getExperimentalAttrib(objectAttribs[i]);
|
|
if (expAttr != null)
|
|
{
|
|
debugServerConsoleMsg(null, "Got matching experiment attrib " + expAttr.name);
|
|
float denom = objectAttribs[i].maxValue - objectAttribs[i].minValue;
|
|
if (denom != 0)
|
|
{
|
|
expAttr.resourceMaxValue += (objectAttribs[i].resourceMaxValue - objectAttribs[i].minValue) / denom;
|
|
expAttr.currentValue += (objectAttribs[i].currentValue - objectAttribs[i].minValue) / denom;
|
|
}
|
|
++expAttr.scratch;
|
|
}
|
|
}
|
|
for (int i = 0; i < experimentalAttribs.length; ++i)
|
|
{
|
|
if (experimentalAttribs[i].scratch > 0)
|
|
{
|
|
experimentalAttribs[i].resourceMaxValue /= experimentalAttribs[i].scratch;
|
|
experimentalAttribs[i].currentValue /= experimentalAttribs[i].scratch;
|
|
debugServerConsoleMsg(null, "experiment attrib " + experimentalAttribs[i].name + ", min = " + experimentalAttribs[i].minValue + ", resourceMax = " + experimentalAttribs[i].resourceMaxValue + ", max = " + experimentalAttribs[i].maxValue + ", current = " + experimentalAttribs[i].currentValue);
|
|
}
|
|
}
|
|
debugServerConsoleMsg(null, "craftinglib.scriptlib calcExperimentalAttribs exit");
|
|
}
|
|
public static float[] convertExperimentalPointsToObjectPoints(draft_schematic schematic, string_id[] attributeNames, int[] experimentPoints) throws InterruptedException
|
|
{
|
|
debugServerConsoleMsg(null, "craftinglib::convertExperimentalPointsToObjectPoints enter");
|
|
if (schematic == null || attributeNames == null || attributeNames.length == 0 || experimentPoints == null || experimentPoints.length == 0 || attributeNames.length != experimentPoints.length)
|
|
{
|
|
debugServerConsoleMsg(null, "convertExperimentalPointsToObjectPoints BAD INPUT");
|
|
return null;
|
|
}
|
|
draft_schematic.attribute[] objectAttribs = schematic.getAttribs();
|
|
draft_schematic.attribute[] experimentalAttribs = schematic.getExperimentalAttribs();
|
|
if (objectAttribs == null || objectAttribs.length == 0 || experimentalAttribs == null || experimentalAttribs.length != experimentPoints.length)
|
|
{
|
|
debugServerConsoleMsg(null, "convertExperimentalPointsToObjectPoints NO ATTRIBS");
|
|
return null;
|
|
}
|
|
for (int i = 0; i < objectAttribs.length; ++i)
|
|
{
|
|
if (objectAttribs[i] != null)
|
|
{
|
|
debugServerConsoleMsg(null, "object attrib " + objectAttribs[i].name + " = " + objectAttribs[i].currentValue);
|
|
}
|
|
}
|
|
for (int i = 0; i < experimentalAttribs.length; ++i)
|
|
{
|
|
if (experimentalAttribs[i] != null)
|
|
{
|
|
debugServerConsoleMsg(null, "exp attrib " + experimentalAttribs[i].name + " = " + experimentalAttribs[i].currentValue);
|
|
}
|
|
}
|
|
float[] objectPoints = new float[objectAttribs.length];
|
|
float[] adjustedObjectAttribs = new float[objectAttribs.length];
|
|
for (int i = 0; i < objectAttribs.length; ++i)
|
|
{
|
|
if (objectAttribs[i] != null)
|
|
{
|
|
objectAttribs[i].scratch = i;
|
|
float denom = objectAttribs[i].maxValue - objectAttribs[i].minValue;
|
|
if (denom != 0)
|
|
{
|
|
adjustedObjectAttribs[i] = (objectAttribs[i].currentValue - objectAttribs[i].minValue) / denom;
|
|
}
|
|
}
|
|
}
|
|
for (int i = 0; i < attributeNames.length; ++i)
|
|
{
|
|
int experimentalAttribIndex = -1;
|
|
for (int j = 0; j < experimentalAttribs.length; ++j)
|
|
{
|
|
if (attributeNames[i].equals(experimentalAttribs[j].name))
|
|
{
|
|
experimentalAttribIndex = j;
|
|
break;
|
|
}
|
|
}
|
|
if (experimentalAttribIndex == -1)
|
|
{
|
|
debugServerConsoleMsg(null, "convertExperimentalPointsToObjectPoints NO EXP ATTRIB");
|
|
return null;
|
|
}
|
|
int attribCount = 0;
|
|
draft_schematic.attribute[] objExpAttribs = schematic.getObjectAttribs(experimentalAttribs[experimentalAttribIndex]);
|
|
if (objExpAttribs != null)
|
|
{
|
|
for (int j = 0; j < objExpAttribs.length; ++j)
|
|
{
|
|
if (objExpAttribs[j] == null)
|
|
{
|
|
continue;
|
|
}
|
|
schematic.setExperimentalAttrib(objExpAttribs[j], experimentalAttribs[experimentalAttribIndex]);
|
|
debugServerConsoleMsg(null, "convertExperimentalPointsToObjectPoints attrib " + objectAttribs[objExpAttribs[j].scratch].name);
|
|
debugServerConsoleMsg(null, "\texp attrib value = " + experimentalAttribs[experimentalAttribIndex].currentValue + ", real attrib value = " + objExpAttribs[j].currentValue + ", adjusted real value = " + adjustedObjectAttribs[objExpAttribs[j].scratch]);
|
|
if (experimentalAttribs[experimentalAttribIndex].currentValue != 0)
|
|
{
|
|
float numer = experimentalAttribs[experimentalAttribIndex].currentValue - adjustedObjectAttribs[objExpAttribs[j].scratch];
|
|
float ratio = numer / experimentalAttribs[experimentalAttribIndex].currentValue;
|
|
objectPoints[objExpAttribs[j].scratch] = experimentPoints[i] * (1.0f + ratio);
|
|
if (objectPoints[objExpAttribs[j].scratch] < 0)
|
|
{
|
|
objectPoints[objExpAttribs[j].scratch] = 0;
|
|
}
|
|
debugServerConsoleMsg(null, "\tnumer = " + numer + ", ratio = " + ratio + ", exp points = " + objectPoints[objExpAttribs[j].scratch]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
debugServerConsoleMsg(null, "convertExperimentalPointsToObjectPoints EXIT OK!");
|
|
return objectPoints;
|
|
}
|
|
public static int calcExperimentPoints(obj_id player, String[] skillMods) throws InterruptedException
|
|
{
|
|
int[] mods = getEnhancedSkillStatisticModifiers(player, skillMods);
|
|
int totalMod = 0;
|
|
if (mods != null)
|
|
{
|
|
for (int i = 0; i < mods.length; ++i)
|
|
{
|
|
totalMod += mods[i];
|
|
}
|
|
}
|
|
totalMod /= 10;
|
|
if (totalMod < 1)
|
|
{
|
|
totalMod = 1;
|
|
}
|
|
return totalMod;
|
|
}
|
|
public static void calcExpFullSinglePointValue(dictionary craftingValuesDictionary, draft_schematic.attribute[] itemAttributes) throws InterruptedException
|
|
{
|
|
for (int i = 0; i < itemAttributes.length; ++i)
|
|
{
|
|
if (itemAttributes[i] == null)
|
|
{
|
|
continue;
|
|
}
|
|
if (!(itemAttributes[i].name).equals("complexity"))
|
|
{
|
|
float onePercent = (itemAttributes[i].maxValue - itemAttributes[i].minValue) / 100.0f;
|
|
float experimentationRange = onePercent * 70.0f;
|
|
float oneExperimentPoint = experimentationRange * 0.1f;
|
|
craftingValuesDictionary.put((itemAttributes[i].name).getAsciiId() + "TenPercent", oneExperimentPoint);
|
|
debugServerConsoleMsg(null, "craftinglib.calcExpFullSinglePointValue: " + (itemAttributes[i].name).getAsciiId() + "TenPercent = " + oneExperimentPoint);
|
|
}
|
|
}
|
|
}
|
|
public static void calcPerExperimentationCheckMod(obj_id player, dictionary craftingValuesDictionary, int experimentPointCount, draft_schematic.attribute[] itemAttributes, String[] skills) throws InterruptedException
|
|
{
|
|
int numExperimentedAttributes = experimentPointCount;
|
|
float numAttributesExperimentedMod = 0;
|
|
float complexityModifier = 0;
|
|
float skillModifier = 0;
|
|
for (int i = 0; i < itemAttributes.length; ++i)
|
|
{
|
|
if (itemAttributes[i] == null)
|
|
{
|
|
continue;
|
|
}
|
|
if ((itemAttributes[i].name).equals("complexity"))
|
|
{
|
|
complexityModifier = 5.0f * (itemAttributes[i].currentValue - itemAttributes[i].minValue) / COMPLEXITY_INCREMENT_MOD;
|
|
break;
|
|
}
|
|
}
|
|
debugServerConsoleMsg(null, "craftinglib::calcPerExperimentationCheckMod - complexityModifier = " + complexityModifier);
|
|
if (numExperimentedAttributes > 1)
|
|
{
|
|
numAttributesExperimentedMod = (numExperimentedAttributes - 1) * 5.0f;
|
|
}
|
|
debugServerConsoleMsg(null, "craftinglib::calcPerExperimentationCheckMod - numAttributesExperimentedMod = " + numAttributesExperimentedMod);
|
|
float craftingStationMod = 0;
|
|
obj_id stationId = getCraftingStation(player);
|
|
if (!isIdValid(stationId))
|
|
{
|
|
stationId = getSelf();
|
|
}
|
|
if (hasObjVar(stationId, OBJVAR_CRAFTING_STATION_BONUS) == true)
|
|
{
|
|
// Cekis: not sure why a float divided by an int is desired here (was just 10), so changing the int to a float
|
|
// as the former would have resulted in potential loss in precision.
|
|
craftingStationMod = getFloatObjVar(stationId, OBJVAR_CRAFTING_STATION_BONUS) / 10.0f;
|
|
}
|
|
debugServerConsoleMsg(null, "craftinglib::calcPerExperimentationCheckMod - craftingStationMod = " + craftingStationMod);
|
|
float playerSkillMod = 0;
|
|
if (skills != null)
|
|
{
|
|
int[] mods = getEnhancedSkillStatisticModifiers(player, skills);
|
|
if (mods != null)
|
|
{
|
|
for (int i = 0; i < mods.length; ++i)
|
|
{
|
|
playerSkillMod += mods[i];
|
|
}
|
|
}
|
|
}
|
|
debugServerConsoleMsg(null, "craftinglib::calcPerExperimentationCheckMod - playerSkillMod = " + playerSkillMod);
|
|
float malleabilitySkillMod = craftingValuesDictionary.getFloat(RESOURCE_MALLEABILITY_SKILL_MOD);
|
|
debugServerConsoleMsg(null, "craftinglib::calcPerExperimentationCheckMod - malleabilitySkillMod = " + malleabilitySkillMod);
|
|
float totalExperimentPointModifier = playerSkillMod + malleabilitySkillMod + craftingStationMod - complexityModifier - numAttributesExperimentedMod;
|
|
debugServerConsoleMsg(null, "craftinglib::calcPerExperimentationCheckMod - total mod = " + totalExperimentPointModifier);
|
|
craftingValuesDictionary.put("totalExperimentPointModifier", totalExperimentPointModifier);
|
|
craftingValuesDictionary.put("playerExperimentSkillMod", playerSkillMod);
|
|
craftingValuesDictionary.put("expItemComplexitySkillMod", complexityModifier);
|
|
craftingValuesDictionary.put("expCraftingStationMod", craftingStationMod);
|
|
craftingValuesDictionary.put("expNumAttributesExperimentMod", numAttributesExperimentedMod);
|
|
}
|
|
public static void calcSuccessPerAttributeExperimentation(dictionary craftingValuesDictionary, float[] experimentPoints, draft_schematic.attribute[] itemAttributes, obj_id player, String[] craftingSkills) throws InterruptedException
|
|
{
|
|
debugServerConsoleMsg(null, "calcSuccessPerAttributeExperimentation enter");
|
|
boolean isPlayerQA = false;
|
|
boolean isPlayerTester = false;
|
|
if (hasObjVar(player, "crafting_qa"))
|
|
{
|
|
isPlayerQA = true;
|
|
}
|
|
if (hasObjVar(player, "crafting_tester"))
|
|
{
|
|
isPlayerTester = true;
|
|
}
|
|
float totalExperimentPointModifier = craftingValuesDictionary.getFloat("totalExperimentPointModifier");
|
|
float playerSkillMod = craftingValuesDictionary.getFloat("playerExperimentSkillMod");
|
|
float complexityModifier = craftingValuesDictionary.getFloat("expItemComplexitySkillMod");
|
|
float craftingStationMod = craftingValuesDictionary.getFloat("expCraftingStationMod");
|
|
float numAttributesExperimentedMod = craftingValuesDictionary.getFloat("expNumAttributesExperimentMod");
|
|
float malleabilitySkillMod = craftingValuesDictionary.getFloat(RESOURCE_MALLEABILITY_SKILL_MOD);
|
|
final float deltaMod = NUMERIC_RANGE_EXPRESSION / BASE_RANGE;
|
|
if (isPlayerQA)
|
|
{
|
|
sendSystemMessageTestingOnly(player, " ");
|
|
sendSystemMessageTestingOnly(player, "EXPERIMENT ---------------------------------");
|
|
sendSystemMessageTestingOnly(player, "EXPERIMENT -- Experimentation Skill Mod = " + playerSkillMod);
|
|
sendSystemMessageTestingOnly(player, "EXPERIMENT -- Resource Malleability Mod = " + malleabilitySkillMod);
|
|
sendSystemMessageTestingOnly(player, "EXPERIMENT -- Crafting Station Mod = " + craftingStationMod);
|
|
sendSystemMessageTestingOnly(player, "EXPERIMENT -- Item Complexity Mod = " + (-1f * complexityModifier));
|
|
sendSystemMessageTestingOnly(player, "EXPERIMENT -- Attributes Mod = " + (-1f * numAttributesExperimentedMod));
|
|
sendSystemMessageTestingOnly(player, "EXPERIMENT -- Sum of Roll Modifiers = " + totalExperimentPointModifier);
|
|
sendSystemMessageTestingOnly(player, "EXPERIMENT --");
|
|
sendSystemMessageTestingOnly(player, "EXPERIMENT -- Modifier Balance Multiplier = " + deltaMod);
|
|
sendSystemMessageTestingOnly(player, "EXPERIMENT --");
|
|
}
|
|
float numericRangeModifiedTargetNumberModifier = totalExperimentPointModifier;
|
|
numericRangeModifiedTargetNumberModifier *= deltaMod;
|
|
if (isPlayerQA)
|
|
{
|
|
sendSystemMessageTestingOnly(player, "EXPERIMENT -- Balanced Roll Modifiers = " + numericRangeModifiedTargetNumberModifier);
|
|
sendSystemMessageTestingOnly(player, "EXPERIMENT --");
|
|
}
|
|
int averageSuccessState = 0;
|
|
int averageSuccessStateCount = 0;
|
|
float critical_s = 0.0f;
|
|
float great_s = 0.0f;
|
|
float good_s = 0.0f;
|
|
float moderate_s = 0.0f;
|
|
float s = 0.0f;
|
|
float moderate_f = 0.0f;
|
|
float big_f = 0.0f;
|
|
float critical_f = 0.0f;
|
|
if (isPlayerTester)
|
|
{
|
|
CustomerServiceLog("crit_fail", "== EXPERIMENTATION_BEGIN == " + getName(player) + " (" + player + ") is starting to experiment on an item");
|
|
}
|
|
float cityRollAdjust = 1.0f;
|
|
int city_id = city.checkCity(player, false);
|
|
if (city_id > 0 && (city.cityHasSpec(city_id, city.SF_SPEC_RESEARCH) || city.cityHasSpec(city_id, city.SF_SPEC_MASTER_MANUFACTURING)))
|
|
{
|
|
cityRollAdjust = 1.15f;
|
|
sendSystemMessage(player, new string_id("city/city", "research_center_message"));
|
|
if (isPlayerQA)
|
|
{
|
|
sendSystemMessageTestingOnly(player, "EXPERIMENT -- 15% raw random bonus for research city");
|
|
}
|
|
}
|
|
debugServerConsoleMsg(null, "craftinglib::calcSuccessPerAttributeExperimentation city adjustment = " + cityRollAdjust);
|
|
float foodRollAdjust = 0;
|
|
if (utils.hasScriptVar(player, "buff.drink_bespin_port.value"))
|
|
{
|
|
int eff = (int)utils.getFloatScriptVar(player, "buff.drink_bespin_port.value");
|
|
buff.removeBuff(player, "drink_bespin_port");
|
|
foodRollAdjust = eff * deltaMod;
|
|
if (isPlayerQA)
|
|
{
|
|
sendSystemMessageTestingOnly(player, "EXPERIMENT -- Food buff effect applied to raw random rolls");
|
|
}
|
|
}
|
|
debugServerConsoleMsg(null, "craftinglib::calcSuccessPerAttributeExperimentation food adjustment = " + foodRollAdjust);
|
|
float forceRollAdjust = 0;
|
|
|
|
{
|
|
int forceBonus = getSkillStatisticModifier(player, "force_experimentation");
|
|
forceRollAdjust = forceBonus * deltaMod;
|
|
if (isPlayerQA)
|
|
{
|
|
sendSystemMessageTestingOnly(player, "EXPERIMENT -- Force Experimentation bonus applied to raw random rolls");
|
|
}
|
|
}
|
|
debugServerConsoleMsg(null, "craftinglib::calcSuccessPerAttributeExperimentation force adjustment = " + forceRollAdjust);
|
|
String expertiseSkill = getCraftingSubskill(craftingSkills);
|
|
float expertiseRollAdjust = 0;
|
|
|
|
{
|
|
int expertiseBonus = getSkillStatisticModifier(player, "expertise_experimentation_increase_" + expertiseSkill);
|
|
expertiseRollAdjust = expertiseBonus * deltaMod;
|
|
if (isPlayerQA)
|
|
{
|
|
sendSystemMessageTestingOnly(player, "EXPERIMENT -- Expertise Experimentation bonus applied to raw random rolls: " + expertiseRollAdjust + " expertiseSkill: " + expertiseSkill);
|
|
}
|
|
}
|
|
for (int i = 0; i < itemAttributes.length; ++i)
|
|
{
|
|
if (itemAttributes[i] == null)
|
|
{
|
|
continue;
|
|
}
|
|
int successState = STATE_UNSET;
|
|
if (!(itemAttributes[i].name).equals("complexity") && experimentPoints[i] > 0)
|
|
{
|
|
float baseRoll = rand(1, (int)NUMERIC_RANGE_EXPRESSION);
|
|
float dieRoll = baseRoll * cityRollAdjust;
|
|
dieRoll += getCraftingInspirationBonus(player, craftingValuesDictionary, baseRoll, 5f);
|
|
dieRoll += foodRollAdjust;
|
|
dieRoll += forceRollAdjust;
|
|
dieRoll += expertiseRollAdjust;
|
|
debugServerConsoleMsg(null, "craftinglib::calcSuccessPerAttributeExperimentation - base roll for attrib " + itemAttributes[i].name + " (" + itemAttributes[i].currentValue + ") = " + baseRoll + ", adjusted roll = " + dieRoll);
|
|
float successAdjust = playerSkillMod / 4000.0f;
|
|
float successThreshold = 5.0f * ((10.0f + experimentPoints[i]) * (1 - successAdjust)) * deltaMod;
|
|
float modifiedSkillRoll = dieRoll + numericRangeModifiedTargetNumberModifier;
|
|
debugServerConsoleMsg(null, "\texpPts = " + experimentPoints[i] + ", success threshold = " + successThreshold + ", mod roll = " + modifiedSkillRoll);
|
|
float moderateSuccess = successThreshold * 1.15f;
|
|
float goodSuccess = successThreshold * 1.30f;
|
|
float greatSuccess = successThreshold * 1.45f;
|
|
float moderateFailure = successThreshold * 0.85f;
|
|
float bigFailure = successThreshold * 0.70f;
|
|
float criticalSuccess = NUMERIC_RANGE_EXPRESSION * (0.95f - successAdjust);
|
|
float criticalFailure = NUMERIC_RANGE_EXPRESSION * (0.05f - successAdjust);
|
|
if (craftingValuesDictionary.containsKey(OBJVAR_REFACTOR))
|
|
{
|
|
criticalSuccess = NUMERIC_RANGE_EXPRESSION + 1;
|
|
criticalFailure = dieRoll - 1;
|
|
}
|
|
else if (hasObjVar(getSelf(), OBJVAR_NO_CRIT_FAIL))
|
|
{
|
|
debugServerConsoleMsg(null, "Schematic is no crit fail, ain't that nice?");
|
|
criticalFailure = dieRoll - 1;
|
|
}
|
|
critical_s = criticalSuccess;
|
|
great_s = greatSuccess;
|
|
good_s = goodSuccess;
|
|
moderate_s = moderateSuccess;
|
|
s = successThreshold;
|
|
moderate_f = moderateFailure;
|
|
big_f = bigFailure;
|
|
critical_f = criticalFailure;
|
|
if (isPlayerTester)
|
|
{
|
|
CustomerServiceLog("crit_fail", "== EXPERIMENTATION_ATTRIBUTE_BEGIN == " + getName(player) + " (" + player + ") is starting to experiment on " + itemAttributes[i].name + " -- Base Roll: " + dieRoll + ", Mod Roll: " + modifiedSkillRoll);
|
|
}
|
|
float oneExperimentPoint = craftingValuesDictionary.getFloat((itemAttributes[i].name).getAsciiId() + "TenPercent");
|
|
float totalAttribExperimentPoints = oneExperimentPoint * experimentPoints[i];
|
|
float successPointScale = 0;
|
|
if (luck.isLucky(player, 0.005f))
|
|
{
|
|
successState = STATE_CRITICAL_SUCCESS;
|
|
successPointScale = 1.20f;
|
|
}
|
|
else if (dieRoll >= criticalSuccess)
|
|
{
|
|
successState = STATE_CRITICAL_SUCCESS;
|
|
successPointScale = 1.15f;
|
|
}
|
|
else if (dieRoll <= criticalFailure)
|
|
{
|
|
if (isPlayerTester)
|
|
{
|
|
CustomerServiceLog("crit_fail", "== EXPERIMENTATION_ATTRIBUTE_FAILURE MOD: " + playerSkillMod + " == " + getName(player) + " (" + player + ") has critically failed while experimenting on " + itemAttributes[i].name + " -- " + dieRoll + " <= " + criticalFailure);
|
|
}
|
|
successState = STATE_CRITICAL_FAILURE;
|
|
successPointScale = -1.0f;
|
|
int screwedAttributeDieRoll = rand(0, itemAttributes.length - 1);
|
|
while (itemAttributes[screwedAttributeDieRoll].minValue == itemAttributes[screwedAttributeDieRoll].maxValue)
|
|
{
|
|
screwedAttributeDieRoll = rand(0, itemAttributes.length - 1);
|
|
}
|
|
float oneScrewedAttributeExperimentPoint = craftingValuesDictionary.getFloat((itemAttributes[screwedAttributeDieRoll].name).getAsciiId() + "TenPercent");
|
|
float randomlyScrewedAttributeValue = itemAttributes[screwedAttributeDieRoll].currentValue - oneScrewedAttributeExperimentPoint;
|
|
if (randomlyScrewedAttributeValue < itemAttributes[screwedAttributeDieRoll].minValue)
|
|
{
|
|
randomlyScrewedAttributeValue = itemAttributes[screwedAttributeDieRoll].minValue;
|
|
}
|
|
debugServerConsoleMsg(null, "craftinglib.calcSuccessPerAttributeExperimentation: crit fail screwing attribute " + itemAttributes[screwedAttributeDieRoll].name + " from " + itemAttributes[screwedAttributeDieRoll].currentValue + " to " + randomlyScrewedAttributeValue);
|
|
itemAttributes[screwedAttributeDieRoll].currentValue = randomlyScrewedAttributeValue;
|
|
}
|
|
else if (modifiedSkillRoll > greatSuccess)
|
|
{
|
|
successState = STATE_GREAT_SUCCESS;
|
|
successPointScale = 1.0f;
|
|
}
|
|
else if (modifiedSkillRoll > goodSuccess)
|
|
{
|
|
successState = STATE_GOOD_SUCCESS;
|
|
successPointScale = 0.5f;
|
|
}
|
|
else if (modifiedSkillRoll > moderateSuccess)
|
|
{
|
|
successState = STATE_MODERATE_SUCCESS;
|
|
successPointScale = 0.25f;
|
|
}
|
|
else if (modifiedSkillRoll > successThreshold)
|
|
{
|
|
successState = STATE_SUCCESS;
|
|
successPointScale = 0.15f;
|
|
}
|
|
else if (modifiedSkillRoll > moderateFailure)
|
|
{
|
|
successState = STATE_FAILURE;
|
|
}
|
|
else if (modifiedSkillRoll > bigFailure)
|
|
{
|
|
successState = STATE_MODERATE_FAILURE;
|
|
successPointScale = -0.5f;
|
|
}
|
|
else
|
|
{
|
|
successState = STATE_BIG_FAILURE;
|
|
successPointScale = -1.0f;
|
|
}
|
|
if (successState != STATE_CRITICAL_SUCCESS && craftingValuesDictionary.containsKey(OBJVAR_FORCE_CRITICAL_SUCCESS))
|
|
{
|
|
if (!craftingValuesDictionary.containsKey(OBJVAR_REFACTOR))
|
|
{
|
|
successState = STATE_CRITICAL_SUCCESS;
|
|
successPointScale = 1.15f;
|
|
craftingValuesDictionary.put(OBJVAR_FORCE_CRITICAL_SUCCESS_RESULT, true);
|
|
}
|
|
}
|
|
if (isPlayerQA)
|
|
{
|
|
sendSystemMessageTestingOnly(player, "EXPERIMENT -- Raw Random Roll: " + itemAttributes[i].name + " = " + dieRoll);
|
|
sendSystemMessageTestingOnly(player, "EXPERIMENT -- FINAL MODIFIED ROLL: " + itemAttributes[i].name + " = " + modifiedSkillRoll);
|
|
if (successState >= 0 && successState < STATE_NAMES.length)
|
|
{
|
|
sendSystemMessageTestingOnly(player, "EXPERIMENT -- Success state for " + itemAttributes[i].name + ": " + STATE_NAMES[successState]);
|
|
}
|
|
sendSystemMessageTestingOnly(player, "EXPERIMENT --");
|
|
}
|
|
if (successState >= 0 && successState < STATE_NAMES.length)
|
|
{
|
|
debugServerConsoleMsg(null, "\tsuccess state = " + successState + "(" + STATE_NAMES[successState] + "), point scale = " + successPointScale);
|
|
}
|
|
else
|
|
{
|
|
debugServerConsoleMsg(null, "\tsuccess state = " + successState + ", point scale = " + successPointScale);
|
|
}
|
|
float postExperimentationAttributeDelta = totalAttribExperimentPoints * successPointScale * EXPERIMENTATION_EFFECTIVENESS_MULTIPLIER;
|
|
float postExperimentationAttributeValue = itemAttributes[i].currentValue + postExperimentationAttributeDelta;
|
|
LOG("crafting", "EXPERIMENT -- postExperimentationAttributeDelta: " + postExperimentationAttributeDelta + " postExperimentationAttributeValue: " + postExperimentationAttributeValue);
|
|
LOG("crafting", "EXPERIMENT -- itemAttributes[i].resourceMaxValue: " + itemAttributes[i].resourceMaxValue + " itemAttributes[i].minValue: " + itemAttributes[i].minValue);
|
|
if (postExperimentationAttributeValue > itemAttributes[i].resourceMaxValue)
|
|
{
|
|
postExperimentationAttributeValue = itemAttributes[i].resourceMaxValue;
|
|
}
|
|
else if (postExperimentationAttributeValue < itemAttributes[i].minValue)
|
|
{
|
|
postExperimentationAttributeValue = itemAttributes[i].minValue;
|
|
}
|
|
itemAttributes[i].currentValue = postExperimentationAttributeValue;
|
|
debugServerConsoleMsg(null, "\tvalue delta = " + postExperimentationAttributeDelta + ", final value = " + postExperimentationAttributeValue);
|
|
averageSuccessState += successState;
|
|
++averageSuccessStateCount;
|
|
}
|
|
craftingValuesDictionary.put((itemAttributes[i].name).getAsciiId() + "successState", successState);
|
|
}
|
|
if (isPlayerQA)
|
|
{
|
|
sendSystemMessageTestingOnly(player, "EXPERIMENT -- Critical Success: raw roll above " + critical_s);
|
|
sendSystemMessageTestingOnly(player, "EXPERIMENT -- Critical Failure: raw roll below " + critical_f);
|
|
sendSystemMessageTestingOnly(player, "EXPERIMENT --");
|
|
sendSystemMessageTestingOnly(player, "EXPERIMENT -- Great Success: mod roll above " + great_s);
|
|
sendSystemMessageTestingOnly(player, "EXPERIMENT -- Good Success: mod roll above " + good_s);
|
|
sendSystemMessageTestingOnly(player, "EXPERIMENT -- Moderate Success: mod roll above " + moderate_s);
|
|
sendSystemMessageTestingOnly(player, "EXPERIMENT -- Success: mod roll above " + s);
|
|
sendSystemMessageTestingOnly(player, "EXPERIMENT -- Failure: mod roll above " + moderate_f);
|
|
sendSystemMessageTestingOnly(player, "EXPERIMENT -- Moderate Failure: mod roll above " + big_f);
|
|
sendSystemMessageTestingOnly(player, "EXPERIMENT -- Big Failure: mod roll below " + big_f);
|
|
}
|
|
averageSuccessState = (int)(((float)averageSuccessState / (float)averageSuccessStateCount) + 0.5f);
|
|
if (averageSuccessState >= STATE_CRITICAL_FAILURE)
|
|
{
|
|
if (isPlayerTester)
|
|
{
|
|
CustomerServiceLog("crit_fail", "== EXPERIMENTATION_FAILURE MOD: " + playerSkillMod + " == " + getName(player) + " (" + player + ") has critically failed the experimentation process -- Average State: " + averageSuccessState);
|
|
}
|
|
}
|
|
if (isPlayerQA)
|
|
{
|
|
if (averageSuccessState >= 0 && averageSuccessState < STATE_NAMES.length)
|
|
{
|
|
sendSystemMessageTestingOnly(player, "EXPERIMENT --");
|
|
sendSystemMessageTestingOnly(player, "EXPERIMENT -- Overall success state: " + STATE_NAMES[averageSuccessState]);
|
|
}
|
|
sendSystemMessageTestingOnly(player, "EXPERIMENT ---------------------------------");
|
|
}
|
|
if (averageSuccessState > STATE_CRITICAL_FAILURE)
|
|
{
|
|
averageSuccessState = STATE_CRITICAL_FAILURE;
|
|
}
|
|
craftingValuesDictionary.put("experimentSuccessState", averageSuccessState);
|
|
}
|
|
public static void storeTissueDataAsObjvars(dictionary craftingValuesDictionary, draft_schematic.attribute[] itemAttributes, obj_id prototype, boolean includeComponents) throws InterruptedException
|
|
{
|
|
obj_id target = getSelf();
|
|
debugServerConsoleMsg(target, "craftinglib.storeTissueDataAsObjvars enter");
|
|
if (includeComponents)
|
|
{
|
|
obj_var_list componentData = getObjVarList(getSelf(), COMPONENT_ATTRIBUTE_INTERNAL_OBJVAR_NAME);
|
|
if (componentData != null)
|
|
{
|
|
obj_var skill_mods = componentData.getObjVar(TISSUE_SKILL_MODS);
|
|
if (skill_mods != null)
|
|
{
|
|
if (skill_mods instanceof obj_var_list)
|
|
{
|
|
obj_var_list skillModList = (obj_var_list)skill_mods;
|
|
int[] mod_idx = skillModList.getIntArrayObjVar(TISSUE_SKILL_INDEX);
|
|
int[] mod_val = skillModList.getIntArrayObjVar(TISSUE_SKILL_VALUE);
|
|
String root = COMPONENT_ATTRIBUTE_OBJVAR_NAME + "." + TISSUE_SKILL_MODS + ".";
|
|
if (((mod_idx != null) && (mod_idx.length > 0)) && ((mod_val != null) && (mod_val.length > 0)))
|
|
{
|
|
setObjVar(target, root + TISSUE_SKILL_INDEX, mod_idx);
|
|
setObjVar(target, root + TISSUE_SKILL_VALUE, mod_val);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
debugServerConsoleMsg(target, "craftinglib.storeTissueDataAsObjvars exit");
|
|
}
|
|
public static draft_schematic.custom[] standardCustomizationProcedure(obj_id player, draft_schematic.custom[] customizations, String[] customizationSkillMods) throws InterruptedException
|
|
{
|
|
LOG("customization", "New customization code activated - NOW IN CRAFTING LIB");
|
|
String[] skills = customizationSkillMods;
|
|
int playerCustomizationMod = 0;
|
|
float playerCustModPercentage = 0;
|
|
if (skills != null)
|
|
{
|
|
int[] mods = getEnhancedSkillStatisticModifiers(player, skills);
|
|
for (int i = 0; i < mods.length; ++i)
|
|
{
|
|
playerCustomizationMod += mods[i];
|
|
}
|
|
}
|
|
if (playerCustomizationMod > 255)
|
|
{
|
|
playerCustomizationMod = 255;
|
|
}
|
|
playerCustModPercentage = playerCustomizationMod / 255f;
|
|
int validCustomizations = 0;
|
|
for (int i = 0; i < customizations.length; i++)
|
|
{
|
|
if (customizations[i].maxValue > 4)
|
|
{
|
|
if (customizations[i].maxValue > playerCustomizationMod)
|
|
{
|
|
customizations[i].maxValue = playerCustomizationMod;
|
|
}
|
|
validCustomizations++;
|
|
}
|
|
else
|
|
{
|
|
customizations[i] = null;
|
|
}
|
|
}
|
|
int playerAccessibleCustomizations = 1;
|
|
if (playerCustomizationMod > 64)
|
|
{
|
|
playerAccessibleCustomizations++;
|
|
}
|
|
if (playerCustomizationMod > 128)
|
|
{
|
|
playerAccessibleCustomizations++;
|
|
}
|
|
if (playerCustomizationMod > 192)
|
|
{
|
|
playerAccessibleCustomizations++;
|
|
}
|
|
int usedPlayerCustomizations = 0;
|
|
for (int j = 0; j < customizations.length; j++)
|
|
{
|
|
if (usedPlayerCustomizations < playerAccessibleCustomizations)
|
|
{
|
|
if (customizations[j] != null)
|
|
{
|
|
usedPlayerCustomizations++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
customizations[j] = null;
|
|
}
|
|
}
|
|
return customizations;
|
|
}
|
|
public static String getCraftingSubskill(String[] craftingSkills) throws InterruptedException
|
|
{
|
|
String strSkill = "artisan";
|
|
if(craftingSkills != null) {
|
|
String[] skillFragment =
|
|
{
|
|
"crafting_artisan",
|
|
"crafting_armorsmith",
|
|
"crafting_architect",
|
|
"crafting_chef",
|
|
"crafting_droid",
|
|
"crafting_shipwright",
|
|
"crafting_tailor",
|
|
"crafting_weaponsmith",
|
|
"crafting_cybernetic"
|
|
};
|
|
String[] skillList =
|
|
{
|
|
"artisan",
|
|
"armorsmith",
|
|
"architect",
|
|
"chef",
|
|
"droid",
|
|
"shipwright",
|
|
"tailor",
|
|
"weaponsmith",
|
|
"cybernetic"
|
|
};
|
|
for (int i = 0; i < craftingSkills.length; i++) {
|
|
for (int j = 0; j < skillFragment.length; j++) {
|
|
if (craftingSkills[i].startsWith(skillFragment[j])) {
|
|
return skillList[j];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return strSkill;
|
|
}
|
|
public static String[] getDraftSchematicGroupsFromSkill(String skillName) throws InterruptedException
|
|
{
|
|
if (skillName == null || skillName.length() <= 0)
|
|
{
|
|
return null;
|
|
}
|
|
String schematicsGranted = dataTableGetString(skill.TBL_SKILL, skillName, "SCHEMATICS_GRANTED");
|
|
if (schematicsGranted == null || schematicsGranted.equals(""))
|
|
{
|
|
return null;
|
|
}
|
|
return split(schematicsGranted, ',');
|
|
}
|
|
public static String[] getDraftSchematicGroupsFromSkills(String[] craftingSkills) throws InterruptedException
|
|
{
|
|
Vector schematicGroups = new Vector();
|
|
schematicGroups.setSize(0);
|
|
for (int i = 0; i < craftingSkills.length; i++)
|
|
{
|
|
String[] groups = getDraftSchematicGroupsFromSkill(craftingSkills[i]);
|
|
if (groups != null && groups.length > 0)
|
|
{
|
|
for (int j = 0; j < groups.length; j++)
|
|
{
|
|
schematicGroups.add(groups[j]);
|
|
}
|
|
}
|
|
}
|
|
String[] _schematicGroups = new String[0];
|
|
if (schematicGroups != null)
|
|
{
|
|
_schematicGroups = new String[schematicGroups.size()];
|
|
schematicGroups.toArray(_schematicGroups);
|
|
}
|
|
return _schematicGroups;
|
|
}
|
|
public static String[] getDraftSchematicsFromGroup(String schematicGroup) throws InterruptedException
|
|
{
|
|
if (schematicGroup == null || schematicGroup.length() <= 0)
|
|
{
|
|
return null;
|
|
}
|
|
int numRows = dataTableGetNumRows(TABLE_SCHEMATIC_GROUPS);
|
|
Vector schematicTemplates = new Vector();
|
|
schematicTemplates.setSize(0);
|
|
for (int i = 0; i < numRows; i++)
|
|
{
|
|
String group = dataTableGetString(TABLE_SCHEMATIC_GROUPS, i, "GroupId");
|
|
if (group.equals(schematicGroup))
|
|
{
|
|
schematicTemplates.add(dataTableGetString(TABLE_SCHEMATIC_GROUPS, i, "SchematicName"));
|
|
}
|
|
}
|
|
String[] _schematicTemplates = new String[0];
|
|
if (schematicTemplates != null)
|
|
{
|
|
_schematicTemplates = new String[schematicTemplates.size()];
|
|
schematicTemplates.toArray(_schematicTemplates);
|
|
}
|
|
return _schematicTemplates;
|
|
}
|
|
public static String[] getDraftSchematicsFromGroups(String[] schematicGroups) throws InterruptedException
|
|
{
|
|
Vector allSchematics = new Vector();
|
|
allSchematics.setSize(0);
|
|
for (int i = 0; i < schematicGroups.length; i++)
|
|
{
|
|
String[] schematics = getDraftSchematicsFromGroup(schematicGroups[i]);
|
|
if (schematics != null && schematics.length > 0)
|
|
{
|
|
for (int j = 0; j < schematics.length; j++)
|
|
{
|
|
allSchematics.add(schematics[j]);
|
|
}
|
|
}
|
|
}
|
|
String[] _allSchematics = new String[0];
|
|
if (allSchematics != null)
|
|
{
|
|
_allSchematics = new String[allSchematics.size()];
|
|
allSchematics.toArray(_allSchematics);
|
|
}
|
|
return _allSchematics;
|
|
}
|
|
public static boolean storeSecondarySkillBonuses(obj_id prototype, draft_schematic schematic) throws InterruptedException
|
|
{
|
|
draft_schematic.slot[] slots = schematic.getSlots();
|
|
// Cekis: never used - waste of processing.
|
|
// draft_schematic.attribute[] objectAttribs = schematic.getAttribs();
|
|
String category = getProtoTypeCategory(prototype);
|
|
for (int i = 0; i < slots.length; ++i)
|
|
{
|
|
if (!isIdValid(slots[i].ingredients[0].ingredient) || !exists(slots[i].ingredients[0].ingredient))
|
|
{
|
|
continue;
|
|
}
|
|
if (hasObjVar(slots[i].ingredients[0].ingredient, OBJVAR_RE_STAT_MODIFIED))
|
|
{
|
|
LOG("crafting", "storeSecondarySkillBonuses::ingredient " + slots[i].ingredients[0].ingredient + " has the objvar " + OBJVAR_RE_STAT_MODIFIED);
|
|
String statModified = getStringObjVar(slots[i].ingredients[0].ingredient, OBJVAR_RE_STAT_MODIFIED);
|
|
LOG("crafting", "storeSecondarySkillBonuses::statModified " + statModified);
|
|
float power = getFloatObjVar(slots[i].ingredients[0].ingredient, OBJVAR_RE_VALUE);
|
|
LOG("crafting", "storeSecondarySkillBonuses::power " + power);
|
|
int ratio = getIntObjVar(slots[i].ingredients[0].ingredient, OBJVAR_RE_RATIO);
|
|
LOG("crafting", "storeSecondarySkillBonuses::ratio " + ratio);
|
|
power = power / ratio;
|
|
LOG("crafting", "storeSecondarySkillBonuses::power after ratio divisor " + power);
|
|
LOG("crafting", "storeSecondarySkillBonuses::power after changed to Int " + (int)power);
|
|
setCategorizedSkillModBonus(prototype, category, statModified, (int)power);
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
public static String getProtoTypeCategory(obj_id prototype) throws InterruptedException
|
|
{
|
|
String category = "";
|
|
if (weapons.isCoredWeapon(prototype))
|
|
{
|
|
category = "weapon";
|
|
}
|
|
else
|
|
{
|
|
category = "armor";
|
|
}
|
|
return category;
|
|
}
|
|
public static boolean validateReComponent(obj_id player, obj_id resource) throws InterruptedException
|
|
{
|
|
if (!isIdValid(player) || !exists(player))
|
|
{
|
|
return false;
|
|
}
|
|
if (!isIdValid(resource) || !exists(resource))
|
|
{
|
|
return false;
|
|
}
|
|
if (hasObjVar(resource, "reverse_engineering.reverse_engineering_modifier"))
|
|
{
|
|
CustomerServiceLog("new_weapon_crafting", "validateReComponent::ingredient " + resource + " has the objvar reverse_engineering.reverse_engineering_modifier");
|
|
String reStatMod = getStringObjVar(resource, "reverse_engineering.reverse_engineering_modifier");
|
|
if (!reverse_engineering.canMakePowerUp(reStatMod))
|
|
{
|
|
CustomerServiceLog("new_weapon_crafting", "validateReComponent::Player " + getFirstName(player) + "(" + player + ") has tried to use an invalid RE modifier. We are killing the crafting process.");
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
public static boolean validateReComponent(obj_id player, draft_schematic schematic) throws InterruptedException
|
|
{
|
|
if (!isIdValid(player) || !exists(player))
|
|
{
|
|
return false;
|
|
}
|
|
draft_schematic.slot[] slots = schematic.getSlots();
|
|
int ratio = 0;
|
|
int powerMod = 0;
|
|
obj_id powerBitId = obj_id.NULL_ID;
|
|
String reStatMod;
|
|
obj_id ingredient;
|
|
for (draft_schematic.slot slot : slots) {
|
|
ingredient = slot.ingredients[0].ingredient;
|
|
if (!isIdValid(ingredient) || !exists(ingredient)) {
|
|
continue;
|
|
}
|
|
if (hasObjVar(ingredient, "reverse_engineering.reverse_engineering_modifier")) {
|
|
CustomerServiceLog("new_weapon_crafting", "ingredient " + ingredient + " has the objvar reverse_engineering.reverse_engineering_modifier");
|
|
reStatMod = getStringObjVar(ingredient, "reverse_engineering.reverse_engineering_modifier");
|
|
ratio = getIntObjVar(ingredient, "reverse_engineering.reverse_engineering_ratio");
|
|
if (!reverse_engineering.canMakePowerUp(reStatMod)) {
|
|
CustomerServiceLog("new_weapon_crafting", "Player " + getFirstName(player) + "(" + player + ") has tried to use an invalid RE modifier. We are killing the crafting process.");
|
|
sui.msgbox(player, new string_id("spam", "bad_re_modifier"));
|
|
return false;
|
|
}
|
|
}
|
|
if (hasObjVar(ingredient, "reverse_engineering.reverse_engineering_power")) {
|
|
powerBitId = ingredient;
|
|
powerMod = getIntObjVar(ingredient, "reverse_engineering.reverse_engineering_power");
|
|
}
|
|
}
|
|
float modifiedPower = 0.0f;
|
|
modifiedPower = powerMod * RE_POWER_MODIFIER;
|
|
modifiedPower = modifiedPower / ratio;
|
|
if (modifiedPower < 1)
|
|
{
|
|
prose_package pp = new prose_package();
|
|
prose.setStringId(pp, new string_id("spam", "low_re_power"));
|
|
prose.setDF(pp, modifiedPower);
|
|
prose.setDI(pp, ratio);
|
|
prose.setTO(pp, Float.toString(RE_POWER_MODIFIER * 100));
|
|
sui.msgbox(player, pp);
|
|
CustomerServiceLog("new_weapon_crafting", "Ingredient " + powerBitId + " has too low reverse engineering power for the modified stat. Refusing to allow Player " + getFirstName(player) + "(" + player + ") to craft.");
|
|
CustomerServiceLog("new_weapon_crafting", "Ingredient " + powerBitId + " would have a modified power level of " + modifiedPower + ". Notifying Player " + getFirstName(player) + "(" + player + ") to craft.");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
public static boolean updatePermanentSchematics(obj_id player) throws InterruptedException
|
|
{
|
|
if (!isIdValid(player) || !exists(player))
|
|
{
|
|
return false;
|
|
}
|
|
if (hasObjVar(player, "schematicsUpdateVersion"))
|
|
{
|
|
int version = getIntObjVar(player, "schematicsUpdateVersion");
|
|
CustomerServiceLog("new_weapon_conversion", "updatePermanentSchematics::player " + getFirstName(player) + "(" + player + ") has already been updated.");
|
|
if (version == OBJVAR_SCHEM_VERSION)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
int[] schemsList = getSchematicListingForPlayer(player);
|
|
if (schemsList == null || schemsList.length <= 0)
|
|
{
|
|
return false;
|
|
}
|
|
for (int i = 0; i < schemsList.length; ++i)
|
|
{
|
|
int row = dataTableSearchColumnForInt(schemsList[i], "crc_schematic_name", weapons.WEAPON_DATA_TABLE);
|
|
if (row < 0)
|
|
{
|
|
continue;
|
|
}
|
|
String schemToGrant = dataTableGetString(weapons.WEAPON_DATA_TABLE, row, "schematic_conversion");
|
|
if (schemToGrant != null && !schemToGrant.equals(""))
|
|
{
|
|
if (!grantSchematic(player, schemToGrant))
|
|
{
|
|
CustomerServiceLog("new_weapon_conversion", "updatePermanentSchematics::player " + getFirstName(player) + "(" + player + ") was NOT granted schematic " + schemToGrant + ", the grantSchematic call returned a false.");
|
|
continue;
|
|
}
|
|
CustomerServiceLog("new_weapon_conversion", "updatePermanentSchematics::player " + getFirstName(player) + "(" + player + ") was granted schematic " + schemToGrant);
|
|
revokeSchematic(player, schemsList[i]);
|
|
}
|
|
}
|
|
setObjVar(player, "schematicsUpdateVersion", OBJVAR_SCHEM_VERSION);
|
|
return true;
|
|
}
|
|
public static String getCraftingStationBuffName(int craftingType) throws InterruptedException
|
|
{
|
|
if (craftingType <= 0)
|
|
{
|
|
return null;
|
|
}
|
|
if (craftingType == STATION_TYPE_FOOD)
|
|
{
|
|
return "food_station";
|
|
}
|
|
if (craftingType == STATION_TYPE_ARMOR)
|
|
{
|
|
return "armor_station";
|
|
}
|
|
if (craftingType == STATION_TYPE_STRUCTURE)
|
|
{
|
|
return "structure_station";
|
|
}
|
|
if (craftingType == STATION_TYPE_WEAPON || craftingType == STATION_TYPE_WEAPON_TOOL)
|
|
{
|
|
return "weapon_station";
|
|
}
|
|
if (craftingType == STATION_TYPE_SPACE)
|
|
{
|
|
return "space_station";
|
|
}
|
|
if (craftingType == STATION_TYPE_FOOD_AND_STRUCTURE)
|
|
{
|
|
return "food_station,structure_station,tcg_diner_crafting_station";
|
|
}
|
|
return null;
|
|
}
|
|
public static String[] getAllStationBuffNames(int craftingType) throws InterruptedException
|
|
{
|
|
if (craftingType < 0)
|
|
{
|
|
return null;
|
|
}
|
|
String buffs = getCraftingStationBuffName(craftingType);
|
|
if (buffs == null || buffs.equals(""))
|
|
{
|
|
return null;
|
|
}
|
|
return split(buffs, ',');
|
|
}
|
|
public static void makeBestResource(obj_id player, String resource, int quantity) throws InterruptedException
|
|
{
|
|
obj_id[] resourceTypes = getAllResourceChildren(resource);
|
|
if (resourceTypes == null || resourceTypes.length == 0)
|
|
{
|
|
return;
|
|
}
|
|
if (quantity <= 0)
|
|
{
|
|
return;
|
|
}
|
|
if (quantity > 1000000)
|
|
{
|
|
quantity = 1000000;
|
|
}
|
|
obj_id best = findBestResourceByAverage(resourceTypes);
|
|
obj_id inv = utils.getInventoryContainer(player);
|
|
obj_id resourceCrate = createResourceCrate(best, quantity, inv);
|
|
}
|
|
public static obj_id[] getAllResourceChildren(String resourceClass) throws InterruptedException
|
|
{
|
|
obj_id[] resources = getResourceTypes(resourceClass);
|
|
String[] resourceChildren = getImmediateResourceChildClasses(resourceClass);
|
|
for (int i = 0; i < resourceChildren.length; i++)
|
|
{
|
|
obj_id[] nextResources = getAllResourceChildren(resourceChildren[i]);
|
|
resources = utils.concatArrays(resources, nextResources);
|
|
}
|
|
return resources;
|
|
}
|
|
public static obj_id findBestResourceByAverage(obj_id[] resourceTypes) throws InterruptedException
|
|
{
|
|
int bestIndex = 0;
|
|
int bestAverage = 0;
|
|
for (int i = 0; i < resourceTypes.length; i++)
|
|
{
|
|
resource_attribute[] resourceAttribs = getResourceAttributes(resourceTypes[i]);
|
|
int resourceAverage = 0;
|
|
for (int j = 0; j < resourceAttribs.length; j++)
|
|
{
|
|
resourceAverage += resourceAttribs[j].getValue();
|
|
}
|
|
resourceAverage = resourceAverage / resourceAttribs.length;
|
|
if (bestAverage < resourceAverage)
|
|
{
|
|
bestIndex = i;
|
|
bestAverage = resourceAverage;
|
|
}
|
|
}
|
|
return resourceTypes[bestIndex];
|
|
}
|
|
public static void makeBestResourceByAttribute(obj_id player, String resource, String attribute, int quantity) throws InterruptedException
|
|
{
|
|
obj_id[] resourceTypes = getAllResourceChildren(resource);
|
|
if (resourceTypes == null || resourceTypes.length == 0)
|
|
{
|
|
return;
|
|
}
|
|
if (quantity <= 0)
|
|
{
|
|
return;
|
|
}
|
|
if (quantity > 1000000)
|
|
{
|
|
quantity = 1000000;
|
|
}
|
|
obj_id best = findBestResourceByAttribute(resourceTypes, attribute);
|
|
obj_id inv = utils.getInventoryContainer(player);
|
|
obj_id resourceCrate = createResourceCrate(best, quantity, inv);
|
|
}
|
|
public static obj_id findBestResourceByAttribute(obj_id[] resourceTypes, String attributeName) throws InterruptedException
|
|
{
|
|
int bestIndex = 0;
|
|
int bestValue = 0;
|
|
for (int i = 0; i < resourceTypes.length; i++)
|
|
{
|
|
resource_attribute[] resourceAttribs = getResourceAttributes(resourceTypes[i]);
|
|
int resourceValue = 0;
|
|
for (int j = 0; j < resourceAttribs.length; j++)
|
|
{
|
|
if (attributeName.equals(resourceAttribs[j].getName()))
|
|
{
|
|
resourceValue = resourceAttribs[j].getValue();
|
|
}
|
|
}
|
|
if (bestValue < resourceValue)
|
|
{
|
|
bestIndex = i;
|
|
bestValue = resourceValue;
|
|
}
|
|
}
|
|
return resourceTypes[bestIndex];
|
|
}
|
|
public static String[] getResourceAttribNames(obj_id resource) throws InterruptedException
|
|
{
|
|
resource_attribute[] resourceAttribs = getResourceAttributes(resource);
|
|
if (resourceAttribs == null || resourceAttribs.length <= 0)
|
|
{
|
|
return null;
|
|
}
|
|
String[] tempAttribNames = new String[resourceAttribs.length];
|
|
for (int i = 0, j = resourceAttribs.length; i < j; i++)
|
|
{
|
|
tempAttribNames[i] = resourceAttribs[i].getName();
|
|
}
|
|
return tempAttribNames;
|
|
}
|
|
public static String[] getAttribNamesByResourceClass(String resourceClass) throws InterruptedException
|
|
{
|
|
obj_id[] resources = getResourceTypes(resourceClass);
|
|
String[] resourceChildren = getImmediateResourceChildClasses(resourceClass);
|
|
for (int i = 0; i < resourceChildren.length; i++)
|
|
{
|
|
obj_id[] nextResources = getAllResourceChildren(resourceChildren[i]);
|
|
resources = utils.concatArrays(resources, nextResources);
|
|
}
|
|
for (int i = 0, j = resources.length; i < j; i++)
|
|
{
|
|
String[] tempAttribNames = getResourceAttribNames(resources[i]);
|
|
if (tempAttribNames != null && tempAttribNames.length > 0)
|
|
{
|
|
return tempAttribNames;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
public static boolean isTrader(obj_id who) throws InterruptedException
|
|
{
|
|
if (!isIdValid(who) || !exists(who))
|
|
{
|
|
return false;
|
|
}
|
|
String profession = skill.getProfessionName(getSkillTemplate(who));
|
|
if (profession.equals("trader"))
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
}
|