Merge pull request 'Updated Documentation & Refactor Task Module' (#8) from master into feature/surrealdb-storage
Reviewed-on: #8
This commit is contained in:
commit
de44e1f1a0
@ -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;
|
||||
};
|
||||
@ -638,6 +638,156 @@ class CfgVehicles {
|
||||
};
|
||||
};
|
||||
|
||||
class FORGE_Module_Delivery: Module_F {
|
||||
scope = 2;
|
||||
displayName = "Delivery Task";
|
||||
category = "FORGE_Modules";
|
||||
|
||||
function = QFUNC(deliveryModule);
|
||||
functionPriority = 1;
|
||||
isGlobal = 1;
|
||||
isTriggerActivated = 1;
|
||||
isDisposable = 1;
|
||||
is3DEN = 0;
|
||||
|
||||
canSetArea = 0;
|
||||
canSetAreaShape = 0;
|
||||
canSetAreaHeight = 0;
|
||||
|
||||
class AttributeValues {};
|
||||
class Attributes: AttributesBase {
|
||||
class TaskID: Edit {
|
||||
property = "FORGE_Module_Delivery_TaskID";
|
||||
displayName = "Task ID";
|
||||
tooltip = "Unique identifier for this task";
|
||||
typeName = "STRING";
|
||||
};
|
||||
class DeliveryZone: Edit {
|
||||
property = "FORGE_Module_Delivery_DeliveryZone";
|
||||
displayName = "Delivery Zone Marker";
|
||||
tooltip = "Name of the marker defining the delivery destination";
|
||||
typeName = "STRING";
|
||||
};
|
||||
class LimitFail: Edit {
|
||||
property = "FORGE_Module_Delivery_LimitFail";
|
||||
displayName = "Fail Limit";
|
||||
tooltip = "Number of cargo items damaged or lost before failing";
|
||||
typeName = "NUMBER";
|
||||
defaultValue = 1;
|
||||
};
|
||||
class LimitSuccess: Edit {
|
||||
property = "FORGE_Module_Delivery_LimitSuccess";
|
||||
displayName = "Success Limit";
|
||||
tooltip = "Number of cargo items that must reach the delivery zone";
|
||||
typeName = "NUMBER";
|
||||
defaultValue = 1;
|
||||
};
|
||||
class CompanyFunds: Edit {
|
||||
property = "FORGE_Module_Delivery_CompanyFunds";
|
||||
displayName = "Reward Funds";
|
||||
tooltip = "Amount of funds awarded on success";
|
||||
typeName = "NUMBER";
|
||||
defaultValue = 0;
|
||||
};
|
||||
class RatingFail: Edit {
|
||||
property = "FORGE_Module_Delivery_RatingFail";
|
||||
displayName = "Rating Loss";
|
||||
tooltip = "Amount of rating lost on failure";
|
||||
typeName = "NUMBER";
|
||||
defaultValue = 0;
|
||||
};
|
||||
class RatingSuccess: Edit {
|
||||
property = "FORGE_Module_Delivery_RatingSuccess";
|
||||
displayName = "Rating Gain";
|
||||
tooltip = "Amount of rating gained on success";
|
||||
typeName = "NUMBER";
|
||||
defaultValue = 0;
|
||||
};
|
||||
class EndSuccess: Combo {
|
||||
property = "FORGE_Module_Delivery_EndSuccess";
|
||||
displayName = "End on Success";
|
||||
tooltip = "End mission when task is completed successfully";
|
||||
typeName = "BOOL";
|
||||
defaultValue = 0;
|
||||
|
||||
class Values {
|
||||
class EnableEndSuccess { name = "Enable"; value = 1; };
|
||||
class DisableEndSuccess { name = "Disable"; value = 0; };
|
||||
};
|
||||
};
|
||||
class EndFail: Combo {
|
||||
property = "FORGE_Module_Delivery_EndFail";
|
||||
displayName = "End on Failure";
|
||||
tooltip = "End mission when task fails";
|
||||
typeName = "BOOL";
|
||||
defaultValue = 0;
|
||||
|
||||
class Values {
|
||||
class EnableEndFail { name = "Enable"; value = 1; };
|
||||
class DisableEndFail { name = "Disable"; value = 0; };
|
||||
};
|
||||
};
|
||||
class TimeLimit: Edit {
|
||||
property = "FORGE_Module_Delivery_TimeLimit";
|
||||
displayName = "Time Limit";
|
||||
tooltip = "Seconds to complete delivery (0 for no limit)";
|
||||
typeName = "NUMBER";
|
||||
defaultValue = 0;
|
||||
};
|
||||
};
|
||||
|
||||
class ModuleDescription: ModuleDescription {
|
||||
description = "Creates a delivery task. Sync with a FORGE_Module_Cargo to register cargo objects.";
|
||||
sync[] = { "Anything" };
|
||||
|
||||
class Anything {
|
||||
description[] = {
|
||||
"Delivery task module",
|
||||
"Sync with FORGE_Module_Cargo which groups the cargo objects"
|
||||
};
|
||||
position = 1;
|
||||
direction = 1;
|
||||
optional = 1;
|
||||
duplicate = 1;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
class FORGE_Module_Cargo: Module_F {
|
||||
scope = 2;
|
||||
displayName = "Cargo Entities";
|
||||
category = "FORGE_Modules";
|
||||
|
||||
function = QFUNC(cargoModule);
|
||||
functionPriority = 1;
|
||||
isGlobal = 1;
|
||||
isTriggerActivated = 0;
|
||||
isDisposable = 1;
|
||||
is3DEN = 0;
|
||||
|
||||
canSetArea = 0;
|
||||
canSetAreaShape = 0;
|
||||
canSetAreaHeight = 0;
|
||||
|
||||
class AttributeValues {};
|
||||
class Attributes: AttributesBase {};
|
||||
class ModuleDescription: ModuleDescription {
|
||||
description = "Grouping module for cargo objects in a delivery task. Sync with objects to mark as cargo, then sync this module to FORGE_Module_Delivery.";
|
||||
sync[] = { "Anything" };
|
||||
|
||||
class Anything {
|
||||
description[] = {
|
||||
"Cargo entities module",
|
||||
"Sync with objects to mark as delivery cargo"
|
||||
};
|
||||
position = 1;
|
||||
direction = 1;
|
||||
optional = 1;
|
||||
duplicate = 1;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
class FORGE_Module_HVT: Module_F {
|
||||
scope = 2;
|
||||
displayName = "HVT Task";
|
||||
@ -757,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.
|
||||
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
PREP(attack);
|
||||
PREP(attackModule);
|
||||
PREP(cargoModule);
|
||||
PREP(defend);
|
||||
PREP(defendModule);
|
||||
PREP(defuse);
|
||||
@ -29,3 +30,4 @@ PREP(initTaskStore);
|
||||
PREP(protectedModule);
|
||||
PREP(shootersModule);
|
||||
PREP(spawnEnemyWave);
|
||||
PREP(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 _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; };
|
||||
|
||||
|
||||
@ -23,29 +23,38 @@ params [["_logic", objNull, [objNull]], ["_units", [], [[]]], ["_activated", tru
|
||||
if !(_activated) exitWith {};
|
||||
|
||||
private _taskID = _logic getVariable ["TaskID", ""];
|
||||
private _limitFail = _logic getVariable ["LimitFail", -1];
|
||||
private _limitSuccess = _logic getVariable ["LimitSuccess", -1];
|
||||
private _companyFunds = _logic getVariable ["CompanyFunds", 0];
|
||||
private _ratingFail = _logic getVariable ["RatingFail", 0];
|
||||
private _ratingSuccess = _logic getVariable ["RatingSuccess", 0];
|
||||
private _endSuccess = _logic getVariable ["EndSuccess", false];
|
||||
private _endFail = _logic getVariable ["EndFail", false];
|
||||
private _timeLimit = _logic getVariable ["TimeLimit", 0];
|
||||
|
||||
["INFO", format ["Attack Module Parameters: TaskID: %1, LimitFail: %2, LimitSuccess: %3, Funds: %4, RatingFail: %5, RatingSuccess: %6, EndSuccess: %7, EndFail: %8, Time: %9", _taskID, _limitFail, _limitSuccess, _companyFunds, _ratingFail, _ratingSuccess, _endSuccess, _endFail, _timeLimit]] call EFUNC(common,log);
|
||||
|
||||
private _syncedEntities = synchronizedObjects _logic;
|
||||
["INFO", format ["Attack Module Synced Entities: %1", _syncedEntities]] call EFUNC(common,log);
|
||||
|
||||
{
|
||||
[_x, _taskID] spawn FUNC(makeTarget);
|
||||
} forEach _syncedEntities;
|
||||
|
||||
private _params = [_taskID, _limitFail, _limitSuccess, _companyFunds, _ratingFail, _ratingSuccess, _endSuccess, _endFail];
|
||||
if (_timeLimit != 0) then {
|
||||
_params pushBack _timeLimit;
|
||||
if (_taskID isEqualTo "") exitWith {
|
||||
["ERROR", "Attack module: no task ID configured."] call EFUNC(common,log);
|
||||
};
|
||||
|
||||
["attack", _params, 0, ""] spawn FUNC(handler);
|
||||
private _syncedEntities = synchronizedObjects _logic;
|
||||
["INFO", format ["Attack Module: TaskID: %1, Synced entities: %2", _taskID, count _syncedEntities]] call EFUNC(common,log);
|
||||
|
||||
private _taskPos = if (_syncedEntities isNotEqualTo []) then {
|
||||
getPosATL (_syncedEntities select 0)
|
||||
} else {
|
||||
getPosATL _logic
|
||||
};
|
||||
|
||||
[
|
||||
"attack",
|
||||
_taskID,
|
||||
_taskPos,
|
||||
format ["Attack: %1", _taskID],
|
||||
"Eliminate all hostile forces in the area.",
|
||||
createHashMapFromArray [
|
||||
["targets", _syncedEntities]
|
||||
],
|
||||
createHashMapFromArray [
|
||||
["limitFail", _logic getVariable ["LimitFail", -1]],
|
||||
["limitSuccess", _logic getVariable ["LimitSuccess", -1]],
|
||||
["funds", _logic getVariable ["CompanyFunds", 0]],
|
||||
["ratingFail", _logic getVariable ["RatingFail", 0]],
|
||||
["ratingSuccess", _logic getVariable ["RatingSuccess", 0]],
|
||||
["endSuccess", _logic getVariable ["EndSuccess", false]],
|
||||
["endFail", _logic getVariable ["EndFail", false]],
|
||||
["timeLimit", _logic getVariable ["TimeLimit", 0]]
|
||||
]
|
||||
] call FUNC(startTask);
|
||||
|
||||
deleteVehicle _logic;
|
||||
|
||||
23
arma/server/addons/task/functions/fnc_cargoModule.sqf
Normal file
23
arma/server/addons/task/functions/fnc_cargoModule.sqf
Normal file
@ -0,0 +1,23 @@
|
||||
#include "..\script_component.hpp"
|
||||
|
||||
/*
|
||||
* Author: IDSolutions
|
||||
* Grouping module for cargo entities in a delivery task.
|
||||
* This module has no logic of its own — it acts as a sync target so that
|
||||
* cargo objects can be grouped and discovered by the parent delivery module
|
||||
* via synchronizedObjects + typeOf "FORGE_Module_Cargo".
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Logic <OBJECT>
|
||||
* 1: Units <ARRAY>
|
||||
* 2: Activated <BOOL>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
params [["_logic", objNull, [objNull]], ["_units", [], [[]]], ["_activated", true, [true]]];
|
||||
|
||||
if !(_activated) exitWith {};
|
||||
@ -2,60 +2,65 @@
|
||||
|
||||
/*
|
||||
* Author: IDSolutions
|
||||
* Creates a defend task module
|
||||
* Initializes the defend task module.
|
||||
* Reads parameters from the logic object and delegates to fnc_startTask.
|
||||
* The designer must place a named marker in Eden for the defense zone.
|
||||
* Enemy waves are spawned automatically by fnc_defend — no entities need
|
||||
* to be synced to this module.
|
||||
*
|
||||
* Arguments:
|
||||
* None
|
||||
* 0: Logic <OBJECT>
|
||||
* 1: Units <ARRAY>
|
||||
* 2: Activated <BOOL>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* call forge_server_task_fnc_defendModule;
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
// Module category
|
||||
private _category = "Forge Tasks";
|
||||
private _subCategory = "Defense Tasks";
|
||||
params [["_logic", objNull, [objNull]], ["_units", [], [[]]], ["_activated", true, [true]]];
|
||||
|
||||
// Create the module
|
||||
private _module = createDialog "RscDisplayAttributes";
|
||||
_module setVariable ["category", _category];
|
||||
_module setVariable ["subcategory", _subCategory];
|
||||
_module setVariable ["description", "Configure a defend task"];
|
||||
if !(_activated) exitWith {};
|
||||
|
||||
// Add fields for task configuration
|
||||
[_module, "Task ID", "taskID", "", true] call BIS_fnc_addAttribute;
|
||||
[_module, "Defense Zone Marker", "defenseZone", "", true] call BIS_fnc_addAttribute;
|
||||
[_module, "Defense Time (seconds)", "defendTime", "600", true] call BIS_fnc_addAttribute;
|
||||
[_module, "Min BLUFOR in Zone", "minBlufor", "1", true] call BIS_fnc_addAttribute;
|
||||
[_module, "Company Funds Reward", "companyFunds", "500000", true] call BIS_fnc_addAttribute;
|
||||
[_module, "Rating Loss on Fail", "ratingFail", "-100", true] call BIS_fnc_addAttribute;
|
||||
[_module, "Rating Gain on Success", "ratingSuccess", "400", true] call BIS_fnc_addAttribute;
|
||||
[_module, "End Mission on Success", "endSuccess", "false", false] call BIS_fnc_addAttribute;
|
||||
[_module, "End Mission on Fail", "endFail", "false", false] call BIS_fnc_addAttribute;
|
||||
[_module, "Enemy Wave Count", "waveCount", "3", false] call BIS_fnc_addAttribute;
|
||||
[_module, "Time Between Waves (seconds)", "waveCooldown", "300", false] call BIS_fnc_addAttribute;
|
||||
private _taskID = _logic getVariable ["TaskID", ""];
|
||||
private _defenseZone = _logic getVariable ["DefenseZone", ""];
|
||||
|
||||
// Add confirm button handler
|
||||
_module setVariable ["onConfirm", {
|
||||
params ["_module"];
|
||||
private _taskID = _module getVariable ["taskID", ""];
|
||||
private _defenseZone = _module getVariable ["defenseZone", ""];
|
||||
private _defendTime = parseNumber (_module getVariable ["defendTime", "600"]);
|
||||
private _companyFunds = parseNumber (_module getVariable ["companyFunds", "500000"]);
|
||||
private _ratingFail = parseNumber (_module getVariable ["ratingFail", "-100"]);
|
||||
private _ratingSuccess = parseNumber (_module getVariable ["ratingSuccess", "400"]);
|
||||
private _endSuccess = _module getVariable ["endSuccess", "false"] == "true";
|
||||
private _endFail = _module getVariable ["endFail", "false"] == "true";
|
||||
private _waveCount = parseNumber (_module getVariable ["waveCount", "3"]);
|
||||
private _waveCooldown = parseNumber (_module getVariable ["waveCooldown", "300"]);
|
||||
private _minBlufor = parseNumber (_module getVariable ["minBlufor", "1"]);
|
||||
if (_taskID isEqualTo "") exitWith {
|
||||
["ERROR", "Defend module: no task ID configured."] call EFUNC(common,log);
|
||||
};
|
||||
if (_defenseZone isEqualTo "" || { markerShape _defenseZone isEqualTo "" }) exitWith {
|
||||
["ERROR", format ["Defend module '%1': DefenseZone marker '%2' is missing or invalid.", _taskID, _defenseZone]] call EFUNC(common,log);
|
||||
};
|
||||
|
||||
// Create the task
|
||||
private _params = [_taskID, _defenseZone, _defendTime, _companyFunds, _ratingFail, _ratingSuccess, _endSuccess, _endFail, _waveCount, _waveCooldown, _minBlufor];
|
||||
private _requesterUid = ["", getPlayerUID player] select hasInterface;
|
||||
["defend", _params, 0, _requesterUid] spawn FUNC(handler);
|
||||
}];
|
||||
["INFO", format [
|
||||
"Defend Module Parameters: TaskID: %1, DefenseZone: %2, DefendTime: %3, WaveCount: %4, WaveCooldown: %5, MinBlufor: %6",
|
||||
_taskID, _defenseZone,
|
||||
_logic getVariable ["DefendTime", 600],
|
||||
_logic getVariable ["WaveCount", 3],
|
||||
_logic getVariable ["WaveCooldown", 300],
|
||||
_logic getVariable ["MinBlufor", 1]
|
||||
]] call EFUNC(common,log);
|
||||
|
||||
[
|
||||
"defend",
|
||||
_taskID,
|
||||
getMarkerPos _defenseZone,
|
||||
format ["Defend: %1", _taskID],
|
||||
"Hold the defense zone against incoming enemy forces.",
|
||||
createHashMap,
|
||||
createHashMapFromArray [
|
||||
["funds", _logic getVariable ["CompanyFunds", 0]],
|
||||
["ratingFail", _logic getVariable ["RatingFail", 0]],
|
||||
["ratingSuccess", _logic getVariable ["RatingSuccess", 0]],
|
||||
["endSuccess", _logic getVariable ["EndSuccess", false]],
|
||||
["endFail", _logic getVariable ["EndFail", false]],
|
||||
["defenseZone", _defenseZone],
|
||||
["defendTime", _logic getVariable ["DefendTime", 600]],
|
||||
["waveCount", _logic getVariable ["WaveCount", 3]],
|
||||
["waveCooldown", _logic getVariable ["WaveCooldown", 300]],
|
||||
["minBlufor", _logic getVariable ["MinBlufor", 1]]
|
||||
]
|
||||
] call FUNC(startTask);
|
||||
|
||||
deleteVehicle _logic;
|
||||
|
||||
@ -23,42 +23,48 @@ params [["_logic", objNull, [objNull]], ["_units", [], [[]]], ["_activated", tru
|
||||
if !(_activated) exitWith {};
|
||||
|
||||
private _taskID = _logic getVariable ["TaskID", ""];
|
||||
private _limitFail = _logic getVariable ["LimitFail", -1];
|
||||
private _limitSuccess = _logic getVariable ["LimitSuccess", -1];
|
||||
private _companyFunds = _logic getVariable ["CompanyFunds", 0];
|
||||
private _ratingFail = _logic getVariable ["RatingFail", 0];
|
||||
private _ratingSuccess = _logic getVariable ["RatingSuccess", 0];
|
||||
private _endSuccess = _logic getVariable ["EndSuccess", false];
|
||||
private _endFail = _logic getVariable ["EndFail", false];
|
||||
private _timeLimit = _logic getVariable ["TimeLimit", 0];
|
||||
|
||||
["INFO", format ["Defuse Module Parameters: TaskID: %1, LimitFail: %2, LimitSuccess: %3, Funds: %4, RatingFail: %5, RatingSuccess: %6, EndSuccess: %7, EndFail: %8, Time: %9", _taskID, _limitFail, _limitSuccess, _companyFunds, _ratingFail, _ratingSuccess, _endSuccess, _endFail, _timeLimit]] call EFUNC(common,log);
|
||||
if (_taskID isEqualTo "") exitWith {
|
||||
["ERROR", "Defuse module: no task ID configured."] call EFUNC(common,log);
|
||||
};
|
||||
|
||||
private _syncedModules = synchronizedObjects _logic;
|
||||
["INFO", format ["Defuse Module Synced Modules: %1", _syncedModules]] call EFUNC(common,log);
|
||||
private _iedModule = (_syncedModules select { typeOf _x isEqualTo "FORGE_Module_Explosives" }) param [0, objNull];
|
||||
private _protectedModule = (_syncedModules select { typeOf _x isEqualTo "FORGE_Module_Protected" }) param [0, objNull];
|
||||
private _iedEntities = if (!isNull _iedModule) then { synchronizedObjects _iedModule } else { [] };
|
||||
private _protectedEntities = if (!isNull _protectedModule) then { synchronizedObjects _protectedModule } else { [] };
|
||||
|
||||
private _iedModule = (_syncedModules select { typeOf _x == "FORGE_Module_Explosives" }) select 0;
|
||||
private _protectedModule = (_syncedModules select { typeOf _x == "FORGE_Module_Protected" }) select 0;
|
||||
["INFO", format [
|
||||
"Defuse Module: TaskID: %1, IEDs: %2, Protected: %3, IED timer: %4s",
|
||||
_taskID, count _iedEntities, count _protectedEntities,
|
||||
_logic getVariable ["TimeLimit", 300]
|
||||
]] call EFUNC(common,log);
|
||||
|
||||
private _explosiveEntities = synchronizedObjects _iedModule;
|
||||
["INFO", format ["Defuse Module Explosive Entites: %1", _explosiveEntities]] call EFUNC(common,log);
|
||||
private _taskPos = if (_iedEntities isNotEqualTo []) then {
|
||||
getPosATL (_iedEntities select 0)
|
||||
} else {
|
||||
getPosATL _logic
|
||||
};
|
||||
|
||||
private _protectedEntities = synchronizedObjects _protectedModule;
|
||||
["INFO", format ["Defuse Module Protected Entities: %1", _protectedEntities]] call EFUNC(common,log);
|
||||
|
||||
{
|
||||
if (!isNull _x) then {
|
||||
[_x, _taskID, _timeLimit] spawn FUNC(makeIED);
|
||||
};
|
||||
} forEach _explosiveEntities;
|
||||
|
||||
{
|
||||
if (!isNull _x) then {
|
||||
[_x, _taskID] spawn FUNC(makeObject);
|
||||
};
|
||||
} forEach _protectedEntities;
|
||||
|
||||
private _params = [_taskID, _limitFail, _limitSuccess, _companyFunds, _ratingFail, _ratingSuccess, _endSuccess, _endFail];
|
||||
["defuse", _params, 0, ""] spawn FUNC(handler);
|
||||
[
|
||||
"defuse",
|
||||
_taskID,
|
||||
_taskPos,
|
||||
format ["Defuse: %1", _taskID],
|
||||
"Locate and defuse all explosive devices before they detonate.",
|
||||
createHashMapFromArray [
|
||||
["ieds", _iedEntities],
|
||||
["protected", _protectedEntities]
|
||||
],
|
||||
createHashMapFromArray [
|
||||
["limitFail", _logic getVariable ["LimitFail", -1]],
|
||||
["limitSuccess", _logic getVariable ["LimitSuccess", -1]],
|
||||
["funds", _logic getVariable ["CompanyFunds", 0]],
|
||||
["ratingFail", _logic getVariable ["RatingFail", 0]],
|
||||
["ratingSuccess", _logic getVariable ["RatingSuccess", 0]],
|
||||
["endSuccess", _logic getVariable ["EndSuccess", false]],
|
||||
["endFail", _logic getVariable ["EndFail", false]],
|
||||
["iedTimer", _logic getVariable ["TimeLimit", 300]]
|
||||
]
|
||||
] call FUNC(startTask);
|
||||
|
||||
deleteVehicle _logic;
|
||||
|
||||
@ -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; };
|
||||
|
||||
@ -2,66 +2,70 @@
|
||||
|
||||
/*
|
||||
* Author: IDSolutions
|
||||
* Creates a delivery task module
|
||||
* Initializes the delivery task module.
|
||||
* Reads parameters from the logic object, collects cargo from the synced
|
||||
* FORGE_Module_Cargo grouping module, and delegates to fnc_startTask.
|
||||
*
|
||||
* Eden layout:
|
||||
* [FORGE_Module_Delivery] --sync--> [FORGE_Module_Cargo] --sync--> cargo_obj1, cargo_obj2
|
||||
*
|
||||
* Arguments:
|
||||
* None
|
||||
* 0: Logic <OBJECT>
|
||||
* 1: Units <ARRAY>
|
||||
* 2: Activated <BOOL>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* call forge_server_task_fnc_deliveryModule;
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
// Module category
|
||||
private _category = "Forge Tasks";
|
||||
private _subCategory = "Delivery Tasks";
|
||||
params [["_logic", objNull, [objNull]], ["_units", [], [[]]], ["_activated", true, [true]]];
|
||||
|
||||
// Create the module
|
||||
private _module = createDialog "RscDisplayAttributes";
|
||||
_module setVariable ["category", _category];
|
||||
_module setVariable ["subcategory", _subCategory];
|
||||
_module setVariable ["description", "Configure a delivery task"];
|
||||
if !(_activated) exitWith {};
|
||||
|
||||
// Add fields for task configuration
|
||||
[_module, "Task ID", "taskID", "", true] call BIS_fnc_addAttribute;
|
||||
[_module, "Fail Limit", "limitFail", "1", true] call BIS_fnc_addAttribute;
|
||||
[_module, "Success Count", "limitSuccess", "3", true] call BIS_fnc_addAttribute;
|
||||
[_module, "Delivery Zone", "deliveryZone", "", true] call BIS_fnc_addAttribute;
|
||||
[_module, "Company Funds Reward", "companyFunds", "250000", true] call BIS_fnc_addAttribute;
|
||||
[_module, "Rating Loss on Fail", "ratingFail", "-75", true] call BIS_fnc_addAttribute;
|
||||
[_module, "Rating Gain on Success", "ratingSuccess", "300", true] call BIS_fnc_addAttribute;
|
||||
[_module, "End Mission on Success", "endSuccess", "false", false] call BIS_fnc_addAttribute;
|
||||
[_module, "End Mission on Fail", "endFail", "false", false] call BIS_fnc_addAttribute;
|
||||
[_module, "Time Limit (seconds)", "timeLimit", "", false] call BIS_fnc_addAttribute;
|
||||
private _taskID = _logic getVariable ["TaskID", ""];
|
||||
if (_taskID isEqualTo "") exitWith {
|
||||
["ERROR", "Delivery module: no task ID configured."] call EFUNC(common,log);
|
||||
};
|
||||
|
||||
// Add confirm button handler
|
||||
_module setVariable ["onConfirm", {
|
||||
params ["_module"];
|
||||
private _syncedModules = synchronizedObjects _logic;
|
||||
private _cargoModule = (_syncedModules select { typeOf _x isEqualTo "FORGE_Module_Cargo" }) param [0, objNull];
|
||||
private _cargoEntities = if (!isNull _cargoModule) then { synchronizedObjects _cargoModule } else { [] };
|
||||
|
||||
private _taskID = _module getVariable ["taskID", ""];
|
||||
private _limitFail = parseNumber (_module getVariable ["limitFail", "1"]);
|
||||
private _limitSuccess = parseNumber (_module getVariable ["limitSuccess", "3"]);
|
||||
private _deliveryZone = _module getVariable ["deliveryZone", ""];
|
||||
private _companyFunds = parseNumber (_module getVariable ["companyFunds", "250000"]);
|
||||
private _ratingFail = parseNumber (_module getVariable ["ratingFail", "-75"]);
|
||||
private _ratingSuccess = parseNumber (_module getVariable ["ratingSuccess", "300"]);
|
||||
private _endSuccess = _module getVariable ["endSuccess", "false"] == "true";
|
||||
private _endFail = _module getVariable ["endFail", "false"] == "true";
|
||||
private _timeLimit = _module getVariable ["timeLimit", ""];
|
||||
["INFO", format [
|
||||
"Delivery Module Parameters: TaskID: %1, DeliveryZone: %2, Cargo count: %3",
|
||||
_taskID,
|
||||
_logic getVariable ["DeliveryZone", ""],
|
||||
count _cargoEntities
|
||||
]] call EFUNC(common,log);
|
||||
|
||||
// Convert time limit to number or nil
|
||||
private _timeLimitNum = if (_timeLimit == "") then { nil } else { parseNumber _timeLimit };
|
||||
private _taskPos = if (_cargoEntities isNotEqualTo []) then {
|
||||
getPosATL (_cargoEntities select 0)
|
||||
} else {
|
||||
getPosATL _logic
|
||||
};
|
||||
|
||||
// Create the task
|
||||
private _params = [_taskID, _limitFail, _limitSuccess, _deliveryZone, _companyFunds, _ratingFail, _ratingSuccess, _endSuccess, _endFail];
|
||||
if (!isNil "_timeLimitNum") then {
|
||||
_params pushBack _timeLimitNum;
|
||||
};
|
||||
[
|
||||
"delivery",
|
||||
_taskID,
|
||||
_taskPos,
|
||||
format ["Delivery: %1", _taskID],
|
||||
"Transport all cargo to the designated delivery zone.",
|
||||
createHashMapFromArray [
|
||||
["cargo", _cargoEntities]
|
||||
],
|
||||
createHashMapFromArray [
|
||||
["limitFail", _logic getVariable ["LimitFail", -1]],
|
||||
["limitSuccess", _logic getVariable ["LimitSuccess", -1]],
|
||||
["funds", _logic getVariable ["CompanyFunds", 0]],
|
||||
["ratingFail", _logic getVariable ["RatingFail", 0]],
|
||||
["ratingSuccess", _logic getVariable ["RatingSuccess", 0]],
|
||||
["endSuccess", _logic getVariable ["EndSuccess", false]],
|
||||
["endFail", _logic getVariable ["EndFail", false]],
|
||||
["timeLimit", _logic getVariable ["TimeLimit", 0]],
|
||||
["deliveryZone", _logic getVariable ["DeliveryZone", ""]]
|
||||
]
|
||||
] call FUNC(startTask);
|
||||
|
||||
private _requesterUid = ["", getPlayerUID player] select hasInterface;
|
||||
["delivery", _params, 0, _requesterUid] spawn FUNC(handler);
|
||||
}];
|
||||
deleteVehicle _logic;
|
||||
|
||||
@ -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; };
|
||||
|
||||
|
||||
@ -23,29 +23,38 @@ params [["_logic", objNull, [objNull]], ["_units", [], [[]]], ["_activated", tru
|
||||
if !(_activated) exitWith {};
|
||||
|
||||
private _taskID = _logic getVariable ["TaskID", ""];
|
||||
private _limitFail = _logic getVariable ["LimitFail", -1];
|
||||
private _limitSuccess = _logic getVariable ["LimitSuccess", -1];
|
||||
private _companyFunds = _logic getVariable ["CompanyFunds", 0];
|
||||
private _ratingFail = _logic getVariable ["RatingFail", 0];
|
||||
private _ratingSuccess = _logic getVariable ["RatingSuccess", 0];
|
||||
private _endSuccess = _logic getVariable ["EndSuccess", false];
|
||||
private _endFail = _logic getVariable ["EndFail", false];
|
||||
private _timeLimit = _logic getVariable ["TimeLimit", 0];
|
||||
|
||||
["INFO", format ["Destroy Module Parameters: TaskID: %1, LimitFail: %2, LimitSuccess: %3, Funds: %4, RatingFail: %5, RatingSuccess: %6, EndSuccess: %7, EndFail: %8, Time: %9", _taskID, _limitFail, _limitSuccess, _companyFunds, _ratingFail, _ratingSuccess, _endSuccess, _endFail, _timeLimit]] call EFUNC(common,log);
|
||||
|
||||
private _syncedEntities = synchronizedObjects _logic;
|
||||
["INFO", format ["Destroy Module Synced Entities: %1", _syncedEntities]] call EFUNC(common,log);
|
||||
|
||||
{
|
||||
[_x, _taskID] spawn FUNC(makeTarget);
|
||||
} forEach _syncedEntities;
|
||||
|
||||
private _params = [_taskID, _limitFail, _limitSuccess, _companyFunds, _ratingFail, _ratingSuccess, _endSuccess, _endFail];
|
||||
if (_timeLimit != 0) then {
|
||||
_params pushBack _timeLimit;
|
||||
if (_taskID isEqualTo "") exitWith {
|
||||
["ERROR", "Destroy module: no task ID configured."] call EFUNC(common,log);
|
||||
};
|
||||
|
||||
["destroy", _params, 0, ""] spawn FUNC(handler);
|
||||
private _syncedEntities = synchronizedObjects _logic;
|
||||
["INFO", format ["Destroy Module: TaskID: %1, Synced entities: %2", _taskID, count _syncedEntities]] call EFUNC(common,log);
|
||||
|
||||
private _taskPos = if (_syncedEntities isNotEqualTo []) then {
|
||||
getPosATL (_syncedEntities select 0)
|
||||
} else {
|
||||
getPosATL _logic
|
||||
};
|
||||
|
||||
[
|
||||
"destroy",
|
||||
_taskID,
|
||||
_taskPos,
|
||||
format ["Destroy: %1", _taskID],
|
||||
"Locate and destroy all designated targets.",
|
||||
createHashMapFromArray [
|
||||
["targets", _syncedEntities]
|
||||
],
|
||||
createHashMapFromArray [
|
||||
["limitFail", _logic getVariable ["LimitFail", -1]],
|
||||
["limitSuccess", _logic getVariable ["LimitSuccess", -1]],
|
||||
["funds", _logic getVariable ["CompanyFunds", 0]],
|
||||
["ratingFail", _logic getVariable ["RatingFail", 0]],
|
||||
["ratingSuccess", _logic getVariable ["RatingSuccess", 0]],
|
||||
["endSuccess", _logic getVariable ["EndSuccess", false]],
|
||||
["endFail", _logic getVariable ["EndFail", false]],
|
||||
["timeLimit", _logic getVariable ["TimeLimit", 0]]
|
||||
]
|
||||
] call FUNC(startTask);
|
||||
|
||||
deleteVehicle _logic;
|
||||
|
||||
@ -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; };
|
||||
|
||||
@ -23,54 +23,56 @@ params [["_logic", objNull, [objNull]], ["_units", [], [[]]], ["_activated", tru
|
||||
if !(_activated) exitWith {};
|
||||
|
||||
private _taskID = _logic getVariable ["TaskID", ""];
|
||||
private _limitFail = _logic getVariable ["LimitFail", -1];
|
||||
private _limitSuccess = _logic getVariable ["LimitSuccess", -1];
|
||||
private _extraction = _logic getVariable ["ExtZone", ""];
|
||||
private _companyFunds = _logic getVariable ["CompanyFunds", 0];
|
||||
private _ratingFail = _logic getVariable ["RatingFail", 0];
|
||||
private _ratingSuccess = _logic getVariable ["RatingSuccess", 0];
|
||||
private _cbrn = _logic getVariable ["CBRN", false];
|
||||
private _execution = _logic getVariable ["Execution", false];
|
||||
private _endSuccess = _logic getVariable ["EndSuccess", false];
|
||||
private _endFail = _logic getVariable ["EndFail", false];
|
||||
private _timeLimit = _logic getVariable ["TimeLimit", 0];
|
||||
private _cbrnZone = _logic getVariable ["CBRNZone", ""];
|
||||
|
||||
["INFO", format [
|
||||
"Hostage Module Parameters: TaskID: %1, LimitFail: %2, LimitSuccess: %3, ExtractionZone: %4, Funds: %5, RatingFail: %6, RatingSuccess: %7, CBRN: %8, Execution: %9, EndSuccess: %10, EndFail: %11, Time: %12, CBRNZone: %13",
|
||||
_taskID, _limitFail, _limitSuccess, _extraction, _companyFunds, _ratingFail, _ratingSuccess, _cbrn, _execution, _endSuccess, _endFail, _timeLimit, _cbrnZone
|
||||
]] call EFUNC(common,log);
|
||||
|
||||
private _syncedModules = synchronizedObjects _logic;
|
||||
["INFO", format ["Hostage Module Synced Entities: %1", _syncedModules]] call EFUNC(common,log);
|
||||
|
||||
private _hostageModule = (_syncedModules select { typeOf _x == "FORGE_Module_Hostages" }) select 0;
|
||||
private _shooterModule = (_syncedModules select { typeOf _x == "FORGE_Module_Shooters" }) select 0;
|
||||
|
||||
private _hostageEntities = synchronizedObjects _hostageModule;
|
||||
["INFO", format ["Hostage Module Hostage Entities: %1", _hostageEntities]] call EFUNC(common,log);
|
||||
|
||||
private _shooterEntities = synchronizedObjects _shooterModule;
|
||||
["INFO", format ["Hostage Module Shooter Entities: %1", _shooterEntities]] call EFUNC(common,log);
|
||||
|
||||
{
|
||||
if (!isNull _x && (_x isNotEqualTo str objNull)) then {
|
||||
[_x, _taskID] spawn FUNC(makeHostage);
|
||||
};
|
||||
} forEach _hostageEntities;
|
||||
|
||||
{
|
||||
if (!isNull _x && (_x isNotEqualTo str objNull)) then {
|
||||
[_x, _taskID] spawn FUNC(makeShooter);
|
||||
};
|
||||
} forEach _shooterEntities;
|
||||
|
||||
private _params = [_taskID, _limitFail, _limitSuccess, _extraction, _companyFunds, _ratingFail, _ratingSuccess, [_cbrn, _execution], _endSuccess, _endFail];
|
||||
if (_timeLimit != 0) then {
|
||||
_params pushBack _timeLimit;
|
||||
_params pushBack _cbrnZone;
|
||||
if (_taskID isEqualTo "") exitWith {
|
||||
["ERROR", "Hostage module: no task ID configured."] call EFUNC(common,log);
|
||||
};
|
||||
|
||||
["hostage", _params, 0, ""] spawn FUNC(handler);
|
||||
private _syncedModules = synchronizedObjects _logic;
|
||||
private _hostageModule = (_syncedModules select { typeOf _x isEqualTo "FORGE_Module_Hostages" }) param [0, objNull];
|
||||
private _shooterModule = (_syncedModules select { typeOf _x isEqualTo "FORGE_Module_Shooters" }) param [0, objNull];
|
||||
private _hostageEntities = if (!isNull _hostageModule) then { synchronizedObjects _hostageModule } else { [] };
|
||||
private _shooterEntities = if (!isNull _shooterModule) then { synchronizedObjects _shooterModule } else { [] };
|
||||
|
||||
["INFO", format [
|
||||
"Hostage Module: TaskID: %1, ExtZone: %2, Hostages: %3, Shooters: %4, CBRN: %5, Execution: %6",
|
||||
_taskID,
|
||||
_logic getVariable ["ExtZone", ""],
|
||||
count _hostageEntities,
|
||||
count _shooterEntities,
|
||||
_logic getVariable ["CBRN", false],
|
||||
_logic getVariable ["Execution", false]
|
||||
]] call EFUNC(common,log);
|
||||
|
||||
private _taskPos = if (_hostageEntities isNotEqualTo []) then {
|
||||
getPosATL (_hostageEntities select 0)
|
||||
} else {
|
||||
getPosATL _logic
|
||||
};
|
||||
|
||||
[
|
||||
"hostage",
|
||||
_taskID,
|
||||
_taskPos,
|
||||
format ["Hostage Rescue: %1", _taskID],
|
||||
"Locate and rescue the hostages and bring them to the extraction zone.",
|
||||
createHashMapFromArray [
|
||||
["hostages", _hostageEntities],
|
||||
["shooters", _shooterEntities]
|
||||
],
|
||||
createHashMapFromArray [
|
||||
["limitFail", _logic getVariable ["LimitFail", -1]],
|
||||
["limitSuccess", _logic getVariable ["LimitSuccess", -1]],
|
||||
["funds", _logic getVariable ["CompanyFunds", 0]],
|
||||
["ratingFail", _logic getVariable ["RatingFail", 0]],
|
||||
["ratingSuccess", _logic getVariable ["RatingSuccess", 0]],
|
||||
["endSuccess", _logic getVariable ["EndSuccess", false]],
|
||||
["endFail", _logic getVariable ["EndFail", false]],
|
||||
["timeLimit", _logic getVariable ["TimeLimit", 0]],
|
||||
["extractionZone", _logic getVariable ["ExtZone", ""]],
|
||||
["cbrn", _logic getVariable ["CBRN", false]],
|
||||
["execution", _logic getVariable ["Execution", false]],
|
||||
["cbrnZone", _logic getVariable ["CBRNZone", ""]]
|
||||
]
|
||||
] call FUNC(startTask);
|
||||
|
||||
deleteVehicle _logic;
|
||||
|
||||
@ -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; };
|
||||
|
||||
@ -23,37 +23,46 @@ params [["_logic", objNull, [objNull]], ["_units", [], [[]]], ["_activated", tru
|
||||
if !(_activated) exitWith {};
|
||||
|
||||
private _taskID = _logic getVariable ["TaskID", ""];
|
||||
private _limitFail = _logic getVariable ["LimitFail", -1];
|
||||
private _limitSuccess = _logic getVariable ["LimitSuccess", -1];
|
||||
private _extraction = _logic getVariable ["ExtZone", ""];
|
||||
private _companyFunds = _logic getVariable ["CompanyFunds", 0];
|
||||
private _ratingFail = _logic getVariable ["RatingFail", 0];
|
||||
private _ratingSuccess = _logic getVariable ["RatingSuccess", 0];
|
||||
private _capture = _logic getVariable ["CaptureHVT", true];
|
||||
private _eliminate = _logic getVariable ["EliminateHVT", false];
|
||||
private _endSuccess = _logic getVariable ["EndSuccess", false];
|
||||
private _endFail = _logic getVariable ["EndFail", false];
|
||||
private _timeLimit = _logic getVariable ["TimeLimit", 0];
|
||||
|
||||
["INFO", format [
|
||||
"HVT Module Parameters: TaskID: %1, LimitFail: %2, LimitSuccess: %3, ExtractionZone: %4, Funds: %5, RatingFail: %6, RatingSuccess: %7, CaptureHvt: %8, EliminateHvt: %9, EndSuccess: %10, EndFail: %11, Time: %12",
|
||||
_taskID, _limitFail, _limitSuccess, _extraction, _companyFunds, _ratingFail, _ratingSuccess, _capture, _eliminate, _endSuccess, _endFail, _timeLimit
|
||||
]] call EFUNC(common,log);
|
||||
|
||||
private _syncedEntities = synchronizedObjects _logic;
|
||||
["INFO", format ["HVT Module Synced Entities: %1", _syncedEntities]] call EFUNC(common,log);
|
||||
|
||||
{
|
||||
if (!isNull _x && (_x isNotEqualTo str objNull)) then {
|
||||
[_x, _taskID] spawn FUNC(makeHVT);
|
||||
};
|
||||
} forEach _syncedEntities;
|
||||
|
||||
private _params = [_taskID, _limitFail, _limitSuccess, _extraction, _companyFunds, _ratingFail, _ratingSuccess, [_capture, _eliminate], _endSuccess, _endFail];
|
||||
if (_timeLimit != 0) then {
|
||||
_params pushBack _timeLimit;
|
||||
if (_taskID isEqualTo "") exitWith {
|
||||
["ERROR", "HVT module: no task ID configured."] call EFUNC(common,log);
|
||||
};
|
||||
|
||||
["hvt", _params, 0, ""] spawn FUNC(handler);
|
||||
private _syncedEntities = synchronizedObjects _logic;
|
||||
["INFO", format [
|
||||
"HVT Module: TaskID: %1, ExtZone: %2, CaptureHVT: %3, HVTs: %4",
|
||||
_taskID,
|
||||
_logic getVariable ["ExtZone", ""],
|
||||
_logic getVariable ["CaptureHVT", true],
|
||||
count _syncedEntities
|
||||
]] call EFUNC(common,log);
|
||||
|
||||
private _taskPos = if (_syncedEntities isNotEqualTo []) then {
|
||||
getPosATL (_syncedEntities select 0)
|
||||
} else {
|
||||
getPosATL _logic
|
||||
};
|
||||
|
||||
[
|
||||
"hvt",
|
||||
_taskID,
|
||||
_taskPos,
|
||||
format ["HVT: %1", _taskID],
|
||||
"Locate and capture or eliminate the high-value target.",
|
||||
createHashMapFromArray [
|
||||
["hvts", _syncedEntities]
|
||||
],
|
||||
createHashMapFromArray [
|
||||
["limitFail", _logic getVariable ["LimitFail", -1]],
|
||||
["limitSuccess", _logic getVariable ["LimitSuccess", -1]],
|
||||
["funds", _logic getVariable ["CompanyFunds", 0]],
|
||||
["ratingFail", _logic getVariable ["RatingFail", 0]],
|
||||
["ratingSuccess", _logic getVariable ["RatingSuccess", 0]],
|
||||
["endSuccess", _logic getVariable ["EndSuccess", false]],
|
||||
["endFail", _logic getVariable ["EndFail", false]],
|
||||
["timeLimit", _logic getVariable ["TimeLimit", 0]],
|
||||
["extractionZone", _logic getVariable ["ExtZone", ""]],
|
||||
["captureHvt", _logic getVariable ["CaptureHVT", true]]
|
||||
]
|
||||
] call FUNC(startTask);
|
||||
|
||||
deleteVehicle _logic;
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -244,42 +244,11 @@ GVAR(MissionManagerBaseClass) = compileFinal createHashMapFromArray [
|
||||
["special", _specialRewards]
|
||||
]
|
||||
}],
|
||||
["createAttackTask", compileFinal {
|
||||
params [
|
||||
["_taskID", "", [""]],
|
||||
["_position", [0, 0, 0], [[]]],
|
||||
["_locationConfig", configNull, [configNull]]
|
||||
];
|
||||
|
||||
if (_taskID isEqualTo "" || { isNull _locationConfig }) exitWith { false };
|
||||
|
||||
private _locationKey = configName _locationConfig;
|
||||
private _locationType = getText (_locationConfig >> "type");
|
||||
if (_locationType isEqualTo "") then { _locationType = "area"; };
|
||||
|
||||
[
|
||||
west,
|
||||
_taskID,
|
||||
[
|
||||
format ["Eliminate hostile forces operating near %1.", _locationKey],
|
||||
format ["Attack: %1", _locationKey],
|
||||
_locationType
|
||||
],
|
||||
_position,
|
||||
"CREATED",
|
||||
1,
|
||||
true,
|
||||
"attack"
|
||||
] call BFUNC(taskCreate);
|
||||
|
||||
true
|
||||
}],
|
||||
["startAttackMission", compileFinal {
|
||||
private _attackConfig = _self getOrDefault ["attackConfig", configNull];
|
||||
private _locationData = _self call ["selectAttackLocation"];
|
||||
if (_locationData isEqualTo createHashMap) exitWith { "" };
|
||||
|
||||
private _location = _locationData getOrDefault ["config", configNull];
|
||||
private _locationKey = _locationData getOrDefault ["key", ""];
|
||||
private _position = _locationData getOrDefault ["position", [0, 0, 0]];
|
||||
private _group = _self call ["spawnAttackGroup", [_position]];
|
||||
@ -292,45 +261,40 @@ GVAR(MissionManagerBaseClass) = compileFinal createHashMapFromArray [
|
||||
};
|
||||
|
||||
private _taskID = format ["task_attack_%1", round (diag_tickTime * 1000)];
|
||||
{
|
||||
[_x, _taskID] call FUNC(makeTarget);
|
||||
} forEach _units;
|
||||
|
||||
_self call ["createAttackTask", [_taskID, _position, _location]];
|
||||
GVAR(TaskStore) call ["registerTaskCatalogEntry", [_taskID, createHashMapFromArray [
|
||||
["type", "attack"],
|
||||
["title", format ["Attack: %1", _locationKey]],
|
||||
["description", format ["Eliminate hostile forces operating near %1.", _locationKey]],
|
||||
["position", _position],
|
||||
["locationKey", _locationKey],
|
||||
["accepted", false],
|
||||
["requesterUid", ""],
|
||||
["orgID", "default"],
|
||||
["source", "mission_manager"]
|
||||
]]];
|
||||
|
||||
private _rewardRange = getArray (_attackConfig >> "Rewards" >> "money");
|
||||
private _reputationRange = getArray (_attackConfig >> "Rewards" >> "reputation");
|
||||
private _penaltyRange = getArray (_attackConfig >> "penalty");
|
||||
private _timeRange = getArray (_attackConfig >> "timeLimit");
|
||||
private _rewards = _self call ["rollRewards"];
|
||||
|
||||
private _params = [
|
||||
private _success = [
|
||||
"attack",
|
||||
_taskID,
|
||||
_position,
|
||||
format ["Attack: %1", _locationKey],
|
||||
format ["Eliminate hostile forces operating near %1.", _locationKey],
|
||||
createHashMapFromArray [["targets", _units]],
|
||||
createHashMapFromArray [
|
||||
["limitFail", 0],
|
||||
["limitSuccess", count _units],
|
||||
["funds", _rewardRange call BFUNC(randomNum)],
|
||||
["ratingFail", _penaltyRange call BFUNC(randomNum)],
|
||||
["ratingSuccess", _reputationRange call BFUNC(randomNum)],
|
||||
["endSuccess", false],
|
||||
["endFail", false],
|
||||
["timeLimit", _timeRange call BFUNC(randomNum)],
|
||||
["equipment", _rewards get "equipment"],
|
||||
["supplies", _rewards get "supplies"],
|
||||
["weapons", _rewards get "weapons"],
|
||||
["vehicles", _rewards get "vehicles"],
|
||||
["special", _rewards get "special"]
|
||||
],
|
||||
0,
|
||||
count _units,
|
||||
_rewardRange call BFUNC(randomNum),
|
||||
_penaltyRange call BFUNC(randomNum),
|
||||
_reputationRange call BFUNC(randomNum),
|
||||
false,
|
||||
false,
|
||||
_timeRange call BFUNC(randomNum),
|
||||
_rewards get "equipment",
|
||||
_rewards get "supplies",
|
||||
_rewards get "weapons",
|
||||
_rewards get "vehicles",
|
||||
_rewards get "special"
|
||||
];
|
||||
"",
|
||||
"mission_manager"
|
||||
] call FUNC(startTask);
|
||||
|
||||
if !(_success) exitWith { "" };
|
||||
|
||||
private _activeMissionRegistry = _self getOrDefault ["activeMissionRegistry", createHashMap];
|
||||
_activeMissionRegistry set [_taskID, createHashMapFromArray [
|
||||
@ -339,7 +303,6 @@ GVAR(MissionManagerBaseClass) = compileFinal createHashMapFromArray [
|
||||
]];
|
||||
_self set ["activeMissionRegistry", _activeMissionRegistry];
|
||||
|
||||
["attack", _params, 0, ""] spawn FUNC(handler);
|
||||
_taskID
|
||||
}],
|
||||
["completeMission", compileFinal {
|
||||
|
||||
199
arma/server/addons/task/functions/fnc_startTask.sqf
Normal file
199
arma/server/addons/task/functions/fnc_startTask.sqf
Normal file
@ -0,0 +1,199 @@
|
||||
#include "..\script_component.hpp"
|
||||
|
||||
/*
|
||||
* Author: IDSolutions
|
||||
* Unified task initializer used by both Eden modules and missionManager-generated
|
||||
* tasks. Registers entities, creates the BIS task, registers the catalog entry,
|
||||
* and dispatches to the task handler.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Task type <STRING> ("attack"|"defuse"|"destroy"|"delivery"|"hostage"|"hvt"|"defend")
|
||||
* 1: Task ID <STRING>
|
||||
* 2: Task position <ARRAY>
|
||||
* 3: Task title <STRING>
|
||||
* 4: Task description <STRING>
|
||||
* 5: Task entities <HASHMAP>
|
||||
* Keys: "targets" <ARRAY> -- attack, destroy
|
||||
* "hostages" <ARRAY> -- hostage
|
||||
* "shooters" <ARRAY> -- hostage
|
||||
* "hvts" <ARRAY> -- hvt
|
||||
* "ieds" <ARRAY> -- defuse
|
||||
* "protected" <ARRAY> -- defuse
|
||||
* "cargo" <ARRAY> -- delivery
|
||||
* 6: Task parameters <HASHMAP>
|
||||
* Common keys:
|
||||
* "limitFail" <NUMBER> (default: -1)
|
||||
* "limitSuccess" <NUMBER> (default: -1)
|
||||
* "funds" <NUMBER> (default: 0)
|
||||
* "ratingFail" <NUMBER> (default: 0)
|
||||
* "ratingSuccess" <NUMBER> (default: 0)
|
||||
* "endSuccess" <BOOL> (default: false)
|
||||
* "endFail" <BOOL> (default: false)
|
||||
* "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> -- required IED countdown in seconds (> 0)
|
||||
* delivery: "deliveryZone" <STRING> -- marker name
|
||||
* hostage: "extractionZone" <STRING> -- marker name
|
||||
* "cbrn" <BOOL> (default: false)
|
||||
* "execution" <BOOL> (default: false)
|
||||
* "cbrnZone" <STRING> (default: "")
|
||||
* hvt: "extractionZone" <STRING> -- marker name (capture mode only)
|
||||
* "captureHvt" <BOOL> (default: true)
|
||||
* defend: "defenseZone" <STRING> -- marker name
|
||||
* "defendTime" <NUMBER> (default: 600)
|
||||
* "waveCount" <NUMBER> (default: 3)
|
||||
* "waveCooldown" <NUMBER> (default: 300)
|
||||
* "minBlufor" <NUMBER> (default: 1)
|
||||
* 7: Minimum org reputation required <NUMBER> (default: 0)
|
||||
* 8: Requester UID <STRING> (default: "")
|
||||
* 9: Source tag <STRING> (default: "eden") -- "eden"|"mission_manager"|"script"
|
||||
*
|
||||
* Return Value:
|
||||
* Success <BOOL>
|
||||
*
|
||||
* Examples:
|
||||
* // From a unit init field -- register entity first, then start task from trigger/init.sqf:
|
||||
* [this, "compound_attack_01"] call forge_server_task_fnc_makeTarget;
|
||||
*
|
||||
* // From a trigger or init.sqf (all-in-one):
|
||||
* [
|
||||
* "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]
|
||||
* ]
|
||||
* ] call forge_server_task_fnc_startTask;
|
||||
*
|
||||
* Public: Yes
|
||||
*/
|
||||
|
||||
params [
|
||||
["_taskType", "", [""]],
|
||||
["_taskID", "", [""]],
|
||||
["_position", [0, 0, 0], [[]]],
|
||||
["_title", "", [""]],
|
||||
["_description", "", [""]],
|
||||
["_entities", createHashMap, [createHashMap]],
|
||||
["_taskParams", createHashMap, [createHashMap]],
|
||||
["_minRating", 0, [0]],
|
||||
["_requesterUid", "", [""]],
|
||||
["_source", "eden", [""]]
|
||||
];
|
||||
|
||||
if (_taskType isEqualTo "" || { _taskID isEqualTo "" }) exitWith {
|
||||
["ERROR", "startTask: missing task type or task ID."] call EFUNC(common,log);
|
||||
false
|
||||
};
|
||||
|
||||
// --- 1. Register task entities ---
|
||||
|
||||
private _iedTimer = _taskParams getOrDefault ["iedTimer", 0];
|
||||
|
||||
{
|
||||
private _role = _x;
|
||||
private _objects = _entities getOrDefault [_role, []];
|
||||
{
|
||||
if (isNull _x) then { continue; };
|
||||
switch (_role) do {
|
||||
case "targets": { [_x, _taskID] call FUNC(makeTarget); };
|
||||
case "hostages": { [_x, _taskID] call FUNC(makeHostage); };
|
||||
case "shooters": { [_x, _taskID] call FUNC(makeShooter); };
|
||||
case "hvts": { [_x, _taskID] call FUNC(makeHVT); };
|
||||
case "ieds": { [_x, _taskID, _iedTimer] call FUNC(makeIED); };
|
||||
case "protected": { [_x, _taskID] call FUNC(makeObject); };
|
||||
case "cargo": { [_x, _taskID] call FUNC(makeCargo); };
|
||||
};
|
||||
} forEach _objects;
|
||||
} forEach ["targets", "hostages", "shooters", "hvts", "ieds", "protected", "cargo"];
|
||||
|
||||
// --- 2. Create BIS task ---
|
||||
|
||||
[west, _taskID, [_description, _title, _taskType], _position, "CREATED", 1, true, _taskType] call BFUNC(taskCreate);
|
||||
|
||||
// --- 3. Register catalog entry ---
|
||||
|
||||
GVAR(TaskStore) call ["registerTaskCatalogEntry", [_taskID, createHashMapFromArray [
|
||||
["type", _taskType],
|
||||
["title", _title],
|
||||
["description", _description],
|
||||
["position", _position],
|
||||
["accepted", false],
|
||||
["requesterUid", _requesterUid],
|
||||
["orgID", "default"],
|
||||
["source", _source]
|
||||
]]];
|
||||
|
||||
// --- 4. Assemble type-specific handler args ---
|
||||
|
||||
private _limitFail = _taskParams getOrDefault ["limitFail", -1];
|
||||
private _limitSuccess = _taskParams getOrDefault ["limitSuccess", -1];
|
||||
private _funds = _taskParams getOrDefault ["funds", 0];
|
||||
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", 0];
|
||||
private _equipRewards = _taskParams getOrDefault ["equipment", []];
|
||||
private _supplyRewards = _taskParams getOrDefault ["supplies", []];
|
||||
private _weaponRewards = _taskParams getOrDefault ["weapons", []];
|
||||
private _vehicleRewards = _taskParams getOrDefault ["vehicles", []];
|
||||
private _specialRewards = _taskParams getOrDefault ["special", []];
|
||||
|
||||
private _rewardTail = [_equipRewards, _supplyRewards, _weaponRewards, _vehicleRewards, _specialRewards];
|
||||
|
||||
private _handlerArgs = switch (_taskType) do {
|
||||
case "attack";
|
||||
case "destroy": {
|
||||
private _args = [_taskID, _limitFail, _limitSuccess, _funds, _ratingFail, _ratingSuccess, _endSuccess, _endFail, _timeLimit];
|
||||
_args + _rewardTail
|
||||
};
|
||||
case "defuse": {
|
||||
[_taskID, _limitFail, _limitSuccess, _funds, _ratingFail, _ratingSuccess, _endSuccess, _endFail] + _rewardTail
|
||||
};
|
||||
case "delivery": {
|
||||
private _deliveryZone = _taskParams getOrDefault ["deliveryZone", ""];
|
||||
private _args = [_taskID, _limitFail, _limitSuccess, _deliveryZone, _funds, _ratingFail, _ratingSuccess, _endSuccess, _endFail, _timeLimit];
|
||||
_args + _rewardTail
|
||||
};
|
||||
case "hostage": {
|
||||
private _extZone = _taskParams getOrDefault ["extractionZone", ""];
|
||||
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, _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, _timeLimit];
|
||||
_args + _rewardTail
|
||||
};
|
||||
case "defend": {
|
||||
private _defenseZone = _taskParams getOrDefault ["defenseZone", ""];
|
||||
private _defendTime = _taskParams getOrDefault ["defendTime", 600];
|
||||
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
|
||||
};
|
||||
default {
|
||||
["ERROR", format ["startTask: unknown task type '%1'.", _taskType]] call EFUNC(common,log);
|
||||
[]
|
||||
};
|
||||
};
|
||||
|
||||
if (_handlerArgs isEqualTo []) exitWith { false };
|
||||
|
||||
// --- 5. Dispatch handler ---
|
||||
|
||||
[_taskType, _handlerArgs, _minRating, _requesterUid] spawn FUNC(handler);
|
||||
|
||||
true
|
||||
@ -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