Objectives
Originally written by Ishtvan on http://forums.thedarkmod.com/topic/4121
Overview
A mapper may add on objectives by setting key/values on a target_tdm_addobjectives entity and triggering it. If you want to add objectives at the very beginning of the map, put in a target_addobjectives and put that entity in as a target of the worldspawn. The worldspawn will trigger it on map start.
Objectives consist of overall objectives, objective components, and boolean relationships for failure and success. A map can have any number of overall objectives, and each objective can have any number of components.
Example
Objective 1 text: "Kidnap Benny and get out to the streets"
Objective 1 Components:
- Benny is KO'd
- Benny is at the map exit
- Player is at the map exit
- NOT( Benny is dead )
Boolean relationship for Obj. 1 COMPLETION: 1 AND 2 AND 3 AND 4
Boolean relationship for Obj. 1 FAILURE: NOT(4) (If Benny is dead we can't kidnap him alive)
Objective Attributes and Spawnargs
- objN_desc (string)
- The description of this objective. This is used to display the objective in the GUI - the user will never see the objective number, only this string.
- objN_state (int) Defines the state of the objective at map start.
- Possible Objective States:
- OBJ_INCOMPLETE = 0
- OBJ_COMPLETE = 1
- OBJ_FAILED = 2
- OBJ_INVALID = 3
- Code defaults to 0.
- objN_mandatory (1/0)
- Set to 0 for optional objective that doesn't fail the mission if you fail it. Code defaults to 1.
- objN_irreversible (1/0)
- Irreversible objectives lock their state once they're changed to COMPLETE or FAILED. Irreversible components will only change state once and then stay in that state. (Note: There are scriptfunctions to reset irreversible objectives and components if the FM author wants to let them change again for some reason). Code defaults to 0.
- objN_ongoing (1/0)
- Use this for objectives that should remain successful, but won't be checked off until the end of the mission. For example, "don't blackjack more than two people" is successful at the start of the mission, because you haven't blackjacked anyone yet, but when you KO one person and the KO callback is made to the objective system, and the system then sees that only one person has been KO'd, the system needs some way of knowing not to say "Objective Complete" when you KO that first person, i.e., that this is an ongoing objective. Code defaults to 0.
- objN_visible (1/0)
- Whether the objective appears in the player's Objectives GUI. Use invalidated and hidden objectives to queue up objectives for later, or hidden but valid objectives as anothe way of scripting events when the player does a certain thing, since objectives can launch an arbitrary script after they're completed. Code defaults to 1.
- objN_difficulty (integer)
- This specifies the difficulty level this objectives applies to. When this spawnarg is set (e.g. "obj2_difficulty" "1"), this objective is only visible at difficulty level 1 (="Hard", remember that difficulty level numbers start with 0). Leave this empty to let the objective apply to all levels.
- objN_enabling_objs (space-delimited integers)
- This is a list of other objectives that must first be completed before this objective can be completed. For example, we shouldn't mark "objective complete" for exiting the mission until all the other mission goals have been completed. An example value for this spawnarg would be "4 6" to let this objective depend on objectives #4 and #6.
- objN_script_complete (string)
- objN_script_failed (string)
- Name of a script to call when this objective is completed or failed. For example, this could be used in campaigns to set up optional objectives in one mission that effect other missions. This feature could also be used as a general scripting aide if the author wants to set up the conditions for something happening using a hidden objective.
- objN_logic_success (string)
- objN_logic_failure (string)
- The logic string (e.g. "1 AND 3") for the objective completion/failure conditions. Specifies the objective components which need to be fulfilled before this entire objective is completed or considered failed.
Objective Component Attributes and Spawnargs
Here, the index N defines the objective number and M refers to the component number. Programmers beware that both numbers start with 1.
- objN_M_state (1/0)
- Defines the state of the component at map start, which can only be "1" (complete) or "0" (incomplete). Code defaults to 0.
- objN_M_player_responsible (1/0)
- Defines whether the player should be responsible for this component to complete. Code defaults to 1.
- objN_M_not (1/0)
- Code defaults to 0. If this is set, the component is considered NOTed. So if the component is to kill 5 AI, and it's NOTted, it will remain true until 5 AI are killed, then be set to false).
- objN_M_irreversible (1/0)
- Defines whether this component state cannot be reverted once it has been changed. Code defaults to 0.
- objN_M_type (string)
- Defines the type of this objective component.
- Possible 'Objective Component' Types:
- kill (also includes non-living things being destroyed)
- ko
- ai_find_item (not implemented)
- ai_find_body (not implemented)
- alert
- destroy (inanimate item destroyed ("killed"))
- item (picked up or dropped an inventory item)
- pickpocket (inventory item acquired from conscious AI)
- location (Item A at location B, where "A" is any entity that must have the key "objective_ent" set to "1" on it, and location B is a special entity info_objective_location. Later on we may support using the D3 location system as well)
- custom (custom component that is set true/false by a map script)
- These components are triggered every N milliseconds by a system clock:
- custom_clocked (runs a custom map script that should check something and set the objective)
- info_location (Item A at info_location area B) - TODO: more information needed
- distance (distance between the origin of entity X and that of entity Y)
Any component can have up to two specifiers, each of which can carry a value. Here, L refers to the number of the specifier, e.g. ("obj2_1_spec4" "name").
- objN_M_specL (string)
- Specification Methods:
- Specification methods determine what the objective component is looking for. Does it look at how many AI of a specific team you've KO'd, how many humans, how many overall, or whether you've KO'd an AI with a certain name? Each objective component can have up to two of the following specifiers (Not all components can take two specifiers, and not all specifiers make sense for all component types, future documentation will cover that).
- The following apply to both AIs and items:
- none
- name (name of entity)
- overall (overall count of something: kills, loot, kos, etc)
- group (inventory group)
- classname (soft/scripting classname)
- spawnclass (hard / SDK classname, e.g. "idPlayer")
- The following specification methods apply only to AI:
- ai_type (human, beast, undead, bot, etc)
- ai_team (mapper defined team of the AI)
- ai_innocence (For distinguishing noncombatants)
- objN_M_args (space-delimited string)
- Integer and String Arguments:
- A component can have an arbitrary number of int and string arguments that are fed in space delimited lists. The type of component and specifier determines which args it will use and what it will do with them. For example, the first integer arg is often used to determine how many times something can happen, e.g., the player is only allowed 4 KOs, or must get 500 loot. Not all events are counted up though. The only things that are counted up are things in the mission statistics like loot and kills, so everything else is pretty much a one shot deal where it happens once. Future documentation will detail which objective events are counted up and which are one shots.
- objN_M_clock_interval (float/seconds)
- For clocked components like "custom_clocked" this determines how often they are updated. The value is to be set in seconds.
Mission Logic
By default, all mandatory objectives need to be completed for mission success. However, it's possible to define a custom success and failure logic string on an objective entity. Be sure to have this addobjectives entity active at map start so that the logic is parsed right at map load.
- mission_logic_success (string)
- Defines the success logic, e.g. "1 AND 2 AND 3".
- mission_logic_failure (string)
- Defines the failure logic. When this condition is fulfilled, the mission has failed.
The above spawnargs apply to all difficulty levels. It's of course possible to override this default for a given difficulty level, by setting these spawnargs. The index N is referring to the difficulty level number (starting from 0 = Easy):
- mission_logic_success_diff_N (string)
- Defines the success logic for the difficulty level N (override the default logic), e.g. "1 AND 2 AND 3".
- mission_logic_failure_diff_N (string)
- Defines the failure logic for the difficulty level N (override the default logic). When this condition is fulfilled, the mission has failed.
Conclusion
Using components that combine component types with up to 2 entity arguments and 2 specifier types, plus objectives that are a boolean combination of those components should hopefully allow for a variety of different objectives.