mirror of
https://github.com/SWG-Source/dsrc.git
synced 2026-09-11 22:45:06 -04:00
Added logic for lair interactivity
This commit is contained in:
@@ -0,0 +1,187 @@
|
||||
package script.library;
|
||||
|
||||
import script.*;
|
||||
|
||||
public class config_utils extends script.base_script
|
||||
{
|
||||
public config_utils()
|
||||
{
|
||||
}
|
||||
|
||||
public static String getStringConfig(String section, String key) throws InterruptedException
|
||||
{
|
||||
return getStringConfig(section, key, null);
|
||||
}
|
||||
|
||||
public static String getStringConfig(String section, String key, String defaultValue) throws InterruptedException
|
||||
{
|
||||
if (section == null || section.length() <= 0 || key == null || key.length() <= 0)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
String value = getConfigSetting(section, key);
|
||||
|
||||
if (value == null || value.length() <= 0)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public static boolean getBooleanConfig(String section, String key) throws InterruptedException
|
||||
{
|
||||
return getBooleanConfig(section, key, false);
|
||||
}
|
||||
|
||||
public static boolean getBooleanConfig(String section, String key, boolean defaultValue) throws InterruptedException
|
||||
{
|
||||
String value = getStringConfig(section, key, null);
|
||||
|
||||
if (value == null)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
value = value.toLowerCase();
|
||||
|
||||
if (value.equals("true") || value.equals("on") || value.equals("1") || value.equals("yes"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (value.equals("false") || value.equals("off") || value.equals("0") || value.equals("no"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
public static int getIntConfig(String section, String key) throws InterruptedException
|
||||
{
|
||||
return getIntConfig(section, key, 0);
|
||||
}
|
||||
|
||||
public static int getIntConfig(String section, String key, int defaultValue) throws InterruptedException
|
||||
{
|
||||
String value = getStringConfig(section, key, null);
|
||||
|
||||
if (value == null)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return Integer.parseInt(value);
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
public static long getLongConfig(String section, String key) throws InterruptedException
|
||||
{
|
||||
return getLongConfig(section, key, 0);
|
||||
}
|
||||
|
||||
public static long getLongConfig(String section, String key, long defaultValue) throws InterruptedException
|
||||
{
|
||||
String value = getStringConfig(section, key, null);
|
||||
|
||||
if (value == null)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return Long.parseLong(value);
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
public static float getFloatConfig(String section, String key) throws InterruptedException
|
||||
{
|
||||
return getFloatConfig(section, key, 0.0f);
|
||||
}
|
||||
|
||||
public static float getFloatConfig(String section, String key, float defaultValue) throws InterruptedException
|
||||
{
|
||||
String value = getStringConfig(section, key, null);
|
||||
|
||||
if (value == null)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return Float.parseFloat(value);
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
public static double getDoubleConfig(String section, String key) throws InterruptedException
|
||||
{
|
||||
return getDoubleConfig(section, key, 0.0);
|
||||
}
|
||||
|
||||
public static double getDoubleConfig(String section, String key, double defaultValue) throws InterruptedException
|
||||
{
|
||||
String value = getStringConfig(section, key, null);
|
||||
|
||||
if (value == null)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return Double.parseDouble(value);
|
||||
}
|
||||
catch (NumberFormatException e)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
public static int getPercentConfig(String section, String key) throws InterruptedException
|
||||
{
|
||||
return getPercentConfig(section, key, 0);
|
||||
}
|
||||
|
||||
public static int getPercentConfig(String section, String key, int defaultValue) throws InterruptedException
|
||||
{
|
||||
return clampInt(getIntConfig(section, key, defaultValue), 0, 100);
|
||||
}
|
||||
|
||||
public static int getIntConfigClamped(String section, String key, int defaultValue, int minValue, int maxValue) throws InterruptedException
|
||||
{
|
||||
return clampInt(getIntConfig(section, key, defaultValue), minValue, maxValue);
|
||||
}
|
||||
|
||||
public static int clampInt(int value, int minValue, int maxValue)
|
||||
{
|
||||
if (value < minValue)
|
||||
{
|
||||
return minValue;
|
||||
}
|
||||
|
||||
if (value > maxValue)
|
||||
{
|
||||
return maxValue;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
}
|
||||
@@ -51,4 +51,34 @@ public class luck extends script.base_script
|
||||
pp = prose.setStringId(pp, new string_id("system_msg", "lucky_fly_text"));
|
||||
showFlyTextPrivateProseWithFlags(player, player, pp, 1.5f, colors.GOLD, FLY_TEXT_FLAG_IS_LUCKY);
|
||||
}
|
||||
|
||||
public static float getLevelCappedLuck(obj_id player) throws InterruptedException
|
||||
{
|
||||
if (!isPlayer(player))
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
int level = getLevel(player);
|
||||
int cap = level * 5;
|
||||
|
||||
float luckValue = getSkillStatisticModifier(player, "luck");
|
||||
float luckBonus = getEnhancedSkillStatisticModifierUncapped(player, "luck_modified");
|
||||
|
||||
luckValue += luckBonus;
|
||||
|
||||
if (luckValue < 0.0f)
|
||||
{
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
if (luckValue > cap)
|
||||
{
|
||||
return cap;
|
||||
}
|
||||
|
||||
return luckValue;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
package script.systems.npc_lair;
|
||||
|
||||
import script.*;
|
||||
import script.library.luck;
|
||||
import script.library.buff;
|
||||
import script.library.collection;
|
||||
import script.library.resource;
|
||||
import script.library.static_item;
|
||||
import script.library.utils;
|
||||
import script.library.config_utils;
|
||||
|
||||
public class lair_interactivity extends script.base_script
|
||||
{
|
||||
@@ -16,6 +20,7 @@ public class lair_interactivity extends script.base_script
|
||||
public static final int LAIR_BUFF_INCREASE = 2;
|
||||
public static final string_id SID_SEARCH_LAIR = new string_id("lair_n", "search_lair");
|
||||
public static final string_id SID_FOUND_NOTHING = new string_id("lair_n", "found_nothing");
|
||||
public static final string_id SID_LAIR_EMPTY = new string_id("lair_n", "lair_empty");
|
||||
public static final string_id SID_INVENTORY_FULL = new string_id("lair_n", "inventory_full");
|
||||
public static final string_id SID_FOUND_EGGS = new string_id("lair_n", "found_eggs");
|
||||
public static final string_id SID_FOUND_BUGS = new string_id("lair_n", "found_bugs");
|
||||
@@ -34,6 +39,21 @@ public class lair_interactivity extends script.base_script
|
||||
"object/tangible/fishing/bait/bait_worm.iff",
|
||||
"object/tangible/fishing/bait/bait_insect.iff"
|
||||
};
|
||||
|
||||
public static final String CONFIG_SECTION_LAIR_INTERACTIVITY = "LairInteractivity";
|
||||
|
||||
public static final String CONFIG_LAIR_INTERACTIVITY_ENABLED = "enabled";
|
||||
public static final String CONFIG_LAIR_EGG_CHANCE = "eggChance";
|
||||
public static final String CONFIG_LAIR_BUG_CHANCE = "bugChance";
|
||||
public static final String CONFIG_LAIR_NOTHING_CHANCE = "nothingChance";
|
||||
public static final String CONFIG_LAIR_EMPTY_CHANCE = "emptyChance";
|
||||
public static final String CONFIG_LAIR_EGG_AMOUNT_MULTIPLIER_PERCENT = "eggAmountMultiplierPercent";
|
||||
public static final String CONFIG_LAIR_RESET_MINUTES = "resetMinutes";
|
||||
public static final String CONFIG_LAIR_SHOW_EMPTY_MESSAGE = "showEmptyMessage";
|
||||
public static final String CONFIG_LAIR_USE_LUCK = "useLuck";
|
||||
|
||||
public static final String LAIR_SEARCHED_TIME = "lair.searched_time";
|
||||
|
||||
public int OnObjectMenuRequest(obj_id self, obj_id player, menu_info mi) throws InterruptedException
|
||||
{
|
||||
if (!hasObjVar(self, "npc_lair.isCreatureLair"))
|
||||
@@ -57,8 +77,264 @@ public class lair_interactivity extends script.base_script
|
||||
searchLair(self, player);
|
||||
return SCRIPT_CONTINUE;
|
||||
}
|
||||
public void searchLair(obj_id self, obj_id player) throws InterruptedException
|
||||
|
||||
public void searchLair(obj_id self, obj_id player) throws InterruptedException
|
||||
{
|
||||
// Missing [LairInteractivity] or enabled=false preserves vanilla/public behavior.
|
||||
if (!config_utils.getBooleanConfig(CONFIG_SECTION_LAIR_INTERACTIVITY, CONFIG_LAIR_INTERACTIVITY_ENABLED))
|
||||
{
|
||||
searchLairVanilla(self, player);
|
||||
return;
|
||||
}
|
||||
|
||||
searchLairInteractivity(self, player);
|
||||
}
|
||||
|
||||
private void searchLairInteractivity(obj_id self, obj_id player) throws InterruptedException
|
||||
{
|
||||
if (utils.hasScriptVar(self, LAIR_SEARCHED))
|
||||
{
|
||||
if (hasLairSearchResetExpired(self))
|
||||
{
|
||||
resetLairSearchState(self);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (config_utils.getBooleanConfig(CONFIG_SECTION_LAIR_INTERACTIVITY, CONFIG_LAIR_SHOW_EMPTY_MESSAGE, true))
|
||||
{
|
||||
sendSystemMessage(player, SID_LAIR_EMPTY);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
obj_id pInv = utils.getInventoryContainer(player);
|
||||
|
||||
if (!isValidId(pInv) || !exists(pInv))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (getVolumeFree(pInv) <= 0)
|
||||
{
|
||||
sendSystemMessage(player, SID_INVENTORY_FULL);
|
||||
return;
|
||||
}
|
||||
|
||||
int result = rollLairSearchResult();
|
||||
|
||||
if (result == 0)
|
||||
{
|
||||
sendSystemMessage(player, SID_FOUND_NOTHING);
|
||||
return;
|
||||
}
|
||||
|
||||
if (result == 1)
|
||||
{
|
||||
searchLairEggs(self, player, pInv);
|
||||
}
|
||||
else
|
||||
{
|
||||
searchLairBugs(player, pInv);
|
||||
}
|
||||
|
||||
rollLairEmpty(self, player);
|
||||
}
|
||||
|
||||
private int rollLairSearchResult() throws InterruptedException
|
||||
{
|
||||
int nothingChance = config_utils.getPercentConfig(CONFIG_SECTION_LAIR_INTERACTIVITY, CONFIG_LAIR_NOTHING_CHANCE, 10);
|
||||
int eggChance = config_utils.getPercentConfig(CONFIG_SECTION_LAIR_INTERACTIVITY, CONFIG_LAIR_EGG_CHANCE, 80);
|
||||
int bugChance = config_utils.getPercentConfig(CONFIG_SECTION_LAIR_INTERACTIVITY, CONFIG_LAIR_BUG_CHANCE, 10);
|
||||
|
||||
int totalChance = nothingChance + eggChance + bugChance;
|
||||
|
||||
if (totalChance <= 0)
|
||||
{
|
||||
nothingChance = 10;
|
||||
eggChance = 80;
|
||||
bugChance = 10;
|
||||
totalChance = 100;
|
||||
}
|
||||
|
||||
int roll = rand(1, totalChance);
|
||||
|
||||
if (roll <= nothingChance)
|
||||
{
|
||||
return 0; // nothing
|
||||
}
|
||||
|
||||
if (roll <= nothingChance + eggChance)
|
||||
{
|
||||
return 1; // eggs
|
||||
}
|
||||
|
||||
return 2; // bugs
|
||||
}
|
||||
|
||||
private void searchLairEggs(obj_id self, obj_id player, obj_id pInv) throws InterruptedException
|
||||
{
|
||||
sendSystemMessage(player, SID_FOUND_EGGS);
|
||||
|
||||
int amount = rand(10, 20);
|
||||
|
||||
int skillMod = getSkillStatMod(player, "creature_harvesting");
|
||||
|
||||
if (skillMod > 0)
|
||||
{
|
||||
amount += rand(1, skillMod);
|
||||
}
|
||||
|
||||
if (buff.hasBuff(player, "lair_egg_buff"))
|
||||
{
|
||||
amount = amount * LAIR_BUFF_INCREASE;
|
||||
}
|
||||
|
||||
int multiplierPercent = config_utils.getIntConfigClamped(
|
||||
CONFIG_SECTION_LAIR_INTERACTIVITY,
|
||||
CONFIG_LAIR_EGG_AMOUNT_MULTIPLIER_PERCENT,
|
||||
100,
|
||||
0,
|
||||
10000
|
||||
);
|
||||
|
||||
amount = amount * multiplierPercent / 100;
|
||||
|
||||
if (amount <= 0)
|
||||
{
|
||||
sendSystemMessage(player, SID_FOUND_NOTHING);
|
||||
return;
|
||||
}
|
||||
|
||||
obj_id[] resourceList = resource.createRandom("meat_egg_" + getCurrentSceneName(), amount, getLocation(self), pInv, player, 2);
|
||||
|
||||
if (resourceList == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
location curloc = getLocation(player);
|
||||
|
||||
if (curloc == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (obj_id obj_id : resourceList)
|
||||
{
|
||||
setLocation(obj_id, curloc);
|
||||
putIn(obj_id, pInv, player);
|
||||
}
|
||||
|
||||
if (config_utils.getBooleanConfig(CONFIG_SECTION_LAIR_INTERACTIVITY, CONFIG_LAIR_USE_LUCK, true))
|
||||
{
|
||||
float luckValue = luck.getLevelCappedLuck(player);
|
||||
|
||||
if (luck.isLucky(player))
|
||||
{
|
||||
static_item.createNewItemFunction(collection.PRISTINE_EGG, player);
|
||||
sendSystemMessage(player, new string_id("collection", "resource_egg"));
|
||||
}
|
||||
|
||||
collection.collectionResource(player, "egg", Math.round(luckValue / 100));
|
||||
}
|
||||
}
|
||||
|
||||
private void searchLairBugs(obj_id player, obj_id pInv) throws InterruptedException
|
||||
{
|
||||
sendSystemMessage(player, SID_FOUND_BUGS);
|
||||
|
||||
if (rand(1, 100) < 50)
|
||||
{
|
||||
createObject(RARE_BUG_SAMPLE_OBJECTS[rand(0, RARE_BUG_SAMPLE_OBJECTS.length - 1)], pInv, "");
|
||||
}
|
||||
else
|
||||
{
|
||||
createObject(BUG_SAMPLE_OBJECTS[rand(0, BUG_SAMPLE_OBJECTS.length - 1)], pInv, "");
|
||||
}
|
||||
}
|
||||
|
||||
private void rollLairEmpty(obj_id self, obj_id player) throws InterruptedException
|
||||
{
|
||||
int emptyChance = config_utils.getPercentConfig(CONFIG_SECTION_LAIR_INTERACTIVITY, CONFIG_LAIR_EMPTY_CHANCE, 34);
|
||||
|
||||
if (emptyChance <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int roll = rand(1, 100);
|
||||
|
||||
if (config_utils.getBooleanConfig(CONFIG_SECTION_LAIR_INTERACTIVITY, CONFIG_LAIR_USE_LUCK, true))
|
||||
{
|
||||
float luckValue = luck.getLevelCappedLuck(player);
|
||||
roll -= Math.round(luckValue / 100);
|
||||
}
|
||||
|
||||
if (roll <= emptyChance)
|
||||
{
|
||||
markLairSearched(self);
|
||||
}
|
||||
}
|
||||
|
||||
private void markLairSearched(obj_id self) throws InterruptedException
|
||||
{
|
||||
utils.setScriptVar(self, LAIR_SEARCHED, 1);
|
||||
|
||||
int resetMinutes = getLairResetMinutes();
|
||||
|
||||
if (resetMinutes > 0)
|
||||
{
|
||||
utils.setScriptVar(self, LAIR_SEARCHED_TIME, getGameTime());
|
||||
}
|
||||
}
|
||||
|
||||
private void resetLairSearchState(obj_id self) throws InterruptedException
|
||||
{
|
||||
utils.removeScriptVar(self, LAIR_SEARCHED);
|
||||
utils.removeScriptVar(self, LAIR_SEARCHED_TIME);
|
||||
}
|
||||
|
||||
|
||||
private boolean hasLairSearchResetExpired(obj_id self) throws InterruptedException
|
||||
{
|
||||
int resetMinutes = getLairResetMinutes();
|
||||
|
||||
if (resetMinutes <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!utils.hasScriptVar(self, LAIR_SEARCHED_TIME))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int searchedTime = utils.getIntScriptVar(self, LAIR_SEARCHED_TIME);
|
||||
int resetSeconds = resetMinutes * 60;
|
||||
|
||||
return getGameTime() - searchedTime >= resetSeconds;
|
||||
}
|
||||
|
||||
|
||||
private int getLairResetMinutes() throws InterruptedException
|
||||
{
|
||||
return config_utils.getIntConfigClamped(
|
||||
CONFIG_SECTION_LAIR_INTERACTIVITY,
|
||||
CONFIG_LAIR_RESET_MINUTES,
|
||||
0,
|
||||
0,
|
||||
10080
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
public void searchLairVanilla(obj_id self, obj_id player) throws InterruptedException
|
||||
{
|
||||
|
||||
//This is the original lair seraching code
|
||||
|
||||
if (utils.hasScriptVar(self, LAIR_SEARCHED))
|
||||
{
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user