Add per-search find-chance and item count to config
YAInteractableEntry gains SearchChance (% chance a search yields anything), SearchMin/SearchMax (item count on success), replacing the global roll constants. Search rolls the chance first; on success spawns a random count in [SearchMin, SearchMax] from the loot table. Defaults: lekarnicka 60% 1-2, fridge 75% 1-2. Fields have inline defaults so older JSON loads safely. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
41c8e29cea
commit
7fb07aac4a
5 changed files with 42 additions and 13 deletions
|
|
@ -40,6 +40,9 @@ Generated on first start under `<ProfileFolder>/YAInteraction/`:
|
|||
- **`settings.json`** — scalar tunables: `WaterAmountMin`, `WaterAmountMax`,
|
||||
`SinkPlayerCooldownSec`, `ObjectCooldownSec`.
|
||||
- **`interactables.json`** — the `Interactables` registry and all `LootTables`.
|
||||
Each search entry has `SearchChance` (% chance a search yields anything),
|
||||
`SearchMin`/`SearchMax` (item count on a successful search), `CooldownSec`,
|
||||
and a `LootTableName`.
|
||||
|
||||
Delete a file and restart to regenerate it from code defaults.
|
||||
|
||||
|
|
|
|||
|
|
@ -57,16 +57,33 @@ class ActionYASearch : YAProxyActionBase
|
|||
return;
|
||||
}
|
||||
|
||||
array<ref YALootEntry> table = YAInteractionManager.GetLootTableForEntry(entry);
|
||||
int rolls = Math.RandomIntInclusive(YAInteractionConfig.SEARCH_ROLLS_MIN, YAInteractionConfig.SEARCH_ROLLS_MAX);
|
||||
array<EntityAI> spawned = YALootTableManager.GetInstance().SpawnFromTable(table, rolls, player, player.GetPosition());
|
||||
|
||||
// Searching gates the object whether or not it yields anything.
|
||||
YAInteractionManager.StampSearchCooldown(posKey, entry.CooldownSec);
|
||||
|
||||
Print(string.Format("[YAInteraction] %1 searched '%2' @ %3 -> %4 item(s)", player.GetIdentity().GetId(), proxyName, posKey, spawned.Count()));
|
||||
// Find-chance roll.
|
||||
if (Math.RandomFloat(0, 100) >= entry.SearchChance)
|
||||
{
|
||||
Print(string.Format("[YAInteraction] %1 searched '%2' @ %3 -> nothing (%4%% chance)", player.GetIdentity().GetId(), proxyName, posKey, entry.SearchChance));
|
||||
player.MessageStatus("You found nothing useful.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (spawned.Count() > 0)
|
||||
player.MessageStatus(string.Format("You found %1 item(s).", spawned.Count()));
|
||||
int count = Math.RandomIntInclusive(entry.SearchMin, entry.SearchMax);
|
||||
array<EntityAI> spawned;
|
||||
if (count > 0)
|
||||
{
|
||||
array<ref YALootEntry> table = YAInteractionManager.GetLootTableForEntry(entry);
|
||||
spawned = YALootTableManager.GetInstance().SpawnFromTable(table, count, player, player.GetPosition());
|
||||
}
|
||||
|
||||
int found;
|
||||
if (spawned)
|
||||
found = spawned.Count();
|
||||
|
||||
Print(string.Format("[YAInteraction] %1 searched '%2' @ %3 -> %4 item(s)", player.GetIdentity().GetId(), proxyName, posKey, found));
|
||||
|
||||
if (found > 0)
|
||||
player.MessageStatus(string.Format("You found %1 item(s).", found));
|
||||
else
|
||||
player.MessageStatus("You found nothing useful.");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,8 +18,8 @@ class YAInteractionConfig
|
|||
|
||||
// Non-JSON engine constants.
|
||||
static const int WATER_LIQUID_TYPE = LIQUID_WATER;
|
||||
static const int SEARCH_ROLLS_MIN = 1;
|
||||
static const int SEARCH_ROLLS_MAX = 2;
|
||||
// (search find-chance and item count are per-interactable: YAInteractableEntry
|
||||
// SearchChance / SearchMin / SearchMax)
|
||||
|
||||
// Progress-bar durations (seconds).
|
||||
static const float SEARCH_TIME = 3.0;
|
||||
|
|
|
|||
|
|
@ -110,9 +110,10 @@ class YAInteractionConfigLoader
|
|||
// Proxy names (from YAProxy scan / DayZ editor): the resolved name carries
|
||||
// a ".NNN" instance suffix (e.g. "fridge.001"); the keyword is matched as
|
||||
// a substring, so the base name is enough.
|
||||
// (proxyName, actionType, lootTable, cooldownSec, searchChance%, searchMin, searchMax)
|
||||
d.Interactables.Insert(MakeEntry("case_sink_a", YAInteractionConfig.ACTION_REPAIR_WATER, "", Settings.SinkPlayerCooldownSec));
|
||||
d.Interactables.Insert(MakeEntry("lekarnicka", YAInteractionConfig.ACTION_SEARCH, YAInteractionConfig.TABLE_MED, Settings.ObjectCooldownSec));
|
||||
d.Interactables.Insert(MakeEntry("fridge", YAInteractionConfig.ACTION_SEARCH, YAInteractionConfig.TABLE_FOOD, Settings.ObjectCooldownSec));
|
||||
d.Interactables.Insert(MakeEntry("lekarnicka", YAInteractionConfig.ACTION_SEARCH, YAInteractionConfig.TABLE_MED, Settings.ObjectCooldownSec, 60.0, 1, 2));
|
||||
d.Interactables.Insert(MakeEntry("fridge", YAInteractionConfig.ACTION_SEARCH, YAInteractionConfig.TABLE_FOOD, Settings.ObjectCooldownSec, 75.0, 1, 2));
|
||||
// Vending machines deferred: in tested buildings the proxy has no targetable
|
||||
// object (target.GetObject()==null), so it can't be detected/overridden
|
||||
// cleanly. VendingTable below is kept for when that's solved or moved to a
|
||||
|
|
@ -151,13 +152,16 @@ class YAInteractionConfigLoader
|
|||
// --- Factory helpers (data classes have no parameterised ctor so the
|
||||
// JSON serializer can default-construct them). ---
|
||||
|
||||
private static YAInteractableEntry MakeEntry(string proxyName, string actionType, string lootTableName, float cooldownSec)
|
||||
private static YAInteractableEntry MakeEntry(string proxyName, string actionType, string lootTableName, float cooldownSec, float searchChance = 100.0, int searchMin = 1, int searchMax = 1)
|
||||
{
|
||||
YAInteractableEntry e = new YAInteractableEntry();
|
||||
e.ProxyName = proxyName;
|
||||
e.ActionType = actionType;
|
||||
e.LootTableName = lootTableName;
|
||||
e.CooldownSec = cooldownSec;
|
||||
e.SearchChance = searchChance;
|
||||
e.SearchMin = searchMin;
|
||||
e.SearchMax = searchMax;
|
||||
return e;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,10 +29,15 @@ class YALootTable
|
|||
|
||||
class YAInteractableEntry
|
||||
{
|
||||
string ProxyName; // in-house proxy selection name (ZenProxyFramework)
|
||||
string ProxyName; // in-house proxy selection name (matched as substring)
|
||||
string ActionType; // "search" or "repair_water" (YAInteractionConfig.ACTION_*)
|
||||
string LootTableName; // named loot table (empty for repair_water)
|
||||
float CooldownSec; // search: per-object cooldown / water: per-player cooldown
|
||||
|
||||
// --- search tuning (ignored for repair_water) ---
|
||||
float SearchChance = 100.0; // % chance a search yields anything (0-100)
|
||||
int SearchMin = 1; // min items on a successful search
|
||||
int SearchMax = 1; // max items on a successful search
|
||||
}
|
||||
|
||||
class YAInteractionData
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue