Self-contained framework for attaching user actions to furniture proxies inside house models. Detection via geometry-LOD selection scan (works on DayZ 1.29); resolved proxy name + world position synced to server via ActionData. No entities used for detection. - modded House: geometry-LOD proxy position/name maps (client-side) - YAProxyActionBase: cursor->proxy matching + sync + subclass hooks - YAProxyActionData: client->server proxy target sync - YAProxyDebug: validation action + per-house scan logging (DEBUG flag) Credit: Zenarchist (ZenProxyFramework) and ShowMeInfoV2. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
66 lines
3.1 KiB
Markdown
66 lines
3.1 KiB
Markdown
# YAProxy
|
|
|
|
A lightweight DayZ framework (1.29+) for attaching user actions to **furniture
|
|
proxies** baked into house models (sinks, fridges, cabinets, vending machines,
|
|
…), which are not separate entities.
|
|
|
|
Credit: technique combines **Zenarchist's ZenProxyFramework** (action API /
|
|
client→server position sync, invisible-entity persistence pattern) and the
|
|
**ShowMeInfoV2** mod (geometry-LOD proxy enumeration that works on 1.29).
|
|
|
|
## How it works
|
|
- `modded House` reads the building's **geometry LOD selections**
|
|
(`GetLODByName(LOD.NAME_GEOMETRY).GetSelections()`), finds those containing a
|
|
proxy path, and builds `position → proxy name` maps (client-side).
|
|
- `YAProxyActionBase` resolves which proxy the cursor is on, and syncs the
|
|
resolved **name + world position** to the server via `ActionData`.
|
|
- Detection uses **no entities**. (Spawning an invisible marker entity is only
|
|
one option a consumer can use for *persistent state*, e.g. "sink is repaired
|
|
for N days" — handled by the consuming mod, not here.)
|
|
|
|
## Writing an action (consumer mods)
|
|
```c
|
|
class ActionMySearch : YAProxyActionBase
|
|
{
|
|
override string GetProxyKeywords() { return "fridge,lekarnicka"; } // substring match; "*" = any
|
|
override float GetDuration() { return 3.0; }
|
|
override string GetText() { return "Search"; }
|
|
|
|
// optional extra availability check (client)
|
|
override bool YA_ExtraCondition(PlayerBase p, ActionTarget t, ItemBase i, string name, vector ws)
|
|
{ return !p.GetItemInHands(); }
|
|
|
|
override void OnFinishProgressServer(ActionData ad)
|
|
{
|
|
string proxy = GetProxyName(ad); // synced proxy name
|
|
vector ws = GetProxyWS(ad); // synced world position
|
|
// ... your effect ...
|
|
}
|
|
}
|
|
```
|
|
Register it (required, or `AddAction` dereferences null):
|
|
```c
|
|
modded class ActionConstructor { override void RegisterActions(TTypenameArray a){ super.RegisterActions(a); a.Insert(ActionMySearch); } }
|
|
```
|
|
Attach it where it should appear:
|
|
- empty-handed → `modded PlayerBase.SetActions(out TInputActionMap m){ super...; AddAction(ActionMySearch, m); }`
|
|
- tool/container in hands → `modded Wrench / Bottle_Base .SetActions(){ super...; AddAction(ActionMySearch); }`
|
|
|
|
For an item-in-hands action, override `CreateConditionComponents()` to use
|
|
`CCINonRuined` instead of the default `CCINotPresent`.
|
|
|
|
## Debug / discovery
|
|
`YAProxyConstants.DEBUG` (default **true** during bring-up) enables:
|
|
- per-house scan logs: `[YAProxy] House 'Land_X' proxies built: map1=N map2=M`
|
|
- an empty-handed **"Proxy: \<name\>"** action on any proxy that, on execute,
|
|
dumps the resolved name, local vs world position, the full house proxy map,
|
|
and the server-synced values.
|
|
|
|
Set `DEBUG = false` for production (and remove `YAProxyDebug.c` if desired).
|
|
|
|
## Notes / limitations
|
|
- A building only scans if its script class is `House`. Many vanilla buildings
|
|
aren't `House` by default; declare them `class Land_X : House {}` (see
|
|
ZenProxyFramework's `ScriptedBuildings.c` for a curated list) as needed.
|
|
- Some proxies are missed by the LOD scan and need manual position overrides
|
|
(also per-building) — a future addition if required.
|