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.

525 lines (523 loc) 33.7 kB
// AUTO-GENERATED addon pack for `xlib` by `anomaly-packer gen-addon`. Lua API of xsmart.script. // Refine `TODO` (= any) by hand where the mod gave no type. /** @noSelf */ declare const xsmart: { JOB_TYPE_CAMPFIRE_POINT: number JOB_TYPE_GENERIC_POINT: number JOB_TYPE_MECHANIC: number JOB_TYPE_MOB_HOME: number JOB_TYPE_TRADER: number /** * Check if smart terrain accepts a faction (Tier 1 of target_precondition) * Dispatches by faction type: mutants check all/all_monster/props[faction], stalkers * (including "zombied") check all/all_stalker/props[faction]. Mirrors engine * target_precondition faction gate at smart_terrain.script:1531-1559. Tier 2 (zoning: * lair/territory/base/resource/surge with time-of-day preconditions) is not checked. * Use this for refill / population / mod logic that needs faction acceptance independent * of routing time-of-day gates. Use full target_precondition for routing decisions. * @scope global - smart.props from simulation_objects_props.ltx; is_squad_monster from _g.script * @safety SAFE - pure Lua table reads, nil-guarded * @cost O(1) | 0 luabind (pure Lua field/table reads) * @src anomaly/smart_terrain.script(1531-1559), anomaly/_g.script(2344), anomaly/simulation_objects_props.ltx * @param smart Smart terrain to check * @param faction Faction community (e.g. "bandit", "monster_predatory_day", "zombied") * @returns True if smart accepts this faction's presence */ accepts_faction(smart: TODO, faction: string): boolean /** * Assign a squad to a smart's roster, or detach with nil. Wraps SIMBOARD:assign_squad_to_smart. * Used by AP's dispatch/commit pair to keep SIMBOARD.smarts[id].squads aligned with AP-driven * moves so has_squad_of_faction / garrison-floor queries read truth. Pass nil * as smart_id on dispatch (clears source roster before engine specific_update bumps squad.smart_id); * pass the destination id on arrival commit. Fires squad_on_leave_smart on source clear, * squad_on_enter_smart on destination add. * @safety SAFE - delegates to SIMBOARD; nil smart_id is the documented detach form * @cost 1 luabind (SIMBOARD method call) + sim_board.script bookkeeping * @src anomaly/sim_board.script(225-266) * @param squad Squad server object * @param smart_id Destination smart id, or nil to detach from current * @returns True on delegate to SIMBOARD; false when squad/SIMBOARD nil or squad is not a sim_squad_scripted instance */ assign_squad_to_smart(squad: TODO, smart_id: number | undefined): boolean /** * Diagnostic dump of smarts with faction, level, and service-role inventory * When level_id is provided, filters to that level only. Per-smart entry appends trader/medic/mechanic * NPC ids when present (role read from xdata.npc_roles via section name). * @scope global - iterates SIMBOARD.smarts; npc_info populated only for online smarts on actor's level * @safety SAFE - pure Lua iteration, nil-guarded * @cost O(n) smarts * O(m) npc_info per smart | per smart: 1 heavy (name) + role_inventory walk; xdata.npc_roles is O(1) per NPC * @src anomaly/sim_board.script(96), anomaly/smart_terrain.script(801,1209) * @param level_id Restrict iteration to this level when provided * @returns Debug summary string */ dump_smarts(level_id: number | undefined): string /** * Find the first smart matching criteria (no distance ranking) * Distance-free variant of find_smart for cases where caller has no meaningful position * (e.g. picking a destination from a different level's coordinate frame). Iterates in * pool hash order; deterministic per session, but no spatial preference. * Use find_smart when the caller has a comparable position; use this when "any matching" is enough. * @scope global - iterates the supplied pool. When opts.source is nil, walks SIMBOARD.smarts_by_names across all levels. * @safety SAFE - nil-guarded; xlevel.get_level_id uses pcall internally * @cost O(n) smarts in pool, worst case (early exit on first match) | 0 luabind on filter-less hit * @src anomaly/sim_board.script(96) * @param opts { level_id, factions, exclude_id, filter, source } * source: optional { [k] = smart, ... } iterable. When present, replaces SIMBOARD.smarts_by_names as the iteration pool. * @returns First matching smart, or nil if none */ find_first_smart(opts: AnyTable): TODO | undefined /** * Nearest base for an NPC routing out of a fight: the nearest is_base smart with no enemy squad stationed (a * place its enemies do not hold). Keys on actual squad occupancy, NOT declared faction props (most vanilla * smarts declare none, so an accepts_faction filter matches nothing). nil when no base qualifies - the caller * then flees in place rather than running to a non-base edge smart. Same find_smart + is_base reuse as * AlifePlus's flee (ap_ext_consequences_basekill), with an occupancy gate instead of a fixed own-faction. * @safety SAFE - nil when no non-enemy-held base on the level * @cost O(n smarts x min(5,squads)) per find_smart, run at a maneuver commit (not per tick) * @see find_smart, is_base, has_enemy_squad * @param community the NPC's community * @param pos the NPC's position * @param level_id the level to search (online NPCs are on the actor's level) * @returns nearest non-enemy-held base, or nil */ find_friendly_base(community: string, pos: TODO, level_id: number): TODO | undefined /** * Find nearest smart terrain matching criteria * Iterates opts.source (when provided) or SIMBOARD.smarts_by_names; cheapest filters first (exclude_id, factions, level_id), distance_to_sqr last * @scope global - iterates the supplied pool. When opts.source is nil, walks SIMBOARD.smarts_by_names across all levels. * Per-candidate scope depends on the filter caller provides (e.g. has_animated_stalker_jobs narrows to level scope, * has_campfire to online scope, is_base global) * @safety SAFE - nil-guarded; xlevel.get_level_id uses pcall internally * @cost O(n) smarts in pool | per non-filtered smart: 1 luabind trivial (distance_to_sqr inline math); cheaper filters (exclude_id, factions, level_id) gate before distance * @src anomaly/sim_board.script(96), anomaly/simulation_objects.script(117) * @param pos Position to search from * @param opts { level_id, factions, min_distance, max_distance, exclude_id, filter, source } * source: optional { [k] = smart, ... } iterable. When present, replaces SIMBOARD.smarts_by_names as the iteration pool. * Use AlifePlus ap_core_cache.smarts_on_level(level_id) to fetch a per-level bucket. * @returns Nearest matching smart */ find_smart(pos: TODO, opts: AnyTable): TODO | undefined /** * Find all smart terrains on a level whose recipes spawn the given faction * Walks SIMBOARD.smarts once; filters by xlevel.get_level_id == level_id then by recipe content * via section_faction match. Returns smart objects directly (caller extracts .id if needed); * smart terrains are not released mid-session so the references stay valid for the session. * Answers the spawning-side question "which smarts on this level produce faction X"; distinct * from accepts_faction (engine routing acceptance) and smart.faction (runtime holder). * @safety SAFE - nil-guarded; returns empty array when SIMBOARD missing or no matches * @cost O(S*R*Q) smarts * recipes * sections (R,Q typically 1-5) | 1 luabind trivial per smart (xlevel.get_level_id cached); section_faction cached per section * @src anomaly/sim_board.script(96) SIMBOARD.smarts, anomaly/smart_terrain.script(1681-1700) respawn_params shape * @src anomaly/configs/misc/squad_descr/squad_descr_default_mutants.ltx * @param level_id Engine level ID * @param faction Faction community ("bandit", "monster_predatory_day", "stalker", ...) * @returns Array of smart_terrain server objects on the level whose recipes produce faction (empty if none) */ find_smarts_spawning(level_id: number, faction: string): AnyTable /** * Get nearest smart terrain to actor * Reads engine-maintained nearest_to_actor_smart table (updated every online smart tick, zero search cost) * @scope online - smart_terrain.nearest_to_actor_smart is updated by smart tick gated on self.online (smart_terrain.script:1256); only online smarts compete for the slot * @safety SAFE - nil-guarded, alife_object returns nil for invalid IDs * @cost O(log n) | 1 luabind medium (alife_object: xr_map find) * @src anomaly/smart_terrain.script(11,1256,1262), anomaly/se_actor.script(96), anomaly/axr_companions.script(412) * @returns Nearest smart terrain to actor */ get_actor_smart(): TODO | undefined /** * Get stalker factions declared in smart terrain's props (LTX simulation_objects_props.ltx) * Builds {[faction]=true} from props keys with value >0 (only STALKER_FACTIONS list); cached * per smart.id since props are static INI. Use accepts_faction for the engine Tier 1 routing * question (includes all/all_stalker fallbacks); use this when you need the literal explicit * faction declaration set. * @scope global - smart.props from simulation_objects_props.ltx * @safety SAFE - pure Lua table reads (no luabind), nil-guarded * @cost O(13) factions first call, O(1) cached | 0 luabind (props is a pure Lua table from LTX parse) * @src anomaly/simulation_objects.script(117), anomaly/smart_terrain.script(1534) * @param smart Smart terrain to check * @returns Faction set {[faction]=true, ...} or empty table */ get_declared_factions(smart: TODO): AnyTable /** * Resolve the job a specific NPC currently holds at this smart (inverse of get_npc_for_job). * Reads the NPC's engine-bound .job -- the descriptor set in select_npc_job. Returns * nil when the NPC has no npc_info entry (not arrived/registered, or smart offline: npc_info is * populated only for online smarts on the actor's level) or holds no job yet. The descriptor * carries .section ("logic@<smart>_<job>") and, for auto-generated jobs, .job_type_id (compare * against JOB_TYPE_GENERIC_POINT / JOB_TYPE_CAMPFIRE_POINT / ...); exclusive LTX jobs carry * .exclusive=true and no .job_type_id. * @scope online - reads smart.npc_info; empty for offline / off-actor-level smarts * @safety SAFE - pure Lua table reads, nil-guarded * @cost O(1) | 0 luabind (npc_info is a pure Lua hash) * @src anomaly/smart_terrain.script(771,801) the .job field set in select_npc_job * @src anomaly/gulag_general.script(281-303) job_type_id table, (1183-1246) exclusive jobs * @param smart Smart terrain to query * @param npc_id NPC server id * @returns Job descriptor { section, job_type_id?, exclusive? } or nil */ get_job_for_npc(smart: TODO, npc_id: number): AnyTable | undefined /** * Resolve the mechanic NPC at a smart. Walks npc_info, returns first live NPC whose get_npc_roles set contains "mechanic". * @safety SAFE - nil-guarded * @cost O(n) n=npc_info entries | per entry: 1 medium (xobject.go) + 1 trivial (alive) + cached role * @src anomaly/smart_terrain.script(801); anomaly/xr_conditions.script(60) check_npc_mechanic * @param smart Smart terrain to query * @returns Online mechanic NPC, or nil if none online at this smart */ get_mechanic_at_smart(smart: TODO): TODO | undefined /** * Resolve the medic NPC at a smart. Walks npc_info, returns first live NPC whose get_npc_roles set contains "medic". * @safety SAFE - nil-guarded * @cost O(n) n=npc_info entries | per entry: 1 medium (xobject.go) + 1 trivial (alive) + cached role * @src anomaly/smart_terrain.script(801); anomaly/xr_conditions.script(67) check_npc_medic * @param smart Smart terrain to query * @returns Online medic NPC, or nil if none online at this smart */ get_medic_at_smart(smart: TODO): TODO | undefined /** * Resolve the NPC currently assigned to a job of the given type_id at this smart. * Returns the online game_object if assigned and online, nil otherwise. * NOTE: this does NOT resolve the trader NPC. JOB_TYPE_TRADER (15) tags the visitor patrol * job slot (`<smart>_beh_trade_<i>` per gulag_general.script:971), not the barman's seated * logic. Probed across 20 vanilla trader smarts: the barman's job entry's job_type_id is nil * even when the smart is online. Use xsmart.get_trader_at_smart for the barman. * @scope online - reads smart.npc_info populated by smart_terrain:update_jobs (smart_terrain.script:376) only when smart is online * @safety SAFE - pure Lua iteration, nil-guarded; xobject.go falls back to nil for offline ids * @cost O(n) n = npc_info entries at smart (typically 1-15) | 1 luabind via xobject.go on match (level.object_by_id) * @src anomaly/smart_terrain.script(801) self.npc_info entries with `job` field * @src anomaly/gulag_general.script(971) job_type_id assignment * @param smart Smart terrain to query * @param type_id Job type id (e.g. JOB_TYPE_CAMPFIRE_POINT, JOB_TYPE_GENERIC_POINT) */ get_npc_for_job(smart: TODO, type_id: number): TODO | undefined /** * Get the SET of roles for an online NPC, cached for the session. * Multi-role NPCs return a set with multiple keys true (e.g. {medic=true, trader=true} * for Pripyat Yar). See _detect_role for the signal cascade and Demonized-classifier * reference. Pre-bind empty sets not cached so a later call after logic binds re-detects. * @safety SAFE - nil-guarded; all engine reads are standard game_object methods * @cost O(1) | 0 luabind cached, 2-5 luabind heavy on miss (community + clsid + section + optional r_string_ex) * @complexity O(1) amortized | luabind cost as above * @see anomaly/xr_logic.script:113 (engine trade= consumer) * @src anomaly_mods/Trader Destockifier .../trader_autoinject.script:85 (Demonized get_trader_type); * anomaly/utils_obj.script:74 (vanilla is_trader 4-signal); anomaly/xr_logic.script:113 (engine trade= consumer) * @param npc Online NPC game_object * @returns Role set, e.g. {trader=true, medic=true}. Empty table for non-service NPCs. */ get_npc_roles(npc: TODO): AnyTable /** * Get spatial proximity between squad and smart terrain * Mirrors am_i_reached decision tree; returns distance, threshold, and match conditions for diagnostics * @scope global - reads game_graph + server-entity position; cross-level safe (returns dist=-1 on level mismatch) * @safety pcall: game_graph() is NULL singleton during transitions, see doc/library/modding/pcall-safety.md * @cost O(1) | gvid match: 0 luabind; cross-vertex: 2 luabind trivial (vertex: ptr+offset, distance_to_sqr inline) + game_graph singleton lookup (pcall-guarded, cached) * @src anomaly/smart_terrain.script(1440-1456) * @param squad Squad to check * @param smart Target smart terrain * @returns dist Meters (0 = gvid match, -1 = different level) * @returns threshold Applicable arrive threshold in meters * @returns gvid_match Game vertex IDs match * @returns same_level Both on same level */ get_proximity(squad: TODO, smart: TODO): LuaMultiReturn<[number, number, boolean, boolean]> /** * Get the upper bound of a squad section's npc_in_squad field * Parses "X, Y" returning Y (range upper) or "X" returning X. 0 when section missing or * field absent. Pairs with section_faction for inspecting squad_descr sections: this * returns "how many NPCs can spawn at most", section_faction returns "what faction they belong to". * @safety SAFE - returns 0 when section missing, has no npc_in_squad field, or value unparseable * @cost O(1) | 0 luabind cached, 1 luabind heavy on miss (ini_sys:r_string_ex: LTX section lookup + string alloc) + 1-2 pure-Lua regex matches * @src anomaly/configs/misc/squad_descr/squad_descr_default_mutants.ltx, anomaly/configs/misc/squad_descr/squad_descr_default_stalkers.ltx * @src anomaly/sim_board.script(149) create_squad reads npc_in_squad upper as the population cap * @param section Squad section name (e.g. "simulation_boar_3_5", "bandit_sim_squad_novice") * @returns Upper bound of npc_in_squad, or 0 when section/field missing */ get_section_npc_max(section: string): number /** * Get squads table for a smart terrain by ID * Returns the raw SIMBOARD.smarts[id].squads hash ({[squad_id]=true}); caller iterates via next() * @scope global - SIMBOARD.smarts populated at register * @safety SAFE - pure Lua, nil-guarded at every level * @cost O(1) | 0 luabind (pure Lua field/table reads) * @src anomaly/sim_board.script(96,258) * @param smart_id Smart terrain server entity ID * @returns Squads table or nil if unavailable */ get_smart_squads(smart_id: number): AnyTable | undefined /** * Resolve the trader NPC at a smart. Walks smart.npc_info, returns first online live NPC * whose get_npc_roles set contains "trader" (Demonized-style trade= classifier). * @safety SAFE - nil-guarded; section_name is a standard CSE method * @cost O(n) n=npc_info entries (typically 5-30) | per entry: 1 medium (xobject.go) + 1 trivial (alive) + cached role * @src anomaly/smart_terrain.script(801) self.npc_info entries; anomaly/utils_obj.script(74) is_trader * @param smart Smart terrain to query * @returns Online trader NPC, or nil if none online at this smart */ get_trader_at_smart(smart: TODO): TODO | undefined /** * Check if smart has any non-stub stalker job * Stubs (generic_point id=0, campfire_point id=1) are pushed unconditionally on every smart; * non-stub = any other job_type_id (conditional auto-gen) or any exclusive LTX job (no * job_type_id field; carries job.exclusive=true per gulag_general.script:1221,1238) * @scope level - reads smart.stalker_jobs which load_jobs only populates for current-actor-level smarts (smart_terrain.script:462) * @safety SAFE - pure Lua iteration, nil-guarded * @cost O(k) k=jobs on smart (~10-30) | 0 luabind (pure Lua array scan) * @src anomaly/gulag_general.script(308,340,492-526) unconditional vs conditional inits * @src anomaly/gulag_general.script(1183-1246) add_exclusive_job (LTX exclusive jobs) * @src doc/library/modding/job-system.md "Unconditional vs Conditional Inits" * @param smart Smart terrain to check */ has_animated_stalker_jobs(smart: TODO): boolean /** * Check if smart terrain is near anomaly zones * Proximity check against db.anomaly_by_name; online scope (switch_distance, not current-level) * @scope online - db.anomaly_by_name populated by anomaly zone binders at net_spawn; binder.object is the online physics object. Same online_distance / offline_distance hysteresis as campfires. * @safety SAFE - nil-guarded, no pcall. binder.object guarded for net_destroy transition edge case * @cost O(k) k=online anomaly zones (5-15) | per zone: binder.object:position() 1 luabind trivial (Fvector return) + distance_to_sqr 1 luabind trivial (inline math) * @src anomaly/db.script(29,94-100), anomaly/bind_anomaly_zone.script(485,492) * @param smart Smart terrain to check * @returns True if smart within 50m of any online anomaly zone */ has_anomaly(smart: TODO): boolean /** * Check if smart terrain has a campfire * Reads db.campfire_table_by_smart_names populated by bind_campfire.script on net_spawn; online scope (switch_distance) * @scope online - per-campfire binder. Entries added at net_spawn (alife_dynamic_object.cpp:129-163), * removed at net_destroy (bind_campfire.script:295-302). Defaults online_distance = 675m (alife_switch_manager_inline.h:38) * @safety SAFE - nil-guarded, next() guards empty sub-tables left by individual campfire net_destroy * @cost O(1) | 1 luabind heavy (smart:name() shared_str alloc) + db.campfire_table_by_smart_names hash read pure Lua * @src anomaly/bind_campfire.script(272-278,295-302), anomaly/axr_turn_on_campfire.script(136-137) * @src doc/library/modding/online-offline-scoping.md online scope * @param smart Smart terrain to check * @returns True if smart has campfire(s) */ has_campfire(smart: TODO): boolean /** * Test if any squad physically stationed at smart is enemy of the asking community * Wraps iter_stationed_squads with per-squad game_relations.is_factions_enemies check. * Cross-level safe. * @safety SAFE - delegates to iter_stationed_squads * @cost O(min(n,5)) squads, short-circuits on first enemy | per squad: 1 medium (alife_object) + 0 luabind + game_relations cached hash * @src anomaly/sim_board.script(96,258), anomaly/sim_squad_scripted.script(295-323), anomaly/game_relations.script(603) * @param smart_id Smart terrain server entity ID * @param community Engine player_id / community string asking "is this place hostile to me" * @param exclude_id Squad id to skip */ has_enemy_squad(smart_id: number, community: string, exclude_id: number | undefined): boolean /** * Check if every squad member has an engine-assigned job at the smart * Snapshot of npc_info[id].job per member; detects the full-job-allocation freeze * (smart_terrain.script:1369-1376 setup_logic loops on nil job). Reliable only when caller * has gated on smart.online && smart.is_on_actor_level (engine select_npc_job is gated there * too). Does NOT predict mid-dwell precondition-flip invalidation (surge start/end, * day<->night for sleeper, zombie state, trader has_items_to_sell). Trailing members live in * arriving_npc[] not npc_info[] for ~5s after positional arrival until engine drains — * caller's polling cadence absorbs the race. For mutant squads (stype=1) this rarely returns * false because mob_home stubs are oversupplied (gulag_general.script:1018-1022 pushes * max_population*4 with no precondition) * @scope online - reads smart.npc_info populated by smart_terrain:update_jobs gated on self.online AND * is_on_actor_level (smart_terrain.script:582-588). Empty for offline smarts even on the actor's level * @safety SAFE - pure Lua table reads (no luabind), nil-guarded * @cost O(n) members | 0 luabind beyond squad_members iterator (xsquad.iter_member_ids returns plain numbers; npc_info is a pure Lua hash) * @src anomaly/smart_terrain.script(309-327, 626-798, 1369-1376), anomaly/gulag_general.script(114-118), anomaly/gulag_general.script(1018-1022) mutant mob_home oversupply * @param smart Smart terrain to check * @param squad Squad whose members to verify * @returns True if every member has a job */ has_jobs_for(smart: TODO, squad: TODO): boolean /** * Test if any live online NPC at the smart has role="mechanic" * @safety SAFE - delegates to _get_role_at_smart * @cost O(n) n=npc_info entries | same as get_mechanic_at_smart * @src anomaly/smart_terrain.script(801) * @param smart Smart terrain to query */ has_mechanic_at_smart(smart: TODO): boolean /** * Test if any live online NPC at the smart has role="medic" * @safety SAFE - delegates to _get_role_at_smart * @cost O(n) n=npc_info entries | same as get_medic_at_smart * @src anomaly/smart_terrain.script(801) * @param smart Smart terrain to query */ has_medic_at_smart(smart: TODO): boolean /** * Check if any squad of given faction is physically stationed at smart (optionally excluding one id) * Wraps iter_stationed_squads with per-squad player_id match. Cross-level safe. * @safety SAFE - delegates to iter_stationed_squads * @cost O(min(n,5)) squads, short-circuits | per squad: 1 medium (alife_object) + 0 luabind * @src anomaly/sim_board.script(96,258), anomaly/sim_squad_scripted.script(295-323) * @param smart_id Smart terrain server entity ID * @param faction Engine player_id / community string * @param exclude_id Squad id to skip */ has_squad_of_faction(smart_id: number, faction: string, exclude_id: number | undefined): boolean /** * Check if smart's stalker_jobs has any entry, or a specific job_type_id * type_id nil matches any non-empty table; integer matches one job_type_id (e.g. JOB_TYPE_TRADER) * @scope level - smart.stalker_jobs populated by gulag_general.load_job gated on smart_terrain.script:462 is_on_actor_level; nil for smarts on other levels * @safety SAFE - pure Lua iteration, nil-guarded * @cost O(k) k=jobs on smart (~10-30) | 0 luabind (pure Lua array scan) * @src anomaly/gulag_general.script(281-303) job_info_by_job_type_id * @src anomaly/smart_terrain.script(457-464) load_jobs is_on_actor_level gate * @src doc/library/modding/online-offline-scoping.md current-level scope * @param smart Smart terrain to check * @param type_id Specific job_type_id, or nil for any non-empty */ has_stalker_jobs(smart: TODO, type_id: number | undefined): boolean /** * @scope global - smart.props from simulation_objects_props.ltx * @returns True if smart has surge shelter (emission-safe indoor) * @src anomaly/smart_terrain.script(1566), anomaly/surge_manager.script(1265) */ has_surge_shelter(smart: TODO): boolean /** * Test if any live online NPC at the smart has role="trader" * @safety SAFE - delegates to _get_role_at_smart * @cost O(n) n=npc_info entries | same as get_trader_at_smart * @src anomaly/smart_terrain.script(801) * @param smart Smart terrain to query */ has_trader_at_smart(smart: TODO): boolean /** * Check if squad has arrived at smart terrain * Delegates to engine's am_i_reached: same game vertex -> true, different level -> false, distance <= arrive_dist^2 * @scope global - engine method on server entity, cross-level safe (returns false for different-level case) * @safety SAFE - am_i_reached used by engine without pcall in specific_update * @cost O(1) | 1 luabind medium (am_i_reached: gvid match check + Fvector distance_to) * @src anomaly/smart_terrain.script(1440), anomaly/sim_squad_scripted.script(304) * @param squad Squad to check * @param smart Target smart terrain * @returns True if arrived */ is_arrived(squad: TODO, smart: TODO): boolean /** * @scope global - smart.props from simulation_objects_props.ltx loaded at on_register; same value on all levels regardless of online state * @src doc/library/modding/online-offline-scoping.md * @returns True if base (surge shelter, faction HQ) */ is_base(smart: TODO): boolean /** * @scope global - smart.props from simulation_objects_props.ltx * @returns True if lair (mutant nest) */ is_lair(smart: TODO): boolean /** * Test if NPC is a mechanic. See get_npc_roles for the detection signals. * @safety SAFE - delegates to get_npc_roles * @cost O(1) | 0 luabind cached, 2-5 luabind heavy on miss * @param npc Online NPC game_object */ is_mechanic_npc(npc: TODO): boolean /** * Test if NPC is a medic. See get_npc_roles for the detection signals. * @safety SAFE - delegates to get_npc_roles * @cost O(1) | 0 luabind cached, 2-5 luabind heavy on miss * @param npc Online NPC game_object */ is_medic_npc(npc: TODO): boolean /** * Test if a position is within radius of any campfire bound to the smart. * Reads db.campfire_table_by_smart_names[smart:name()] (bind_campfire, online scope) and measures * against each binder.object. Tells a real fire seat (the seat ring is <=8m from the fire, * xr_campfire_point.script:65-101) from the campfire_point random-cover fallback, which lands * decoupled from the fire. * @scope online - campfire binders exist while the campfire is online (switch_distance) * @safety SAFE - nil-guarded; binder.object guarded for the net_destroy transition edge * @cost O(k) k=campfires at smart (1-3) | per fire: 1 luabind trivial (object:position) + distance_to_sqr inline * @src anomaly/bind_campfire.script(20-27) campfire_table_by_smart_names binders with .object * @param smart Smart terrain to query * @param position World position to test * @param radius Meters * @returns True if position is within radius of any bound campfire */ is_near_campfire(smart: TODO, position: TODO, radius: number): boolean /** * @scope global - smart.props from simulation_objects_props.ltx * @returns True if resource point */ is_resource(smart: TODO): boolean /** * Check if smart terrain is empty (no squads assigned) * Reads SIMBOARD.smarts[smart_id].squads; next() is cheapest empty check (no luabind). * Signature matches the other SIMBOARD-indexing functions (get_smart_squads, * has_squad_of_faction): takes smart_id directly so callers do not pay alife_object lookups. * @scope global - SIMBOARD.smarts populated at server-entity register (sim_board.script init_smart); roster reflects sim intent, not physical occupancy * @safety SAFE - pure Lua, nil-guarded at every level * @cost O(1) | 0 luabind (pure Lua field/table reads) * @src anomaly/sim_board.script(96), xcvb/night_mutants.script(92) * @param smart_id Smart terrain server entity ID * @returns True if empty */ is_smart_empty(smart_id: number): boolean /** * @scope global - smart.props from simulation_objects_props.ltx * @returns True if territory (contestable) */ is_territory(smart: TODO): boolean /** * Test if NPC is a trader. See get_npc_roles for the detection signals. * @safety SAFE - delegates to get_npc_roles * @cost O(1) | 0 luabind cached, 2-5 luabind heavy on miss * @param npc Online NPC game_object */ is_trader_npc(npc: TODO): boolean /** * Iterate squads physically stationed at smart, capped (default 5). * Walks SIMBOARD.smarts[smart_id].squads, yields each se whose current_action=1 AND * current_target_id=smart_id (xsquad.is_stationed). Skips in-transit squads. The cap is a * safety belt against mod-induced roster explosion: stops after `cap` non-excluded ids are * inspected, regardless of how many were stationed. If every inspected id was in-transit the * iterator yields zero. Cross-level safe (SIMBOARD persists offline + cross-level). * * Closure-based: one closure + upvalues per call (~6 captures). next() over the hash is * zero-allocation per step. Re-entrant: each call returns a fresh closure with fresh state. * @safety SAFE - nil-guarded, single-pass snapshot of SIMBOARD roster at call time * @cost O(min(n, cap)) | per yielded id: 1 medium (alife_object) + 0 luabind (is_stationed field reads) * @src anomaly/sim_board.script(96,258), anomaly/sim_squad_scripted.script(295-323) * @param smart_id Smart terrain server entity ID * @param exclude_id Squad id to skip (typically the candidate itself) * @param cap Walk cap (default 5) * @returns Iterator yielding stationed se squads */ iter_stationed_squads(smart_id: number, exclude_id: number | undefined, cap: number | undefined): (this: void, ...args: any[]) => any /** * Get the faction (player_id) a squad section produces * Reads the `faction` field from the squad's INI definition in configs/misc/squad_descr/. * This is the same string that ends up as squad.player_id after SIMBOARD:create_squad, * and the same string xcreature.community returns for a live squad spawned from this section. * Coarse vocabulary: stalker factions ("bandit", "stalker", "dolg", ...) and monster_* * categories ("monster_predatory_day", "monster_special", "monster_zombied_night", ...). * No species-level granularity -- the section's npc_random field holds the species pool. * Use this to classify a smart's respawn_params.squads pool by what it will spawn. * @scope global - reads ini_sys (system.ltx merged INI); section metadata is static * @safety SAFE - returns nil when section missing or has no faction field * @cost O(1) | 0 luabind cached, 1 luabind medium on miss (session-lifetime per-section cache) * @src anomaly/configs/misc/squad_descr/squad_descr_default_mutants.ltx, anomaly/configs/misc/squad_descr/squad_descr_default_stalkers.ltx * @src anomaly/sim_board.script(139) * @param section Squad section name (e.g. "simulation_dog", "bandit_sim_squad_novice") * @returns Faction the squad will have (e.g. "monster_predatory_day", "bandit"), or nil */ section_faction(section: string): string | undefined /** * Iterator over all smart terrains in SIMBOARD * Stateful iterator using next() on SIMBOARD.smarts; skips entries without valid smrt ref * @scope global - iterates SIMBOARD.smarts (all levels) * @safety SAFE - nil-guarded, returns empty iterator when SIMBOARD unavailable * @cost O(n) smarts | 0 luabind (pure Lua table iteration) * @src anomaly/sim_board.script(96), anomaly/smart_terrain.script(1) * @returns Iterator yielding smart terrain server objects */ smart_iter(): (this: void, ...args: any[]) => any /** * Get the SIMBOARD smarts-by-name dict for whole-world iteration. Callers iterate with * pairs(); use this when an index build or cross-level scan needs every smart, not the * filtered/ranked output of find_smart. Returns nil before SIMBOARD setup completes (pre * actor_on_first_update); callers must nil-check. * @scope global - SIMBOARD.smarts_by_names populated at sim_board init across all levels * @safety SAFE - nil-guarded; returns nil if SIMBOARD or smarts_by_names is unavailable * @complexity O(1) | 0 luabind, table identity return * @see anomaly/sim_board.script (SIMBOARD.smarts_by_names initialized at sim_board setup) * @returns { [name] = smart_terrain, ... } or nil if SIMBOARD not loaded */ smarts_by_names(): AnyTable | undefined }