Enhance documentation and functionality across various server addons
- Updated README.md files for extension, garage, locker, main, organization, phone, store, and task addons to provide clearer overviews, dependencies, main components, and usage notes. - Improved task module documentation to clarify timer semantics and server task flows, ensuring accurate usage of time limits. - Adjusted default values for task time limits and IED timers to enforce positive countdown requirements. - Added new CAD addon for dispatch coordination, including its overview, dependencies, main components, and event handling.
This commit is contained in:
parent
5576cc4746
commit
9d789440e0
@ -1,3 +1,32 @@
|
||||
# forge_server_actor
|
||||
# Forge Server Actor
|
||||
|
||||
Description for this addon
|
||||
## Overview
|
||||
The actor addon is the server-side bridge for player identity and character
|
||||
state. It keeps Arma-facing actor snapshots in SQF while durable and hot actor
|
||||
state are owned by the Rust extension.
|
||||
|
||||
Actor records include UID, name, loadout, position, direction, stance, rank,
|
||||
life state, phone number, email, organization, and holster state.
|
||||
|
||||
## Dependencies
|
||||
- `forge_server_main`
|
||||
- `forge_server_common`
|
||||
- `forge_server_extension` at runtime for actor extension calls
|
||||
- `forge_client_actor` for response RPCs
|
||||
|
||||
## Main Components
|
||||
- `fnc_initActorStore.sqf` initializes `ActorModel` and `ActorStore`.
|
||||
- `ActorModel` provides defaults, player snapshot conversion, migration, and
|
||||
validation.
|
||||
- `ActorStore` wraps extension hot-state calls and exposes event-facing actor
|
||||
operations.
|
||||
|
||||
## Runtime Behavior
|
||||
- Missing persistent actors can be created from live player snapshots.
|
||||
- Hot actor reads are migrated and hydrated before use.
|
||||
- `saveHotState` in the main addon snapshots and saves actor state on player
|
||||
disconnect and mission end.
|
||||
|
||||
## Event Surface
|
||||
The addon handles server events for actor init, get, set, multi-set, save, and
|
||||
remove requests, then replies to the requesting player through client actor RPCs.
|
||||
|
||||
@ -1,3 +1,39 @@
|
||||
# forge_server_bank
|
||||
# Forge Server Bank
|
||||
|
||||
Description for this addon
|
||||
## Overview
|
||||
The bank addon owns the SQF bridge for player accounts, cash and bank balances,
|
||||
PIN/session handling, transfers, checkout charging, earnings deposits, and
|
||||
credit-line repayment.
|
||||
|
||||
Account truth lives in the extension hot cache. SQF handles Arma-facing
|
||||
validation, client messaging, session state, and payment integration with other
|
||||
server addons.
|
||||
|
||||
## Dependencies
|
||||
- `forge_server_main`
|
||||
- `forge_server_common`
|
||||
- `forge_server_extension` at runtime for bank extension calls
|
||||
- `forge_server_org` at runtime for credit-line repayment
|
||||
- `forge_client_bank` and `forge_client_notifications` for response RPCs
|
||||
|
||||
## Main Components
|
||||
- `fnc_initBank.sqf` initializes all bank stores and helpers.
|
||||
- `fnc_initModel.sqf` defines account defaults and migration behavior.
|
||||
- `fnc_initPayloadBuilder.sqf` builds UI, checkout, and organization payment
|
||||
context.
|
||||
- `fnc_initSessionManager.sqf` manages PIN and authorization session state.
|
||||
- `fnc_initMessenger.sqf` sends account syncs, alerts, and notifications.
|
||||
- `fnc_initStore.sqf` wraps hot bank calls and account mutations.
|
||||
|
||||
## Supported Operations
|
||||
- initialize and hydrate player bank state
|
||||
- deposit, withdraw, transfer, and deposit earnings
|
||||
- validate PIN-backed sessions
|
||||
- charge checkout previews and committed purchases
|
||||
- repay organization credit lines with rollback on failure
|
||||
- save hot bank state to durable storage
|
||||
|
||||
## Runtime Notes
|
||||
`forge_server_main_fnc_saveHotState` saves bank hot state on disconnect and
|
||||
mission shutdown. Store checkout and task rewards use this addon for
|
||||
authoritative player balance changes.
|
||||
|
||||
38
arma/server/addons/cad/README.md
Normal file
38
arma/server/addons/cad/README.md
Normal file
@ -0,0 +1,38 @@
|
||||
# Forge Server CAD
|
||||
|
||||
## Overview
|
||||
The CAD addon coordinates dispatch-facing operational state: groups,
|
||||
assignments, dispatch orders, support requests, task assignment, permissions,
|
||||
hydrate payloads, and recent activity.
|
||||
|
||||
CAD state is extension-backed but intentionally transient. It is scoped to the
|
||||
active server or mission lifecycle and starts fresh after restart.
|
||||
|
||||
## Dependencies
|
||||
- `forge_server_main`
|
||||
- `forge_server_common`
|
||||
- `forge_server_actor`
|
||||
- `forge_server_org`
|
||||
- `forge_server_task`
|
||||
- `forge_server_extension` at runtime for CAD extension calls
|
||||
- `forge_client_cad` and `forge_client_notifications` for response RPCs
|
||||
|
||||
## Main Components
|
||||
- `fnc_initCadStore.sqf` coordinates repositories and request handling.
|
||||
- `fnc_initActivityRepository.sqf` records recent CAD activity.
|
||||
- `fnc_initAssignmentRepository.sqf` manages task assignments and dispatch
|
||||
orders.
|
||||
- `fnc_initGroupRepository.sqf` manages group membership, role, and status.
|
||||
- `fnc_initPermissionService.sqf` resolves dispatch permissions.
|
||||
- `fnc_initPersistenceService.sqf` bridges SQF state to extension hot CAD
|
||||
storage.
|
||||
- `fnc_initRequestRepository.sqf` manages support requests.
|
||||
|
||||
## Event Surface
|
||||
The addon handles hydrate, task assignment, dispatch order, support request,
|
||||
task acknowledge/decline, and group update events. Successful mutations can
|
||||
invalidate CAD state globally so clients refresh their views.
|
||||
|
||||
## Notes
|
||||
CAD hydrate payloads include active task catalog entries from `TaskStore` and
|
||||
organization context from `ActorStore`.
|
||||
@ -1,3 +1,23 @@
|
||||
# forge_server_common
|
||||
# Forge Server Common
|
||||
|
||||
Common functionality shared between addons.
|
||||
## Overview
|
||||
The common addon provides shared SQF utilities used by server-side Forge
|
||||
addons. It contains lightweight helpers only; gameplay domain state belongs in
|
||||
the specific domain addons or the Rust extension.
|
||||
|
||||
## Dependencies
|
||||
- `forge_server_main`
|
||||
|
||||
## Main Components
|
||||
- `fnc_baseStore.sqf` provides shared hash-map object behavior such as JSON
|
||||
conversion.
|
||||
- `fnc_log.sqf` standardizes server log messages.
|
||||
- `fnc_getPlayer.sqf` resolves online players by UID.
|
||||
- `fnc_formatNumber.sqf` formats numeric values for notifications and UI text.
|
||||
- `fnc_generateHash.sqf` and `fnc_generateSecureData.sqf` provide hashing and
|
||||
random data helpers.
|
||||
- `fnc_timeToSeconds.sqf` converts time values into seconds.
|
||||
|
||||
## Notes
|
||||
Keep this addon free of domain-specific behavior. If a helper needs actor,
|
||||
bank, org, task, store, or CAD state, it belongs in that addon instead.
|
||||
|
||||
@ -1,3 +1,31 @@
|
||||
# forge_server_economy
|
||||
# Forge Server Economy
|
||||
|
||||
Description for this addon
|
||||
## Overview
|
||||
The economy addon contains server-side systems for world economic interactions
|
||||
that are still implemented in SQF.
|
||||
|
||||
Current stores cover fuel tracking, medical service behavior, and a placeholder
|
||||
service economy store.
|
||||
|
||||
## Dependencies
|
||||
- `forge_server_main`
|
||||
- `forge_server_common` at runtime for logging, formatting, and player lookup
|
||||
- `forge_server_bank` at runtime for medical service charges
|
||||
- `forge_client_actor` and `forge_client_notifications` for response RPCs
|
||||
|
||||
## Main Components
|
||||
- `fnc_initFEconomyStore.sqf` tracks active refueling sessions and reports fuel
|
||||
totals.
|
||||
- `fnc_initMEconomyStore.sqf` manages medical spawn occupancy, healing charges,
|
||||
respawn placement, death inventory handling, and body-bag transfer.
|
||||
- `fnc_initSEconomyStore.sqf` initializes the service economy placeholder.
|
||||
|
||||
## Event Surface
|
||||
The addon registers CBA server events for fuel start/tick/stop, player killed,
|
||||
player respawn, and healing. Medical store initialization runs after post-init
|
||||
to discover configured medical spawn objects.
|
||||
|
||||
## Notes
|
||||
The service economy store is currently a stub. Fuel and medical behavior should
|
||||
stay server-authoritative because they mutate money, inventory, and respawn
|
||||
state.
|
||||
|
||||
@ -1,3 +1,29 @@
|
||||
# forge_server_extension
|
||||
# Forge Server Extension
|
||||
|
||||
Extension functionality shared between addons.
|
||||
## Overview
|
||||
The extension addon is the SQF bridge to the `forge_server` arma-rs extension.
|
||||
It normalizes `callExtension` responses, routes large payloads through the
|
||||
transport layer, and exposes helper functions used by extension-backed server
|
||||
addons.
|
||||
|
||||
## Dependencies
|
||||
- `forge_server_main`
|
||||
|
||||
## Main Components
|
||||
- `fnc_extCall.sqf` is the primary extension call wrapper.
|
||||
- `fnc_transport.sqf` stages large requests and assembles chunked responses.
|
||||
- `fnc_setHandler.sqf` registers local SQF handlers for extension callback
|
||||
integration.
|
||||
|
||||
## Transport Behavior
|
||||
Most commands use direct `callExtension`. Commands that can return large
|
||||
payloads, or requests whose encoded arguments exceed the chunk threshold, are
|
||||
routed through `transport:invoke` or staged transport requests.
|
||||
|
||||
The wrapper falls back to direct calls if the transport route is unsupported and
|
||||
the request was not chunked.
|
||||
|
||||
## Notes
|
||||
Domain addons should call `EFUNC(extension,extCall)` instead of calling the
|
||||
extension directly. This keeps response handling, chunking, and error logging
|
||||
consistent.
|
||||
|
||||
@ -1,3 +1,30 @@
|
||||
# forge_server_garage
|
||||
# Forge Server Garage
|
||||
|
||||
Description for this addon
|
||||
## Overview
|
||||
The garage addon is the server-side bridge for player vehicle storage and
|
||||
owner-scoped vehicle unlock storage.
|
||||
|
||||
Garage hot state is owned by the extension. SQF validates Arma-facing requests,
|
||||
serializes vehicle payloads, sends client syncs, and marks editor-placed garage
|
||||
objects.
|
||||
|
||||
## Dependencies
|
||||
- `forge_server_main`
|
||||
- `forge_server_common`
|
||||
- `forge_server_extension` at runtime for garage extension calls
|
||||
- `forge_client_garage` for response RPCs
|
||||
|
||||
## Main Components
|
||||
- `fnc_initGarage.sqf` initializes garage world objects.
|
||||
- `fnc_initGarageStore.sqf` manages player garage hot state.
|
||||
- `fnc_initVGStore.sqf` manages owner-scoped vehicle unlock state.
|
||||
|
||||
## Supported Operations
|
||||
- initialize player garage data
|
||||
- save player and owner-scoped garage state
|
||||
- store and retrieve player vehicles
|
||||
- initialize and save owner-scoped vehicle storage
|
||||
|
||||
## Runtime Notes
|
||||
`forge_server_main_fnc_saveHotState` saves both `GarageStore` and
|
||||
`VGarageStore` on disconnect and mission shutdown.
|
||||
|
||||
@ -1,3 +1,30 @@
|
||||
# forge_server_locker
|
||||
# Forge Server Locker
|
||||
|
||||
Description for this addon
|
||||
## Overview
|
||||
The locker addon is the server-side bridge for player item storage and
|
||||
owner-scoped arsenal unlock storage.
|
||||
|
||||
Locker hot state is owned by the extension. SQF handles client events, payload
|
||||
validation, synchronization, and save calls.
|
||||
|
||||
## Dependencies
|
||||
- `forge_server_main`
|
||||
- `forge_server_common`
|
||||
- `forge_server_extension` at runtime for locker extension calls
|
||||
- `forge_client_locker` for response RPCs
|
||||
|
||||
## Main Components
|
||||
- `fnc_initLocker.sqf` initializes locker world objects.
|
||||
- `fnc_initLockerStore.sqf` manages player locker hot state.
|
||||
- `fnc_initVAStore.sqf` manages owner-scoped arsenal unlock state.
|
||||
|
||||
## Supported Operations
|
||||
- initialize player locker data
|
||||
- save player and owner-scoped locker state
|
||||
- override locker data from trusted server-side callers
|
||||
- initialize and save owner-scoped arsenal storage
|
||||
|
||||
## Runtime Notes
|
||||
`forge_server_main_fnc_saveHotState` saves both `LockerStore` and `VAStore` on
|
||||
disconnect and mission shutdown. Store checkout and task rewards can grant
|
||||
assets into organization-owned storage through the org addon.
|
||||
|
||||
@ -1,3 +1,29 @@
|
||||
# forge_server_main
|
||||
# Forge Server Main
|
||||
|
||||
Main Addon for forge-server
|
||||
## Overview
|
||||
The main addon owns server-side bootstrap behavior for Forge. It prepares
|
||||
functions, wires extension callbacks and ICom events, initializes shared stores,
|
||||
and flushes hot state when players disconnect or the mission ends.
|
||||
|
||||
## Dependencies
|
||||
- `cba_main`
|
||||
- `ace_main`
|
||||
|
||||
## Main Components
|
||||
- `fnc_initStores.sqf` initializes core server stores in dependency order.
|
||||
- `fnc_saveHotState.sqf` snapshots and saves extension-backed hot state.
|
||||
- `fnc_initValidationHarness.sqf` provides targeted runtime smoke checks for
|
||||
multi-module flows.
|
||||
- `XEH_preInit.sqf` registers ICom and extension callback handlers.
|
||||
- `XEH_postInit.sqf` starts store initialization.
|
||||
|
||||
## Store Initialization
|
||||
The main addon initializes shared base stores, actor, bank, garage, locker,
|
||||
organization, store, and validation harness state. Some addons initialize their
|
||||
own state in pre-init or post-init when they are intentionally independent of
|
||||
the main bootstrap flow.
|
||||
|
||||
## Hot State Flush
|
||||
On player disconnect, mission ended, and MP ended events, `saveHotState`
|
||||
persists actor, bank, locker, virtual arsenal, garage, virtual garage, and
|
||||
organization hot state for the relevant UID or all known UIDs.
|
||||
|
||||
@ -1,3 +1,36 @@
|
||||
# forge_server_org
|
||||
# Forge Server Organization
|
||||
|
||||
Description for this addon
|
||||
## Overview
|
||||
The organization addon is the server-side bridge for player organizations,
|
||||
membership, treasury funds, reputation, credit lines, shared assets, fleet
|
||||
entries, and invitations.
|
||||
|
||||
Organization hot state is owned by the extension. SQF coordinates Arma-facing
|
||||
events, UI payloads, membership syncs, and integration with actor, bank, store,
|
||||
and task flows.
|
||||
|
||||
## Dependencies
|
||||
- `forge_server_main`
|
||||
- `forge_server_common`
|
||||
- `forge_server_extension` at runtime for organization extension calls
|
||||
- `forge_server_actor` at runtime for organization membership lookups
|
||||
- `forge_client_org` and `forge_client_notifications` for response RPCs
|
||||
|
||||
## Main Components
|
||||
- `fnc_initOrgStore.sqf` initializes `OrgModel` and `OrgStore`.
|
||||
- `fnc_initPayloadBuilder.sqf` builds portal, organization, member, asset, and
|
||||
fleet payloads.
|
||||
|
||||
## Supported Operations
|
||||
- initialize and hydrate organization portal data
|
||||
- register, leave, and disband organizations
|
||||
- invite, accept, and decline members
|
||||
- assign and repay credit lines
|
||||
- update funds and reputation
|
||||
- grant assets and fleet vehicles
|
||||
- save organization hot state
|
||||
|
||||
## Runtime Notes
|
||||
The addon ensures the `default` organization exists during store creation.
|
||||
Task rewards and store checkout both rely on `OrgStore` for authoritative
|
||||
organization-owned state.
|
||||
|
||||
@ -1,19 +1,33 @@
|
||||
forge_server_phone
|
||||
===================
|
||||
# Forge Server Phone
|
||||
|
||||
This addon provides the phone user interface and functionality for the in-game phone system. It handles all phone-related features including the UI display, interactions, and core phone operations.
|
||||
## Overview
|
||||
The phone addon is the server-side bridge for contacts, SMS messages, and email.
|
||||
Phone runtime state is owned by the extension. SQF stores preserve the
|
||||
event-facing API and synchronize client UI state.
|
||||
|
||||
Server State
|
||||
------------
|
||||
## Dependencies
|
||||
- `forge_server_main`
|
||||
- `forge_server_common` at runtime for online player lookup
|
||||
- `forge_server_extension` at runtime for phone extension calls
|
||||
- `forge_client_phone` for response RPCs
|
||||
|
||||
Phone contacts, messages, and emails are owned by the server extension. SQF phone stores act as bridge objects for CBA events and UI sync only.
|
||||
## Main Components
|
||||
- `fnc_initPhoneStore.sqf` coordinates the phone facade.
|
||||
- `fnc_initContactStore.sqf` manages contacts.
|
||||
- `fnc_initMessageStore.sqf` manages SMS messages and threads.
|
||||
- `fnc_initEmailStore.sqf` manages email messages.
|
||||
- `fnc_initPlayer.sqf` initializes phone data for a player.
|
||||
|
||||
Persistent SurrealDB tables:
|
||||
## Persistent Extension Tables
|
||||
- `phone_user`: owner row for an initialized phone profile
|
||||
- `phone_contact`: per-owner contact rows keyed by owner UID and contact UID
|
||||
- `phone_message`: shared message records
|
||||
- `phone_message_index`: per-owner message visibility and read state
|
||||
- `phone_email`: shared email records
|
||||
- `phone_email_index`: per-owner email visibility and read state
|
||||
- `phone_sequence`: global sequence state for generated message and email IDs
|
||||
|
||||
- `phone_user`: owner row for an initialized phone profile.
|
||||
- `phone_contact`: per-owner contact rows keyed by owner UID and contact UID.
|
||||
- `phone_message`: shared message records.
|
||||
- `phone_message_index`: per-owner message visibility and read state.
|
||||
- `phone_email`: shared email records.
|
||||
- `phone_email_index`: per-owner email visibility and read state.
|
||||
- `phone_sequence`: global sequence state for generated message and email IDs.
|
||||
## Event Surface
|
||||
The addon handles client requests to initialize phone state, add/remove/refresh
|
||||
contacts, send/read/delete messages, send/read/delete emails, and remove phone
|
||||
state.
|
||||
|
||||
@ -1,18 +1,35 @@
|
||||
# forge_server_store
|
||||
# Forge Server Store
|
||||
|
||||
Server-side SQF module for storefront entities, catalog hydration, and checkout
|
||||
coordination.
|
||||
## Overview
|
||||
The store addon manages server-side storefront entities, catalog hydration, and
|
||||
checkout coordination.
|
||||
|
||||
## Stores and Services
|
||||
SQF owns Arma-facing storefront discovery and request validation. The Rust
|
||||
extension owns authoritative checkout calculation through `store:checkout`.
|
||||
|
||||
- `StorefrontStore` builds storefront hydrate payloads, validates checkout
|
||||
requests, calls the Rust `store:checkout` backend, syncs UI patches, and saves
|
||||
hot state for related modules.
|
||||
- `StoreCatalogService` scans live Arma config categories, builds catalog
|
||||
responses, resolves checkout entries, and calculates authoritative prices.
|
||||
## Dependencies
|
||||
- `forge_server_main`
|
||||
- `forge_server_common`
|
||||
- `forge_server_extension` at runtime for checkout calls
|
||||
- `forge_server_actor`, `forge_server_bank`, and `forge_server_org` at runtime
|
||||
for checkout context and payment state
|
||||
- `forge_client_store` for response RPCs
|
||||
|
||||
## Main Components
|
||||
- `fnc_initStore.sqf` marks editor-placed store objects with `isStore = true`.
|
||||
- `fnc_initCatalogService.sqf` scans live Arma config categories, builds
|
||||
catalog responses, resolves checkout entries, and calculates authoritative
|
||||
catalog prices.
|
||||
- `fnc_initStorefrontStore.sqf` builds hydrate payloads, validates checkout
|
||||
requests, calls `store:checkout`, syncs client patches, and coordinates
|
||||
related bank/org persistence.
|
||||
|
||||
## Editor Entities
|
||||
`fnc_initStore` matches non-null mission namespace objects whose variable names
|
||||
contain `store`, mirroring the garage entity initialization pattern.
|
||||
|
||||
`fnc_initStore` marks editor-placed store objects with `isStore = true`. It
|
||||
matches non-null mission namespace objects whose variable names contain
|
||||
`store`, mirroring the garage entity initialization pattern.
|
||||
## Checkout Flow
|
||||
Store checkout can charge cash, bank balance, organization funds, or approved
|
||||
credit lines depending on the hydrated session context. Checkout results can
|
||||
grant locker assets, organization assets, and fleet vehicles through the
|
||||
related domain stores.
|
||||
|
||||
@ -355,9 +355,9 @@ class CfgVehicles {
|
||||
class TimeLimit: Edit {
|
||||
property = "FORGE_Module_Defuse_TimeLimit";
|
||||
displayName = "Time Limit";
|
||||
tooltip = "Time in seconds before detenation (0 for no limit)";
|
||||
tooltip = "Time in seconds before detonation; must be greater than 0";
|
||||
typeName = "NUMBER";
|
||||
defaultValue = 0;
|
||||
defaultValue = 300;
|
||||
};
|
||||
};
|
||||
|
||||
@ -608,7 +608,7 @@ class CfgVehicles {
|
||||
class TimeLimit: Edit {
|
||||
property = "FORGE_Module_Hostage_TimeLimit";
|
||||
displayName = "Time Limit";
|
||||
tooltip = "Time in seconds before HVTs escape (0 for no limit)";
|
||||
tooltip = "Time in seconds before hostages are executed (0 for no limit)";
|
||||
typeName = "NUMBER";
|
||||
defaultValue = 0;
|
||||
};
|
||||
@ -730,9 +730,9 @@ class CfgVehicles {
|
||||
class TimeLimit: Edit {
|
||||
property = "FORGE_Module_Delivery_TimeLimit";
|
||||
displayName = "Time Limit";
|
||||
tooltip = "Seconds to complete delivery (-1 for no limit)";
|
||||
tooltip = "Seconds to complete delivery (0 for no limit)";
|
||||
typeName = "NUMBER";
|
||||
defaultValue = -1;
|
||||
defaultValue = 0;
|
||||
};
|
||||
};
|
||||
|
||||
@ -907,7 +907,7 @@ class CfgVehicles {
|
||||
class TimeLimit: Edit {
|
||||
property = "FORGE_Module_HVT_TimeLimit";
|
||||
displayName = "Time Limit";
|
||||
tooltip = "Time in seconds before HVTs escape (0 for no limit)";
|
||||
tooltip = "Time in seconds before the HVT task fails (0 for no limit)";
|
||||
typeName = "NUMBER";
|
||||
defaultValue = 0;
|
||||
};
|
||||
|
||||
@ -16,6 +16,7 @@ system intentionally starts clean after each server or mission restart.
|
||||
- notify task participants and sync org updates to online members
|
||||
|
||||
## Dependencies
|
||||
- `forge_server_extension`
|
||||
- `forge_server_common`
|
||||
- `forge_server_actor`
|
||||
- `forge_server_bank`
|
||||
@ -58,6 +59,10 @@ Org rewards always go to the bound owner org. Player earnings still use per-play
|
||||
|
||||
## Usage
|
||||
|
||||
Task time limits use `0` for no limit on attack, destroy, delivery, hostage,
|
||||
and HVT tasks. Defuse IED timers are different: each IED must have a positive
|
||||
countdown value.
|
||||
|
||||
### Start Through The Handler
|
||||
Use the handler when you want reputation gating and task ownership binding.
|
||||
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
* 5: Amount of rating the company and player recieve if the task is successful <NUMBER> (default: 0)
|
||||
* 6: Should the mission end (MissionSuccess) if the task is successful <BOOL> (default: false)
|
||||
* 7: Should the mission end (MissionFailed) if the task is failed <BOOL> (default: false)
|
||||
* 8: Amount of time before target(s) escape <NUMBER> (default: -1)
|
||||
* 8: Amount of time before target(s) escape <NUMBER> (default: 0, 0 = no limit)
|
||||
* 9: Equipment rewards <ARRAY> (default: [])
|
||||
* 10: Supply rewards <ARRAY> (default: [])
|
||||
* 11: Weapon rewards <ARRAY> (default: [])
|
||||
@ -39,7 +39,7 @@ params [
|
||||
["_ratingSuccess", 0, [0]],
|
||||
["_endSuccess", false, [false]],
|
||||
["_endFail", false, [false]],
|
||||
["_time", -1, [0]],
|
||||
["_timeLimit", 0, [0]],
|
||||
["_equipmentRewards", [], [[]]],
|
||||
["_supplyRewards", [], [[]]],
|
||||
["_weaponRewards", [], [[]]],
|
||||
@ -58,7 +58,7 @@ waitUntil {
|
||||
};
|
||||
|
||||
_targets = GVAR(TaskStore) call ["getTaskEntities", ["targets", _taskID]];
|
||||
private _startTime = if (!isNil "_time") then { floor(time) } else { nil };
|
||||
private _startTime = if (_timeLimit isNotEqualTo 0) then { floor(time) } else { nil };
|
||||
|
||||
waitUntil {
|
||||
sleep 1;
|
||||
@ -66,8 +66,8 @@ waitUntil {
|
||||
|
||||
private _targetsKilled = ({ !alive _x } count _targets);
|
||||
|
||||
if (_time isNotEqualTo -1) then {
|
||||
private _timeExpired = (floor time - _startTime >= _time);
|
||||
if (_timeLimit isNotEqualTo 0) then {
|
||||
private _timeExpired = (floor time - _startTime >= _timeLimit);
|
||||
|
||||
if (_targetsKilled < _limitSuccess && _timeExpired) then { _result = 1; };
|
||||
|
||||
|
||||
@ -53,7 +53,7 @@ private _taskPos = if (_syncedEntities isNotEqualTo []) then {
|
||||
["ratingSuccess", _logic getVariable ["RatingSuccess", 0]],
|
||||
["endSuccess", _logic getVariable ["EndSuccess", false]],
|
||||
["endFail", _logic getVariable ["EndFail", false]],
|
||||
["timeLimit", _logic getVariable ["TimeLimit", -1]]
|
||||
["timeLimit", _logic getVariable ["TimeLimit", 0]]
|
||||
]
|
||||
] call FUNC(startTask);
|
||||
|
||||
|
||||
@ -36,7 +36,7 @@ private _protectedEntities = if (!isNull _protectedModule) then { synchronizedOb
|
||||
["INFO", format [
|
||||
"Defuse Module: TaskID: %1, IEDs: %2, Protected: %3, IED timer: %4s",
|
||||
_taskID, count _iedEntities, count _protectedEntities,
|
||||
_logic getVariable ["TimeLimit", 0]
|
||||
_logic getVariable ["TimeLimit", 300]
|
||||
]] call EFUNC(common,log);
|
||||
|
||||
private _taskPos = if (_iedEntities isNotEqualTo []) then {
|
||||
@ -63,7 +63,7 @@ private _taskPos = if (_iedEntities isNotEqualTo []) then {
|
||||
["ratingSuccess", _logic getVariable ["RatingSuccess", 0]],
|
||||
["endSuccess", _logic getVariable ["EndSuccess", false]],
|
||||
["endFail", _logic getVariable ["EndFail", false]],
|
||||
["iedTimer", _logic getVariable ["TimeLimit", 0]]
|
||||
["iedTimer", _logic getVariable ["TimeLimit", 300]]
|
||||
]
|
||||
] call FUNC(startTask);
|
||||
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
* 6: Amount of rating the company and player receive if the task is successful <NUMBER> (default: 0)
|
||||
* 7: Should the mission end (MissionSuccess) if the task is successful <BOOL> (default: false)
|
||||
* 8: Should the mission end (MissionFailed) if the task is failed <BOOL> (default: false)
|
||||
* 9: Amount of time to complete delivery <NUMBER> (default: -1)
|
||||
* 9: Amount of time to complete delivery <NUMBER> (default: 0)
|
||||
* 10: Equipment rewards <ARRAY> (default: [])
|
||||
* 11: Supply rewards <ARRAY> (default: [])
|
||||
* 12: Weapon rewards <ARRAY> (default: [])
|
||||
@ -41,7 +41,7 @@ params [
|
||||
["_ratingSuccess", 0, [0]],
|
||||
["_endSuccess", false, [false]],
|
||||
["_endFail", false, [false]],
|
||||
["_time", -1, [0]],
|
||||
["_timeLimit", 0, [0]],
|
||||
["_equipmentRewards", [], [[]]],
|
||||
["_supplyRewards", [], [[]]],
|
||||
["_weaponRewards", [], [[]]],
|
||||
@ -60,7 +60,7 @@ waitUntil {
|
||||
};
|
||||
|
||||
_cargo = GVAR(TaskStore) call ["getTaskEntities", ["cargo", _taskID]];
|
||||
private _startTime = if (_time isNotEqualTo -1) then { floor(time) } else { nil };
|
||||
private _startTime = if (_timeLimit isNotEqualTo 0) then { floor(time) } else { nil };
|
||||
|
||||
waitUntil {
|
||||
sleep 1;
|
||||
@ -69,8 +69,8 @@ waitUntil {
|
||||
private _cargoDelivered = ({ _x inArea _deliveryZone && (damage _x) < 0.7 } count _cargo);
|
||||
private _cargoDamaged = ({ damage _x >= 0.7 } count _cargo);
|
||||
|
||||
if (_time isNotEqualTo -1) then {
|
||||
private _timeExpired = (floor time - _startTime >= _time);
|
||||
if (_timeLimit isNotEqualTo 0) then {
|
||||
private _timeExpired = (floor time - _startTime >= _timeLimit);
|
||||
|
||||
if (_cargoDamaged >= _limitFail) then { _result = 1; };
|
||||
if (_cargoDelivered < _limitSuccess && _timeExpired) then { _result = 1; };
|
||||
|
||||
@ -63,7 +63,7 @@ private _taskPos = if (_cargoEntities isNotEqualTo []) then {
|
||||
["ratingSuccess", _logic getVariable ["RatingSuccess", 0]],
|
||||
["endSuccess", _logic getVariable ["EndSuccess", false]],
|
||||
["endFail", _logic getVariable ["EndFail", false]],
|
||||
["timeLimit", _logic getVariable ["TimeLimit", -1]],
|
||||
["timeLimit", _logic getVariable ["TimeLimit", 0]],
|
||||
["deliveryZone", _logic getVariable ["DeliveryZone", ""]]
|
||||
]
|
||||
] call FUNC(startTask);
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
* 5: Amount of rating the company and player recieve if the task is successful <NUMBER> (default: 0)
|
||||
* 6: Should the mission end (MissionSuccess) if the task is successful <BOOL> (default: false)
|
||||
* 7: Should the mission end (MissionFailed) if the task is failed <BOOL> (default: false)
|
||||
* 8: Amount of time before target(s) escape <NUMBER> (default: -1)
|
||||
* 8: Amount of time before target(s) escape <NUMBER> (default: 0, 0 = no limit)
|
||||
* 9: Equipment rewards <ARRAY> (default: [])
|
||||
* 10: Supply rewards <ARRAY> (default: [])
|
||||
* 11: Weapon rewards <ARRAY> (default: [])
|
||||
@ -39,7 +39,7 @@ params [
|
||||
["_ratingSuccess", 0, [0]],
|
||||
["_endSuccess", false, [false]],
|
||||
["_endFail", false, [false]],
|
||||
["_time", -1, [0]],
|
||||
["_timeLimit", 0, [0]],
|
||||
["_equipmentRewards", [], [[]]],
|
||||
["_supplyRewards", [], [[]]],
|
||||
["_weaponRewards", [], [[]]],
|
||||
@ -58,7 +58,7 @@ waitUntil {
|
||||
};
|
||||
|
||||
_targets = GVAR(TaskStore) call ["getTaskEntities", ["targets", _taskID]];
|
||||
private _startTime = if (!isNil "_time") then { floor(time) } else { nil };
|
||||
private _startTime = if (_timeLimit isNotEqualTo 0) then { floor(time) } else { nil };
|
||||
|
||||
waitUntil {
|
||||
sleep 1;
|
||||
@ -66,8 +66,8 @@ waitUntil {
|
||||
|
||||
private _targetsDestroyed = ({ !alive _x } count _targets);
|
||||
|
||||
if (!isNil "_time") then {
|
||||
private _timeExpired = (floor time - _startTime >= _time);
|
||||
if (_timeLimit isNotEqualTo 0) then {
|
||||
private _timeExpired = (floor time - _startTime >= _timeLimit);
|
||||
|
||||
if (_targetsDestroyed < _limitSuccess && _timeExpired) then { _result = 1; };
|
||||
|
||||
|
||||
@ -53,7 +53,7 @@ private _taskPos = if (_syncedEntities isNotEqualTo []) then {
|
||||
["ratingSuccess", _logic getVariable ["RatingSuccess", 0]],
|
||||
["endSuccess", _logic getVariable ["EndSuccess", false]],
|
||||
["endFail", _logic getVariable ["EndFail", false]],
|
||||
["timeLimit", _logic getVariable ["TimeLimit", -1]]
|
||||
["timeLimit", _logic getVariable ["TimeLimit", 0]]
|
||||
]
|
||||
] call FUNC(startTask);
|
||||
|
||||
|
||||
@ -15,7 +15,7 @@
|
||||
* 7: Subcategory of task <ARRAY> (default: [false, true])
|
||||
* 8: Should the mission end (MissionSuccess) if the task is successful <BOOL> (default: false)
|
||||
* 9: Should the mission end (MissionFailed) if the task is failed <BOOL> (default: false)
|
||||
* 10: Amount of time before hostage(s) die <NUMBER> (default: -1)
|
||||
* 10: Amount of time before hostage(s) are executed <NUMBER> (default: 0, 0 = no limit)
|
||||
* 11: Marker name for the cbrn zone <STRING> (default: "")
|
||||
* 12: Equipment rewards <ARRAY> (default: [])
|
||||
* 13: Supply rewards <ARRAY> (default: [])
|
||||
@ -45,7 +45,7 @@ params [
|
||||
["_type", [["_cbrn", false, [false]], ["_hostage", true, [false]]]],
|
||||
["_endSuccess", false, [false]],
|
||||
["_endFail", false, [false]],
|
||||
["_time", -1, [0]],
|
||||
["_timeLimit", 0, [0]],
|
||||
["_cbrnZone", "", [""]],
|
||||
["_equipmentRewards", [], [[]]],
|
||||
["_supplyRewards", [], [[]]],
|
||||
@ -75,7 +75,7 @@ waitUntil {
|
||||
|
||||
_hostages = GVAR(TaskStore) call ["getTaskEntities", ["hostages", _taskID]];
|
||||
_shooters = GVAR(TaskStore) call ["getTaskEntities", ["shooters", _taskID]];
|
||||
private _startTime = if (_time isNotEqualTo -1) then { floor(time) } else { nil };
|
||||
private _startTime = if (_timeLimit isNotEqualTo 0) then { floor(time) } else { nil };
|
||||
|
||||
waitUntil {
|
||||
sleep 1;
|
||||
@ -86,8 +86,8 @@ waitUntil {
|
||||
private _hostagesKilled = ({ !alive _x } count _hostages);
|
||||
private _shootersAlive = ({ alive _x } count _shooters);
|
||||
|
||||
if (_time isNotEqualTo -1) then {
|
||||
private _timeExpired = (floor time - _startTime >= _time);
|
||||
if (_timeLimit isNotEqualTo 0) then {
|
||||
private _timeExpired = (floor time - _startTime >= _timeLimit);
|
||||
|
||||
if (_hostagesFreed < _limitSuccess && _timeExpired) then { _result = 1; };
|
||||
if (_hostagesKilled >= _limitFail) then { _result = 1; };
|
||||
|
||||
@ -67,7 +67,7 @@ private _taskPos = if (_hostageEntities isNotEqualTo []) then {
|
||||
["ratingSuccess", _logic getVariable ["RatingSuccess", 0]],
|
||||
["endSuccess", _logic getVariable ["EndSuccess", false]],
|
||||
["endFail", _logic getVariable ["EndFail", false]],
|
||||
["timeLimit", _logic getVariable ["TimeLimit", -1]],
|
||||
["timeLimit", _logic getVariable ["TimeLimit", 0]],
|
||||
["extractionZone", _logic getVariable ["ExtZone", ""]],
|
||||
["cbrn", _logic getVariable ["CBRN", false]],
|
||||
["execution", _logic getVariable ["Execution", false]],
|
||||
|
||||
@ -15,7 +15,7 @@
|
||||
* 7: Subcategory of task <ARRAY> (default: [true, false])
|
||||
* 8: Should the mission end (MissionSuccess) if the task is successful <BOOL> (default: false)
|
||||
* 9: Should the mission end (MissionFailed) if the task is failed <BOOL> (default: false)
|
||||
* 10: Amount of time before hvt(s) die <NUMBER> (default: -1)
|
||||
* 10: Amount of time before HVT task fails <NUMBER> (default: 0, 0 = no limit)
|
||||
* 11: Equipment rewards <ARRAY> (default: [])
|
||||
* 12: Supply rewards <ARRAY> (default: [])
|
||||
* 13: Weapon rewards <ARRAY> (default: [])
|
||||
@ -45,7 +45,7 @@ params [
|
||||
["_type", [["_capture", true, [false]], ["_eliminate", false, [false]]]],
|
||||
["_endSuccess", false, [false]],
|
||||
["_endFail", false, [false]],
|
||||
["_time", -1, [0]],
|
||||
["_timeLimit", 0, [0]],
|
||||
["_equipmentRewards", [], [[]]],
|
||||
["_supplyRewards", [], [[]]],
|
||||
["_weaponRewards", [], [[]]],
|
||||
@ -66,7 +66,7 @@ waitUntil {
|
||||
};
|
||||
|
||||
_hvts = GVAR(TaskStore) call ["getTaskEntities", ["hvts", _taskID]];
|
||||
private _startTime = if (!isNil "_time") then { floor(time) } else { nil };
|
||||
private _startTime = if (_timeLimit isNotEqualTo 0) then { floor(time) } else { nil };
|
||||
|
||||
waitUntil {
|
||||
sleep 1;
|
||||
@ -76,8 +76,8 @@ waitUntil {
|
||||
private _hvtsKilled = ({ !alive _x } count _hvts);
|
||||
private _hvtsInZone = ({ _x inArea _extZone } count _hvts);
|
||||
|
||||
if (!isNil "_time") then {
|
||||
private _timeExpired = (floor time - _startTime >= _time);
|
||||
if (_timeLimit isNotEqualTo 0) then {
|
||||
private _timeExpired = (floor time - _startTime >= _timeLimit);
|
||||
|
||||
if (_capture && _hvtsKilled >= _limitFail) then { _result = 1; };
|
||||
if (_capture && _hvtsCaptive < _limitSuccess && _timeExpired) then { _result = 1; };
|
||||
|
||||
@ -59,7 +59,7 @@ private _taskPos = if (_syncedEntities isNotEqualTo []) then {
|
||||
["ratingSuccess", _logic getVariable ["RatingSuccess", 0]],
|
||||
["endSuccess", _logic getVariable ["EndSuccess", false]],
|
||||
["endFail", _logic getVariable ["EndFail", false]],
|
||||
["timeLimit", _logic getVariable ["TimeLimit", -1]],
|
||||
["timeLimit", _logic getVariable ["TimeLimit", 0]],
|
||||
["extractionZone", _logic getVariable ["ExtZone", ""]],
|
||||
["captureHvt", _logic getVariable ["CaptureHVT", true]]
|
||||
]
|
||||
|
||||
@ -2,12 +2,12 @@
|
||||
|
||||
/*
|
||||
* Author: IDSolutions
|
||||
* Assigns an IED to a task and starts countdown timer
|
||||
* Assigns an IED to a task and starts its required countdown timer
|
||||
*
|
||||
* Arguments:
|
||||
* 0: The object <OBJECT>
|
||||
* 1: ID of the task <STRING>
|
||||
* 2: The Countdown Timer <NUMBER>
|
||||
* 2: Countdown timer in seconds <NUMBER> (must be greater than 0)
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
@ -22,7 +22,7 @@ params [["_entity", objNull, [objNull]], ["_taskID", "", [""]], ["_time", 0, [0]
|
||||
|
||||
if (isNull _entity) exitWith { ["ERROR", "Attempt to create entity from null object"] call EFUNC(common,log); };
|
||||
if (_taskID == "") exitWith { ["ERROR", "No task ID provided for entity"] call EFUNC(common,log); };
|
||||
if (_time < 0) exitWith { ["ERROR", "Invalid time provided for IED"] call EFUNC(common,log); };
|
||||
if (_time <= 0) exitWith { ["ERROR", "Invalid time provided for IED"] call EFUNC(common,log); };
|
||||
|
||||
["INFO", format ["Make IED: %1", _this]] call EFUNC(common,log);
|
||||
|
||||
|
||||
@ -29,12 +29,12 @@
|
||||
* "ratingSuccess" <NUMBER> (default: 0)
|
||||
* "endSuccess" <BOOL> (default: false)
|
||||
* "endFail" <BOOL> (default: false)
|
||||
* "timeLimit" <NUMBER> (default: -1, -1 = no limit)
|
||||
* "timeLimit" <NUMBER> (default: 0, 0 = no limit)
|
||||
* Reward keys:
|
||||
* "equipment" <ARRAY>, "supplies" <ARRAY>, "weapons" <ARRAY>,
|
||||
* "vehicles" <ARRAY>, "special" <ARRAY>
|
||||
* Type-specific keys:
|
||||
* defuse: "iedTimer" <NUMBER> -- IED countdown in seconds (default: 0)
|
||||
* defuse: "iedTimer" <NUMBER> -- required IED countdown in seconds (> 0)
|
||||
* delivery: "deliveryZone" <STRING> -- marker name
|
||||
* hostage: "extractionZone" <STRING> -- marker name
|
||||
* "cbrn" <BOOL> (default: false)
|
||||
@ -138,7 +138,7 @@ private _ratingFail = _taskParams getOrDefault ["ratingFail", 0];
|
||||
private _ratingSuccess = _taskParams getOrDefault ["ratingSuccess", 0];
|
||||
private _endSuccess = _taskParams getOrDefault ["endSuccess", false];
|
||||
private _endFail = _taskParams getOrDefault ["endFail", false];
|
||||
private _timeLimit = _taskParams getOrDefault ["timeLimit", -1];
|
||||
private _timeLimit = _taskParams getOrDefault ["timeLimit", 0];
|
||||
private _equipRewards = _taskParams getOrDefault ["equipment", []];
|
||||
private _supplyRewards = _taskParams getOrDefault ["supplies", []];
|
||||
private _weaponRewards = _taskParams getOrDefault ["weapons", []];
|
||||
@ -150,8 +150,7 @@ private _rewardTail = [_equipRewards, _supplyRewards, _weaponRewards, _vehicleRe
|
||||
private _handlerArgs = switch (_taskType) do {
|
||||
case "attack";
|
||||
case "destroy": {
|
||||
private _args = [_taskID, _limitFail, _limitSuccess, _funds, _ratingFail, _ratingSuccess, _endSuccess, _endFail];
|
||||
if (_timeLimit >= 0) then { _args pushBack _timeLimit; };
|
||||
private _args = [_taskID, _limitFail, _limitSuccess, _funds, _ratingFail, _ratingSuccess, _endSuccess, _endFail, _timeLimit];
|
||||
_args + _rewardTail
|
||||
};
|
||||
case "defuse": {
|
||||
@ -159,8 +158,7 @@ private _handlerArgs = switch (_taskType) do {
|
||||
};
|
||||
case "delivery": {
|
||||
private _deliveryZone = _taskParams getOrDefault ["deliveryZone", ""];
|
||||
private _args = [_taskID, _limitFail, _limitSuccess, _deliveryZone, _funds, _ratingFail, _ratingSuccess, _endSuccess, _endFail];
|
||||
if (_timeLimit >= 0) then { _args pushBack _timeLimit; };
|
||||
private _args = [_taskID, _limitFail, _limitSuccess, _deliveryZone, _funds, _ratingFail, _ratingSuccess, _endSuccess, _endFail, _timeLimit];
|
||||
_args + _rewardTail
|
||||
};
|
||||
case "hostage": {
|
||||
@ -168,18 +166,14 @@ private _handlerArgs = switch (_taskType) do {
|
||||
private _cbrn = _taskParams getOrDefault ["cbrn", false];
|
||||
private _execution = _taskParams getOrDefault ["execution", false];
|
||||
private _cbrnZone = _taskParams getOrDefault ["cbrnZone", ""];
|
||||
private _args = [_taskID, _limitFail, _limitSuccess, _extZone, _funds, _ratingFail, _ratingSuccess, [_cbrn, _execution], _endSuccess, _endFail];
|
||||
if (_timeLimit >= 0) then {
|
||||
_args pushBack _timeLimit;
|
||||
_args pushBack _cbrnZone;
|
||||
};
|
||||
private _args = [_taskID, _limitFail, _limitSuccess, _extZone, _funds, _ratingFail, _ratingSuccess, [_cbrn, _execution], _endSuccess, _endFail, _timeLimit];
|
||||
_args pushBack _cbrnZone;
|
||||
_args + _rewardTail
|
||||
};
|
||||
case "hvt": {
|
||||
private _extZone = _taskParams getOrDefault ["extractionZone", ""];
|
||||
private _captureHvt = _taskParams getOrDefault ["captureHvt", true];
|
||||
private _args = [_taskID, _limitFail, _limitSuccess, _extZone, _funds, _ratingFail, _ratingSuccess, [_captureHvt, !_captureHvt], _endSuccess, _endFail];
|
||||
if (_timeLimit >= 0) then { _args pushBack _timeLimit; };
|
||||
private _args = [_taskID, _limitFail, _limitSuccess, _extZone, _funds, _ratingFail, _ratingSuccess, [_captureHvt, !_captureHvt], _endSuccess, _endFail, _timeLimit];
|
||||
_args + _rewardTail
|
||||
};
|
||||
case "defend": {
|
||||
@ -188,8 +182,7 @@ private _handlerArgs = switch (_taskType) do {
|
||||
private _waveCount = _taskParams getOrDefault ["waveCount", 3];
|
||||
private _waveCooldown = _taskParams getOrDefault ["waveCooldown", 300];
|
||||
private _minBlufor = _taskParams getOrDefault ["minBlufor", 1];
|
||||
[_taskID, _defenseZone, _defendTime, _funds, _ratingFail, _ratingSuccess, _endSuccess, _endFail,
|
||||
_waveCount, _waveCooldown, _minBlufor] + _rewardTail
|
||||
[_taskID, _defenseZone, _defendTime, _funds, _ratingFail, _ratingSuccess, _endSuccess, _endFail, _waveCount, _waveCooldown, _minBlufor] + _rewardTail
|
||||
};
|
||||
default {
|
||||
["ERROR", format ["startTask: unknown task type '%1'.", _taskType]] call EFUNC(common,log);
|
||||
|
||||
@ -29,7 +29,7 @@ docs/ Framework-level documentation
|
||||
| Organization | Player organizations, membership, treasury, credit lines, shared assets, and fleet data. | `arma/client/addons/org` | `arma/server/addons/org` | `lib/models/src/org.rs`, `lib/services/src/org.rs` | `org:*`, `org:hot:*` |
|
||||
| Phone | Contacts, messages, and email state. | `arma/client/addons/phone` | `arma/server/addons/phone` | `lib/models/src/phone.rs`, `lib/services/src/phone.rs` | `phone:*` |
|
||||
| Store | Storefront entity setup, catalog hydration, checkout workflows, and checkout charging integration. | `arma/client/addons/store` | `arma/server/addons/store` | `lib/models/src/store.rs`, `lib/services/src/store.rs` | `store:checkout` |
|
||||
| Task | Mission/task catalog, ownership, status, reward context, and task counters. | none | `arma/server/addons/task` | `lib/models/src/task.rs`, `lib/services/src/task.rs` | `task:*` |
|
||||
| Task | Server-owned mission/task flows, catalog, ownership, status, participant tracking, rewards, and defuse counters. | none | `arma/server/addons/task` | `lib/models/src/task.rs`, `lib/services/src/task.rs` | `task:*` |
|
||||
| Owned Garage | Organization or owner-scoped vehicle unlock storage. | via garage/org UI | server extension only | `lib/models/src/v_garage.rs`, `lib/services/src/v_garage.rs` | `owned:garage:*` |
|
||||
| Owned Locker | Organization or owner-scoped arsenal unlock storage. | via locker/org UI | server extension only | `lib/models/src/v_locker.rs`, `lib/services/src/v_locker.rs` | `owned:locker:*` |
|
||||
|
||||
|
||||
@ -4,6 +4,20 @@ The task module stores transient mission task metadata for active server or
|
||||
mission lifecycle workflows. SQF still owns Arma-only runtime state such as
|
||||
objects and participants.
|
||||
|
||||
The server addon at `arma/server/addons/task` also owns task execution:
|
||||
creating BIS tasks, registering task entities, tracking participants, binding
|
||||
task ownership, applying player/org rewards, and clearing task state when a
|
||||
task completes.
|
||||
|
||||
Runtime dependencies:
|
||||
|
||||
- `forge_server_extension`
|
||||
- `forge_server_common`
|
||||
- `forge_server_actor`
|
||||
- `forge_server_bank`
|
||||
- `forge_server_org`
|
||||
- `forge_client_notifications`
|
||||
|
||||
## Data Model
|
||||
|
||||
Catalog entries are flexible JSON objects. The service normalizes these fields
|
||||
@ -102,6 +116,78 @@ private _context = fromJSON (_result select 0);
|
||||
|
||||
The reward context contains `requesterUid` and `orgId`.
|
||||
|
||||
## Server Task Flows
|
||||
|
||||
The task addon provides these server-owned task flows:
|
||||
|
||||
- `attack`
|
||||
- `defend`
|
||||
- `defuse`
|
||||
- `delivery`
|
||||
- `destroy`
|
||||
- `hostage`
|
||||
- `hvt`
|
||||
|
||||
Use `forge_server_task_fnc_startTask` when creating tasks from modules,
|
||||
mission scripts, or generated mission-manager content. It registers task
|
||||
entities, creates the BIS task, stores the catalog entry, then dispatches
|
||||
through `forge_server_task_fnc_handler`.
|
||||
|
||||
```sqf
|
||||
[
|
||||
"attack",
|
||||
"compound_attack_01",
|
||||
getPosATL leader1,
|
||||
"Attack: East Compound",
|
||||
"Eliminate all hostile forces.",
|
||||
createHashMapFromArray [["targets", [unit1, unit2, unit3]]],
|
||||
createHashMapFromArray [
|
||||
["limitFail", 0],
|
||||
["limitSuccess", 3],
|
||||
["funds", 50000],
|
||||
["ratingFail", -10],
|
||||
["ratingSuccess", 20],
|
||||
["timeLimit", 900]
|
||||
],
|
||||
0,
|
||||
getPlayerUID player,
|
||||
"script"
|
||||
] call forge_server_task_fnc_startTask;
|
||||
```
|
||||
|
||||
Use `forge_server_task_fnc_handler` directly when the task entities are already
|
||||
registered and you want reputation gating plus ownership binding:
|
||||
|
||||
```sqf
|
||||
[
|
||||
"delivery",
|
||||
["delivery_1", 1, 3, "delivery_zone", 250000, -75, 300, false, false, 900],
|
||||
250,
|
||||
getPlayerUID player
|
||||
] call forge_server_task_fnc_handler;
|
||||
```
|
||||
|
||||
Direct task function calls still work for mission-authored or server-owned
|
||||
tasks, but they do not provide a requester UID. Ownership falls back to the
|
||||
`default` org.
|
||||
|
||||
## Timer Semantics
|
||||
|
||||
Task time limits use `0` for no limit:
|
||||
|
||||
- attack `timeLimit`
|
||||
- destroy `timeLimit`
|
||||
- delivery `timeLimit`
|
||||
- hostage `timeLimit`
|
||||
- HVT `timeLimit`
|
||||
|
||||
Positive values are measured in seconds. Do not pass `-1` as a no-limit value;
|
||||
the task runtime treats any non-zero task time limit as active.
|
||||
|
||||
Defuse IED timers are different. `iedTimer` must be greater than `0`, because
|
||||
IEDs are expected to have an active countdown. The Eden defuse module defaults
|
||||
to `300` seconds.
|
||||
|
||||
## Defuse Counter
|
||||
|
||||
```sqf
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user