/** * Copyright (c)2000-2002 Sony Online Entertainment Inc. * All Rights Reserved * * Title: resource.scriptlib * Description: scriptlib for resource related functions * @author $Author:$ * @version $Revision:$ */ /***** INCLUDES ********************************************************/ include library.buff; include library.city; include library.utils; /***** CONSTANTS *******************************************************/ //RESOLUTION = number of points on a side - must be odd const int SURVEY_RESOLUTION_MIN = 3; const int SURVEY_RESOLUTION_MAX = 6; const int SURVEY_RESOLUTION_DEFAULT = 3; //RANGE = distance on a side - must be a power of 2 const int SURVEY_RANGE_MIN = 16; const int SURVEY_RANGE_MAX = 384; const int SURVEY_RANGE_DEFAULT = 64; const string VAR_SURVEY_BASE = "survey"; const string VAR_SURVEY_CLASS = VAR_SURVEY_BASE + ".resource_class"; const string VAR_SURVEY_RESOLUTION_MIN = VAR_SURVEY_BASE + ".resolution.min"; const string VAR_SURVEY_RESOLUTION_MAX = VAR_SURVEY_BASE + ".resolution.max"; const string VAR_SURVEY_RESOLUTION_VALUE = VAR_SURVEY_BASE + ".resolution.value"; const string VAR_SURVEY_RANGE_MIN = VAR_SURVEY_BASE + ".range.min"; const string VAR_SURVEY_RANGE_MAX = VAR_SURVEY_BASE + ".range.max"; const string VAR_SURVEY_RANGE_VALUE = VAR_SURVEY_BASE + ".range.value"; const string VAR_SAMPLE_STAMP = VAR_SURVEY_BASE + ".sample.stamp"; const string HANDLER_SET_RANGE = "handleSetRange"; const string HANDLER_SET_RESOLUTION = "handleSetResolution"; const string VAR_SETTINGS_BASE = VAR_SURVEY_BASE + ".settings"; const string VAR_SETTINGS_PLAYER = VAR_SETTINGS_BASE + ".player"; const string VAR_SETTINGS_INDEX = VAR_SETTINGS_BASE + ".index"; const string VAR_SETTINGS_RANGES = VAR_SETTINGS_BASE + ".ranges"; const string VAR_SETTINGS_RESOLUTIONS = VAR_SETTINGS_BASE + ".resolutions"; const string PID_NAME = "resourceSpecialEvent"; //RESOURCE CLASS DEFINES const int CLASS_RESOURCE = 0; const int CLASS_INORGANIC = 1; const int CLASS_MINERAL = 2; const int CLASS_WATER = 3; const int CLASS_CHEMICAL = 4; const int CLASS_GAS = 5; const int CLASS_ENERGY = 6; const int CLASS_ORGANIC = 7; const int CLASS_FOOD = 8; const int CLASS_CREATURE_STRUCTURAL = 9; const int CLASS_FLORA_RESOURCE = 10; const int CLASS_FLORA_STRUCTURAL = 11; const int CLASS_ENERGY_WIND = 12; const int CLASS_ENERGY_SOLAR = 13; const int CLASS_MAX = 14; //last class entry + 1 const string[] CLASS_NAME = { "resource", "inorganic", "mineral", "water", "chemical", "gas", "energy", "organic", "creature_food", "creature_structural", "flora_resources", "flora_structural", "energy_renewable_unlimited_wind", "energy_renewable_unlimited_solar" }; //******* RESOURCE TYPE(RT) DEFINES ***** const string RT_ORGANIC = "organic"; const string RT_INORGANIC = "inorganic"; //SOLIDS const string RT_MINERAL = "mineral"; //GASES const string RT_GAS = "gas"; const string RT_LIQUID_VAPORS = "liquid_vapors"; //LIQUIDS const string RT_LIQUID_WATER = "water"; const string RT_LIQUID_CHEMICAL = "chemical"; //CREATURE RESOURCES const string RT_CREATURE_RESOURCES = "creature_resources"; //FLORA RESOURCES const string RT_FLORA_RESOURCES = "flora_resources"; //FLORA FOOD const string RT_FLORA_FOOD = "flora_food"; //FLORA STRUCTURAL const string RT_FLORA_STRUCTURAL = "flora_structural"; //ENERGY RESOURCES const string RT_ENERGY_WIND = "energy_renewable_unlimited_wind"; const string RT_ENERGY_SOLAR = "energy_renewable_unlimited_solar"; const string RT_ENERGY_GEO = "energy_renewable_site_limited_geothermal"; //******* SURVEY SKILLMOD DEFINES ***** const string MOD_SURVEY_ORGANIC = "survey_organic"; const string MOD_SURVEY_ORGANIC_RANGE = "survey_organic_range"; const string MOD_SURVEY_ORGANIC_RESOLUTION = "survey_organic_resolution"; const string MOD_SURVEY_INORGANIC = "survey_inorganic"; const string MOD_SURVEY_INORGANIC_RANGE = "survey_inorganic_range"; const string MOD_SURVEY_INORGANIC_RESOLUTION = "survey_inorganic_resolution"; //SOLIDS const string MOD_SURVEY_SOLID = "survey_solid"; const string MOD_SURVEY_SOLID_RANGE = "survey_solid_range"; const string MOD_SURVEY_SOLID_RESOLUTION = "survey_solid_resolution"; //GASES const string MOD_SURVEY_GAS = "survey_gas"; const string MOD_SURVEY_GAS_RANGE = "survey_gas_range"; const string MOD_SURVEY_GAS_RESOLUTION = "survey_gas_resolution"; //LIQUIDS const string MOD_SURVEY_LIQUID = "survey_liquid"; const string MOD_SURVEY_LIQUID_RANGE = "survey_liquid_range"; const string MOD_SURVEY_LIQUID_RESOLUTION = "survey_liquid_resolution"; //CREATURE RESOURCES const string MOD_SURVEY_CREATURE = "survey_creature"; const string MOD_SURVEY_CREATURE_RANGE = "survey_creature_range"; const string MOD_SURVEY_CREATURE_RESOLUTION = "survey_creature_resolution"; //FLORA RESOURCES const string MOD_SURVEY_FOOD = "survey_food"; const string MOD_SURVEY_FOOD_RANGE = "survey_food_range"; const string MOD_SURVEY_FOOD_RESOLUTION = "survey_food_resolution"; //FLORA STRUCTURAL RESOUCES const string MOD_SURVEY_FLORA_STRUCTURAL = "survey_flora_structural"; const string MOD_SURVEY_FLORA_STRUCTURAL_RANGE = "survey_flora_structural_range"; const string MOD_SURVEY_FLORA_STRUCTURAL_RESOLUTION = "survey_flora_structural_resolution"; //ENERGY WIND RESOUCES const string MOD_SURVEY_ENERGY_WIND = "survey_energy_wind"; const string MOD_SURVEY_ENERGY_WIND_RANGE = "survey_energy_wind_range"; const string MOD_SURVEY_ENERGY_WIND_RESOLUTION = "survey_energy_wind_resolution"; //ENERGY SOLAR RESOUCES const string MOD_SURVEY_ENERGY_SOLAR = "survey_energy_solar"; const string MOD_SURVEY_ENERGY_SOLAR_RANGE = "survey_energy_solar_range"; const string MOD_SURVEY_ENERGY_SOLAR_RESOLUTION = "survey_energy_solar_resolution"; //ENERGY GEO THERMAL RESOURCES const string MOD_SURVEY_ENERGY_GEO = "survey_energy_geo_thermal"; const string MOD_SURVEY_ENERGY_GEO_RANGE = "survey_energy_geo_thermal_range"; const string MOD_SURVEY_ENERGY_GEO_RESOLUTION = "survey_energy_geo_thermal_resolution"; //All Resources const string MOD_SURVEY_ALL = "survey_resources_all"; const float SAMPLE_DENSITY_THRESHOLD = 0.3f; const int BASE_HARVEST_XP = 40; // OLD VALUE const int TIME_SAMPLE = 300; const int TIME_SAMPLE = 18; const int TIME_FAIL_BONUS = 180; const int BASE_SAMPLE_AMOUNT = 22; const string STF_SURVEY = "survey"; const string_id SID_WRONG_TOOL = new string_id(STF_SURVEY, "wrong_tool"); const string_id SID_NSF_SKILL = new string_id("error_message","prose_nsf_skill"); const string_id SID_NSF_SKILL_PLURAL = new string_id("error_message","prose_nsf_skill_plural"); const string_id SID_SAMPLE_LOCATED = new string_id(STF_SURVEY, "sample_located"); const string_id SID_SAMPLE_FAILED = new string_id(STF_SURVEY, "sample_failed"); const string_id SID_DENSITY_BELOW_THESHOLD = new string_id(STF_SURVEY, "density_below_threshold"); const string_id SID_TRACE_AMOUNT = new string_id(STF_SURVEY, "trace_amount"); const string_id SID_EFFICIENCY_TOO_LOW = new string_id(STF_SURVEY, "efficiency_too_low"); const string_id SID_TOOL_RECHARGE_TIME = new string_id(STF_SURVEY, "tool_recharge_time"); const string_id SID_NO_INV_SPACE = new string_id(STF_SURVEY, "no_inv_space"); const string_id SID_CRITICAL_SUCCESS = new string_id(STF_SURVEY, "critical_success"); const string_id SID_NODE_NOT_CLOSE = new string_id(STF_SURVEY, "node_not_close"); const string_id SID_NODE_RECOVERY = new string_id(STF_SURVEY, "node_recovery"); const string_id SID_GAMBLE_SUCCESS = new string_id(STF_SURVEY, "gamble_success"); const string_id SID_GAMBLE_FAIL = new string_id(STF_SURVEY, "gamble_fail"); const string_id SID_PET_SEARCH_SUCCESS = new string_id(STF_SURVEY, "pet_search_success"); const string_id SID_PET_SEARCH_FAIL = new string_id(STF_SURVEY, "pet_search_fail"); const string_id SID_GAMBLE_RARE = new string_id(STF_SURVEY, "gamble_rare"); const string_id SID_EFFECTS_OF_RADIATION_SICKNESS = new string_id(STF_SURVEY, "effects_of_radiation_sickness"); const string_id SID_SUI_SURVEY_TOOL_PROPERTIES_TITLE = new string_id(STF_SURVEY, "sui_survey_tool_properties_title"); const string_id SID_SUI_SURVEY_TOOL_PROPERTIES_HEADER = new string_id(STF_SURVEY, "sui_survey_tool_properties_header"); const string_id SID_SUI_SURVEY_TOOL_PROPERTIES_RESOURCE_HEADER = new string_id(STF_SURVEY, "sui_survey_tool_properties_resource_header"); const string_id SID_SUI_SURVEY_TOOL_PROPERTIES_RESOURCE = new string_id(STF_SURVEY, "sui_survey_tool_properties_resource"); const string_id SID_SUI_SURVEY_TOOL_PROPERTIES_RESOLUTION = new string_id(STF_SURVEY, "sui_survey_tool_properties_resolution"); const string_id SID_SUI_SURVEY_TOOL_PROPERTIES_RESOLUTION_MIN = new string_id(STF_SURVEY, "sui_survey_tool_properties_resolution_min"); const string_id SID_SUI_SURVEY_TOOL_PROPERTIES_RESOLUTION_MAX = new string_id(STF_SURVEY, "sui_survey_tool_properties_resolution_max"); const string_id SID_SUI_SURVEY_TOOL_PROPERTIES_RESOLUTION_VAL = new string_id(STF_SURVEY, "sui_survey_tool_properties_resolution_val"); const string_id SID_SUI_SURVEY_TOOL_PROPERTIES_RANGE = new string_id(STF_SURVEY, "sui_survey_tool_properties_range"); const string_id SID_SUI_SURVEY_TOOL_PROPERTIES_RANGE_MIN = new string_id(STF_SURVEY, "sui_survey_tool_properties_range_min"); const string_id SID_SUI_SURVEY_TOOL_PROPERTIES_RANGE_MAX = new string_id(STF_SURVEY, "sui_survey_tool_properties_range_max"); const string_id SID_SUI_SURVEY_TOOL_PROPERTIES_RANGE_VAL = new string_id(STF_SURVEY, "sui_survey_tool_properties_range_val"); const string_id SID_SURVEY_ERROR = new string_id("error_message","survey_error"); const string DATATABLE_RESOURCES = "datatables/resource/resource_tree.iff"; const string DATATABLE_COL_ENUM = "Enum"; const string DATATABLE_COL_RESOURCE_CRATE_TYPE = "Resource Container Type"; const string DEFAULT_CONTAINER = "object/resource_container/simple.iff"; const int CONTAINER_VOLUME_MAX = 100000; const string MSG_SELECT_RANGE = "@" + STF_SURVEY + ":select_range"; const string MSG_SELECT_CLASS = "@" + STF_SURVEY + ":select_class"; // get sample fail codes const int SAMPLE_STOP_LOOP = 0; const int SAMPLE_CONTINUE_LOOP = 1; const int SAMPLE_CONTINUE_LOOP_NOSAMPLE = 2; const int SAMPLE_PAUSE_LOOP_EVENT = 3; /***** FUNCTIONS ********************************************************/ /***** GENERAL RESOURCE FUNCTIONS ***************************************/ /************************************************************************ * @brief sets the string value of VAR_SURVEY_CLASS with the appropriate name * * @param string resource_type * @param string parent_class * * @return boolean ***********************************************************************/ boolean isResourceDerivedFrom(string resource_type, string parent_class) { if ( (resource_type.equals("")) || (parent_class.equals("")) ) { return false; } if ( resource_type.equals(parent_class) ) { return true; } obj_id resourceId = getResourceTypeByName(resource_type); if ( (resourceId == null) || (resourceId == obj_id.NULL_ID) ) { return false; } if ( isResourceDerivedFrom(resourceId, parent_class) ) { return true; } return false; } /************************************************************************ * @brief attempts to create and contain the specified resource and amt * in the target container. returns obj_id array of resource containers * * @param obj_id resourceId * @param int amt * @param obj_id targetContainer * @param obj_id playerId * * @return obj_id[]; null on error ***********************************************************************/ obj_id[] create(obj_id resourceId, int amt, obj_id targetContainer, obj_id playerId) { if ( (resourceId == null) || (resourceId == obj_id.NULL_ID) ) { return null; } if ( (targetContainer == null) || (targetContainer == obj_id.NULL_ID) ) { return null; } if ( amt < 1 ) { return null; } int total = amt; resizeable obj_id[] ret = new obj_id[0]; string containerTemplate = getResourceContainerTemplate(resourceId); if ( (containerTemplate == null) || (containerTemplate.equals("")) ) { containerTemplate = DEFAULT_CONTAINER; } int chunks = (int)(amt / CONTAINER_VOLUME_MAX); if ( amt % CONTAINER_VOLUME_MAX > 0 ) { chunks++; } for ( int i = 0; i < chunks; i++ ) { if ( total > 0 ) { obj_id crate = createObject(containerTemplate, targetContainer, ""); if ( (crate == null) || (crate == obj_id.NULL_ID) ) { } else { int containerAmount = CONTAINER_VOLUME_MAX; if ( total < CONTAINER_VOLUME_MAX ) { containerAmount = total; } addResourceToContainer(crate, resourceId, containerAmount, playerId); total -= containerAmount; ret = utils.addElement(ret, crate); } } } if ( (ret == null) || (ret.length == 0) ) { return null; } return ret; } obj_id[] create(obj_id resourceId, int amt, obj_id targetContainer) { return create(resourceId, amt, targetContainer, obj_id.NULL_ID); } /************************************************************************ * @brief attempts to create and contain a random resource and amt * in the target container. returns obj_id array of resource containers * * @param string resourceClass * @param int amt * @param loc loc * @param obj_id targetContainer * @param obj_id playerId * * @return obj_id[]; null on error ***********************************************************************/ obj_id[] createRandom(string resourceClass, int amt, location loc, obj_id targetContainer, obj_id playerId, int min) { if ( (resourceClass == null) || (resourceClass.equals("")) ) return null; if ( loc == null ) return null; if ( min < 1 ) min = 1; if(!isIdValid(targetContainer)) return null; if (getVolumeFree(targetContainer) <= 0) return null; // Get the resource ID. obj_id resourceId = null; // Resolve targetContainer's location in the world cell if the passed in location is invalid. if ((loc == null || loc.compareTo(new location()) == 0 || (loc.cell != null && loc.cell != obj_id.NULL_ID)) && isIdValid(targetContainer)) { obj_id topmost = getTopMostContainer(targetContainer); if (topmost != targetContainer) { loc = getLocation(topmost); } resourceId = pickRandomNonDepeletedResource(resourceClass); if ( (resourceId == null) || (resourceId == obj_id.NULL_ID) ) return null; } else { // Find valid resources at the passed in location resource_density[] availableResources = requestResourceList(loc, 0.0f, 1.0f, resourceClass); if (availableResources == null || availableResources.length == 0) return null; int idx = rand(0, availableResources.length-1); resourceId = availableResources[idx].getResourceType(); if ( (resourceId == null) || (resourceId == obj_id.NULL_ID) ) return null; } // Store efficiency. float eff = getResourceEfficiency( resourceId, loc ); // Harvest! int finalAmount = oneTimeHarvest( resourceId, amt, loc ); if ( finalAmount < min ) finalAmount = min; // Store final amount. utils.setScriptVar( playerId, "resource.lastEff", eff ); utils.setScriptVar( playerId, "resource.lastAmt", finalAmount ); utils.setScriptVar( playerId, "resource.lastId", resourceId ); // Return the crates! return create( resourceId, finalAmount, targetContainer, playerId ); } obj_id[] createRandom(string resourceClass, int amt, location loc, obj_id targetContainer, obj_id playerId) { return createRandom(resourceClass, amt, loc, targetContainer, playerId, 1); } obj_id[] createRandom(string resourceClass, int amt, location loc, obj_id targetContainer) { return createRandom(resourceClass, amt, loc, targetContainer, obj_id.NULL_ID, 1); } /***** SURVEYING RELATED FUNCTIONS ***************************************/ /************************************************************************ * @brief sets the string value of VAR_SURVEY_CLASS with the appropriate name * * @param obj_id tool * @param int resource_class * * @return boolean ***********************************************************************/ boolean setToolClass(obj_id tool, int resource_class) { if ( tool == null ) { return false; } if ( (resource_class < CLASS_RESOURCE) || (resource_class >= CLASS_MAX) ) { return false; } return setObjVar(tool, VAR_SURVEY_CLASS, CLASS_NAME[resource_class]); } /************************************************************************ * @brief shows list box for selecting survey tool resolution * * @param obj_id user * @param obj_id tool * * @return boolean ***********************************************************************/ boolean requestSetToolRatio(obj_id user, obj_id tool) { if ( (user == null) || (tool == null) ) { return false; } string resource_class = getStringObjVar(tool, resource.VAR_SURVEY_CLASS); if ( resource_class.equals("") ) { sendSystemMessageTestingOnly(user, "ERROR: survey tool broken -> no assigned resource class"); return false; } string baseMod = getSkillModForClass(resource_class); if ( baseMod.equals("") ) { sendSystemMessageTestingOnly(user, "ERROR: survey tool broken -> unknown resource class"); return false; } int rangeVal = getSkillStatMod(user, "surveying") / 20; if (rangeVal < 1) rangeVal = 1; int resVal = getSkillStatMod(user, "surveying") / 20; //if ( rangeVal < 1 ) //{ // prose_package pp = prose.getPackage(SID_NSF_SKILL, getName(tool)); // sendSystemMessageProse(user, pp); // return false; //} int range_min = getIntObjVar(tool, VAR_SURVEY_RANGE_MIN); int range_max = getIntObjVar(tool, VAR_SURVEY_RANGE_MAX); int res_min = getIntObjVar(tool, VAR_SURVEY_RESOLUTION_MIN); int res_max = getIntObjVar(tool, VAR_SURVEY_RESOLUTION_MAX); resizeable string[] options = new string[0]; resizeable int[] ranges = new int[0]; resizeable int[] resolutions = new int[0]; float res = SURVEY_RESOLUTION_MIN; int count = 1; for ( int range = range_min; range <= range_max; range += ((range_max-range_min)/5) ) { if ( count > rangeVal ) break; res += (res_max - res_min) / 5.0; ranges = utils.addElement(ranges, range); resolutions = utils.addElement(resolutions, (int) res); options = utils.addElement(options, "" + range + "m x " + ((int) res) + "pts"); count++; } if(ranges.length == 0 || resolutions.length == 0) { return false; } removeObjVar(tool, VAR_SETTINGS_BASE); setObjVar(tool, VAR_SETTINGS_PLAYER, user); setObjVar(tool, VAR_SETTINGS_RANGES, ranges); setObjVar(tool, VAR_SETTINGS_RESOLUTIONS, resolutions); sui.listbox(tool, user, MSG_SELECT_RANGE, options, HANDLER_SET_RANGE); return true; } /************************************************************************ * @brief attempts to retrieve a sample of resource given the below params * * @param obj_id user * @param obj_id tool * @param string type * * @return boolean ***********************************************************************/ int getSample( obj_id user, obj_id tool, string type ) { if ( (user == null) || (tool == null) || (type.equals("")) ) { return SAMPLE_STOP_LOOP; } //debugSpeakMsg(user, "getSample: type = " + type); obj_id typeId = getResourceTypeByName(type); if ( !isIdValid(typeId) ) { debugSpeakMsg(user, "resource::getSample: unable to retrieve obj_id for " + type); sendSystemMessage(user, SID_SURVEY_ERROR); return SAMPLE_STOP_LOOP; } /* // Old time based sample gating. int stamp = getIntObjVar(user, VAR_SAMPLE_STAMP); int deltaTime = getGameTime() - stamp; if ( deltaTime < TIME_SAMPLE ) { int timeToRecharge = TIME_SAMPLE - deltaTime; prose_package pp = prose.getPackage(SID_TOOL_RECHARGE_TIME, timeToRecharge); sendSystemMessageProse(user, pp); return SAMPLE_STOP_LOOP; } */ string resource_class = getStringObjVar(tool, resource.VAR_SURVEY_CLASS); if ( resource_class == null || resource_class.equals("") ) { sendSystemMessageTestingOnly(user, "ERROR: survey tool broken -> no assigned resource class"); return SAMPLE_STOP_LOOP; } if ( !isResourceDerivedFrom(typeId, resource_class) ) { prose_package pp = prose.getPackage(SID_WRONG_TOOL, type); sendSystemMessageProse(user, pp); return SAMPLE_STOP_LOOP; } float density = getResourceEfficiency(typeId, getLocation(user)); //debugSpeakMsg(user, type + " density = " + density); if ( density < 0 ) { return SAMPLE_STOP_LOOP; } else if ( density < 0.1f ) { prose_package proseFailed = prose.getPackage(SID_EFFICIENCY_TOO_LOW, type); sendSystemMessageProse(user, proseFailed); return SAMPLE_STOP_LOOP; } int modVal = getSkillStatMod(user, "surveying"); //if ( modVal < 1 ) // return SAMPLE_STOP_LOOP; float threshold = SAMPLE_DENSITY_THRESHOLD * ((100f - modVal)/100f); //lower threshold based on skill! if ( density > threshold ) { float deltaDensity = density - threshold; float famt = BASE_SAMPLE_AMOUNT * deltaDensity; //shrink base amount based on deltaDensity //debugSpeakMsg(user, "sample amt = " + amt); if ( famt < 1 ) //ensure that the int conversion leaves us with return amount > 0 { prose_package proseFailed = prose.getPackage(SID_TRACE_AMOUNT, type); sendSystemMessageProse(user, proseFailed); return SAMPLE_STOP_LOOP; } // Check for critical event flags. location nodecritloc = null; int gamble = 0; if ( utils.hasScriptVar( user, "survey_event.tool" ) ) { if ( utils.hasScriptVar( user, "survey_event.gamble" ) ) { // Handle critical gamble event. gamble = utils.getIntScriptVar( user, "survey_event.gamble" );; utils.removeScriptVar( user, "survey_event.gamble" ); utils.removeScriptVar( user, "survey_event.tool" ); } else { // Handle critical node event. obj_id crittool = utils.getObjIdScriptVar( user, "survey_event.tool" ); if ( crittool != tool ) utils.removeScriptVar( user, "survey_event.tool" ); else { nodecritloc = utils.getLocationScriptVar( user, "survey_event.location" ); // Are we near the crit loc? location ploc = getLocation( user ); if ( utils.getDistance2D( ploc, nodecritloc ) > 5 ) { utils.removeScriptVar( user, "survey_event.tool" ); utils.removeScriptVar( user, "survey_event.location" ); nodecritloc = null; sendSystemMessage( user, SID_NODE_NOT_CLOSE ); } } } } int city_id = city.checkCity( user, false ); // Perform a skill check here. float chance = 50f + 20f*((modVal-15f)/85f); if ( chance > 70 ) chance = 70; int roll = rand( 1, 100 ); if ( city_id > 0 && city.cityHasSpec( city_id, city.SF_SPEC_SAMPLE_RICH ) ) chance += 10; if ( (roll <= chance) || (gamble > 0) || (nodecritloc != null) ) { float resultModifier = ((2*chance) - roll)/(2*chance); int amt = (int)(famt * resultModifier); if ( amt == 0 ) amt = 1; // At least one. // Grant a bonus. if ( city_id > 0 && city.cityHasSpec( city_id, city.SF_SPEC_SAMPLE_RICH ) ) amt *= 1.2; // Should we force a critical? if ( gamble == 1 ) { sendSystemMessage( user, SID_GAMBLE_SUCCESS ); amt *= 4; } else if ( gamble == 2 ) { sendSystemMessage( user, SID_GAMBLE_FAIL ); } else if (gamble == 3 ) { sendSystemMessage( user, SID_PET_SEARCH_SUCCESS ); amt *= 3; } else if ( gamble == 4 ) { sendSystemMessage( user, SID_PET_SEARCH_FAIL); } else if ( gamble == 5 ) { sendSystemMessage( user, SID_GAMBLE_RARE); } else if ( nodecritloc != null ) { // Node success. sendSystemMessage( user, SID_NODE_RECOVERY ); amt *= 3; utils.removeScriptVar( user, "survey_event.location" ); utils.removeScriptVar( user, "survey_event.tool" ); } else { // Chance of critical event. int critRoll = rand( 1, 100 ); int rollResult = 10; if(isGod (user)) //Default 10 - Set to 100 for testing pourposes { rollResult = 100; } if ( roll <= rollResult ) { critRoll = rand( 1, 100 ); if ( critRoll <= 50 ) { // Critical success. sendSystemMessage( user, SID_CRITICAL_SUCCESS ); amt *= 2; } else if ( critRoll <= 75 ) { // Concentrated node. Checks if the player meets the requirement for the sampling pet collection. // If true the SUI will be set up with a third option that advances the collection utils.setScriptVar( user, "survey_event.tool", tool ); //Deactivated Pet Sampling collection for now. //Hand sampling pet collection check obj_id beastCheck = (beast_lib.getBeastOnPlayer(user)); if(beastCheck != null) { //Concentrated node event for players with an active collection string[] nodeOptions = new string[3]; nodeOptions[0] = "@survey:cnode_1"; nodeOptions[1] = "@survey:cnode_2"; nodeOptions[2] = "@survey:cnode_collection"; if(!sui.hasPid(user, PID_NAME)) { int pid = sui.listbox( user, user, "@survey:cnode_d", sui.OK_CANCEL, "@survey:cnode_t", nodeOptions, "handleSurveyNodeChoice", true ); sui.setPid(user, pid , PID_NAME); } } else { //Concentrated node for players without the active collection //debugSpeakMsg( user, "Inside pet sample collection. failed check"); string[] nodeOptions = new string[2]; nodeOptions[0] = "@survey:cnode_1"; nodeOptions[1] = "@survey:cnode_2"; if(!sui.hasPid(user, PID_NAME)) { int pid = sui.listbox( user, user, "@survey:cnode_d", sui.OK_CANCEL, "@survey:cnode_t", nodeOptions, "handleSurveyNodeChoice", true ); sui.setPid(user, pid , PID_NAME); } } return SAMPLE_PAUSE_LOOP_EVENT; } else { // Gambler's node. utils.setScriptVar( user, "survey_event.tool", tool ); //Hand sampling collection check string collectionName = "col_resource_" + resource_class + "_01"; if(!hasCompletedCollectionSlot(user, collectionName)) { string[] nodeOptions = new string[3]; nodeOptions[0] = "@survey:gnode_1"; nodeOptions[1] = "@survey:gnode_2"; nodeOptions[2] = "@survey:gnode_collection"; if(!sui.hasPid(user, PID_NAME)) { int pid = sui.listbox( user, user, "@survey:gnode_d", sui.OK_CANCEL, "@survey:gnode_t", nodeOptions, "handleSurveyGambleChoice", true ); sui.setPid(user, pid , PID_NAME); } } else { string[] nodeOptions = new string[2]; nodeOptions[0] = "@survey:gnode_1"; nodeOptions[1] = "@survey:gnode_2"; if(!sui.hasPid(user, PID_NAME)) { int pid = sui.listbox( user, user, "@survey:gnode_d", sui.OK_CANCEL, "@survey:gnode_t", nodeOptions, "handleSurveyGambleChoice", true ); sui.setPid(user, pid , PID_NAME); } } return SAMPLE_PAUSE_LOOP_EVENT; } } } int expertiseResourceIncrease = (int)getSkillStatisticModifier(user, "expertise_resource_sampling_increase"); if(expertiseResourceIncrease > 0) { amt += (int)(amt * (float)(expertiseResourceIncrease / 100.0f)); } //TCG ITEM - Consumable Buff: increases the number of resources gathered by 50% for 1 hour. if(buff.hasBuff(user, "tcg_series4_falleens_fist")) { amt = (int)(amt * 1.5f); LOG("sissynoid", "Granting 50% Increase due to Falleen's Fist Buff"); } string crateTemplate = getResourceContainerTemplate(typeId); if ( !crateTemplate.equals("") ) { obj_id pInv = utils.getInventoryContainer(user); if ( pInv != null ) { obj_id crate = createObject( crateTemplate, pInv, "" ); if ( addResourceToContainer( crate, typeId, amt, user ) ) { location curloc = getLocation( user ); setLocation( crate, curloc ); putIn( crate, pInv, user ); // new player quest if ( hasScript(user, "theme_park.new_player.new_player") ) { dictionary webster = new dictionary(); webster.put("sampling", 1); messageTo(user, "handleNewPlayerArtisanAction", webster, 1, false); } if (hasScript (user, "toad.survey_quest")) { dictionary merriam = new dictionary(); merriam.put ("resource", typeId); messageTo (user, "forceSensitiveQuestInfo", merriam, 1, false); } prose_package proseSuccess = prose.getPackage( SID_SAMPLE_LOCATED, type, amt ); sendSystemMessageProse( user, proseSuccess ); //int xpToGrant = (int)(BASE_HARVEST_XP * resultModifier); //xp.grant(user, xp.HARVEST_INORGANIC, xpToGrant); if ( isResourceDerivedFrom(typeId, "radioactive") ) { //do damage here //debugSpeakMsg(player, "I should have taken radioactive sampling damage"); int pe = resource.getResourceAttribute(typeId, "res_potential_energy"); //debugSpeakMsg(player, resource_type + "'s potential energy value = " + pe); if ( pe > 500 ) { int damage = (pe - 500) / 2; if(damage < 1) damage = 1; int current = getAttrib(user, HEALTH); if(damage > current) damage = (current - 1); addAttribModifier(user, HEALTH, (damage * -1), 0, 0, MOD_POOL); int fatigue = damage / 4; addShockWound(user, fatigue); sendSystemMessage(user, SID_EFFECTS_OF_RADIATION_SICKNESS); } } return SAMPLE_CONTINUE_LOOP; } else { setObjVar( user, "sampleCrateGenFailed", 1 ); sendSystemMessage( user, SID_NO_INV_SPACE ); setObjVar( user, VAR_SAMPLE_STAMP, getGameTime() - TIME_FAIL_BONUS ); return SAMPLE_STOP_LOOP; } } } } } else { prose_package proseFailed = prose.getPackage( SID_DENSITY_BELOW_THESHOLD, type ); sendSystemMessageProse( user, proseFailed ); return SAMPLE_STOP_LOOP; } setObjVar( user, VAR_SAMPLE_STAMP, getGameTime() - TIME_FAIL_BONUS ); prose_package proseFailed = prose.getPackage( SID_SAMPLE_FAILED, type ); sendSystemMessageProse( user, proseFailed ); return SAMPLE_CONTINUE_LOOP_NOSAMPLE; } /************************************************************************ * @brief returns the template string for the resource class from the datatable * * @param obj_id typeId * * @return string; "" on error ***********************************************************************/ string getResourceContainerTemplate(obj_id typeId) { if ( typeId == null ) { return ""; } string tpf = getResourceContainerForType(typeId); if ( tpf.equals("") ) { return DEFAULT_CONTAINER; } return tpf; } /************************************************************************ * @brief shows the tool properties * * @param obj_id target * @param obj_id tool * * @return boolean ***********************************************************************/ boolean showToolProperties(obj_id target, obj_id tool) { if ( (target == null) || (tool == null) ) { return false; } resizeable string[] dsrc = new string[0]; string resource_class = getStringObjVar(tool, resource.VAR_SURVEY_CLASS); dsrc = utils.addElement(dsrc, utils.packStringId(SID_SUI_SURVEY_TOOL_PROPERTIES_RESOURCE_HEADER)); prose_package ppResource = prose.getPackage(SID_SUI_SURVEY_TOOL_PROPERTIES_RESOURCE); prose.setTO(ppResource, resource_class); dsrc = utils.addElement(dsrc, " \0" + packOutOfBandProsePackage(null, ppResource)); dsrc = utils.addElement(dsrc, " "); int res_min = getIntObjVar(tool, resource.VAR_SURVEY_RESOLUTION_MIN); int res_max = getIntObjVar(tool, resource.VAR_SURVEY_RESOLUTION_MAX); int res_val = getIntObjVar(tool, resource.VAR_SURVEY_RESOLUTION_VALUE); dsrc = utils.addElement(dsrc, utils.packStringId(SID_SUI_SURVEY_TOOL_PROPERTIES_RESOLUTION)); prose_package ppResMin = prose.getPackage(SID_SUI_SURVEY_TOOL_PROPERTIES_RESOLUTION_MIN); prose.setDI(ppResMin, res_min); dsrc = utils.addElement(dsrc, " \0" + packOutOfBandProsePackage(null, ppResMin)); prose_package ppResMax = prose.getPackage(SID_SUI_SURVEY_TOOL_PROPERTIES_RESOLUTION_MAX); prose.setDI(ppResMax, res_max); dsrc = utils.addElement(dsrc, " \0" + packOutOfBandProsePackage(null, ppResMax)); prose_package ppResVal = prose.getPackage(SID_SUI_SURVEY_TOOL_PROPERTIES_RESOLUTION_VAL); prose.setDI(ppResVal, res_val); dsrc = utils.addElement(dsrc, " \0" + packOutOfBandProsePackage(null, ppResVal)); dsrc = utils.addElement(dsrc, " "); int range_min = getIntObjVar(tool, resource.VAR_SURVEY_RANGE_MIN); int range_max = getIntObjVar(tool, resource.VAR_SURVEY_RANGE_MAX); int range_val = getIntObjVar(tool, resource.VAR_SURVEY_RANGE_VALUE); dsrc = utils.addElement(dsrc, utils.packStringId(SID_SUI_SURVEY_TOOL_PROPERTIES_RANGE)); prose_package ppRangeMin = prose.getPackage(SID_SUI_SURVEY_TOOL_PROPERTIES_RANGE_MIN); prose.setDI(ppRangeMin, range_min); dsrc = utils.addElement(dsrc, " \0" + packOutOfBandProsePackage(null, ppRangeMin)); prose_package ppRangeMax = prose.getPackage(SID_SUI_SURVEY_TOOL_PROPERTIES_RANGE_MAX); prose.setDI(ppRangeMax, range_max); dsrc = utils.addElement(dsrc, " \0" + packOutOfBandProsePackage(null, ppRangeMax)); prose_package ppRangeVal = prose.getPackage(SID_SUI_SURVEY_TOOL_PROPERTIES_RANGE_VAL); prose.setDI(ppRangeVal, range_val); dsrc = utils.addElement(dsrc, " \0" + packOutOfBandProsePackage(null, ppRangeVal)); if ( (dsrc != null) && (dsrc.length > 0) ) { string title = utils.packStringId(SID_SUI_SURVEY_TOOL_PROPERTIES_TITLE); string header = utils.packStringId(SID_SUI_SURVEY_TOOL_PROPERTIES_HEADER); sui.listbox(target, title, header, dsrc); return true; } return false; } /************************************************************************ * @brief determines if the specified class falls under categorization FLORA STRUCTURAL * * @param string resource_class * * @return boolean ***********************************************************************/ string getSkillModForClass(string resource_class) { if ( resource_class.equals("resource")) { return MOD_SURVEY_ALL; } if ( resource_class.equals("") ) { return ""; } if ( isFloraResource(resource_class) ) { return MOD_SURVEY_FLORA_STRUCTURAL; } if ( isCreatureResource(resource_class) ) { return MOD_SURVEY_CREATURE; } if ( isLiquid(resource_class) ) { return MOD_SURVEY_LIQUID; } if ( isGas(resource_class) ) { return MOD_SURVEY_GAS; } if ( isSolid(resource_class) ) { return MOD_SURVEY_SOLID; } if ( isEnergyWindResource(resource_class) ) { return MOD_SURVEY_ENERGY_WIND; } if ( isEnergySolarResource(resource_class) ) { return MOD_SURVEY_ENERGY_SOLAR; } if ( isEnergyGeoThermal(resource_class) ) { return MOD_SURVEY_ENERGY_GEO; } if ( isInorganic(resource_class) ) { return MOD_SURVEY_INORGANIC; } if ( isOrganic(resource_class) ) { return MOD_SURVEY_ORGANIC; } return ""; } /************************************************************************ * @brief determines if the specified class falls under categorization SOLID * * @param string resource_class * * @return boolean ***********************************************************************/ boolean isEnergyGeoThermal(string resource_class) { if ( resource_class.equals("") ) { return false; } if ( isResourceClassDerivedFrom(resource_class, RT_ENERGY_GEO) ) { return true; } return false; } /************************************************************************ * @brief determines if the specified class falls under categorization SOLID * * @param string resource_class * * @return boolean ***********************************************************************/ boolean isOrganic(string resource_class) { if ( resource_class.equals("") ) { return false; } if ( isResourceClassDerivedFrom(resource_class, RT_ORGANIC) ) { return true; } return false; } /************************************************************************ * @brief determines if the specified class falls under categorization SOLID * * @param string resource_class * * @return boolean ***********************************************************************/ boolean isInorganic(string resource_class) { if ( resource_class.equals("") ) { return false; } if ( isResourceClassDerivedFrom(resource_class, RT_INORGANIC) ) { return true; } return false; } /************************************************************************ * @brief determines if the specified class falls under categorization SOLID * * @param string resource_class * * @return boolean ***********************************************************************/ boolean isSolid(string resource_class) { if ( resource_class.equals("") ) { return false; } if ( isResourceClassDerivedFrom(resource_class, RT_MINERAL) ) { return true; } return false; } /************************************************************************ * @brief determines if the specified class falls under categorization GAS * * @param string resource_class * * @return boolean ***********************************************************************/ boolean isGas(string resource_class) { if ( resource_class.equals("") ) { return false; } if ( isResourceClassDerivedFrom(resource_class, RT_GAS) ) { return true; } return false; } /************************************************************************ * @brief determines if the specified class falls under categorization LIQUID * * @param string resource_class * * @return boolean ***********************************************************************/ boolean isLiquid(string resource_class) { if ( resource_class.equals("") ) { return false; } if ( isResourceClassDerivedFrom(resource_class, RT_LIQUID_WATER) ) { return true; } if ( isResourceClassDerivedFrom(resource_class, RT_LIQUID_CHEMICAL) ) { return true; } return false; } /************************************************************************ * @brief determines if the specified class falls under categorization CREATURE RESOURCE * * @param string resource_class * * @return boolean ***********************************************************************/ boolean isCreatureResource(string resource_class) { if ( resource_class.equals("") ) { return false; } if ( isResourceClassDerivedFrom(resource_class, RT_CREATURE_RESOURCES) ) { return true; } return false; } /************************************************************************ * @brief determines if the specified class falls under categorization FLORA RESOURCE * * @param string resource_class * * @return boolean ***********************************************************************/ boolean isFloraResource(string resource_class) { if ( resource_class.equals("") ) { return false; } if ( isResourceClassDerivedFrom(resource_class, RT_FLORA_RESOURCES) ) { return true; } return false; } /************************************************************************ * @brief determines if the specified class falls under categorization FLORA RESOURCE * * @param string resource_class * * @return boolean ***********************************************************************/ boolean isFloraFoodResource(string resource_class) { if ( resource_class.equals("") ) { return false; } if ( isResourceClassDerivedFrom(resource_class, RT_FLORA_FOOD) ) { return true; } return false; } /************************************************************************ * @brief determines if the specified class falls under categorization FLORA STRUCTURAL * * @param string resource_class * * @return boolean ***********************************************************************/ boolean isFloraStructuralResource(string resource_class) { if ( resource_class.equals("") ) { return false; } if ( isResourceClassDerivedFrom(resource_class, RT_FLORA_STRUCTURAL) ) { return true; } return false; } /************************************************************************ * @brief determines if the specified class falls under categorization ENERGY WIND * * @param string resource_class * * @return boolean ***********************************************************************/ boolean isEnergyWindResource(string resource_class) { if ( resource_class.equals("") ) { return false; } if ( isResourceClassDerivedFrom(resource_class, RT_ENERGY_WIND) ) { return true; } return false; } /************************************************************************ * @brief determines if the specified class falls under categorization ENERGY SOLAR * * @param string resource_class * * @return boolean ***********************************************************************/ boolean isEnergySolarResource(string resource_class) { if ( resource_class.equals("") ) { return false; } if ( isResourceClassDerivedFrom(resource_class, RT_ENERGY_SOLAR) ) { return true; } return false; } string getResourceName( string resource_class ) { int rowNum = dataTableSearchColumnForString( resource_class, 1, DATATABLE_RESOURCES ); if ( rowNum < 0 ) return ""; dictionary row = dataTableGetRow( DATATABLE_RESOURCES, rowNum ); int i = 0; string res = null; while ( (res == null) || (res == "") ) { res = row.getString( "CLASS " + i++ ); } return res; } /************************************************************************ * @brief determines the total energon value on the player * * @param string resource_class * * @return boolean ***********************************************************************/ int getEnergyTotalOnTarget(obj_id target) { if ( !isIdValid(target) ) { return -1; } int cnt = 0; //obj_id[] crates = utils.getContainedGOTObjects(target, GOT_resource_container, true, true); obj_id[] items = getInventoryAndEquipment(target); if ( (items != null) && (items.length > 0) ) { for ( int i = 0; i < items.length; i++ ) { if ( isGameObjectTypeOf(getGameObjectType(items[i]), GOT_resource_container) ) { obj_id rId = getResourceContainerResourceType(items[i]); if ( isIdValid(rId) ) { if ( isResourceDerivedFrom(rId, "energy") || isResourceDerivedFrom(rId, "radioactive") ) { cnt += getPotentialEnergyValue(items[i]); } } } } } return cnt; } int getPotentialEnergyValue(obj_id crate) { if ( !isIdValid(crate) ) return 0; int amt = getResourceContainerQuantity(crate); if ( amt < 1 ) return 0; obj_id rType = getResourceContainerResourceType(crate); if ( !isIdValid(rType) ) return 0; float ratio = getEnergyPowerRatio(rType); return Math.round(ratio * amt); } float getEnergyPowerRatio(obj_id rType) { int potential = getResourceAttribute(rType, "res_potential_energy"); if ( potential < 1 ) return 1f; if ( potential <= 500 ) return 1f; else return 1f + (potential-500f)/500f; } int getResourceAttribute(string resourceName, string attribName) { if ( resourceName == null || resourceName.equals("") ) return -1; return getResourceAttribute(getResourceTypeByName(resourceName), attribName); } /************************************************************************ * @brief determines the first type of geo thermal energy in the player, if there are multiples this will only return 1 * however it will return all instances of that one type contained in the player * * @param obj_id player * * @return dictionary ***********************************************************************/ dictionary getGeoThermalEnergyInformationOnTarget(obj_id target) { if ( !isIdValid(target) ) { return null; } int cnt = 0; string resourceName = ""; int resourceQuality = 0; obj_id[] items = getInventoryAndEquipment(target); resizeable obj_id [] tempListUniqueList = new obj_id[0]; dictionary resourceInfo = new dictionary(); if ( (items != null) && (items.length > 0) ) { for ( int i = 0; i < items.length; i++ ) { if ( isGameObjectTypeOf(getGameObjectType(items[i]), GOT_resource_container) ) { obj_id resourceType = getResourceContainerResourceType(items[i]); if ( isIdValid(resourceType) ) { if ( isResourceDerivedFrom(resourceType, "energy_renewable_site_limited_geothermal") ) { if(tempListUniqueList.length == 0 ) { tempListUniqueList.addElement(resourceType); resourceName = getResourceName(resourceType); resourceQuality = getResourceAttribute(resourceType, "res_quality"); } if( tempListUniqueList.contains(resourceType) ) { cnt += getResourceContainerQuantity(items[i]); } } } } } } resourceInfo.put("resourceName", resourceName); resourceInfo.put("cnt", cnt); resourceInfo.put("resourceQuality", resourceQuality); return resourceInfo; } //------------------------------------------------ // cleanupTool //------------------------------------------------ void cleanupTool(obj_id player, obj_id tool) { if(isIdValid(player)) { removeObjVar( player, "surveying.sampleLocation" ); utils.removeScriptVar(player, "surveying.takingSamples" ); utils.removeScriptVar(player, "surveying.tool" ); utils.removeScriptVar(player, "surveying.surveying" ); } if(isIdValid(tool)) { utils.removeScriptVar(tool, "surveying.takingSamples" ); utils.removeScriptVar(tool, "surveying.player" ); utils.removeScriptVar(tool, "surveying.surveying" ); } } // Returns true if the player has illicit contraband items boolean consumeResource(obj_id player, string resource, int quantity) { obj_id[] contents = getInventoryAndEquipment(player); if(contents == null || contents.length < 1) { return false; } //debugSpeakMsg(player, "hasResource "); for(int i = 0, j = contents.length; i < j; i++) { if(!isIdValid(contents[i]) || !exists(contents[i])) { continue; } // debugSpeakMsg(player, "hasResource 2" + getName(contents[i])); if(!isResourceContainer(contents[i])) { continue; } //debugSpeakMsg(player, "hasResource 3"); obj_id container = getResourceContainerResourceType(contents[i]); if(!isIdValid(container)) { continue; } //debugSpeakMsg(player, "hasResource 4"); string name = getResourceClass(container); string typeName = getResourceName(container); string parent = getResourceParentClass(name); parent = getResourceParentClass(parent); parent = getResourceParentClass(parent); if(resource.equals(parent) && getResourceContainerQuantity(contents[i]) >= quantity) { // sendSystemMessageTestingOnly(player, "container: " + container + " class: " + name + " name: " + typeName + " parent: " + parent); removeResourceFromContainer(contents[i], getResourceContainerResourceType(contents[i]), quantity); return true; } } return false; } // Returns true if the player has illicit contraband items boolean hasResource(obj_id player, string resource, int quantity) { obj_id[] contents = getInventoryAndEquipment(player); if(contents == null || contents.length < 1) { return false; } //debugSpeakMsg(player, "hasResource "); for(int i = 0, j = contents.length; i < j; i++) { if(!isIdValid(contents[i]) || !exists(contents[i])) { continue; } // debugSpeakMsg(player, "hasResource 2" + getName(contents[i])); if(!isResourceContainer(contents[i])) { continue; } //debugSpeakMsg(player, "hasResource 3"); obj_id container = getResourceContainerResourceType(contents[i]); if(!isIdValid(container)) { continue; } //debugSpeakMsg(player, "hasResource 4"); string name = getResourceClass(container); string typeName = getResourceName(container); string parent = getResourceParentClass(name); parent = getResourceParentClass(parent); parent = getResourceParentClass(parent); if(resource.equals(parent) && getResourceContainerQuantity(contents[i]) >= quantity) { // sendSystemMessageTestingOnly(player, "container: " + container + " class: " + name + " name: " + typeName + " parent: " + parent); return true; } } return false; }