Firing Drills – Arma 3
Jump to navigation
Jump to search
mNo edit summary |
m (Fixed texture path) |
||
Line 45: | Line 45: | ||
# Insert a ''Firing Drill'' module | # Insert a ''Firing Drill'' module | ||
## It's not exposed in Eden Editor, so place any other module. We may change this after this documentation is completed. | ## It's not exposed in Eden Editor, so place any other module. We may change this after this documentation is completed. | ||
## Save the scenario. | ## Save the scenario (be sure binarization is disabled via the checkbox or preferences). | ||
## Close Eden Editor to avoid auto-saves. | ## Close Eden Editor to avoid auto-saves. | ||
## Open the scenario SQM file in a text editor. | ## Open the scenario SQM file in a text editor. | ||
Line 545: | Line 545: | ||
| [[File:arma3 fd decal sidearm6 ca.png|150px]] || ''A3\missions_f_beta\data\img\decals\decal_sidearm6_ca'' || Sidearm-type weapon CP requirement | | [[File:arma3 fd decal sidearm6 ca.png|150px]] || ''A3\missions_f_beta\data\img\decals\decal_sidearm6_ca'' || Sidearm-type weapon CP requirement | ||
|- | |- | ||
| [[File:arma3 fd decal stand1 ca.png|150px]] || ''A3\missions_f_beta\data\img\decals\decal_stand1_ca | | [[File:arma3 fd decal stand1 ca.png|150px]] || ''A3\missions_f_beta\data\img\decals\decal_stand1_ca'' || Stand here | ||
|- | |- | ||
| [[File:arma3 fd decal target noshoot2 ca.png|150px]] || ''A3\missions_f_beta\data\img\decals\decal_target_noshoot2_ca'' || Behind this obstacle: target (left) / no-shoot target (right) | | [[File:arma3 fd decal target noshoot2 ca.png|150px]] || ''A3\missions_f_beta\data\img\decals\decal_target_noshoot2_ca'' || Behind this obstacle: target (left) / no-shoot target (right) |
Revision as of 10:22, 29 October 2020
Template:SideTOC Template:Cfg ref
This guide will describe how to design and implement a custom Firing Drill Challenge as available in the vanilla game.
See also:
- Arma 3 Field Manual - Firing Drills (for players)
- Arma 3 Time Trials (very similar setup and approach)
Terminology
- Firing Drill (FD) - a live-fire exercise in which a competitor is graded for tactically moving through a course while engaging a set of targets
- Competitor - the actor performing the drill
- Range Officer (RO) - the actor observing the drill and providing feedback / guidance
- Course of Fire (CoF) - the physical space and layout in which the drill is performed
- Checkpoint (CP) - a navigation point within a course which a competitor must follow in a fixed sequence (if so defined as a rule - see below)
- The first CP is the start.
- The last CP is the finish.
- A strict CP contains shooting boxes (marked areas) from which to fire.
- Target - an artificial object shot to complete a drill or to receive time bonuses
- Appearing targets appear and disappear based on activation triggers (see below).
- Accuracy targets contain zones corresponding to extra time bonuses.
- Moving targets travel on rails between positions.
- No-shoot targets are not allowed be hit (adding a time penalty).
- Bonus targets are optional (rewarding a time bonus).
- Rule - these help to determine the completion and scoring conditions for a drill
- Training rules - a rule-set allowing familiarization of the CoF (targets at CPs do not need to be shot to move on)
- Competitive rules - a rule-set used for Achievements / Leaderboards (targets at CPs need to be shot to move on)
- Time - the time from the start it takes to complete a drill (raw)
- Time bonuses / penalties are substracted / added to arrive at the final time.
- The fastest / lowest time is the best and wins.
- There are bronze, silver and gold medal times to beat.
- There may be one special time to beat (typically faster than gold).
Setup
- Open Eden Editor with the terrain of your choice loaded.
- Insert a player character named
BIS_FD_Competitor
// Fixed system name - Now is a good time to save your scenario a first time. Use a name that is safe to reference as config class, so no spaces - f.e.
MyFirstFiringDrill
// Referenced later - Insert a NPC Range Master character of type B_RangeMaster_F named
BIS_rangeOfficer
// Fixed system name / place in a separate group - Insert a Firing Drill module
- It's not exposed in Eden Editor, so place any other module. We may change this after this documentation is completed.
- Save the scenario (be sure binarization is disabled via the checkbox or preferences).
- Close Eden Editor to avoid auto-saves.
- Open the scenario SQM file in a text editor.
- Replace the module's class by ModuleFiringDrill_F.
- Save the SQM.
- Re-open the scenario in Eden Editor.
- Insert an ellipse trigger with default properties named f.e.
BIS_FD_COF
// Referenced later- Re-size the trigger to encompass your entire CoF and a little extra buffer area (you'll likely re-size it later as you progress).
- For each CP (including start and finish), insert a trigger with default properties named f.e.
BIS_FD_CP1
// Referenced later- Re-size the trigger to meet your CP activation expectations.
- For each optional shooting box within the CP, insert a trigger with default properties named f.e.
BIS_FD_CP2_Box
// Referenced later
- Insert a Target - Oval (Ground) prop named
BIS_FD_ruleSelector1
// Referenced later- Using a similar workflow as above, manually change its class name to Land_Target_Oval_NoPop_F (all targets need their hidden NoPop variant).
- Position this target in comfortable shooting range / direction from the start CP (a few meters at most, oriented to be clearly visible and safe).
- In the target's Texture #0 field, enter:
A3\modules_f_beta\data\FiringDrills\training_red_ca
// Other colors have corresponding textures - see below
- Copy and paste the first rule target and name it
BIS_FD_ruleSelector2
// Referenced later- Position it near the first rule target, typically right from it.
- In the target's Texture #0 field, enter:
A3\modules_f_beta\data\FiringDrills\competitive_red_ca
// Other colors have corresponding textures - see below
- Copy and paste a rule target and name it
BIS_FD_restartSelector1
// Referenced later- Position it near the finish CP (a few meters from it, oriented to be clearly visible and safe).
- In the target's Texture #0 field, enter:
A3\modules_f_beta\data\FiringDrills\restart_red_ca
// Other colors have corresponding textures - see below
- Copy and paste a rule target and name it
BIS_FD_quitSelector1
// Referenced later- Position it near the restart target, typically right from it.
- In the target's Texture #0 field, enter:
A3\modules_f_beta\data\FiringDrills\quit_ca
// Fixed texture no matter the drill color
- For each target at each CP, generally do the following (more specifics detailed below):
- Insert the desired target object named f.e.
BIS_FD_target2_1
// Referenced later (apply a logical naming pattern, such as numbering based on CP index and target index) - Using a similar workflow as above, manually replace its class name with the corresponding NoPop variant (see the look-up table below).
- Insert the desired target object named f.e.
- Set up drill properties via description.ext (see below).
- Configure your drill via CfgFiringDrills and CfgMissions (see below).
Moving Targets
TODO
Randomized Targets
TODO
Common Additions
TODO: elaborate
- CP marking objects
- Recolored objects
- Start whiteboard
- Ammunition containers
- Decorative props / sponsoring
Configuration
description.ext
#include "\A3\Missions_F_Beta\Challenges\description.hpp" // This will set up various system default settings, such as custom debriefings
onLoadName = "CoF: My First Drill"; // Name of your drill (normally the same as defined in CfgMissions)
onLoadMission = "Can you beat my splendid drill?!"; // Overview text of your drill (normally the same as defined in CfgMissions)
loadScreen = "myfirstfiringdrill_overview_CO.paa"; // Overview picture of your drill (normally the same as defined in CfgMissions)
briefingName = "CoF: My First Drill"; // Same name as above
overviewPicture = "myfirstfiringdrill_overview_CO.paa"; // Same picture as above
overviewText = "Can you beat my splendid drill?!"; // Same text as above
//author = "Range Officer Bob"; // You! < this cannot work in the current version due to duplicate definition; fix coming in 2.02
doneKeys[] = {"MyFirstFiringDrill_done"}; // Registers having completed (achieved competitive gold or special) your drill
CfgFiringDrills
Drill
class CfgFiringDrills
{
class MyFirstFiringDrill // This class name must correspond to the missionName (also CfgMissions class)
{
displayName = "CoF: My First Drill"; // Vanilla drills use a format like this, but it's not enforced
// This color is used in many places
// It can be any color, but for best results pick a fully supported color (see section below)
color[] = { __EVAL(177/255), __EVAL(51/255), __EVAL(57/255), 1 };
colorName = "red"; // This version of the color is more restrictive and can only use specific supported colors (see section below)
objectCOF = "BIS_FD_COF"; // The CoF trigger referenced in the setup guide
// statistic = ""; // Steam stats are not supported for user-generated drills (used for Achievements)
// leaderboard = ""; // Steam Leaderboards are not supported for user-generated drills
onReset = "reset.sqf"; // This script is executed each time the drill resets (restarts)
// List any number of objects that you want to be re-colored to the drill color above (f.e. road cones, small flags, etc.)
recolor[] =
{
"BIS_FD_recolor1",
"BIS_FD_recolor2"
};
// Set up objects that should have special decal textures applied (this was more useful before Eden Editor - see vanilla decals below)
// In vanilla drills these are often graffiti on wooden shoot house walls
decals[] =
{
{ "BIS_FD_decal1", "A3\Missions_F_Beta\data\img\decals\decal_sidearm1_ca", 5 } // Object reference, texture path, hidden selection index
};
// Object references to the 4 special targets for drill mechanics, as defined in the setup guide
ruleSelectors[] =
{
"BIS_FD_ruleSelector1",
"BIS_FD_ruleSelector2"
};
restartSelectors[] = { "BIS_FD_restartSelector1" };
quitSelectors[] = { "BIS_FD_quitSelector1" };
containersWeapons[] = { "BIS_weaponsFD1" }; // All containers that should be filled with the drill weapons
containersMagazines[] = { "BIS_ammoFD1_1", "BIS_ammoFD1_2", "BIS_ammoFD1_3", "BIS_ammoFD1_4" }; // All containers that should be filled with the drill ammunition
containersMagazinesCount[] = { 10, 10 }; // The count of magazines of each type in the containers
weapons[] = { "SMG_02_ACO_F", "hgun_Rook40_F" }; // The legal weapons for this drill (retrieve via Virtual Arsenal export f.e.)
magazines[] = { "30Rnd_9x21_Mag", "16Rnd_9x21_Mag" }; // The legal magazines for this drill
weaponsCompetitor[] = { "SMG_02_ACO_F", "hgun_Rook40_F" }; // Starting weapons for the competitor
magazinesCompetitor[] = {"30Rnd_9x21_Mag", "16Rnd_9x21_Mag"}; // Starting magazines for the competitor
magazinesCompetitorCount = 6; // The starting magazine count per weapon for the competitor
competitorStart = "BIS_rangeOfficer1A"; // Marker reference to a non-default (re)starting position for the competitor (used for the special intro in CoF: Green)
timesMedals[] = { 60, 45, 30 }; // Bronze, silver, gold medal times (be sure to follow this order or results may glitch)
timeSpecial = 15; // Optional special time that is faster than gold (when defining this, you do need to also provide the data below)
nameSpecial = "Nemesis"; // Optional special time label for the HUD
colorSpecial = "#ffa500"; // Optional special time color for the HUD
iconSpecial = "\A3\Ui_f\data\GUI\Cfg\Ranks\colonel_gs"; // Optional special time icon for the HUD
// Rule-set parameters for competitive and training
// All vanilla drills use these same settings
// It is possible to tweak these values, but that will likely create confusion for players!
class RuleSets
{
// CP mode: 1 - CPs on but targets don't need shooting / 2 - CPs on and all non-optional targets need shooting
// Target randomization: rule not used - ignored
// Weapons used: 1 - any weapon can be used everywhere / 2 - CPs may define a required weapon (or incur a time penalty)
// Shooting boxes: 1 - shooting boxes in CPs are ignored / 2 - shooting boxes in CPs are forced (shooting outside of them incurs a time penalty)
// Stances used: 1 - any stance can be used everywhere / 2 - CPs may define a required stance (or incur a time penalty)
// Medals: 0 - medal times are not tracked / 1 - medal times are tracked and feedback is given
competitive[] = { 2, 0, 2, 2, 2, 1 };
training[] = { 1, 2, 1, 1, 1, 0 };
};
// Legacy class used before Eden Editor to load precise object compositions (should not be needed anymore)
// class DynOs
// {
// script = "dyno_myfirstfiringdrill.sqf"; // Valid DynO mapper output script
// positionAnchor[] = {500, 500}; // DynO mapper anchor position in the world
// };
// All of the drill's CPs
class CheckPoints
{
class CP1 // Start
{
object = "BIS_FD_CP1"; // The CP trigger referenced in the setup guide
};
class CP2 // CP #1
{
object = "BIS_FD_CP2";
// Normally targets (positions) are only randomized once on starting a drill, not when restarting it in the same session
// This changes that (undefined uses 0)
resetRandomizeTargets = 1;
disableFeedback = 1; // Disables the default Range Officer radio feedback for this CP (undefined uses 0)
height = 5; // Only use this ASL forced height for CPs above ground, such as on top of a movement obstacle or inside a building on a raised floor
onActivate = "CP2_onActivate.sqf"; // Script executed when this CP is activated (passed [CP object])
onDeactivate = "CP2_onDeactivate.sqf"; // Script executed when this CP is deactivated (passed [CP object])
onClear = "CP2_onClear.sqf"; // Script executed when this CP is cleared (passed [CP object])
weapons[] = {"hgun_Rook40_F"}; // Makes this the required weapon(s) to use at this CP when strict / competitive rules are used
stances[] = {"crouch"}; // Makes this the required stance(s) to use at this CP when strict / competitive rules are used (prone / crouch / stand)
shootingBoxes[] = {"BIS_FD_CP2_Box"}; // Trigger reference to one or more shooting boxes within the CP when strict / competitive rules are used
binocularCompetitor = "Binocular"; // Optionally defining a non-default binocular class (this is the default)
nvgCompetitor = ""; // Optionally defining a non-default NVG class (this is the default so no NVG)
// Configuring all targets associated with this CP
class Targets
{
class T1
{
object = "BIS_FD_target2_1"; // Object reference for the target placed as in the setup guide
type = "PopUp_Acc1"; // Target type profile as defined in the central CfgFiringDrills (see vanilla targets below)
upTime = 5; // How long in seconds does the target stay active before counting as missed (if not hit)?
};
class T2: T1
{
object = "BIS_FD_target2_2";
trigger = "BIS_FD_target2_1"; // Reference to another target which must be hit for this one to activate
triggerTime = 2; // How long in seconds after triggering this target does it actually activate?
// Marker or object references to positions and directions used (in pairs) to randomize the target
// Normally it would happen once when starting, but for this CP every time you restart
positions[] =
{
"BIS_FD_target2_2",
"BIS_FD_target2_2_Pos2"
};
directions[] =
{
"BIS_FD_target2_2",
"BIS_FD_target2_2_Pos2"
};
};
class T3
{
object = "BIS_FD_target2_3";
type = "PopUp";
trigger[] = {"BIS_FD_target2_1", "BIS_FD_target2_2"}; // Triggers can also be multiple other targets to have hit
// Marker or object position references to form a chain of movement waypoints for this target
// These are matched to the times in seconds for each segment of movement
positionsMove[] =
{
"BIS_FD_target2_3_WP1"
};
timesMove[] =
{
3
};
hitCondition = "targets_hitCondition.sqf"; // Special compiled script called when the target is hit, which can determine if the hit is legal or not (return true to count as hit, false otherwise)
};
class T4
{
object = "BIS_FD_target2_4";
type = "PopUp_Acc2";
upTime = 10;
triggerChance = 0.5; // Chance to trigger this target at all (0 - 1, so 50% in this case)
};
class T5
{
object = "BIS_FD_target2_5";
type = "PopUp";
// Chance for this trigger to even spawn at all (0 - 1, so 80% in this case)
// Be careful not to create impossible situations, where this target is a trigger for another target!
chance = 0.8;
};
class NoShoot1
{
object = "BIS_FD_noShoot2_1";
noShoot = 1; // Makes this target illegal to hit (incurring a time penalty if hit)
};
class Bonus1
{
object = "BIS_FD_bonus2_1";
optional = 1; // Makes this an optional target that does not need shooting even on strict / competitive rules
noRecolor = 1; // By default most optional targets get recolored to the drill color, but here you can disable that (undefined uses 0)
bonus = 5; // Defines the bonus points received for hitting this target (translates to -5 seconds)
type = "Balloon"; // Some vanilla target type profiles are well-suited as optional, such as this one
onActivate = "targets_onActivate.sqf"; // Script executed when this target activates (passed [target object])
onDeactivate = "targets_onDeactivate.sqf"; // Script executed when this target deactivates (passed [target object])
onHit = "targets_onHit.sqf"; // Script executed on hitting this target (passed [target, projectile velocity array, hit selections array, shooter object])
onReset = "targets_onReset.sqf"; // Script executed when this target resets (passed [target object])
};
};
};
class CP3 // Finish
{
object = "BIS_FD_CP3";
};
};
};
};
System
class CfgFiringDrills
{
// Below point bonuses and penalties are multiplied by this factor to determine time bonuses and penalties
pointTimeMultiplier = 0.1;
bonusWeapon = 1; // Bonus for using the correct weapon at a CP (never awarded - disabled)
bonusShootingBox = 3; // Bonus for shooting from shooting boxes at a CP (never awarded - disabled)
bonusStance = 1.5; // Bonus for using the correct stance at a CP (never awarded - disabled)
penaltyWeapon = 3; // Penalty for engaging using an incorrect weapon at a CP
penaltyShootingBox = 5; //Penalty for engaging from outside a shooting box at a CP
penaltyStance = 2; // Penalty for engaging from the incorrect stance at a CP
penaltyNoShoot = 50; // Penalty for hitting a no-shoot target (so this is 5 seconds)
penaltyMissed = 25; // Penalty for failing to hit an activated target
// HUD icons for the medal times
iconsMedals[] =
{
"A3\modules_f_beta\data\FiringDrills\medal_bronze_ca", // Bronze
"A3\modules_f_beta\data\FiringDrills\medal_silver_ca", // Silver
"A3\modules_f_beta\data\FiringDrills\medal_gold_ca" // Gold
};
// HUD colors for the medal times
colorsMedals[] =
{
"#A0522D", // Bronze
"#C0C0C0", // Silver
"#FFD700" // Gold
};
// The vanilla configuration defines several common target type profiles
// This example configures a theoretical new one
class Targets
{
class MyFirstTarget
{
selectionsHit[] = {"target"}; // All named selections on the model that count as valid hit
onReset = "myFirstTarget_onReset.sqf"; // Optional script executed when the target is reset
onActivate = "myFirstTarget_onActivate.sqf"; // Optional script executed when the target is activated
onDeactivate = "myFirstTarget_onDeactivate.sqf"; // Optional script executed when the target is deactivated
onHit = "myFirstTarget_onHit.sqf"; // Optional script executed when the target is hit while activated
downTime = 0.5; // An extra delay in seconds before a valid target hit is registered (i.e. onHit is executed - undefined uses 0)
noRecolor = 1; // This target is never re-colored by the drill color (mainly applies to optional targets - undefined uses 0)
// Certain targets over 200 meters away from the competitor will open a Picture-in-Picture camera feed to show hits
cameraPos[] = {0, -1.5, 0.5}; // Relative camera position from the target center
cameraTarget[] = {0, 0, 1}; // Relative camera target from the target center
cameraFOV = 0.4; // Camera Field of View setting (zoom)
// Accuracy (bonus) hit zones
class Zones
{
class Top
{
center[] = {0, 0, 0.5}; //Relative center position of the zone from the target center
maxDistances[] = //Radii in meters of accuracy rings within this zone
{
0.15,
0.25
};
bonuses[] = //Bonuses associated to the rings defined above
{
6,
3
};
};
};
// In some cases the same target model has several texture variants with different accuracy zones
// These can be overridden within the same target profile by creating a sub-class of the same class as the specific target itself
// In that sub-class, define only the relevant class Zones
// class MyTargetType
// {
// class Zones { ... };
// };
};
};
};
CfgMissions
class CfgMissions
{
// This will expose the drill in the SINGLEPLAYER > CHALLENGES > Firing Drills menu
class Challenges
{
class Firing_Drills
{
class MyFirstFiringDrill // This class should correspond to the class in CfgFiringDrills above
{
directory = "myfirstfiringdrill.stratis"; // Full path to your drill's scenario folder
briefingName = "CoF: My First Drill"; // Name of your drill (normally the same as defined in CfgFiringDrills)
overviewText = "Can you beat my splendid drill?!"; // Overview text of your drill
overviewPicture = "myfirstfiringdrill_overview_CO.paa"; // Overview picture of your drill
overviewScript = "\A3\Modules_F_Beta\FiringDrills\scripts\overviewScript.sqf"; // Standard system script to handle the pause menu properly - don't change
author = "Range Officer Bob"; // You!
};
// Alternatively you can list your drill in one of the vanilla color categories: Red, Blue, Orange, Purple
// class Blue
// {
// Define your drill here instead for example
// };
};
};
};
Targets
Run-Time Tools
- BIS_FD_weaponsCompetitor: an array of weapon classes provided to the competitor when the drill (re)starts
- BIS_FD_magazinesCompetitor: an array of magazine classes provided to the competitor when the drill (re)starts
- BIS_FD_magazinesCompetitorCount: the amount of magazines per type provided to the competitor when the drill (re)starts - default is 5
- BIS_FD_targetHitCode: code which can be called with dummy parameters to simulate a fake target hit for special events (expects hitPart Event Handler parameters)
- BIS_FD_hasReset: code which returns true when the drill has reset, ended, or is ending
- BIS_FD_phase: 0 - drill pre-init / 1 - drill selecting rules / 2 - drill started / 3 - drill terminated / -1 - drill restarting
Colors
- colorName: "red" - multi-gun
- color:
__EVAL(177/255), __EVAL(51/255), __EVAL(57/255), 1
- Training rules selector: A3\modules_f_beta\data\FiringDrills\training_red_ca
- Competitive rules selector: A3\modules_f_beta\data\FiringDrills\competitive_red_ca
- Restart selector: A3\modules_f_beta\data\FiringDrills\restart_red_ca
- color:
- colorName: "green" - introduction / tutorial
- color:
__EVAL(173/255), __EVAL(191/255), __EVAL(131/255), 1
- Training rules selector: A3\modules_f_beta\data\FiringDrills\training_green_ca
- Competitive rules selector: A3\modules_f_beta\data\FiringDrills\competitive_green_ca
- Restart selector: A3\modules_f_beta\data\FiringDrills\restart_green_ca
- color:
- colorName: "orange" - long-range
- color:
__EVAL(240/255), __EVAL(130/255), __EVAL(49/255), 1
- Training rules selector: A3\modules_f_beta\data\FiringDrills\training_orange_ca
- Competitive rules selector: A3\modules_f_beta\data\FiringDrills\competitive_orange_ca
- Restart selector: A3\modules_f_beta\data\FiringDrills\restart_orange_ca
- color:
- colorName: "blue" - Close Quarters Combat
- color:
__EVAL(103/255), __EVAL(139/255), __EVAL(155/255), 1
- Training rules selector: A3\modules_f_beta\data\FiringDrills\training_blue_ca
- Competitive rules selector: A3\modules_f_beta\data\FiringDrills\competitive_blue_ca
- Restart selector: A3\modules_f_beta\data\FiringDrills\restart_blue_ca
- color:
- colorName: "purple" - specialist marksman
- color:
__EVAL(176/255), __EVAL(64/255), __EVAL(167/255), 1
- Training rules selector: A3\modules_f_beta\data\FiringDrills\training_purple_ca
- Competitive rules selector: A3\modules_f_beta\data\FiringDrills\competitive_purple_ca
- Restart selector: A3\modules_f_beta\data\FiringDrills\restart_purple_ca
- color:
- colorName: "gray" - CTRG
- color:
__EVAL(90/255), __EVAL(89/255), __EVAL(90/255), 1
- Training rules selector: A3\modules_f_beta\data\FiringDrills\training_gray_ca
- Competitive rules selector: A3\modules_f_beta\data\FiringDrills\competitive_gray_ca
- Restart selector: A3\modules_f_beta\data\FiringDrills\restart_gray_ca
- color:
- colorName: "white" - not used / supported in vanilla
Decals
Tips
- Vanilla CoFs are designed to be somewhat realistic and safe as a non-lethal competitive shooting training / sport. Try to imagine and implement range safety concerns in your target and prop placement. For example, don't place targets in a line of sight of the start, Range Officer, or other spectators. Generally try to solidly block off areas behind targets where possible.
- For random / moving target position references, use small colored helper spheres in Eden Editor. Just remember to hide them all in an init script for example:
{hideObject _x} forEach (allMissionObjects "Sign_Sphere10cm_F");
- In special cases you may wish for a more complex target trigger. Do this by placing a dummy trigger object (f.e. a Game Logic) with named reference. Configure this reference as the target's trigger. When you want to trigger this target, execute in any script environment:
YourTriggerObject setVariable ["state", 3];
- There are several useful variables stored in the scenario and CP / target objects (but in most cases manipulating them directly will break the system; read them only):
- BIS_FD_CPs: array of CP object references
- CP
- "CP": CP index number
- "activated": true when activated
- "clear": true when cleared
- Target (most configuration parameters are also stored as similarly named variables, f.e. "optional")
- "state": 0 - spawned / 1 - will trigger / 2 - triggered / 3 - hit / 4 - missed
- "targets": array of all CP target object references
- In order to make targets that are not positioned on the ground work well (especially after drill resets), you will need to execute on them:
this setVariable ["BIS_DynO_ASL", true]
- While designing a drill, you may wish to use function BIS_fnc_moduleFDAutoTraining, which let's you quickly go to a specific CP.
[5, true] spawn BIS_fnc_moduleFDAutoTraining
// Skip instantly to CP with index 5 (using false will teleport between CPs until reaching the specified one)
- Vanilla no-shoot targets are using the Simple Target (Target_F) with init:
this setObjectTexture [0, ""]; this setObjectTexture [1, "#(argb,8,8,3)color(0.4,0.0,0.5,1.0,co)"];
- Balancing a drill can be quite hard, since there is a broad range of skills in the playerbase.
- You should set appropriate medal times.
- It's recommended to start harder / more difficult, rather than too easy. It's better to nerf later than to go the other way (since you cannot easily undo recorded times).
- Start by simply playtesting the drill a lot and determining your own best medal times (or invite other playtesters and record their runs / times - video recordings can also be helpful for spotting issues).
- Real balancing typically starts towards the end of development, because even slight changes can affect times a lot, let alone adding / removing CPs or targets.
- You can also attempt to mathematically balance a drill (this is not fool-proof, but it may help validate your times):
- Start by sprinting the quickest route possible through all CPs to get a baseline time.
- Tally all possible bonuses (optional targets and accuracy bonuses).
- Tally all non-optional targets and multiply by a reasonable time-on-target.
- Take into account also target triggers and other time factors.
- Combine the data above to arrive at a final time.
- This still does not completely simulate the best possible time of course; for example weapon reloads are not included.
- Vanilla drills apply the following abstract goals per medal:
- Bronze: achievable by doing a casual drill (perhaps missing a few targets) but not taking many risks. For a typical user it should take 1-3 attempts.
- Silver: achievable by doing a good drill and taking some risks (sprinting and cutting some corners). Might take 2-5 attempts for example.
- Gold: meant to be hard. This needs to be a perfectly run drill, at full speed and taking risks. It may take more than 5 attempts.
- Special: designed to be extremely hard. Some may never beat this.