UNPKG

anomaly-packer

Version:

Anomaly Packer is a utility package for STALKER Anomaly creators to help them develop addons at speed with TypeScript's type-safety and game-oriented build tools.

307 lines (305 loc) 20.4 kB
// AUTO-GENERATED addon pack for `xlib` by `anomaly-packer gen-addon`. Lua API of xsquad.script. // Refine `TODO` (= any) by hand where the mod gave no type. /** @noSelf */ declare const xsquad: { /** * Acquire: set scripted_target (routes to specific_update), clear __lock (AP does not use it) * scripted_target alone overrides simulation targeting; __lock cleared so generic_update can run if another mod clears scripted_target * @safety SAFE - pure field writes on squad userdata, rejects nil/empty :name() * @cost O(1) | 1 luabind heavy (target_smart:name() shared_str alloc) + 4 trivial userdata field writes (scripted_target, __lock, rush_to_target, assigned_target_id, current_action) * @src anomaly/sim_squad_scripted.script(258,233-238), anomaly/xr_reach_task.script(289-314) * @param squad Squad server object * @param target_smart Target smart terrain * @param rush Rush to target (move.run + anim.danger when online) * @returns Success */ acquire_squad(squad: AnyTable, target_smart: AnyTable, rush: boolean | undefined): boolean /** * Dump SIMBOARD squads as a diagnostic string * Shows raw engine fields plus commander's service role. When level_id is provided, filters to that level. * Offline commanders show role="off"; non-service-NPC commanders show role="none". * @safety SAFE - iter_squads handles nil SIMBOARD, read-only field access * @cost O(n) squads | per squad: 1 medium (sim:object) + 1 heavy (community shared_str) + 1 medium (npc_count) + 0-2 trivial (lvid cached, vertex field) + commander_role * @src anomaly/sim_squad_scripted.script(35,39), xlibs/xdata.script npc_roles * @param level_id Restrict to this level when provided * @returns Diagnostic dump */ dump_squads(level_id: number | undefined): string /** * Find squad matching criteria within distance range * Iterates opts.source (when provided) or SIMBOARD.squads; resolves each via alife_object, filters by faction/distance/level * @scope global - iterates the supplied pool. When opts.source is nil, walks SIMBOARD.squads across all levels. * @safety SAFE - SIMBOARD iteration, alife_object returns nil for deleted * @cost O(n) squads in pool | per squad: 1 medium (sim:object xr_map find) + 1 trivial (distance_to_sqr inline math); is_protected adds up to 4 luabind on commander resolve * @src anomaly/sim_board.script(84), anomaly/_g.script(2044), xray/xrGame/alife_object_registry_inline.h(36) * @param pos Origin position * @param opts { factions, max_distance, min_distance, exclude_squad_id, level_id, * exclude_at_smart_id, exclude_permanent, exclude_active_role, exclude_task_target, * exclude_scripted, exclude_filter, exclude_ids, source } * source: optional { [squad_id] = true, ... } iterable. When present, replaces SIMBOARD.squads as the iteration pool. * Use AlifePlus ap_core_cache.squads_on_level(level_id) to fetch a per-level bucket. * @returns Nearest matching squad */ find_squad(pos: TODO, opts: AnyTable): AnyTable | undefined /** * Find multiple squads matching criteria * Same as find_squad but returns up to max_count results via random sampling * @scope global - iterates the supplied pool. When opts.source is nil, walks SIMBOARD.squads across all levels. * @safety SAFE - SIMBOARD iteration, alife_object returns nil for deleted * @cost O(n) squads in pool | per squad: 1 medium (sim:object xr_map find) + 1 trivial (distance_to_sqr inline math); is_protected adds up to 4 luabind on commander resolve * @src anomaly/sim_board.script(84), anomaly/_g.script(2044), xray/xrGame/alife_object_registry_inline.h(36) * @param pos Origin position * @param opts { factions, max_distance, min_distance, exclude_squad_id, level_id, * max_count, exclude_at_smart_id, exclude_permanent, exclude_active_role, * exclude_task_target, exclude_scripted, exclude_filter, exclude_ids, source } * source: optional { [squad_id] = true, ... } iterable. When present, replaces SIMBOARD.squads as the iteration pool. * Use AlifePlus ap_core_cache.squads_on_level(level_id) to fetch a per-level bucket. * @returns Array of squad server objects */ find_squads(pos: TODO, opts: AnyTable): AnyTable /** * Get squad commander's character name (human-readable) * Tries online game_object first (db.storage hit + character_name = 3 luabind), falls back * to cse_alife_trader_abstract:character_name() for offline commanders (4 luabind, server-side * string field). m_character_name is populated at NPC spawn (TranslateName of generated * name_X:lname_Y) and persists in saves; both paths return identical strings since * set_character_name_script propagates writes to both the cse field and the inventory owner. * @safety SAFE - all lookups nil-guarded; IsStalker filters non-stalker classes on both paths * @cost O(1) | 3 luabind online (commander_id, IsStalker, character_name); 4 luabind offline (+alife_object, +clsid) * @src xray/xrServerEntities/xrServer_Objects_ALife_Monsters_script.cpp(74), xray/xrServerEntities/xrServer_Objects_ALife_Monsters.cpp(284, 518) * @param squad Squad server object * @returns Commander's character name, or nil for empty squads / non-stalkers / unregistered commanders */ get_commander_name(squad: TODO): string | undefined /** * Get squad commander's character rank as integer * Tries online game_object first (db.storage hit + character_rank = 3 luabind), falls back * to cse_alife_trader_abstract:rank() for offline commanders (4 luabind). The two paths read * different fields (CharacterInfo().Rank() online vs CSE_ALifeTraderAbstract::m_rank offline) * but they are kept in sync atomically by CInventoryOwner::SetRank (InventoryOwner.cpp:462-465); * both seeded from RankDef at first specific_character() resolution. * @safety SAFE - all lookups nil-guarded; IsStalker filters non-stalker classes on both paths * @cost O(1) | 3 luabind online (commander_id, IsStalker, character_rank); 4 luabind offline (+alife_object, +clsid, +rank) * @src xray/xrGame/script_game_object_script3.cpp(309), xray/xrServerEntities/xrServer_Objects_ALife_Monsters_script4.cpp(125) * @param squad Squad server object * @returns Commander rank, or 0 for empty squads / non-stalkers / unresolved commanders */ get_commander_rank(squad: TODO): number /** * Get raw squad community id (faction key), untranslated * The untranslated sibling of get_community_name: returns the engine community string * (e.g. "dolg", "stalker") for use as a faction KEY, not display text. get_community_name * runs the result through game.translate_string and must not be used where the raw id matters. * @safety SAFE - nil-guarded squad + method presence check * @cost O(1) | 1 luabind (get_squad_community heavy shared_str return) on hit * @src anomaly/sim_squad_scripted.script(857) get_squad_community * @param squad Squad server object * @returns Raw community id, or nil if no squad / no community method */ get_community(squad: TODO): string | undefined /** * Get translated squad community name * Safe wrapper: nil-guarded get_squad_community + game.translate_string * @safety SAFE - nil-guarded, falls back to "stalker" translation key * @cost O(log n) | 2 luabind (get_squad_community heavy shared_str return, translate_string medium std::map find on STRING_TABLE_MAP) * @src anomaly/sim_squad_scripted.script(105), anomaly/_g.script(2273), xray/xrGame/string_table.cpp(226) * @param squad Squad server object * @returns Translated community name (never nil) */ get_community_name(squad: TODO): string /** * Get squad containing an NPC by member ID * Looks up se_npc via alife_object, reads group_id, resolves squad via alife_object * @safety SAFE - returns nil for invalid IDs, group_id >= INVALID_ENTITY_ID means no squad * @cost O(log n) | 2 luabind medium (alife_object for NPC + alife_object for squad, both xr_map finds) + 1 trivial (group_id field read on cse userdata) * @src anomaly/_g.script(2044), xray/xrGame/alife_simulator_script.cpp(40) * @param npc_id NPC ID (can be offline) * @returns Squad server object or nil if not in squad */ get_squad_by_member(npc_id: number): TODO | undefined /** * Get squad's current smart terrain * Reads smart_id or assigned_target_id, resolves via alife_object, rejects non-smart entities via clsid check * @safety SAFE - returns nil for nil squad, missing entity, or non-smart entity * @cost O(log n) | 2 luabind (alife_object medium + clsid trivial) * @src anomaly/sim_squad_scripted.script(102,288), anomaly/_g.script(2044), xray/xrGame/alife_object_registry_inline.h(36) * @param squad Squad object * @returns Current smart terrain or nil */ get_squad_smart(squad: TODO): TODO | undefined /** * Check if squad currently has a system-assigned role that prevents scripting * Dynamic, re-evaluated every call (roles change as tasks are accepted/dismissed). * @safety SAFE - nil-guarded, O(t) task_info scan for task_giver * @cost O(1) commander resolve + O(t) task_info scan (t = 3-10 typical) | 3 luabind: commander_id trivial + alife_object medium + section_name heavy; task scan pure Lua * @src anomaly/axr_companions.script(25,150), anomaly/axr_task_manager.script task_info * @param squad Squad server object * @returns True if has active role (nil squad returns true for safety) * @returns Reason: "nil", "task_giver", "companion" * @returns Commander section_name */ has_active_role(squad: TODO): LuaMultiReturn<[boolean, string | undefined, string | undefined]> /** * Short-circuiting boolean: any squad within max_distance matches? * Same filter scaffolding as find_squad (faction, exclusion, level, distance) plus optional * opts.match per-squad predicate. Exits true on first match — no collection, no sampling. * Use when the consumer is boolean (does X exist nearby?) and find_squads' collect-all-then-sample * pattern wastes the walk. * @scope global - iterates the supplied pool. When opts.source is nil, walks SIMBOARD.squads across all levels. * @safety SAFE - SIMBOARD iteration, alife_object returns nil for deleted * @cost O(n) squads in pool worst case, short-circuits on first match | per squad: 1 medium (sim:object xr_map find) + 1 trivial (distance_to_sqr inline math); opts.match cost set by caller * @src anomaly/sim_board.script(84), anomaly/_g.script(2044), xray/xrGame/alife_object_registry_inline.h(36) * @param pos Origin position * @param opts { factions, max_distance, min_distance, exclude_squad_id, level_id, * exclude_at_smart_id, exclude_permanent, exclude_active_role, exclude_task_target, * exclude_scripted, exclude_filter, exclude_ids, source, match } * source: optional { [squad_id] = true, ... } iterable. When present, replaces SIMBOARD.squads as the iteration pool. * Use AlifePlus ap_core_cache.squads_on_level(level_id) to fetch a per-level bucket. * match: optional function(squad) -> boolean per-squad predicate evaluated after distance gate. * @returns True on first matching squad, false after walking pool */ has_squad(pos: TODO, opts: AnyTable): boolean /** * Check if squad has permanent protected identity (story, trader, named NPC, empty) * Static within session. Cached per squad object (weak keys, GC-safe). * @safety SAFE - returns true for nil (fail-safe), alife_object returns nil for invalid * @cost O(1) cache hit | uncached 4-5 luabind mixed weights (story_id 0, commander_id trivial, alife_object medium, section_name heavy, clsid trivial, community heavy) * @src anomaly/_g.script(2674) get_object_story_id * @param squad Squad server object * @returns True if permanent (nil squad returns true for safety) * @returns Reason: "nil_squad", "not_squad", "story_id", "trader", "named_npc", "empty_squad" * @returns Commander section_name (for "trader" and "named_npc" reasons) */ is_permanent_squad(squad: TODO): LuaMultiReturn<[boolean, string | undefined, string | undefined]> /** * Check all protection guards with shared commander context * Order: exclude_filter (cheapest) -> scripted -> permanent -> active_role (reuses cmd_id) -> task_target * @safety SAFE - nil-guarded, returns true for nil squad (fail-safe) * @cost O(1) cached | 0 luabind (cache hit) or 4-5 luabind medium (miss: alife_object, clsid, community) * @src xray/alife_object_registry_inline.h, anomaly/_g.script * @param squad Squad server object * @param opts { exclude_filter, exclude_filter_reason, exclude_scripted, exclude_permanent, exclude_active_role, exclude_task_target } * @returns protected * @returns reason ("is_permanent", "has_active_role", "is_task_target", "is_scripted", or opts.exclude_filter_reason) * @returns detail (sub-reason: "story_id", "trader", "task_giver", "companion", "scripted:target", etc.) * @returns name (section_name, from permanent cache) */ is_protected(squad: TODO, opts: AnyTable): LuaMultiReturn<[boolean, string | undefined, string | undefined, string | undefined]> /** * Check if squad has engine/vanilla scripting fields set. * Checks runtime fields set by the engine or Anomaly's vanilla systems. * Mod-specific fields (__lock, registered_with_warfare) handled by AP ownership registry. * * Fields checked (order = priority): * scripted_target - Any mod calling acquire_squad or setting directly (AP, Guards Spawner, etc.) * action_condlist - Vanilla Anomaly: LTX condlist-driven target logic * random_targets - Vanilla Anomaly: random patrol system * * @safety SAFE - pure Lua field reads, nil-guarded, no luabind * @cost O(1) | 0-3 luabind for the .scripted_target/.action_condlist/.random_targets field reads (each is a userdata field access, trivial when present, falls through on nil) * @src anomaly/sim_squad_scripted.script(37-39,55-69,105,336) * @param squad Squad server object * @returns True if scripted (nil returns true for safety) * @returns Reason: "nil", "scripted:{target}", "condlist", "random_targets" */ is_scripted(squad: TODO): LuaMultiReturn<[boolean, string | undefined]> /** * Class identity check for sim_squad_scripted instances. * Canonical Anomaly idiom: obj:clsid() == clsid.online_offline_group_s * (anomaly/axr_task_manager.script:1128, dialogs_axr_companion.script:231). * Required wherever a saved id may resolve to a different engine class after the * original squad was released and the server-entity slot reassigned (id recycling). * @safety SAFE - nil-guarded; tests for clsid method presence before calling * @cost O(1) | 2 luabind trivial (clsid field access + call) * @src anomaly/class_registrator.script(132), xray/xrGame/clsid_game.h * @param obj Server entity to test * @returns True if obj is a sim_squad_scripted instance */ is_squad(obj: TODO | undefined): boolean /** * Check if squad is engine-stationed (current_action=1, not in transit) * Engine sets current_action=1 in specific_update when am_i_reached returns true, then keeps * it until either idle_time elapses or a new target is assigned. Sticky while staying, * bounded by smart's idle_time. Returns false during transit, before first arrival, and * after idle expiry triggers reassignment. * @safety SAFE - pure Lua field reads, nil-guarded * @cost O(1) | 0 luabind (current_action / current_target_id are plain CSE fields) * @src anomaly/sim_squad_scripted.script(295-323) arrival + stay + reset lifecycle * @param squad Squad server object * @param smart_id When given, checks stationed at THIS specific smart */ is_stationed(squad: TODO, smart_id: number | undefined): boolean /** * Check if squad is an active task target (assault, bounty, hostage, delivery, dominance, rescue, etc.) * O(1) hash check against task_squads, then member-level bounty/hostage fallback for timing gaps * @safety SAFE - nil-guarded, returns true for nil (fail-safe) * @cost O(1) typical (hash hit, pure Lua) | O(m*b) worst case via _check_member_task_target * @src anomaly/sim_offline_combat.script(53), anomaly/axr_task_manager.script bounties_by_id hostages_by_id * @param squad Squad server object * @returns True if squad is a task target (nil squad returns true for safety) * @returns Reason: "nil", "task_squads", "bounty", "hostage" */ is_task_target(squad: TODO): LuaMultiReturn<[boolean, string | undefined]> /** * Iterate squad member IDs as plain numbers * Wraps engine member iterator with nil/empty guard, yields k.id per member * @safety SAFE - nil-guarded, engine iterator yields nil on empty squad * @cost O(n) members | 0-1 luabind per member (squad_members C++ iterator + .id field read trivial) * @src xray/xrServerEntities/xrServer_Objects_ALife_script.cpp, anomaly/sim_squad_scripted.script(413) * @param squad Squad server object * @returns Iterator yielding member IDs (numbers) */ iter_member_ids(squad: TODO): (this: void, ...args: any[]) => any /** * Iterate all SIMBOARD squads as resolved server entities * Handles SIMBOARD/alife nil guards and skips deleted squads (nil from alife_object) * Caller must not mutate SIMBOARD.squads (release_squad, SIMBOARD:create_squad, anything touching the * table) mid-iteration: next() continuation is then undefined. Collect IDs first, mutate after the loop * (see release_squads two-pass at :711-736). * @safety SAFE - alife_object returns nil for deleted, skipped automatically * @cost O(n) squads | 1 luabind medium per squad (sim:object: xr_map find) * @src anomaly/sim_board.script(84), anomaly/_g.script(2044), xray/xrGame/alife_object_registry_inline.h(36) * @returns Iterator yielding squad server objects */ iter_squads(): (this: void, ...args: any[]) => any /** * Reassert: restore scripted_target if another mod overwrote it between scans, clear __lock * Returns false (no-op) when scripted_target already matches; callers use return value for debug logging * @safety SAFE - pure field writes, nil-guarded * @cost O(1) | 1 luabind trivial (read scripted_target) + 2 luabind trivial on mismatch (write scripted_target, __lock) * @param squad Squad server object * @param target Expected scripted_target value * @returns True if target was overwritten and restored */ reassert_target(squad: AnyTable, target: string): boolean /** * Release: clear scripted_target (stops specific_update) + __lock (unblocks generic_update so sim resumes) * Inverse of acquire_squad/target_actor; squad returns to SIMBOARD autonomous targeting * @safety SAFE - pure field writes, nil-guarded * @cost O(1) | 3 luabind trivial (scripted_target, __lock, rush_to_target field writes on squad userdata) * @src anomaly/sim_squad_scripted.script(258) * @param squad Squad server object */ release_squad(squad: AnyTable): void /** * Release squads from SIMBOARD (delete from world) * Collects IDs first to avoid mutating SIMBOARD.squads during iteration, then calls remove_squad on each * @safety SAFE - iter_squads handles nil SIMBOARD; remove_squad is engine standard cleanup * @cost O(n) squads | per squad: 1 luabind medium (sim:object xr_map find via iter_squads); protection guards add 4-5 luabind on commander resolve * @src anomaly/debug_cmd_list.script(2146), anomaly/sim_squad_scripted.script(413), anomaly/sim_board.script SIMBOARD:remove_squad * @param opts { common_only = bool } - if common_only, skip non-common squads * @returns Count of squads released */ release_squads(opts: AnyTable | undefined): number /** * Acquire (actor): set scripted_target="actor", clear __lock, squad pursues player * Engine resolves "actor" to id=0 in get_script_target; no arrival detection (player moves) * @safety SAFE - pure field writes, nil-guarded * @cost O(1) | 4 luabind trivial (scripted_target, __lock, rush_to_target, current_action field writes on squad userdata) * @src anomaly/sim_squad_scripted.script(102,128-129) * @param squad Squad to command * @param rush Sprint to target * @returns Success */ target_actor(squad: TODO, rush: boolean): boolean }