https://wiki.thedarkmod.com/api.php?action=feedcontributions&user=RJFerret&feedformat=atomThe DarkMod Wiki - User contributions [en]2024-03-29T05:42:19ZUser contributionsMediaWiki 1.39.5https://wiki.thedarkmod.com/index.php?title=Triggers&diff=17833Triggers2014-07-09T18:44:44Z<p>RJFerret: /* Triggers */ +target requirement</p>
<hr />
<div>There are many different ways of triggering [[Entity|entities]], the Trigger entities themselves, as well as through [[Stim/Response]], [[Conversations]], Movers, [[Objectives]], and more. How the trigger occurs will typically dictate which manner you choose for your map. <br />
<br />
=Triggers=<br />
To create triggers that rely on boundaries (once, multiple and their derivations), you need to drag out a worldspawn brush, right-click, select "Create Entity". (They will not function if abutted against others.) Triggers need to be connected to their subjects, either via "Connect Selected Entities" menu option/shortcut key, or adding "Target", "Target0", "Target1" or subsequent "Target"# spawnargs. Triggers without targets (to be added via a target_changetarget entity later) won't exist, so need a dummy target. The triggers below are listed roughly by frequency of usage, with related triggers beneath.<br />
<br />
==trigger_once==<br />
When the origin of an entity is within the bounds of this entity, the target(s) will be triggered, then the trigger_once is removed. (Note, to resize the brush after creating the entity, select it then press Tab once.)<br />
<br />
==trigger_once_entityname==<br />
Similar to [[Triggers#trigger_once|trigger_once]], but may be set to only respond to the entity specified by the spawnarg, "entityname". Note the entity must move into the boundaries itself, not be moved by the player (AI walking themselves for example). (If you want something to happen based on the player dropping or placing an item somewhere, use the [[Objectives]] system instead.)<br />
<br />
==trigger_multiple==<br />
Similar to [[Triggers#trigger_once|trigger_once]] but will activate again and again, use "Wait" spawnarg to control how many seconds between triggerings. <br />
<br />
==trigger_entityname ==<br />
Similar to [[Triggers#trigger_multiple|trigger_multiple]] but only reacts to the entity defined by the "entityname" spawnarg.<br />
<br />
== trigger_facing ==<br />
Also similar to [[Triggers#trigger_multiple|trigger_multiple]], but requires the triggering entity to be within 30° of the specified "angle" spawnarg. For details see [[Trigger Facing]].<br />
<br />
==trigger_relay ==<br />
Most commonly used to trigger many targets, or do so after a delay (per the "delay" spawnarg). May be set to only work once (spawnarg "wait" "-1") or limit firing based upon how many seconds have passed. The "random" spawnarg may be used with "wait" to vary the firings. Very useful as the target of worldspawn, to trigger things at map start (since worldspawn currently only activate one "Target"), or as the target of Objectives.<br />
<br />
==trigger_count ==<br />
This will fire at it's targets upon a specific number of times being triggered itself, based upon the "count" spawnarg. If "count" "3" is set, it will do nothing until the third triggering. Set "repeat" to "1" if it should do it again and again instead of just once.<br />
<br />
== trigger_timer ==<br />
This trigger will fire repeatedly every "wait" # seconds. The spawnarg "start_on" defines if it should do so at the start of the map, or wait to be triggered (defaults to 0, off at map start). Spawnarg "random" adds variability to the triggerings.<br />
<br />
== trigger_fade ==<br />
Will cause the display to fade or dissolve to a specified color. The spawnarg "fadeColor" specifies which color, and how transparent in RGBA (red, green, blue, and alpha, ranging from 0-1). Default is fade to black: "fadeColor" "0 0 0 1". To fade up from whatever, use alpha of 0, IE to fade up from black, "0 0 0 0". "fadeTime" controls how quickly the fade transpires.<br />
<br />
== trigger_hurt ==<br />
Applied to a worldspawn brush to define boundaries à la a [[Triggers#trigger_multiple|trigger_multiple]], by default it causes 10 points of damage/second to the activator (player or AI). It may be triggered on/off. The spawnarg, "delay" may be set to vary frequency of damage application. One of various "def_damage" may be specified, generally found in the root directory of the entities, or to see specific details, in the defs file, "damage.def". Note those referencing "triggerhurt" simply cause damage, while others feature additional effects such as push and knockbacks (launching the player away).<br />
<br />
If you need varying amount of damage based on proximity, the [[Stim/Response_Key/Values#Damage_Stim|Stim/Response]] system offers control of various types of falloff.<br />
<br />
== trigger_presize ==<br />
Akin to [[Triggers#trigger_multiple|trigger_multiple]] without the need of creating a brush first, and defaults to not being touched by players/AIs, but triggered by other entities/script.<br />
<br />
== trigger_touch ==<br />
Continuously checks if entities are touching, costly performance wise, probably done via [[Objectives]] more efficiently.<br />
<br />
=Triggering via Path Nodes=<br />
Several [[Path Nodes|path nodes]] will trigger their targets upon AI completing the associated node action (as of TDM v2.02). These include, path_corner (upon reaching), path_turn, path_wait, path_sit, path_sleep and path_anim.<br />
<br />
=Triggering Stim/Response=<br />
'''To Trigger Something Else:'''<br />
<br />
Any Response type may have an effect of "Trigger", in which another entity selected is triggered. Note the "Trigger" effect is all the way at the bottom of the drop down, which might not be displayed on screen (Toggle Effect is the last displayed on mine), you may cursor down or use the End key to get to Trigger.<br />
<br />
'''Be Triggered:'''<br />
<br />
Within the [[Stim/Response]] editor, add a response stim set to "Trigger", now when this entity is targeted, whatever specified effect will occur.<br />
<br />
An example would be to not have something able to be frobbed until something obscuring it is removed or opened. Make the response effect "Set Frobable" for the entity in question, and check "frobability" on. Now when the item is triggered, by a door, or frob response on something in front moved/picked up, it will become frobable.<br />
<br />
=Triggering via Conversation=<br />
The command, [[Conversations#Conversation Commands 2|ActivateTarget]] will trigger the specified entity at that time in the Conversation script.<br />
<br />
=Triggering via Doors, Buttons, Levers, Movers=<br />
[[Doors]] trigger their targets by default upon opening (spawnarg "trigger_on_open" "1"). They may also trigger when completely open by changing "trigger_when_opened" to 1 instead of the default 0, or when fully closed via "trigger_on_close". Note, those conditions on Buttons came from doors, so are counter-intuitive.<br />
<br />
=Triggering via Objectives=<br />
In the [[Objectives Editor]] you may select an entity to be triggered upon an objective succeeding or failing. Therefore all the possible objective conditions may become trigger events (knock out an AI, move an object away from another or to a spot, cause another objective to become visible, disappear or complete, etc.)<br />
<br />
=Triggering via Worldspawn=<br />
You may set "Target" on Worldspawn (usually at a trigger_relay since it only may target one entity currently) to cause things to be triggered at map start. If you use this to kill an AI or other affect with audio, note if in range of the player's start, it will be heard during the fade up from black.<br />
<br />
=Triggering via Lights=<br />
Lights trigger their target(s) both upon being extinguished and lit. This is useful to match window glow to actual light condition. Depending on the light, it may be tricky to set the targets however. A basic light entity can simply have target(s) spawnargs, but a candle, lamp or torch with attached flame entity, you need to use the "set" spawnarg. For example, "set target0 on flame" "EntityToBeTriggered".<br />
<br />
=Trigger a Script=<br />
Point any trigger at a target_callscriptfunction entity and give it the spawnarg, "call" ''ScriptFunctionName'', where ''ScriptFunctionName'' matches "void ''ScriptFunctionName''()" in the map's .script file. See [[Scripting_basics#Script_invocation|script invocation]] for more info.<br />
<br />
[[Category:Editing]]</div>RJFerrethttps://wiki.thedarkmod.com/index.php?title=Objectives_Editor&diff=17832Objectives Editor2014-07-09T05:34:37Z<p>RJFerret: /* Components */ typo and extraneous</p>
<hr />
<div>''Written by HappyCheeze and Fidcal. Small additions by Sotha and Springheel.''<br />
<br />
==Introduction==<br />
<br />
{{clear}}<br />
The objectives editor is a very useful tool located inside Darkradiant (Version 0.9.7 or later) that allows the map author to set objectives or goals that the player must do in order to win the level. The opposite is also true, the author can set restrictions that the player must adhere to, or will fail the mission.<br />
<br />
<br />
==Adding Objectives Entities==<br />
<br />
IMPORTANT: The add objectives entity has been renamed to atdm:target_addobjectives so ignore any reference to the old name target_tdm_addobjectives in the images.<br />
<br />
<br />
To access the objectives editor once inside Darkradiant, click the pull-down menu Map>Objectives... <br />
[[Image:Objmenu.png]]<br />
<br />
<br />
Upon clicking you will see a separate window that looks like this. <br />
[[Image:Objedblank.png|left]]<br />
<br />
<br />
<br />
<br />
<br />
{{clear}}<br />
To start things off, click the <br />
[[Image:%2Badd.png]]Button<br />
<br />
[[Image:Msnobjadd.png]]<br />
<br />
This will create an Entity that stores all of the objectives information that will you be editing.<br />
<br />
<br />
<br />
<br />
<br />
Now we've spawned our objectives entity,<br />
{{clear}}<br />
[[Image:Objentity.png]]<br />
{{clear}}<br />
Notice the numbers in the “[]”'s. Those are the entities' coordinates on the map. These numbers will most likely be different from yours. When the objectives entity spawns it is placed randomly around the origin (As of 0.9.7 this is how it is, it might change in future versions, but for now this is how it is).<br />
<br />
*Note:Be mindful that sometimes this entity will spawn outside your map and into the void. This will cause a leak, so look around the origin.<br />
<br />
**Alternatively you can right-click in an orthogonal view, create entity, Targets/atdm:target_addobjectives. This will create a small yellow box like placing any entity or object. Then when you open the objectives editor it will be in the list. Good to do this where the players starts, it will always be easy to find.<br />
<br />
==Adding Objectives==<br />
<br />
Now we're ready to start adding some objectives.<br />
<br />
Click the second [[Image:%2Badd.png]] Button<br />
<br />
<br />
<br />
<br />
[[Image:Newobj1.png|left]]<br />
{{clear}}<br />
<br />
Under Objectives you'll notice there's a new Objective. You can add more as needed.<br />
<br />
<br />
==Editing Objectives==<br />
<br />
Click an objective in the list than click [[Image:Edit.png]]<br />
<br />
<br />
This will bring up this window.<br />
{{clear}}<br />
[[Image:Editobj.png]]<br />
<br />
<br />
Now we're editing our first objective. It may seem a little confusing at a first glance but a lot of it is self explanitory and a little practice will take you a long way.<br />
<br />
So what do all these various lines and checkboxes do? <br />
They effect the objective components at the bottom.<br />
<br />
What do they all mean?<br />
<br />
'''Description''': This what the player will read in the objectives menu. For example: “Steal the scepter”, “Don't kill any guards”, “Get back to where you entered the warehouse”. Its explaining what you want to player read so he/she knows what to do. A good rule to follow is to make them short and to the point.<br />
<br />
'''Difficulty''':These refer to Easy/Medium/Hard difficulty levels. If the author wishes, they can be different for each difficulty. For example: on Hard difficulty the player will have to avoid being seen. On Easy the player will only have to steal 200 gold at the minimum. All Levels means that the objectives that are checked under this will be there regardless of difficulty. <br />
<br />
'''Initial State''':This is the condition of the objective at mission start. There are four options. Complete, Incomplete, Invalid, Failed. Typically the objective will be incomplete and the player has to complete it in-game to fulfil the objective.<br />
<br />
'''Flags''':<br />
<br />
''Mandatory'' means the objective in question is necessary to complete the game. If it is unchecked than the objective will be optional. <br />
<br />
''Ongoing'' means that the objective won't show completion until the end of the mission. Use this with do NOT type objectives, eg, do NOT kill.<br />
<br />
''Irreversible'' means that once the objective is done it will not UNcheck even if logically in the game it becomes no longer true. Example: get a special object. If the player later drops it normally the objective will then UNcheck because the player no longer has got it. But sometimes you don't want it to reverse. Example: get magic skull. New objective: throw it in magic pool. Player no longer has 'got' the skull so normally it would then UNcheck the objective. Make it irreversible and it won't. Another example is to go to a location. If the player then leaves it would UNcheck so make it irreversible.<br />
<br />
''Visible'' means that objective will be visible in the objectives menu ingame. If unchecked than there will be no objective shown. (The objective will still work, it just won't show up in the menu).<br />
<br />
<br />
'''Enabling Objectives:'''<br />
These are other objectives that must be completed before this objective can be done. Example: ''"When you have completed your main objectives, escape from the castle."'' So, those main objectives would be the enabling objectives and if the player escapes the castle without doing them first then the escape objective does not check off either.<br />
<br />
You can list them as "1 AND 2" if objectives 1&2 need to be completed first.<br />
<br />
Or, if there are 3 different objectives for each difficulty (as in most loot objectives) the following will work: 1 AND (2 OR 3 OR 4). (where 2,3&4 are the loot objectives)<br />
<br />
<br />
<br />
<br />
'''Logic Success:'''<br />
These are only needed if you have more than one type component. For example, if you can escape the castle by either of two routes this would be an objective with two go to ''location'' components. These components would be numbered 1 and 2 so the logic success would be "1 or 2" since either would work. If however you wanted say the player to escape the castle via a special corridor then the player has to go to both corridor location and exit castle location so that would be logic success 1 AND 2. Those components need not necessarily be the same type - the player might be required to pull a lever AND escape for example (even though he could escape without pulling the lever but you don't want him to.)<br />
<br />
Note: I needed to make the "or" lower-case for it to work for me in 2.01. -RJFerret<br />
<br />
<br />
'''Scripts''': Under Construction<br />
<br />
==Components==<br />
<br />
'''Components''': These are the type of objective you want, eg, steal, kill - or rather 'types' because each objective can have more than one (eg, go to exit A or go to exit B or it could be go to exit A AND go to exit B! - see logic success) These type components are used by the editor to specify what objectives need to be done. The map author can choose from a variety of options under '''Type''' with varying degrees of specification. For example: Knocking out an AI named "Roy". Not being seen by the ANY enemy. (less examples, should cover this in the coming up tutorial.)<br />
<br />
'''Components Flags''': Components have their own special flags as well. <br />
<br />
''Satisfied at Start'': For some objectives it makes sense to have them done at start. For example: Not killing anyone.<br />
<br />
''Irreversible'': Once the objective has reached a certain state, it will stay that way and not change. <br />
<br />
''Boolean NOT'': Adds "NOT" to your component so the player has to do the opposite of said objective. For example: Do NOT kill any AI on team 2.<br />
<br />
''Player Responsible'': The player MUST follow through with the objective himself. For example:The player must kill the zombie to complete the objective, instead of letting something else take care of it.<br />
<br />
Now it might seem a bit crazy trying to take all of this in at once, so lets start with something easy.<br />
<br />
== Tutorial ==<br />
<br />
*Note:This tutorial is assuming you've learned the basics for using Darkradiant.<br />
<br />
You should already be in Darkradiant. Start a new map if you're in an existing one. <br />
<br />
We'll start with the basic cube room. Nothing fancy, just make a room, stick in a player start, a light and plaster on some textures.<br />
[[Image:cube.png|left]]<br />
{{clear}}<br />
For this tutorial, our player is going to have to knock out a guard and steal a trophy.<br />
<br />
So lets start with adding the AI, I chose atdm:ai_citywatch. Select him, go into the entity editor ("N") and change his NAME to "Roy" (without quotes).<br />
<br />
<br />
Now its time to open up our objectives editor. <br />
<br />
<br />
[[Image:Objmenu.png|left]]<br />
{{clear}}<br />
Now as you just learned, click add, click the atdm:target_addobjectives_1 and click add again.<br />
<br />
The ''Edit Objective'' window should be open now. Clear the text under '''Description''' and type in "Knock out the guard". Set the initial state to 'Complete'. Check the '''Mandatory''' and '''Visible''' flags.<br />
<br />
<br />
Time for a new step, click the [[Image:%2Badd.png]] button under '''Components''' and the word "Kill" should appear. Select it and you will see some more options. Under '''Type''' select "AI is knocked out". <br />
<br />
under '''Knockout target:''' select "Name of single entity" and type in the box to the right of it, "roy" (without quotes). Set amount to 1.<br />
<br />
Now compare your screen to this, it should be the same.<br />
[[Image:Editprogress.png|left|]]<br />
{{clear}}<br />
If all looks good than click OK.<br />
<br />
Its always a good idea to test things to make sure everything is running right. So save your map, get into TDM and load your map.<br />
<br />
First, hit ESC and click ''Objectives''. You should see your objective onscreen.<br />
[[Image:Onjyes.png]]<br />
*NOTE:If you don't see it on screen, you probably forgot to check the '''Visible''' box.<br />
<br />
Now its time to test your objective. Exit out of the objectives menu and launch a gas arrow or use the blackjack on poor Roy. When he goes down you should see the words "Objective Complete" appear onscreen and since thats the only objective we've added so far you'll win the mission.<br />
*NOTE:If you don't win nor see the on screen message, go back and try to figure what you did wrong.<br />
<br />
If all is well than its time to move on. Exit TDM and go back into Darkradiant. <br />
<br />
Now it is time to add the trophy. In your map add a trophy somewhere, I used the entity loot>atdm:loot_trophy_old<br />
change its name to "trophy" and go back into objectives editor.<br />
<br />
Add another objective and edit it. <br />
'''Description''' should be ''Steal the Trophy''. State is ''Complete'', '''Flags''' should be ''Mandatory'' and ''Visible''. Click ADD and select '''Player possesses item''. Change '''Item:''' to ''Name of single entity'' and type in the box to right, "trophy". Change the amount to "1".<br />
<br />
Your objective should look like this.<br />
[[Image:Trophyedit.PNG|left]]<br />
{{clear}}<br />
Since this is a tutorial this map is very small and very basic so we are tossing all pre-thought and planning for the objectives out the window. As maps get bigger, more elaborate, complex, so too will the objectives be to suit the level. You might want to the trophy in a vault. Maybe the guards will be patrolling. <br />
<br />
Save your map and load it up in TDM. Look at the objectives menu to see if the fresh addition is there. And than take it and see if it completes the objective.<br />
<br />
Congratulations!<br />
<br />
You now have a basic understanding of how the objectives editor works. For more advanced work, look for more tutorials in the future or go on the forums.<br />
<br />
== FAQs & Examples ==<br />
<br />
===KO objective but AI already dead!===<br />
<br />
;*If I kill the guard I don't fail the mission, but I can't complete it either.<br />
:Answer: I'll quote Ishtvan for this one. <br />
:''"The system is not smart enough to know automatically that someone who's killed can't be KO'd later, so if you want it to fail when they're killed, you have to put that in specifically. Note that this doesn't have to be a whole 'nother objective, it can be a component of the KO objective, so you have two components, KO them, and don't kill them. We could potentially make this automatic later on, but that's the way it is right now."''<br />
:Until this is fixed, I'd recommend making a knockout objective optional, unless you want to put in the kill component.<br />
<br />
===Kill objective thwarted by another AI===<br />
<br />
;*I put a monster in my map and he killed the guard, yet I still passed/failed the objective.<br />
: Answer: Check the '''Player Responsible''' Flag, this means that the player MUST do it himself in order to get credit.<br />
<br />
===Leak caused by Objectives Entity===<br />
<br />
;*Help! My objectives entity is outside the map and I have a leak! I can't find it! I even used the pointfile!! help!!!!<br />
: Answer: The objectives entity is a very small, yellow cube that is spawned around the origin. Its about the size of a light entity.<br />
<br />
<br />
===How to directly trigger an objective or component to complete===<br />
If the actions that the player has to do in a mission are not directly covered by the normal objectives properties, for example, the player must open a door, then objectives can be triggered to complete by any target entity.<br />
<br />
In the objectives editor, to your objective add a component type : custom script. (this might just say 'custom' or similar.) The objective now just awaits some external trigger or script in the game to set it complete. To do this with a trigger...<br />
<br />
* Create a new entity : ''target_tdm_setobjectivestate''<br />
* Give it the properties/values...<br>obj_idN O <br>... where O is the objective number and N is simply the obj_id number if you want several on the same entity. Just use obj_id1 if you only want one.<br> obj_state 1<br />
<br />
You must then target that from some [[Triggers|triggering entity]] like a button, lever, door (see [[Doors]]) or you can trigger it from stims & responses or from a custom script.<br />
<br />
In a similar way, you can trigger individual components using entity target_tdm_setobjective_component_state. In this give it the properties/values...<br />
<br />
* Create a new entity : target_tdm_setobjective_component_state<br />
* Give it the properties/values...<br>comp_idN C<br>... where N is just this ID number and C is the component number.<br>obj_state 1<br />
<br />
Again, trigger that as above.<br />
<br />
===How to make my invisible objective become visible to the player later===<br />
<br />
There are two methods. One way ''adds'' a new objective at the end of the current list of objectives. The other way makes an existing objective visible. This is the one for general use because it appears in the position in the list where you first put it rather than on the end. It makes sense to have your objectives in some kind of order so for example, you might have right at the end of the list 'when all else is done, escape from Castle...'<br />
<br />
====To make an invisible objective visible later====<br />
<br />
* Create a new entity : ''atdm:target_setobjective_visibility''<br />
* Give it the properties/values...<br>obj_idN O <br>... where O is the objective number and N is simply the obj_id number if you want several on the same entity. Just use obj_id1 if you only want one.<br />
<br />
You must then target that from some triggering entity like a button, lever, door (see [[Doors]]) or you can trigger it from stims & responses or from a custom script. Note that sometimes it helps to put in a delay (see below.) It will by default then become visible. You can do it the other way round and make an objective become invisible (remember it is still active by default) by changing the spawnarg value 1 to...<br />
<br />
obj_visibility 0<br />
<br />
<br />
====To add a new objective on the end of the list====<br />
<br />
* In the objectives editor use the top Add button to create a new ''atdm:target_addobjectives'' entity.<br />
* Add the new objective(s) just as described above<br />
* Find the atdm:target_addobjectives entity in the map (you normally need to check it is not in the void anyway plus you might like to place it near where it makes sense the new objective shows.<br />
* Add to the atdm:target_addobjectives entity the property ''wait_for_trigger'' and the value 1. Otherwise it will show right at the start of the game.<br />
* You then need to target that atdm:target_addobjectives from some triggering entity like a button, lever, door (see [[Doors]]) or you can trigger it from stims & responses or from a custom script. Note that it may help to include a delay (see below.)<br />
* The new objective(s) will show as added at the end of the list of objectives when triggered.<br />
<br />
====Inserting a delay before new objective shows====<br />
<br />
It often helps to include a delay from triggering before the ''New Objective'' message shows. To do this:<br />
<br />
* Create a ''trigger_relay'' entity.<br />
* Give it the properties:<br />
** ''wait -1''<br />
** ''delay N'' (replace N with delay time in seconds)<br />
** ''target'' <the name of the atdm:target_addobjectives><br />
** Make your original trigger target this relay instead of the atdm:target_addobjectives directly.<br />
<br />
===Completing Objective Components in a Certain Order===<br />
<br />
Suppose you want the player to complete two or more parts of an objective but in a certain order. Example : "Close the office door then open the safe." In that example you want the player to close the door first not just do both in any order. If you just make the two components they default to a Success Logic of 1 AND 2 which means the player must do both to complete the objective but it does not matter which order. So if the player opens the safe and then closes the office door then the objective will check off - perhaps not what you want. This is how to do it if you want to force the order in which the player does the components...<br />
<br />
There are two possible outcomes :<br />
<br />
If you want the mission to '''fail''' set the failure logic for that objective to<br />
<br />
''NOT(1) AND 2'', i.e., door is open AND safe is open.<br />
<br />
But if you just want the objective to not complete (so the player can try again)...<br />
<br />
Make '''two''' objectives, both using the door and safe components - the first is invisible but still active:<br />
<br />
# Objective 1: success logic: Door closed, safe not open = 1 AND NOT(2)<br />
# Objective 2: success logic: Door closed, safe open = 1 AND 2<br>(Objective 2 enabling objectives = 1)<br />
<br />
<br />
===An Objective to place an object in a Certain Location===<br />
<br />
To make an objective where an object (body, junk object, readable, or even the player) has to be placed somewhere:<br />
<br />
* Create a brush where you want the object to be put. This might be the size of a room, a street, or a chest or wherever you want the object. Better to make it too large than too small--the origin point of the object needs to be inside the brush to activate it.<br />
* Texture it with common > clip<br />
* With the brush selected, Create entity > info > info_tdm_objective_location <br />
* Give this entity a name you can remember like BodyDrop. Write it down or in a text editor<br />
* Give your object, eg, a ragdoll, a name, eg, JakesCorpse and note it down.<br />
* If it is not the player, then give it the property "objective_ent" and set it to "1"<br />
* Menu > Map > Objectives<br />
* If you haven't yet got any objectives then click the + Add button at top right. This creates a atdm:target_addobjectives entity so later make sure it is not in the void or you get a leak. Put it somewhere convenient. It is not visible in game.<br />
* Select the atdm:target_addobjectives in the Objectives entities list top left<br />
* In the objectives list below click the +Add button on the right.<br />
* This creates a new objective in the objectives list. Select it.<br />
* Click the edit button on the right.<br />
* Type a description near the top, eg, Carry Jake's body back to X and drop it in the soandso<br />
* In the components list further down click the +Add button on the right.<br />
* This creates a default Kill objective. Select it. Click the Edit button.<br />
* Just below it click the Type bar and from the list that show select 'Item is in location' ('''NOT''' Item is in '''info'''_location!!)<br />
* Further down click the bar below 'Entity' and select 'Name of single entity'<br />
* On the right of that type or paste in the name of the object (eg ragdoll) entity eg, JakesCorpse<br />
* Below, click the bar below Location and select 'Name of single entity'<br />
* On the right of that type or paste in the location entity name you gave above, eg, BodyDrop<br />
* Click the OK button and OK again and save your map.<br />
<br />
=== Classic "Get X Loot" Objectives ===<br />
<br />
Use the "overall (component specific)" option of "Player posess item" for loot.<br />
<br />
How do you find out how much loot is in your map? The easiest way is to set up an easy objective to lead to mission success. On the Mission Statistics screen, it will list your loot total.<br />
<br />
=== Optional 'No alerts', KO's, and Kills ===<br />
<br />
It is recommended that 'No alerts', KO's, and Kills be optional or at least provide a separate difficulty level that approximates another where these are enforced. Many players find these restrictions limiting and often very annoying. Some will abandon an FM in frustration if they find they can barely move without triggering an alert - mission failed.<br />
<br />
To create a "NOT" objective (do NOT kill X, do NOT find more than 3 potions, etc), you need to select the "Boolean" checkbox. This will turn the objective into its opposite ("Kill 3 AI" turns into "Do NOT kill 3 AI").<br />
<br />
'''Important''': No kill objectives need be set as "Satisfied at Game Start" and "ongoing" or they will not work!<br />
<br />
=== Using Objectives to trigger things ===<br />
<br />
You can use objectives like a trigger. Don't put the target spawnarg on the objective entity, however; you have to use the Objective Editor. The "Completion Target" and "Failure Target" fields can take any kind of entity that can normally be triggered, like a speaker or an atdm:teleport.<br />
<br />
You can trigger more than one thing, but then you must create a trigger_relay entity. Put the name of that entity in the "Completion Target" field, and then target your other triggers from the relay.<br />
<br />
=== The standard "exit here when you're done objective" ===<br />
* Place a (large!) brush in the location you want to work as the exit.<br />
* Give it texture textures/common/clip<br />
* Make the thing into an entity info_tdm_objective_location<br />
* Give it name player_exit<br />
* Go to objectives editor and make an objective "After you're done, go to the exit" or something like that. Set it to be INCOMPLETE and mandatory.<br />
* Set enabling objectives. Here you need to set which objectives need to be complete for the exit to work. If you have objective numbers 1 and 2 must be completed in order the player to exit, you need to put text "1 AND 2" in the enabling objectives box. If you need to have objectives 1,2 and 5 completed you need to put "1 AND 2 AND 5" If you have some objectives that only appear under certain difficulty levels (like loot objectives), you can do this: Enabling objectives: 1 AND (2 OR 3 OR 4)<br />
You can check the objective numbers in the objective editor window under "#" mark.<br />
* set the component to be:<br />
* Type: item in location '''(NOT item in info_location!!)'''<br />
* Entity: any entity with SDK-level spawnclass idPlayer (Note the capital "P"--won't work without!!)<br />
* Location: name of single entity player_exit<br />
<br />
'''NOTE''': You must make the brush for the info_tdm_objective_location '''large'''! I have had this objective completely fail when using a vaguely player-sized brush. Expanding the brush to fill the entire room made the objective work.<br />
<br />
== Troubleshooting ==<br />
<br />
My objective doesn't work, what's wrong? Can't count the number of times I had to ask that. Here are a list of helpful suggestions:<br />
<br />
* Case sensitivity. I had an objective that didn't work because I had "idplayer" instead of "idPlayer".<br />
* The most common error with the exit objective is using the 'in info_location' component rather than the 'in location' component.<br />
* The info_tdm_objective_location entity uses the spawnarg interval with 1 second as default. This might not be long enough for a small volume if the player (or other entity) can pass through in less. It should be as high as possible for performance but not so high the player might pass through in less.<br />
* No kill objectives need be set as "Satisfied at Game Start" or they will not work!<br />
<br />
===Technical info===<br />
<br />
;*I have some other questions about objectives<br />
: Answer:This article talks about more specific, more technical and advanced work. [[Objectives]]<br />
<br />
{{tutorial-editing}} {{darkradiant}}</div>RJFerrethttps://wiki.thedarkmod.com/index.php?title=Triggers&diff=17822Triggers2014-07-07T23:11:34Z<p>RJFerret: /* trigger_count */ +repeat</p>
<hr />
<div>There are many different ways of triggering [[Entity|entities]], the Trigger entities themselves, as well as through [[Stim/Response]], [[Conversations]], Movers, [[Objectives]], and more. How the trigger occurs will typically dictate which manner you choose for your map. <br />
<br />
=Triggers=<br />
To create triggers that rely on boundaries (once, multiple and their derivations), you need to drag out a worldspawn brush, right-click, select "Create Entity". (They will not function if abutted against others.) Triggers need to be connected to their subjects, either via "Connect Selected Entities" menu option/shortcut key, or adding "Target", "Target0", "Target1" or subsequent "Target"# spawnargs. The triggers below are listed roughly by frequency of usage, with related triggers beneath.<br />
<br />
==trigger_once==<br />
When the origin of an entity is within the bounds of this entity, the target(s) will be triggered, then the trigger_once is removed. (Note, to resize the brush after creating the entity, select it then press Tab once.)<br />
<br />
==trigger_once_entityname==<br />
Similar to [[Triggers#trigger_once|trigger_once]], but may be set to only respond to the entity specified by the spawnarg, "entityname". Note the entity must move into the boundaries itself, not be moved by the player (AI walking themselves for example). (If you want something to happen based on the player dropping or placing an item somewhere, use the [[Objectives]] system instead.)<br />
<br />
==trigger_multiple==<br />
Similar to [[Triggers#trigger_once|trigger_once]] but will activate again and again, use "Wait" spawnarg to control how many seconds between triggerings. <br />
<br />
==trigger_entityname ==<br />
Similar to [[Triggers#trigger_multiple|trigger_multiple]] but only reacts to the entity defined by the "entityname" spawnarg.<br />
<br />
== trigger_facing ==<br />
Also similar to [[Triggers#trigger_multiple|trigger_multiple]], but requires the triggering entity to be within 30° of the specified "angle" spawnarg. For details see [[Trigger Facing]].<br />
<br />
==trigger_relay ==<br />
Most commonly used to trigger many targets, or do so after a delay (per the "delay" spawnarg). May be set to only work once (spawnarg "wait" "-1") or limit firing based upon how many seconds have passed. The "random" spawnarg may be used with "wait" to vary the firings. Very useful as the target of worldspawn, to trigger things at map start (since worldspawn currently only activate one "Target"), or as the target of Objectives.<br />
<br />
==trigger_count ==<br />
This will fire at it's targets upon a specific number of times being triggered itself, based upon the "count" spawnarg. If "count" "3" is set, it will do nothing until the third triggering. Set "repeat" to "1" if it should do it again and again instead of just once.<br />
<br />
== trigger_timer ==<br />
This trigger will fire repeatedly every "wait" # seconds. The spawnarg "start_on" defines if it should do so at the start of the map, or wait to be triggered (defaults to 0, off at map start). Spawnarg "random" adds variability to the triggerings.<br />
<br />
== trigger_fade ==<br />
Will cause the display to fade or dissolve to a specified color. The spawnarg "fadeColor" specifies which color, and how transparent in RGBA (red, green, blue, and alpha, ranging from 0-1). Default is fade to black: "fadeColor" "0 0 0 1". To fade up from whatever, use alpha of 0, IE to fade up from black, "0 0 0 0". "fadeTime" controls how quickly the fade transpires.<br />
<br />
== trigger_hurt ==<br />
Applied to a worldspawn brush to define boundaries à la a [[Triggers#trigger_multiple|trigger_multiple]], by default it causes 10 points of damage/second to the activator (player or AI). It may be triggered on/off. The spawnarg, "delay" may be set to vary frequency of damage application. One of various "def_damage" may be specified, generally found in the root directory of the entities, or to see specific details, in the defs file, "damage.def". Note those referencing "triggerhurt" simply cause damage, while others feature additional effects such as push and knockbacks (launching the player away).<br />
<br />
If you need varying amount of damage based on proximity, the [[Stim/Response_Key/Values#Damage_Stim|Stim/Response]] system offers control of various types of falloff.<br />
<br />
== trigger_presize ==<br />
Akin to [[Triggers#trigger_multiple|trigger_multiple]] without the need of creating a brush first, and defaults to not being touched by players/AIs, but triggered by other entities/script.<br />
<br />
== trigger_touch ==<br />
Continuously checks if entities are touching, costly performance wise, probably done via [[Objectives]] more efficiently.<br />
<br />
=Triggering via Path Nodes=<br />
Several [[Path Nodes|path nodes]] will trigger their targets upon AI completing the associated node action (as of TDM v2.02). These include, path_corner (upon reaching), path_turn, path_wait, path_sit, path_sleep and path_anim.<br />
<br />
=Triggering Stim/Response=<br />
'''To Trigger Something Else:'''<br />
<br />
Any Response type may have an effect of "Trigger", in which another entity selected is triggered. Note the "Trigger" effect is all the way at the bottom of the drop down, which might not be displayed on screen (Toggle Effect is the last displayed on mine), you may cursor down or use the End key to get to Trigger.<br />
<br />
'''Be Triggered:'''<br />
<br />
Within the [[Stim/Response]] editor, add a response stim set to "Trigger", now when this entity is targeted, whatever specified effect will occur.<br />
<br />
An example would be to not have something able to be frobbed until something obscuring it is removed or opened. Make the response effect "Set Frobable" for the entity in question, and check "frobability" on. Now when the item is triggered, by a door, or frob response on something in front moved/picked up, it will become frobable.<br />
<br />
=Triggering via Conversation=<br />
The command, [[Conversations#Conversation Commands 2|ActivateTarget]] will trigger the specified entity at that time in the Conversation script.<br />
<br />
=Triggering via Doors, Buttons, Levers, Movers=<br />
[[Doors]] trigger their targets by default upon opening (spawnarg "trigger_on_open" "1"). They may also trigger when completely open by changing "trigger_when_opened" to 1 instead of the default 0, or when fully closed via "trigger_on_close". Note, those conditions on Buttons came from doors, so are counter-intuitive.<br />
<br />
=Triggering via Objectives=<br />
In the [[Objectives Editor]] you may select an entity to be triggered upon an objective succeeding or failing. Therefore all the possible objective conditions may become trigger events (knock out an AI, move an object away from another or to a spot, cause another objective to become visible, disappear or complete, etc.)<br />
<br />
=Triggering via Worldspawn=<br />
You may set "Target" on Worldspawn (usually at a trigger_relay since it only may target one entity currently) to cause things to be triggered at map start. If you use this to kill an AI or other affect with audio, note if in range of the player's start, it will be heard during the fade up from black.<br />
<br />
=Triggering via Lights=<br />
Lights trigger their target(s) both upon being extinguished and lit. This is useful to match window glow to actual light condition. Depending on the light, it may be tricky to set the targets however. A basic light entity can simply have target(s) spawnargs, but a candle, lamp or torch with attached flame entity, you need to use the "set" spawnarg. For example, "set target0 on flame" "EntityToBeTriggered".<br />
<br />
=Trigger a Script=<br />
Point any trigger at a target_callscriptfunction entity and give it the spawnarg, "call" ''ScriptFunctionName'', where ''ScriptFunctionName'' matches "void ''ScriptFunctionName''()" in the map's .script file. See [[Scripting_basics#Script_invocation|script invocation]] for more info.<br />
<br />
[[Category:Editing]]</div>RJFerrethttps://wiki.thedarkmod.com/index.php?title=Doors&diff=17821Doors2014-07-07T21:19:51Z<p>RJFerret: /* Door Controllers */ language tweak, "may" instead of "can" since can makes it sound like you can't have multiple on both sides</p>
<hr />
<div>{{todo}}<br />
''Written by Fidcal'' ''edit Baddcog''<br />
<br />
==Quick Summary==<br />
<br />
Quick way to get an unlocked door in your map:<br />
<br />
* Insert one of the prefab doors complete with handles and select its skin property and click the button to change its skin appearance to whatever you want. Set any other properties you need.<br />
<br />
Alternatively,<br />
<br />
* Create a door from the entity list<br />
* Use the "skin" spawnarg on the door to change its appearance. <br />
* Create a handle from the entity list<br />
* Add the ''door_handle'' property to the door and give it the name of the handle<br />
* To the door handle add the value frob_peer and use the name of the door.<br />
* To open clockwise, change the ''rotate'' property from <code>0 90 0</code> to <code>0 -90 0</code><br />
<br />
==Introduction==<br />
<br />
This tutorial explains how to put doors into your map using Dark Radiant, as well as adjust them and their properties.<br />
<br />
The rest of this tutorial assumes that you have a basic understanding of using DarkRadiant. If you haven't done so, please go read the [[Dark Radiant Must Know Basic Intro]] article first.<br />
<br />
Additionally:<br />
<br />
* Up, down, right, and left in Dark Radiant's ''top'' orthoview are regarded here as the standard map directions of North, South, East, and West where useful for clarity.<br />
* Where the term ''brush'' is used with a door it mostly also applies to a door made up of a group of brushes and/or patches.<br />
* Where the term ''door'' is used it often will also apply to any object you wish to rotate when frobbed, for instance an openable window, box lid, or even more exotic objects that the imaginative mapper might conceive like a signal, engine part, toy, or whatever. So long as it needs to turn or slide just a fixed amount when frobbed then return when frobbed again then the following applies.<br />
<br />
==Door types==<br />
<br />
All tangible objects in Dark Mod are ''entities'', having either a pre-made model shape or else brush/patch(es). So there are two ways to create a door in Dark Radiant: as a model door or a textured brush door (or a hybrid of the two).<br />
<br />
Models are ready made door objects but cannot within Dark Radiant (at the time of writing) be resized, rescaled, cropped or clipped whereas brushes are very flexible in that respect and can be worked into custom shapes for your map, including secret doors that blend into walls and other surfaces.<br />
<br />
Most of the current door models are found in two places along with the door handles.<br />
*Model Viewer: doors created from here will be static in the world and have no props other than material type.<br />
You can add any props to them to make them working doors. If nothing else it is a good place to view the different size and skin options for the doors.<br />
*Entity List: most of the door models can be found here. These doors have properties already assigned so they are ready to be used. Only one base door of each type is listed, create the size/hinge count door you want (2 hinge doors have a 'no hinge' skin). You can choose a skin for the door once it has been created in the editor with the "skin" spawnarg (use the model name of the door you want, taken from the model list, as its value). This is the easiest way to create a door. The same goes for door handles.<br />
<br />
Remember also that door functions may be applied to objects other than doors, such as openable windows, drawbridges, gates, etc. In fact, anything that needs a partial rotation or slide when frobbed then return when frobbed again, such as a signal device. Lockboxes and chests use similar properties.<br />
<br />
You can create one door/handle set and copy/paste it, but you need to take great care that all the name props are changed to match in each clone. Otherwise you get handles that fly off when a distant door moves, and handles that don't move.<br />
<br />
==Creating a Door==<br />
<br />
Put simply, to make a door you will be creating an 'entity with model' or 'entity with brush' or some variation thereof.<br />
<br />
===Creating a Model Door===<br />
<br />
There are several approaches to making a model door; the simplest is to create a door from the entity list; or create a door from the model viewer (good for static unusable prop doors).<br />
<br />
'''Entity List''':<br />
<br />
*Deselect everything in editor by hitting the Esc button<br />
*Right-click an ortho view and select Create Entity<br />
*Navigate to darkmod/movers/''atdm:door_...'', choose the door you want<br />
*Click Add<br />
*To change its appearance, add a "skin" spawnarg to the door, with the value being the model name of the door you want.<br />
<br />
You now have a workable door in your level.<br />
<br />
'''Model Viewer''':<br />
<br />
* Right click in the orthoview, select ''Create Model'' then <code>darkmod</code> and select a door.<br />
* Note that you can left drag the image in the ''Choose Model'' dialog to rotate it around.<br />
* Click [[Image:Button ok.png]] and you have a static door.<br />
* If you want to make it work (openable, frobbable) then:<br />
** Select the entity inspector,<br />
** Select the top classname line so it highlights<br />
** Select the func_static line in the input box ''below'' the properties window.<br />
** Edit <code>func_static</code> to <code>atdm:mover_door</code><br />
** Click {{check}} or press {{key-enter}}<br />
<br />
Alternatively you can do it the old way:<br />
<br />
* Create any temporary brush<br />
* Right click in orthoview and select <code>Create Entity</code> then <code>atdm:mover_door</code>.<br />
* Left lick the model name line in the entity inspector.<br />
* Below it on the ''Entity Inspector'' panel you should now see a button 'Choose Model'<br />
* Left click it, select a door model from the darkmod group.<br />
* Note that you can left drag the image in the ''Choose Model'' dialog to rotate it around.<br />
* The temporary brush was deleted.<br />
<br />
<br />
In all three instances, you now have a working door with default properties. <br />
<br />
Name your door by adding the prop (or modifing it) to name ''My_Door_1''. You can use any name that you feel is appropriate but all doors with handles attached ''must'' have their own specific name. Use the name My_Door_1 for your first attempt as it will be referenced when you get around to attaching handles (see below).<br />
<br />
To add a handle and other adjustments, see [[#Customising and Adjusting Door Properties]] below.<br />
<br />
===Creating a Textured Brush Door===<br />
<br />
'''Tip:''' If unsure of size then you might insert a temporary human AI first to get a sense of height.<br />
<br />
==== The simplest brush door: ====<br />
<br />
* Drag out a new brush to the size required, eg, a seven foot high door is 84" x 1.1 = about 90 units in Dark Radiant.<br />
* Give it a door texture from the texture browser (or wall texture for a secret door)<br />
* Right click in orthoview and select ''Create Entity'' then <code>atdm:mover_door</code><br />
<br />
You now have a working door but it will rotate around its center. To move the rotation point to where you want the door hinges to be:<br />
* Select the door and press 'v' to enter vertex editing mode. The door's origin will show up as a small green square in the middle of the brush.<br />
* In top-down orthoview, move the origin from the center to the corner of the brush. This is easiest in drag mode ('q'), although you can use translate mode ('w') by manually selecting the vertex first.<br />
<br />
==== Multi-brush doors: ====<br />
<br />
More complex multi-brush doors can be created using the [[Clipper]] tool, CSG, etc. - this is not covered in this tutorial. Then assign <code>atdm:mover_door</code> for that whole brush structure. Also you can collect various brushes positioned together in relation to one another as needed, select them all, then assign <code>atdm:mover_door</code> for the group. All the brushes will be children of the <code>atdm:mover_door</code> entity and will rotate and be frobbable, etc. as one unit, as one door. To add further brushes or even model shapes later see the section on [[#Adding handles and other items to doors]].<br />
<br />
Name your door by adding the prop (or modifing it) to name My_Door_1. You can use any name that you feel is appropriate but all doors with handles attached must have their own specific name. Use the name My_Door_1 for your first attempt as it will be referenced when you get around to attaching handles (see below). (repeated from above in case you didn't choose to create a model door)<br />
<br />
=== Double Doors ===<br />
Double doors are automatically recognised by the code when the doors are spawned. The prerequisite is that both doors are sharing/touching the same visportal. The spawnarg ''auto_setup_double_door'' (which defaults to "1") will take care of setting up the open/lock peer relationship between the two doors. The doors will open/close and lock/unlock along with each other as a result.<br />
<br />
What happens behind the scenes: the doors are adding each other to their internal open_peer and lock_peer list, which causes the double doors to perform the same action when frobbed or used.<br />
<br />
Note that ''auto_setup_double_door'' will not set the frob_peer relationship, i.e. each door will frob-highlight on its own without highlighting the other door. You'll need to add that spawnarg manually if you want to highlight the entire double door as one.<br />
<br />
==Customising and Adjusting Door Properties==<br />
<br />
Handles, lockplates, etc. can be added to doors and door properties can be adjusted for rotation, sliding, locking, and more.<br />
<br />
Some of the door models have hinge plates and lockboxes that are reskinnable with a good variety of skins.<br />
<br />
===Door handles and other door attachments===<br />
<br />
'''Summary: just add the property ''bind'' with the door's name to the attachment and position it where you want it on the door. If it's a ''atdm:mover_door_handle'' then it automatically will work as a handle but you can bind virtually anything.'''<br />
You can add handles and other items to doors such that they move correctly with the door whether rotating, sliding, or both and even if the door is not vertical such as a skylight or trapdoor.<br />
Handle models come in two types, ''single handles'' and ''double handles''. A single handle is one sided, this means the handle will be inside the door or outside the door, but not both. A double handle has a lever on the inside of the door and a handle on the outside of the door. Each has benefits.<br />
<br />
*'''''Single door handles''''':<br />
Single door handles can be used on a static door, a door that's just for show that no AI's or the player can use. In this case you should just create a door handle from the model viewer, it will be static and have no properties such as scripts. It is for looks only.<br />
<br />
I will call this ''multiple handles'', see more below.<br />
<br />
These can also be useful on brush doors created in the editor that may be very thin or very wide.<br />
<br />
*'''''Double door handles''''':<br />
These are models have have a handle inside and outside. The bonus is that they only use one entity. Maps are limited to about 4,000 entities but when you count lights, AI, sound speakers, ect... you can run out of entities quickly on a large map. If you plan on building a large map this is the way to go, even in a small map they have benefits, namely that you only have to attach one handle per door.<br />
<br />
Whether you decide to use a single handle or a double handle you must first follow the instructions below and attach one handle first. If you choose a double handle, follow the instructions below and you are done. If you choose a single handle type follow the instructions then also follow the ''multiple handle'' instructions for the second handle.<br />
<br />
Both single and double handle types can be found in two places. The model viewer which will create a static model good for show, you can manually add props to make them work OR you can look in the entity browser.<br />
Using a handle from the entity browser saves you a little bit of time as some props are already added, you just need to add the frob_peer names for the doors/handles and the door_handle name to the door.<br />
<br />
=== Adding a working model door handle===<br />
<br />
Quick summary:<br />
* Create a model or brush handle and make it an ''atdm:mover_door_handle'' entity.<br />
* Position it on your door. Use the opposite side from the door's multicolor X-Y-Z indicator (highlight the door to see it) if it's not obvious which side it goes on. <br />
* '''Bind''' the handle to the door (bind <doorname>)<br />
* It should now be a working handle though may need adjustments of rotation etc. see later. <br />
<br />
<br />
Important: read preceding section on door handle types and performance issues first.<br />
<br />
This works with both a model door and a brush door:<br />
<br />
'''Rotation''':<br />
* By default the door handle entity rotates ''anti-clockwise'' (looked at from the front) then springs back. A ''double handle'' model is OK but two singles (see ''Multiple door handles'' below) need more care as only one is the functioning entity and the other is just attached to it. So anti-clockwise is fine for a door with its hinge on the left and the handle on the right - the handle will rotate down then spring back. If you put the functioning door handle on the other side you will have to change the default ''rotate'' property from -45 0 0 to 45 0 0. '''''Therefore it is easier to generally put this handle on the side of the door where the hinge is on the left and the non-functioning attachment handle on the other side.'''''<br />
*If your door only needs one handle, eg, a cupboard door, and from outside its hinge is on the right then you will need to change the ''rotate'' property of the handle as described above.<br />
<br />
'''''The functioning handle entity:'''''<br />
* Create an entity door handle (movers folder) or create a brush or model handle and assign it the entity ''atdm:mover_door_handle''.<br />
* Position it where you wish on your door.<br />
* '''Bind''' the handle to the door, by adding the "bind" spawnarg to the handle.<br />
<br />
You now have a working door handle with default properties.<br />
<br />
*'''Multiple door handles''':<br />
Now that you've got a handle attached to one side of the door it is time to add one to the other side (unless you used a double handle).<br />
* Create the new handle. The single handles come in left and right persuasions. A door needs a left facing handle on one side and a right facing handle on the other, so if you have already added the left handle create a right handle and line it up on the other side of the door.<br />
* Name this handle. I prefer to keep a naming convention for each door and it's respective handles, it makes things alot easier. The door is named '''My_Door_1''', the first handle is named '''My_Handle_1''' so name the second handle '''My_Handle_1_1'''. This will make it stay with the first handle in the entity list. This is important to keep organized. If you name it My_Handle_2 then when you get to another door named My_Door_2 you'll be confused.<br />
* Place and '''bind''' that handle to your door.<br />
<br />
You now have two single door handles on either side of the door that rotate together as if they were physically attached.<br />
<br />
'''To add a brush to a brush door''':<br />
* Select the new brush ''and'' the brush door all together; ''the entity '''must''' be selected '''last'''.''<br />
* Use {{menu|Edit|Reparent primitives}}. This ensures the parent entity adopts the new item(s).<br />
* If you have trouble selecting them in the orthoview because other brushes, etc. get selected then try in the camera view or as a last resort move them temporarily to an open area (but keep them in the same positions relative to each other.) Use {{key-shift}}+{{LMB}} on new item(s) then {{key-shift}}+{{LMB}} on main entity. Once they are all selected, use the {{menu|Edit|Reparent primitives}}.<br />
<br />
'''To add ''model'' static items''': knockers, hinges, static handles etc. to a ''Model Door'':<br />
* Select item<br />
* Right click in orthoview and select ''Create Entity'' then <code>entity func_static</code><br />
* Position it where you wish on your door.<br />
* To synchronize this with your particular door you need to add the property ''bind'' and the individual door name to the brush entity. To do this...<br />
** Select the model door.<br />
** In the entity inspector, select the ''name'' line<br />
** Select the bottom line in the input box ''below'' the properties window.<br />
** Copy the name<br />
** Deselect the door with {{key-esc}}<br />
** Select the brush entity<br />
** Add a property "bind" to it.<br />
** Change the value of the property by pasting in the door name<br />
** Click {{check}} or press {{key-enter}}<br />
<br />
'''To add ''brush'' static items''': knockers, hinges, static handles to a Model Door:<br />
* This method is not ideal but it seems to work OK.<br />
* Select the brush.<br />
* Right click in orthoview and select Create Entity then ''atdm:mover_door_handle''<br />
* Position it where you wish on your door.<br />
<br />
To synchronize this with your particular door you need to add the property ''door_handle'' on the door, and give as the value the name of the brush you just created.<br />
<br />
This brush turns like a handle. To stop it:<br />
<br />
* Adding ''rotate 0 0 0'' or disabling the handle script won't help.<br />
* Add a real working handle (as in the section above ''To add a working model door handle...'' and it must be added LAST.)<br />
<br />
If you don't want too see a real working handle added maybe try another tiny brush with the handle function and hide it inside the door?<br />
<br />
===Locking Doors===<br />
<br />
To lock a door check the ''show inherited properties'' in the entity inspector for a ''atdm:mover_door'' entity and you should see the ''locked'' property. Select it and in the input box below the properties you can change its value:<br />
<br />
* 0 = unlocked (default)<br />
* 1 = locked<br />
<br />
If locked it will require an entity that is associated with it to be able to act as a key to unlock it.<br />
<br />
Currently door handles on locked doors will rotate when frobbed, they will bounce back though and the door will stay locked until unlocked.<br />
<br />
===Keys===<br />
<br />
Assigning specific keys to specific doors is simple.<br />
<br />
* It is recommended that you create an existing key entity. These keys have all required props, they just need to be named.<br />
<br />
Alternatively you can create a key from the Model Viewer and want it to be useable<br />
* Make sure it has the properties:<br />
useable 1 [so it can be used by the door]<br />
frobable 1<br />
inv_name <unique name><br />
inv_category Keys<br />
inv_target player1<br />
inv_icon guis/assets/hud/inventory_icons/<icon name><br />
inv_stackable 0 or 1 where 1 can be used on all copies of the same key so they show as one entry in the inventory with a total.<br />
<br />
Add to the door the property <code>used_by</code> with the name of the key as the value. Multiple keys can open the same door by using several <tt>used_by</tt> spawnargs:<br />
<br />
"used_by" "doorkey_1"<br />
"used_by1" "doorkey_2<br />
<br />
==== Keys carried by AI ====<br />
<br />
So you have a door and you have a guard Ai and you want the guard to be able to open/close/lock the door but you also want the player to be able to pickpocket the key. For more info on attaching key, props etc - see [[Attaching Props to AI]].<br />
<br />
*"def_attach6" "atdm:prop_silverkey" //the entity to spawn - in this case a key.<br />
*"pos_attach6" "belt_back_right" //where the key will spawn on the Ai.<br />
*"name_attach6" "door_key" //this gives 'attach6' arg the name "door_key" and is the name the arg "used_by" will need, eg: "used_by" "door_key"<br />
*"set inv_name on door_key" "Door key" //The name the key get when the play adds it to their inventory.<br />
*"set name on door_key" "door_key" //here it gets a name to be used in the map in general.<br />
<br />
Or simply:<br />
<br />
* load a key entity<br />
* position where you want it in relation to the AI, bind it to them<br />
* Add the spawnarg "bindToJoint" "Hips" (or other location, see AI for list)<br />
* adjust existing spawnargs accordingly (be sure the name and door's/chest's "used_by" match, if you aren't using a prefab chest w/key)<br />
<br />
====Master Key for Testing====<br />
<br />
By default, ALL locks can be opened by any key named ''key_master''. Just create a key in your map, name it ''key_master'' and it becomes a master key for use while testing. Add inv_map_start 1 to it so it is in the player inventory at game start. Remember to delete it when your mission is finished.<br />
<br />
===Lockpicks===<br />
''by Baddcog''<br />
<br />
There are two lock pick types.<br />
*'''s'''=snake<br />
*'''t'''=triangular<br />
<br />
A lock can be set with many pins. Each pin has a click sequence and each needs a designated lockpick type (see above). Keep in mind that the lockpicking in The Darkmod is much more involved than in T2 or T3. The player has to listen to sounds or watch a handle or lockbar to know when a lock is pin is picked.<br />
<br />
This means that authors can be very evil and really frustrate the player, in which case their missions will probably not be played. So be nice to the player and don't waste your time. Use simple locks for the most part and save complicated locks for important sections and to build tension. Don't make the player have 20 pins to pick all with different lockpicks. In most cases 1 or 2 pins will suffice and it isn't necessary to use both lockpicks on every lock.<br />
Also try to include a lock lever on lockboxes or chests, door handles will rotate as the pins are being picked. This gives the player visual clues to help with the picking (and essential in noisy environments where you can't hear the clicks.)<br />
IMO this system is a huge leap foward for lockpicking but also has the ability to completely frustrate the player as stated above. Keep this in mind when designing your lockpick systems.<br />
<br />
These props go on the door itself, or the lid of a chest, eg,<br />
*'''lock_pins''' 1327<br />
*'''lock_picktype''' stts<br />
<br />
The lock_pins property specifies how many pins each lockpicktype has.<br />
The lockpick_type property specifies how many times the player has to switch picks and which pick they have to use. You can see there must always be an equal number of lock_pins and lock_picktypes specified<br />
<br />
So looking at the example above we have lockpick_type s(snake), t(triangular), t(triangular), and s(snake). The player will have to use these lockpicks in this order. Once the snake lockpick's pins are open the player can advance to the triangular pick and so forth.<br />
5 is added to every click sequence so 5 is the minimum click pattern even if you set it to 0.<br />
In the example above the lockpins specify in order which pick types have how many pins, so the s pick has 1 + 5 = 6 clicks, the t pick has 8 and so on.<br />
The above is a difficult lock and to avoid annoying the player it is best only used rarely on a special lock like an important big vault door. Ordinary footlockers and common doors can be just 1 or 2 click sequences, eg, lock_pins 2 and lock_picktype t means the player uses one pick and listens for the end of one sequence of 7 clicks.<br />
<br />
lockpick_rotate - is placed on the door. It is the amount the visible rotating handle or pin rotates while picking. For a rotating handle or lockbar normally ignore this and leave the default. During lockpicking it oscillates and progresses to the normal full turn of the handle. Example 0 45 0.<br />
<br />
lockpick_translate - is placed on the door. It is the amount the visible handle or pin moves in a straight line while picking. Use this if you have eg, a lockbar that you want to move in a straight line and not rotate, eg sliding catch. Example 0 -5 0<br />
<br />
By default, doors are pickable. If you don't set up the above lockpick spawnargs then it can't be picked. So there is normally no need to enable lockpicking - just set up the above spawnargs. There is a ''pickable'' spawnarg set to 1 by default. If set to 0 then the door becomes unpickable. But hard to think of an application except in testing or perhaps a special custom situation where it is switched by script perhaps.<br />
<br />
===Open, Partially Open, or Closed Door at Game Start===<br />
<br />
By default, doors are closed at game start. If you want a door to be already open or partially open then do the following.<br />
<br />
'''Note well: Create all doors in their ''closed'' position. Adjust as follows and they will automatically be at the open position when game starts.'''<br />
<br />
Already Open Rotating Door:<br />
* Select the door.<br />
* Select the entity inspector<br />
* Check ''show inherited properties''<br />
* Select the ''open'' property<br />
* Edit the value to 1 in the input box below and tick the check button<br />
* The door will now be fully open at game start.<br />
<br />
* If you want it only partly open:<br />
* Make sure its ''open'' property is set to 1 as above.<br />
* Right click the entity inspector and select ''add property'' <br />
* Click the + sign on the left of the top line where atdm:mover_door is listed to open the folder. (if atdm:mover_door is not listed then the entity was likely changed from eg, func_static. If so, save the map and reload to update the add property list)<br />
* scroll down, select ''start_rotate'' then click {{ok}}<br />
* This adds it to the property list.<br />
* Now select ''start_rotate'' in the property list.<br />
* Edit the bottom line of the input box ''below'' the properties window to the angle you want in the same form as described in the ''Rotate Direction and Open Angle'' section. So for example, to have a door that has a fully open default ''rotate'' value of 0 90 0 to start only half open you would give it a ''start_rotate'' value of 0 45 0. <br />
* In a similar way add the property ''first_frob_open".<br />
* Set it to 1 and a partly open door should then open fully on the first frob.<br />
* Set it to 0 and a partly open door should close on the first frob.<br />
<br />
<br />
Already Open Sliding Door:<br />
* Select the door.<br />
* Select the entity inspector<br />
* Check ''show inherited properties''<br />
* Select the ''open'' property<br />
* Edit the value to 1 in the input box below and click {{check}} or press {{key-enter}}<br />
* The door will now be fully open at game start.<br />
<br />
* If you want it only partly open:<br />
* Right click the entity inspector and select ''add property'' <br />
* Make sure its ''open'' property is set to 1<br />
* Click the + sign on the left of the top line where atdm:mover_door is listed to open the folder.<br />
* scroll down, select ''start_position'' then click OK. (if atdm:mover_door is not listed then the entity was likely changed from eg, func_static. If so, save the map and reload to update the add property list)<br />
* This adds it to the property list.<br />
* Now select ''start_position'' in the property list.<br />
* Edit the bottom line of the input box ''below'' the properties window to the position you want in the same form as described in the ''Sliding (Translation) Amount and Direction'' section. So for example, to have a door that has a fully open default ''translate'' value of 0 50 0 to start only half open you would give it a ''start_position'' value of 0 25 0.<br />
* In a similar way add the property ''first_frob_open".<br />
* Set it to 1 and a partly open door should then open fully on the first frob.<br />
* Set it to 0 and a partly open door should close on the first frob.<br />
<br />
===Rotation Centre, Pivot, Hinge point===<br />
<br />
The centre of rotation of a door is at the origin point of its entity and the door rotates with reference to the orientation of that origin point, not the world map. See ''Rotate Direction...'' for more about that. This section only deals with the ''position'' of the rotation centre in the door.<br />
<br />
Model Door Centre of Rotation:<br><br />
The centre of rotation of a model door cannot be changed within Dark Radiant. Because a model door rotates around the centre 'spine' of its back edge this will cause clipping (penetration into solid) as in this example (where the door is set to open to 89 degrees for clarity):<BR>[[Image:modelClipping.jpg]]<BR> So care is needed with placement. You will not normally position a door right next to a wall as in the example but against a shallow frame so clipping will barely be noticeable but either way it can be fixed. You can correct it by adding a translation (see ''Sliding (Translation) Directions'') value of half the door width in the direction of the door handle. This will gently move the door out as it rotates to clear any solid on that side as in this diagram:<br><br />
[[Image:DoorClip.jpg]]<br><br />
Half a door width will typically be about 2. Any 'attachments' such as door handles will still synchronize with the door movement whether the door is rotating, sliding, or both.<br />
<br />
<br />
Brush Door Centre of Rotation:<br><br />
The centre of rotation of a brush door ''can'' be changed. The default origin point of a brush is at its centre. Therefore a default rotating brush door will rotate around its centre when you first create it. So, mappers will commonly need to move that rotation point to a corner or even to some other offset position for example, for an openable window using the door function.<br />
<br />
Put simply, to move the rotation point of a brush door you need to move the entity origin relative to the brush(es.)<br />
<br />
Moving the entity origin (centre of rotation) relative to a brush door:<br />
<br />
* Select the brush door<br />
* Select ''Vertices mode'' (default shortcut key is {{key|name=V}} or button on top toolbar 'Select Vertices')<br />
* Drag the door's entity origin to the point where you want the door to rotate. This should be on the corner on the leading edge side (the side to where the door is opening.) to avoid clipping as in this diagram....<br />
[[Image:getCorner.jpg]]<br />
* You should now find that door rotates around that point.<br />
<br />
===Rotate Direction and Open Angle===<br />
<br />
By default, rotating doors open anti-clockwise (viewed from above) by 90 degrees from the start orientation. If you want to change this edit the ''rotate'' property in the entity inspector. Don't confuse this ''rotate'' property with the ''rotation'' property. In the entity inspector remember that to see the inherited rotate property you must check the box 'Show inherited properties'.<br />
<br />
The three values shown in the rotate property are degrees from the closed position around Y Z X (absolute map axes Front, Top, Side views in DR's ortho view.)<br />
<br />
* Positive Y = Open clockwise (Dark Radiant grid front view, looking north)<br />
* Negative Y = Open anti-clockwise (Dark Radiant grid front view, looking north)<br />
<br />
* Positive Z = Open anti-clockwise (Dark Radiant grid top view, looking down)<br />
* Negative Z = Open clockwise (Dark Radiant grid top view, looking down)<br />
<br />
* Positive X = Open anti-clockwise (Dark Radiant grid side view, looking west)<br />
* Negative X = Open clockwise (Dark Radiant grid side view, looking west)<br />
<br />
There is a problem when you come to rotations that are not around the main Y Z X axes of the map, for instance a drawbridge that lowers down to the south east. You might think you can combine Y Z X values to get the result you want - and this can be done (for south east use 45 45 90) but it is a bit of a kludge and the drawbridge twists eccentrically as it lowers (though it arrives correctly!)<br />
<br />
The values are in the range -179 to +180. Positive values give an anti-clockwise opening rotation (looking down from above) and negative values give a clockwise opening rotation. The value 180 is unique in that it continues in an anti-clockwise rotation when closing rather than returning clockwise so might be used if you can think of some object that might need such a motion when frobbed!<br />
<br />
Edit the rotate value by selecting it and using the input box at the bottom and clicking the check(tick) button. That will change the angle the door will open to. Note that the line with the original default of 0 90 0 will still be there but your new entry will be added on a separate line and that is the one that will work in the game. CAUTION: when adjusting later make sure you have your new line selected and not the original! If you do it will appear to change but your first setting will remain unaltered.<br />
<br />
Examples:<br />
* 0 90 0 = Opens anti-clockwise round the entity's 'vertical' to 90 degrees - typical default vertical door.<br />
* 0 0 90 = Lowers a drawbridge from the entity 'vertical' to horizontal.<br />
* 0 0 -45 = Opens clockwise by 45 degrees viewed from the east side. This might suit a skylight in a sloping roof.<br />
<br />
'rotate' cannot be combined with translate motions (see [[#Sliding (Translation) Amount and Direction]]) in one door; you need to bind one door to another and link they by targetting one to the other. By that means you can produce exotic and useful motions. A door opening against an upward-sloping floor can thus have a ''lifting hinge'' and raise up slightly to clear the floor; a door can rotate towards you and slide back to one side very effectively.<br />
<br />
===Sliding (Translation) Amount and Direction===<br />
<br />
By default a Dark Mod door will rotate open. For most sliding doors you want to stop them rotating as well as make them slide. You cannot delete (remove) the ''rotate'' property - you have to set the ''rotate'' property to 0 0 0 to stop a door rotating (see ''Rotate Direction and Open Angle''.)<br />
<br />
Now edit the ''translate'' property value by selecting it (remember to have inherited properties box checked) and using the input box at the bottom and clicking the check(tick) button. That will change the distance the door will slide to. Note that the line with the original default of 0 0 0 will still be there but your new entry will be added on a separate line and that is the one that will work in the game. CAUTION: when adjusting later make sure you have your new line selected and not the original! If you do it will appear to change but your first setting will remain unaltered.<br />
<br />
Typically (but not always) you will want your sliding door to slide the width of the door. The three values in the translate property by default are 0 0 0 and are X Y Z ''absolute map'' values (irrespective of door orientation) where:<br />
<br />
* Positive X = Slide East (Right side of Dark Radiant grid in top view)<br />
* Negative X = Slide West (Left side of Dark Radiant grid in top view)<br />
* Positive Y = Slide North (top of Dark Radiant grid in top view)<br />
* Negative Y = Slide South (bottom of Dark Radiant grid in top view)<br />
* Positive Z = Slide Up (Top of Dark Radiant grid in side views)<br />
* Negative Z = Slide Down (Bottom of Dark Radiant grid in side views)<br />
<br />
So for a 50 unit wide door you want to slide fully to the east you would use 50 0 0 for the translate property values. A 100 unit portcullis sliding vertically up would need 0 0 100 to be fully raised.<br />
<br />
=== Doors Collision/Push Behaviour ===<br />
Doors push all entities by default, except for the player. Doors will also stop moving when anything blocks their movement. However, this default behaviour can be changed by setting appropriate spawnargs:<br />
<br />
Set '''push_player''' to '''1''' to let the player be pushed by this door:<br />
"push_player" "1" // Push the player too (default is off)<br />
<br />
By default '''stop_when_blocked''' is set to 1 and if a door is blocked by an entity then even if the entity is removed afterwards, the door stays where it is. The next frob will close the door.<br />
<br />
Set '''stop_when_blocked''' to '''0''' to prevent the door from ending the opening sequence when anything blocks its way. It will still pause - but continue to open if the block is removed.<br />
"stop_when_blocked" "0" // door keeps moving after being blocked (default is off)<br />
With this setting, doors will still stop at blocking entities (the player, for instance), but will continue to move when the entity moves out of the way.<br />
<br />
There is another spawnarg which stops a door pushing a moveable. Apply this to the ''moveable'', not the door...<br />
<br />
"notPushable" "1"<br />
<br />
===Door Sounds===<br />
<br />
The sound of doors opening and closing is set in the snd_open and snd_close properties. You can silence them by setting the following properties as shown:<br />
<br />
''snd_open nosound''<br><br />
''snd_close nosound''<br />
<br />
Don't just use a dash - as it seems to cause a sound of its own.<br />
<br />
The above sounds are triggered as the door begins to open (eg, unlatch sound) and when it finally closes (eg, slam). For special doors that need an ongoing sound, eg, a big stone slab that moves slowly, then use:<br />
<br />
''snd_move''<br />
The sound played as the door moves.<br />
<br />
''snd_locked''<br><br />
The sound played when a player or an AI tries to open a locked door.<br />
<br />
''snd_unlock string''<br><br />
The sound played when a door is unlocked.<br />
<br />
===Sound Propagation through Doors and Doorways===<br />
<br />
''This information will change significantly with the release of 2.0. See'' [[Controlling Sound Loss Across Portals]]<br />
<br />
<br />
The sound volume reduction to the player (ie, the sound the player hears) is fixed and constant in a cvar which adds a distance factor to the original sound. It is recommended that you do not change that because it will affect other FMs. Currently there is no way to change the way that sound to the player is reduced through doors and doorways.<br />
<br />
<br />
Sound propagation to AI, eg, impact sounds or guard yells is treated separately:<br />
<br />
Sound propagation to AI relies on visportals. For details study [[Sound Propagation: Part 1]] and [[Sound Propagation: Part 2]] as well as [[Visportals]] This tutorial will just cover the relevant sound and sound propagation ''properties'' of doors. If you set the ''show inherited properties'' box in the entity inspector you can see them as described here.<br />
<br />
Remember, the following have no effect on what the player hears through a door or doorway.<br />
<br />
''loss_open''<br><br />
Drop in sound volume in dB propagated to AI (not player) when going through an open door. (default 1dB)<br />
<br />
''loss_closed''<br><br />
Drop in sound volume in dB propagated to AI (not player) when going through a closed door. (default 15dB) You would want to set this very high to block all sound with a thick door but very low for a barred gate for example.<br />
<br />
''loss_double_open''<br><br />
Drop in sound volume in dB propagated to AI (not player) when going through double doors when only one is open. (default 1dB)<br />
<br />
There are also various sound properties for lockpicking:<br><br />
''snd_lockpick_pin_1 through 14'' and ''snd_lockpick_pin_success''<br />
<br />
===Speed of Door Opening and Closing===<br />
<br />
Rotating Door Speed:<br><br />
At the time of writing, the time a rotating door takes to open or close is set in the ''move_time'' property whatever its maximum open angle. So with rotation set at say 150 degrees the door just opens faster than at say 80 degrees. This is likely to be changed to a constant angular velocity so check to see if there a new property added if the following no longer works. The problem is that if an interruptable (see Extra Notes) door is frobbed while in motion it stops; another frob will reverse the motion - so even if the door is only open a crack it will still take the full time to close and vice versa.<br />
<br />
To change the time a rotating door takes to open or close, make sure the door is selected then...<br />
<br />
* Right click the entity inspector and check ''show inherited properties''<br />
* Scroll down, select ''move_time''<br />
* Edit the second line of the input box ''below'' the properties window to the time you want.<br />
* The time is in seconds and decimal fractions can be used.<br />
* The default is 1 second and if set to this then the door opens and closes in one second whatever the maximum open angle, great or small.<br />
<br />
<br />
Sliding Door Speed:<br><br />
The speed of a sliding door is set in the ''translate_speed'' property. To add this, make sure the door is selected then...<br />
<br />
* Right click the entity inspector and check ''show inherited properties''<br />
* Scroll down, select ''translate_speed''<br />
* Edit the second line of the input box ''below'' the properties window to the speed you want.<br />
* The speed is in Dark Radiant grid units per second.<br />
* The default is 0 and if set to this then the door slides open in one second whatever the distance, great or small.<br />
* CAUTION: If you later change the door back to a rotating door then delete the ''translate_speed'' property or ensure it is set to 0 as (at the time of writing but this will be fixed) a bug makes rotating doors open and close instantly. (Note: you can still mix sliding with rotating but check - this bug might only be if ''translate'' is set to 0 0 0)<br />
<br />
===Visportals and Doors===<br />
<br />
A visportal face surrounded by solid at its edges and in contact with a door is closed when the door is closed and enabled when the door is open. In most cases you will place a visportal in contact with a working door unless you can see through the door (such as a true glass door or barred gate*.) For full details see [[Visportals]].<br />
<br />
''*As of 2.0 it is possible to make visportals that remain transparent when closed for gates and windows. See'' [[Controlling Sound Loss Across Portals]]<br />
<br />
==Auto-Closing/Opening Doors==<br />
Doors that automatically close after being open for some time are easy to setup: Each frobmover entity supports these spawnargs:<br />
<br />
;"auto_close_time":Set this to something >= 0 to let the mover automatically close (again) after this time when being fully opened (measured in seconds). Defaults to -1, which means 'do not autoclose'. The event is also activated when the mover starts at the open position at map start.<br />
;"auto_open_time":"Set this to something >= 0 to let the mover automatically open (again) after this time when being fully closed (measured in seconds). Defaults to -1, which means 'do not autoopen'. The event is also activated when the mover starts at the closed position at map start.<br />
<br />
Old text:<br />
<br />
Note that auto-closing doors and AI closing doors behind them, is very much work in progress at the time of writing, so for now, this is another method that works. Check first if true AI closing of doors is working yet before bothering with this!<br />
<br />
I have one door that I particularly want the AI to close as there is a bit of frame lag inside if not. So I set this up and it works good as an auto-closing door - not as good as a true AI closing door as it will auto close when the player goes through as well but it does look very effective to see AI going through and closing the door behind them. Not tested exhaustively so I don't know if there could be any downside. Here's what to do....<br />
<br />
First a quick summary to make it more clear:<br />
<br />
'''''A trigger_relay is used both as a relay AND carries a stim. We put the trigger_relay with its stim in the path of the open door. The door has a response property. When it opens and contacts the stim its response is to send a signal back to the relay. The relay pauses then closes the door...'''''<br />
<br />
* First, optionally give your door a suitable name like autodoor1, whatever.<br />
* Copy that name to the clipboard.<br />
<br />
Next we need a relay with a delay:<br />
<br />
* Create entity > darkmod > trigger_relay<br />
<br />
* Place it roughly at the position the door will be at when open and to be on the safe side 3/4th of the way to the far end of the door (not the hinge end) to give max distance from the close door.<br />
<br />
* Add the property 'target' and paste in the door name you just copied.<br />
<br />
* Give the relay itself a name, eg, autoDoor_relay_1, and copy that name to the clipboard, you'll need that too in a bit.<br />
<br />
* Add the property delay and the value 3 - this is the delay in seconds before the door will close; 3 seems about right but 2 might be worth a try because to that 3 is added a random value between 0 to 0.5 seconds from the Time Interval we entered for the stim firings.<br />
<br />
* Add the property 'wait' and the value 3. This is the time before it can work again in seconds. If you set it too low then in theory the door might trigger again but in this situation I don't think it's possible. Too long, eg, one minute, and it won't work if the AI goes back through the door before then. If this value is -1 then the whole thing will only work ONCE so might be used for an AI who goes through once, closes it behind him, but you don't want it to be an autodoor thereafter.<br />
<br />
<br />
That's the relay, now we add a stim to it:<br />
<br />
* Still with the trigger relay selected, go to {{menu|Entity|Stim/Response}}<br />
<br />
* Custom stim tab.<br />
<br />
* Click Add stim type, select the new custom stim type you just made at the bottom of the list and type in eg, autoDoorStim at top right in the input box.<br />
<br />
* Click the stim tab and the little drop down arrow against the 'type' selector at bottom left and you should see your new custom stim name. Select it.<br />
<br />
* Select the new autoDoorStim in the list and on the right you need only type in the radius box 15.0 There is quite a lot of room for error. I had it working on 10 and also on 25. The value should be less than the distance to the closed door else it will trigger open! But no so small that the door might not reach it.<br />
<br />
* Select the check box for Time Interval and enter 500 (millisecs.) This is so it doesn't keep firing more frequently than is necessary. This stim will be firing all through your mission whether the door is used or not so if you had dozens of these then maybe it would affect performance. Too big a number and there may be a long delay before the door shuts - but it will be random depending on the next time the stim happens to fire. We'll control the delay we want more precisely later.<br />
<br />
* Click {{ok}} to confirm it.<br />
<br />
<br />
That's the stim set up, now for the response to it which is put on the door....<br />
<br />
* Select the doorm, then use {{menu|Entity|Stim/response}} and select the response tab.<br />
<br />
* Click the little drop down arrow against the 'type' selector at bottom left and you should see your new custom stim name. Select it.<br />
<br />
* Right click in the big ''Response Effects'' box on the bottom right of the panel.<br />
<br />
* Add New Effect and you should get a default 'Activate Response' response added to the list. Double click it.<br />
<br />
* In the Effect selector at the stop select 'Trigger'<br />
<br />
* in the Target box, paste in the name of the relay you copied or you can select it from the list at the little arrow.<br />
<br />
* Leave the Activator box empty.<br />
<br />
* Click {{apply}} and then {{ok}} on the main S & R panel bottom right.<br />
<br />
It should now work. No need to wait for an AI, just frob the door and watch it close itself. If not, check the position of the stim brush is close to where the door stops when open.<br />
<br />
==AI Door management==<br />
<br />
See also [[#Keys_carried_by_AI]] above.<br />
<br />
By default AI will open doors and close them behind them. Here are some spawnargs the mapper can use to modify that behaviour:<br />
<br />
;"ai_should_not_handle" :If set to 1, AI will not attempt to handle it and add it to the forbidden areas when closed (so that it doesn't try to path through). They might still walk through the door when it is open though. Useful if you have some special use door that you don't want the AI to operate.<br />
<br />
;"ai_should_not_close" :If set to 1, AI will not close the door behind them unless it obstructs them.<br />
<br />
;"canRemainOpen" :If set to 1, it's the same as "ai_should_not_close, with the added behavior that this is ignored if the door needs to be relocked, or the door is marked "shouldBeClosed". '''(This spawnarg is available starting in TDM 2.02.)'''<br />
<br />
<br />
To get AI to unlock/relock specific doors there are two methods currently:<br />
<br />
1. add the following spawnarg/value to the AI:<br />
<br />
;"can_unlock1" ''<doorname>''<br />
<br />
'''Do NOT use can_unlock_1.'''<br />
<br />
For additional doors on the same AI use ''can_unlock2 doorname'' etc.<br />
<br />
<br />
2. In the editor position an actual key that works for that door on the AI and also add to the key bind <AIname> and also bindToJoint LeftHips_Dummy (see other joints names elsewhere in wiki.) Currently, if the player pickpockets the key then the AI seeks an alternate route but otherwise does nothing (?) This may be upgraded in the future to better strategies.<br />
<br />
3. There is the possibility in the future of an additional method which would just use special attach spawnargs to make the above easier. The key would spawn at the correct position at game start. Watch this space.<br />
<br />
<br />
===Door Handling Positions===<br />
<br />
It is also possible to set custom door handling positions for the AI. This is especially useful when the standard routine that lets the AI choose their standing positions while opening and closing the door fails, leaving them circling around in front of the door helplessly.<br />
<br />
Place a movers > ''atdm:door_handling_position'' entity where you want the AI to stand while opening/closing the door from this side.<br />
<br />
On the door, you need to set the spawnarg "door_handle_position" "name_of_door_handling_position". You can also place a ''door_handling_position'' on each side of the door, and the AI will automatically choose the right one. In this case, you need to set spawnargs with "door_handle_position_1" etc., and the corresponding names of the ''door_handling_position'' entities on the door.<br />
<br />
The ''door_handling_position'' entities can also carry spawnargs that define the behaviour of the AI, which are useful for example for doors that can only be opened or locked from one side:<br />
<br />
'''"ai_no_open"''' If set to true, the AI will not try to open the door from this side (but will still walk through when the door is already open).<br />
<br />
'''"ai_no_close"''' If set to true, the AI will not attempt to close the door from this side.<br />
<br />
'''"ai_no_unlock"''' If set true, the AI will not be able to unlock the door from this side, but still use it when it is not locked.<br />
<br />
'''"ai_no_lock"''' If this is set true, the AI will not lock the door from this side.<br />
<br />
===Door Controllers===<br />
<br />
'''Available in TDM 2.02+'''<br />
<br />
You can design a door so it's operated by buttons or levers or switches (aka ''controllers''):<br />
<br />
1. Set up the door in the normal manner. It can be a rotating door, a sliding door, a locked door, etc.<br />
<br />
2. Turn off the "frobable" spawnarg on the door. ("frobable" "0")<br />
<br />
3. Create a controller on each side of the door. If you're setting up a locked door, there's no need to put any locking information on the controllers.<br />
<br />
4. Give each controller the door as a target. (Alternatively, you can give the door these spawnargs: "door_controller1" "<name of controller 1>", "door_controller2" "<name of controller 2>".)<br />
<br />
When the game starts, it will transfer any locking information from the door to the controllers.<br />
<br />
Both the player and any AI that wants to use the door will use the controllers to operate it. Any key, "can_unlock", or lockpick settings you would normally use at the door are now used at the controllers.<br />
<br />
Controllers and ''door_handling_position'' entities can be used on the same door, but in that situation the ''door_handling_position'' entities don't define where the AI stands to operate the door. They simply provide the "ai_no_*" spawnargs that define AI behavior on each side of the door.<br />
<br />
You may have a controller on only one side of the door. Note that, since the door is not frobable, the player and the AIs won't be able to operate the door from the non-controller side, even if that side has a ''door_handling_position'' entity.<br />
<br />
===AI locking doors behind them===<br />
<br />
If one AI is involved (no one else is in the queue), he'll lock it behind him if he had to unlock it in the first place.<br />
<br />
Prior to TDM 1.08, if more than one AI is using the door at the same time (there's a queue), the first AI unlocks the door, and the last AI through will only lock it if it's marked "should_always_be_locked" AND they have a "can_unlock" for that door or they have a key for that door. The last AI to use the door doesn't know that the first AI found it locked, because that info is kept per AI, and not per door. <br />
<br />
Starting in TDM 1.08, if the first AI in a door queue found the door locked, that information is remembered by the door and the last AI through uses it to relock the door, as long as they have a "can_unlock" for that door or they have a key for that door.<br />
<br />
In the rare case where a door is set up to use door-handling position entities (necessary for AI to use sliding doors), either or both of those entities can have the "ai_no_lock" spawnarg, which means AI aren't allowed to lock the door from that side.<br />
<br />
==Doors as Triggers==<br />
<br />
''by Ishtvan & greebo''<br />
<br />
Doors (or any binary frob mover, buttons, levers, etc) now have the option to [[Triggers|trigger]] their target on closing or opening. (For definition purposes, a button is defined as "closed" in the state when it starts out and "open" in the state you press it down to. I know that's a little non-intuitive, but it came from deriving from doors).<br />
<br />
New spawnargs on frob movers:<br />
;"trigger_on_open" :If set to 1, this binary mover will trigger its targets when it starts out completely closed and is opened.<br />
;"trigger_when_opened":If set to 1, this binary mover will trigger its targets when it is completely opened. Code defaults to 0.<br />
;"trigger_on_close":If set to 1, this binary mover will trigger its targets when it completely closes after being open.<br />
<br />
== Suspicious Doors ==<br />
<br />
If you give a door the spawnarg '''"shouldBeClosed" "1"''', then AI will treat it as suspicious if they find the door open.<br />
<br />
Doors with that spawnarg should work like this:<br />
<br />
- an AI opening the door knows he's not to become suspicious if he opened the door<br />
<br />
- nearby AI alerted by the open door will also not react if they can see the door, and can see the AI that opened it<br />
<br />
- AI who come upon the open door later probably won't be able to see the AI that opened it, so they'll treat it as suspicious<br />
<br />
- if the AI who opened the door comes upon the door later, and it's still open, and no one's touched it since he opened it, he'll see his name on the door and won't become suspicious. "Oh, crap. I forgot to close it earlier."<br />
<br />
- If an AI comes upon an open door that should be closed, he should close it whether he becomes suspicious or not.<br />
<br />
'''Post TDM 2.00:'''<br />
- AI turn to look at a door they see opening. The player can crack open a suspicious door to peek out w/o grabbing the attention of a nearby AI. After 5s, the AI will notice the cracked open door. Non-suspicious doors can be cracked open indefinitely w/o nearby AI noticing.<br />
<br />
==Skins: A Wide Variety of Door Textures==<br />
<br />
This is to remind you that as with many Dark Mod models, there is a wide range of extras skins (textures) available for door models. There are now several basic door entities of different sizes so choose your size first. Then enter the spawnarg: skin with any temporary value. Now select it and click the skin button at the bottom of Dark Radiant's Entity Inspector and you will find a large of range of skin textures from which to select to give you a choice of appearances for your door.<br />
<br />
<br />
<br />
==Extra Notes==<br />
The property ''interruptable'' determines whether a door can be stopped by frobbing while it is opening or closing. So by frobbing then frobbing again, the player can open a door to any position, eg, slightly ajar to peek through.<br />
<br />
''func_darkmod_door'' is no longer used (just in case you come across it in the Dark Mod forums or wiki.) '''<code>atdm:mover_door</code>''' is the entity to use.<br />
<br />
{{tutorial-editing}}</div>RJFerrethttps://wiki.thedarkmod.com/index.php?title=Conversation_Tutorial&diff=17820Conversation Tutorial2014-07-07T21:02:20Z<p>RJFerret: /* Triggering */ wikilink</p>
<hr />
<div>Presumably your AI are pathing along, minding their own business, when you want them to interact, say something specific, or glance at one another. Here's how to set that up, step by step... ([[Conversations]] are more than just talk, they may control movement, animations, or other things.)<br />
<br />
<br />
= Triggering =<br />
First they have to run into a [[Triggers|trigger]] to initiate a "conversation", either as the target of a [[Path Nodes|path node]] (as of TDM 2.02), another trigger entity, a stim/response trigger, or equivalent.<br />
<br />
The trigger targets an "atdm:target_startconversation" entity (found in targets folder). That entity gets the spawnarg "conversation" "whatever" (substitute "whatever" with a label to identify this conversation compared to future ones in the list).<br />
<br />
=Sounds/Lines=<br />
Before you jump in, you will need to type in which soundshaders you will be using if you want them to talk. So if you haven't already picked your lines, pop in a temporary Speaker and get the names of the [[Sound_Folder_Structure|soundshaders]] you'll want to use.<br />
<br />
For example, I have an AI greet a horse with "tdm_ai_wench_greet_civilian_to_civilian", to which the horse whinnies via "animal_horse_idle", then she commiserates to it from, "tdm_ai_wench_idle". If you desire a specific line, or custom, you'll have to create your own soundshader (a text file listing an audiofile).<br />
<br />
=Conversation Editor window=<br />
Now enter the Conversation Editor (map menu), which will create an entity if you don't already have one, be sure it's not placed in the void!<br />
<br />
Click +Add down at the bottom to create a new conversation, then edit it. You'll notice toward the top, "Actors must be within talk distance" and "always facing", these cause them to move toward each other, and/or turn when the conversation is triggered, not that the conversation waits until they are in range. +Add an actor (you may have just one, or multiple AI interacting), it's/their names go here to identify who does what/when in the next step.<br />
<br />
Now in the bottom you may add commands, which run in sequence (generally). You may choose for one to not wait, in which case the next will occur perhaps before the current completes. This can be good to have AI talk more naturally overlapping, rather than a lengthy pause between each spoken line.<br />
<br />
Typical commands are "Talk" to say something (paste in a soundshader name you noted earlier), look at something or someone (including player1), wait a few seconds, etc. For example, my wench looks at the horse, says her line, the horse whinnies in reply, then she delivers her final line. That's it, now check to see how it works out in game.<br />
<br />
(Note: if you want to mute your AI generally, so they don't use their usual vocalizations the rest of the time (perhaps not making sense leading in or out of your conversation), change "def_vocal_set" to "atdm:ai_vocal_set_mute".)<br />
<br />
=See also=<br />
[[Conversations]]<br />
<br />
[[Cutscenes Part 3: Lighting, Placing the Player, and Conversations#Conversations]]<br />
<br />
[[Category:Tutorial]]</div>RJFerrethttps://wiki.thedarkmod.com/index.php?title=Conversations&diff=17819Conversations2014-07-07T21:00:20Z<p>RJFerret: /* Triggering a Conversation */ that's what I get for not previewing</p>
<hr />
<div>Conversations between AI have a HUGE impact on player immersion, and they're not hard to do.<br />
<br />
If you have no way to record dialogue, you can always look through the vocal sets...it's quite possible to create short conversations with barks that already exist.<br />
<br />
== Overview ==<br />
All the info regarding a conversation is contained within a [[atdm:conversation_info]] entity. Each of these entities can define one or more conversations. There is a custom conversation editor GUI for [[DarkRadiant]] (on the map menu), which is the easiest way to make and edit them; but you can add these entities yourself and set the spawnargs manually if you wish. <br />
<br />
For instructions on how to use the conversation editor, see: [[Cutscenes Part 3: Lighting, Placing the Player, and Conversations]] or [[Conversation Tutorial]].<br />
<br />
Each conversation can have one or more ''Actors''. These are the AI which will participate in the conversation.<br />
<br />
Each conversation consists of a sequence of so-called ''Conversation Commands'', which are specific actions you can use to make the ''actors'' do what you want them to. Examples are "Talk", "Attack", "WalkToEntity", etc. You can add as many conversation commands as you like.<br />
<br />
=== Add a Conversation Info entity ===<br />
Right-click somewhere in the grid view and hit "Create Entity" which will open the dialog for selecting the [[Entity Class|entity classes]]. Go to Conversation and select '''[[atdm:conversation_info]]'''.<br />
<br />
(Note, make sure the entity isn't 'in the void' or you will get a leak in your map. Otherwise, it doesn't matter where the entity is placed.)<br />
<br />
=== Add the conversation spawnargs ===<br />
Once the entity is created you can start defining your conversation. The easiest way is to use the conversation editor. <br />
<br />
Here is an example of a simplistic "conversation" containing exactly one command:<br />
"conv_1_name" "Testconversation 1" // defines the name of the conversation (mandatory)<br />
"conv_1_actor_1" "atdm:ai_builder_guard_1" // first actor<br />
"conv_1_actor_2" "atdm:ai_builder_guard_2" // second actor<br />
<br />
// Here's the first conversation command (defined as ''cmd_1'')<br />
"conv_1_cmd_1_actor" "1" // Actor 1 takes this action<br />
"conv_1_cmd_1_type" "Talk" // the action is "Talk" (uppercase T is required)<br />
"conv_1_cmd_1_arg_1" "tdm_test_conversation_1_1" // play the sound shader: 'tdm_test_conversation_1_1'<br />
<br />
So basically, this conversation has a name ''Testconversation 1'', two actors (builder_guard_1 and 2) and lets the actor 1 play the sound shader ''tdm_test_conversation_1_1''.<br />
<br />
As you can see, the naming convention for the spawnargs is like this:<br />
conv_<number>_<key><br />
<br />
The purpose of ''<number>'' is to distinguish multiple conversations defined on the same conversation info entity. You can use a single entity for all the conversations in your map if you wish, although you'll probably want to keep them separate in order to trigger them at different times (see below). <br />
<br />
The <key> is then defining the properties and commands of this conversation. Each conversation can have multiple commands, that's why these spawnargs are equipped with indices as well ("conv_1_cmd_N_...").<br />
<br />
The above example is defining a command called ''Talk''. There are more ''conversation commands'' available, each having a varying number of arguments. See the section below for details.<br />
<br />
Each conversation ''must'' have a name and at least one actor and one command, otherwise the parser will flag the conversation as invalid and it will therefore be ignored.<br />
<br />
''Note:'' The <number> value is always numeric and starts with 1.<br />
<br />
== Spawnargs ==<br />
=== Conversation ===<br />
These spawnargs can be used to define properties that affect the conversation as a whole.<br />
<br />
The first two MUST be set by the mapper; the rest have defaults and only need to be changed if you want a non-standard result.<br />
<br />
The uppercase N indicates the conversation number (starting from 1).<br />
;'''conv_N_name''' (string)<br />
: defines the name of the conversation. This is a mandatory spawnarg, a conversation without a name will be ignored.<br />
;'''conv_N_actor_Y''' (entity name)<br />
: define the names of the AI participating in this conversation. At least one actor is required, otherwise the conversation is invalid.<br />
<br />
<br />
'''The following are optional:'''<br />
<br />
;'''conv_N_actors_must_be_within_talkdistance''' (1/0) default is 1<br />
: if set to "1", all actors are told to walk towards each other before the conversation actually starts.<br />
;'''conv_N_talk_distance''' (float) default is 60<br />
: defines the maximum distance AI should be away from each other while talking. When the spawnarg '''actors_must_be_within_talkdistance''' is set to 1, this distance tells the AI when to stop when walking towards each other.<br />
;'''conv_N_actors_always_face_each_other_while_talking''' (1/0) default is 1<br />
: if set to "1", all actors are facing each other while talking. The talker turns towards another actor (usually the actor 0 or 1), and all other actors (the listeners) turn to face the talker.<br />
;'''conv_N_max_play_count''' (int) default is -1<br />
: defines the maximum number of times this conversation is allowed to "play". After this number has been exhausted, the conversation won't be started anymore.<br />
;'''conv_N_cmd_Y_...'''<br />
: the conversation commands (see below). One conversation must have at least one and is allowed to have multiple conversation commands.<br />
<br />
=== Conversation Commands ===<br />
These spawnargs are used to tell the actors what to do during the conversation.<br />
<br />
The prefix <tt>conv_N_</tt> refers to the conversation these commands are associated with. The number M refers to the command number (starting at 1).<br />
;'''conv_N_cmd_M_actor''' (integer actor number, starting from 1)<br />
: defines which actor should perform this command. Use the "Actor Number" you assigned earlier. Note that the value of this spawnarg is a number X referring to the <tt>conv_N_actor_X</tt> definition above. You address a conversation's actor by this number, ''not'' by its name. ;'''conv_N_cmd_M_type''' (string == command type name)<br />
: defines the type of command you want to give (this is a mandatory spawnarg, each command must have a type). The most common is probably "Talk". See below for a list of available type names. ''Ex: "conv_1_cmd_1_type" "Talk" '' <br />
<br />
;'''conv_N_cmd_M_wait_until_finished''' (1/0), default is 1 (note: default is 0 in the editor)<br />
: defines whether the conversation should wait for the actor to complete this command before the next command is executed. Setting this to "0" allows to step over to the next command with nearly no time loss. This can be used to issue two or more commands at virtually the same time to an actor, so that the commands "Talk" and "PlayAnimOnce" are executed side-by-side by the same AI, for instance.<br />
Note: I set a single conversation for an AI to walk to an entity. This failed unless this spawnarg was set to 1 so possibly the last command in the list needs it?<br />
;'''conv_N_cmd_M_arg_L'''<br />
:defines the arguments of this conversation command. The actual arguments depend on the command type, each type is requiring a different amount of arguments, and some of them are optional. See below for a description of the command's arguments. The index L starts at the number 1, there is no upper limit imposed by the code.<br />
<br />
== Triggering a Conversation ==<br />
<br />
Now that your conversation is created, you need to trigger it.<br />
<br />
To trigger a conversation you need to create a ''target_tdm_startconversation'' entity. Give it the spawnarg "conversation" with the name of the conversation you want to start (ex "conversation" "Testcoversation 1") then target that entity from any trigger you like such as a trigger_once entity or [[Path Nodes|path node]] (as of TDM v2.02).<br />
<br />
== Conversation Commands ==<br />
The following is a list of available conversation commands:<br />
*'''WaitSeconds'''<br />
: Lets the actor wait the given amount of seconds. Note that the <tt>wait_until_finished</tt> property is not affecting this command (would be pointless).<br />
:*Argument 1: (float) The amount of seconds to wait.<br />
*'''WalkToActor'''<br />
: Lets the actor walk to another actor, which must be participating in this conversation.<br />
:* Argument 1: (integer) The actor number of the AI to walk to.<br />
:* Argument 2: (optional float) The distance at which the actor stops "before" the actor. This value is optional and defaults to 50.<br />
*'''WalkToPosition'''<br />
: Lets the actor walk to the given position.<br />
:* Argument 1: (vector) The world position to walk to (e.g. "-32 4 196").<br />
*'''WalkToEntity'''<br />
: Lets the actor walk to the given entity.<br />
:* Argument 1: (string) The name of the entity to walk to.<br />
:* Argument 2: (optional float) The distance at which the actor stops "before" the entity. This value is optional and defaults to 50.<br />
*'''StopMove'''<br />
: Tells the entity to stop its current movement (no arguments).<br />
*'''Talk'''<br />
: Lets the actor talk a given string.<br />
:* Argument 1: (string) The sound shader to play<br />
:* Argument 2: (optional string) The language string to display as subtitle in the <tt>#str_9NNNN</tt> format. Conversation strings should start in the 9xxxx number range and are defined in the strings/*.lang file. ''Note: this feature is not yet implemented''.<br />
*'''PlayAnimOnce'''<br />
: Lets the actor play an animation once.<br />
:* Argument 1: (string) the name of the animation to play (see the actor's [[modelDef]] file)<br />
:* Argument 2: (optional integer) the number of blendframes to use when switching anims. This is optional and defaults to 4.<br />
*'''PlayAnimCycle'''<br />
: Lets the actor play an animation over and over. Note that the property <tt>wait_until_finished</tt> is not allowed here, as this command never stops, so execution will immediately proceed to the next command.<br />
:* Argument 1: (string) the name of the animation to play (see the actor's [[modelDef]] file)<br />
:* Argument 2: (optional integer) the number of blendframes to use when switching anims. This is optional and defaults to 4.<br />
*'''ActivateTarget'''<br />
:Triggers the given entity.<br />
:* Argument 1: (string) the name of the entity to trigger.<br />
*'''LookAtActor'''<br />
:Lets the actor look at another actor (must be participating in the conversation).<br />
:* Argument 1: (integer) the actor number of the AI to look at.<br />
:* Argument 2: (optional float) the "look duration" in seconds, the head is turning back to its previous position afterwards. This is optional and defaults to 5 seconds.<br />
*'''LookAtPosition'''<br />
:Lets the actor look at the given position.<br />
:* Argument 1: (vector) the world position to look at (e.g. "-32 4 196").<br />
:* Argument 2: (optional float) the "look duration" in seconds, the head is turning back to its previous position afterwards. This is optional and defaults to 5 seconds.<br />
*'''LookAtEntity'''<br />
:Lets the actor look at the given entity.<br />
:* Argument 1: (string) the name of the entity to look at.<br />
:* Argument 2: (optional float) the "look duration" in seconds, the head is turning back to its previous position afterwards. This is optional and defaults to 5 seconds.<br />
*'''TurnToActor'''<br />
: Lets the actor turn towards the given actor, which must participate in this conversation too (the whole body is rotated towards the actor). This command has no duration, so the property <tt>wait_until_finished</tt> is effectless here.<br />
:* Argument 1: (integer) the actor number of the AI to turn towards.<br />
*'''TurnToPosition'''<br />
: Lets the actor turn towards the given position (the whole body is affected). This command has no duration, so the property <tt>wait_until_finished</tt> is effectless here.<br />
:* Argument 1: (vector) the position in world coordinates which the actor should turn towards (e.g. "-32 4 196").<br />
*'''TurnToEntity'''<br />
: Lets the actor turn towards the given entity (whole body is affected). This command has no duration, so the property <tt>wait_until_finished</tt> is effectless here.<br />
:* Argument 1: (string) the entity to turn towards.<br />
*'''AttackActor'''<br />
: Lets the actor attack the other actor (which must be partipicating in this conversation as well). This command has no duration, so the property <tt>wait_until_finished</tt> is effectless here.<br />
:* Argument 1: (integer) the actor number of the AI to attack.<br />
*'''AttackEntity'''<br />
: Lets the actor attack the given entity (which can be any other AI or any other player). This command has no duration, so the property <tt>wait_until_finished</tt> is effectless here.<br />
:* Argument 1: (string) the entity to attack (e.g. "player1").<br />
*'''InteractWithEntity'''<br />
: Lets the actor walk to an entity, play the "use" anim and trigger the entity's frobaction script. Doors will be opened, buttons be pushed, etc.<br />
:* Argument 1: (string) the entity to interact with.<br />
*'''RunScript'''<br />
: Runs a local or global script function. Local script functions (those defined on the actor's scriptobject) must not take any arguments, global scriptfunctions must take an <tt>entity</tt> as argument (the actor will be passed as "owner" to this global function). Note that if <tt>wait_until_finished</tt> is set to "1" the command will not finish until the script is completely done (i.e. non-terminating eachFrame loops within the script function would cause this command to last forever).<br />
:* Argument 1: (string) the name of the local or global script function.<br />
*'''WaitForActor'''<br />
: Lets the actor wait until the other actor (specified in the first argument) has finished executing his current conversation command. If the other actor is already done with his command, WaitForActor does nothing.<br />
:* Argument 1: (integer) the actor number of the AI to wait for.<br />
*'''WaitForAllActors'''<br />
: Lets the conversation wait until all actors are finished executing their commands. Afterwards the conversation is allowed to continue with the next command.<br />
:* no arguments<br />
<br />
== How to get AI to patrol after finishing a conversation ==<br />
<br />
''Sometimes you want AI to stay put until their conversation is triggered, and then start a regular patrol. Here's one way how(courtesy of grayman), see another below in Notes:''<br />
<br />
Guards Bob and Sam will have the conversation. Neither is targetted at any path_corners.<br />
<br />
When the conversation is over, you want Bob to start patrolling, starting with path_corner_1.<br />
<br />
When the conversation is over, you want Sam to start patrolling, starting with path_corner_2.<br />
<br />
A player-activated trigger fires the entity that starts the conversation.<br />
<br />
In the conversation, have these two steps at or near the end:<br />
<br />
Trigger the entity StartBobPatrol<br />
<br />
Trigger the entity StartSamPatrol<br />
<br />
"StartBobPatrol" is an atdm:target_changetarget with these spawnargs:<br />
<br />
"add" "path_corner_1"<br />
"target" "Bob"<br />
<br />
"StartSamPatrol" is an atdm:target_changetarget with these spawnargs:<br />
<br />
"add" "path_corner_2"<br />
"target" "Sam"<br />
<br />
When the conversation ends, both guards will go their separate ways.<br />
<br />
== Notes ==<br />
* It's possible to define conversations with only one actor. This can be used to let AI talk a single sentence or perform some other actions.<br />
* The flags <tt>actors_must_be_within_talkdistance</tt> and <tt>actors_always_face_each_other_while_talking</tt> have no effect when only one actor is present in the conversation. The flags are automatically set to 0 in the code.<br />
* Starting with 1.08, an actor who begins a conversation sitting on a path_waitfortrigger can be moved off that trigger at the end of the conversation by having the last step in the conversation activate a trigger_once whose target is the actor, and which has a 'delay' spawnarg set to at least 1 second. W/o the delay, the actor will ignore the activation and remain where they are.<br />
* Simpler to walk off might be to have the last command in your conversation trigger an atdm:target_changetarget. In that entity, give it these spawnargs: "target" "<name of AI who's leaving>" and "add" "<name of path_corner you want him to walk to>"<br />
<br />
== Volume of Custom Lines ==<br />
The soundshader files for unique lines control how far the sound reaches and volume, it's not set within the editor.<br />
minDistance 1<br />
maxDistance 25<br />
volume 1<br />
Regular AI spoken lines have maxDistance 25, yells 30.<br />
<br />
== Debugging Conversations ==<br />
There are several possibilities to debug conversations, in case something isn't working correctly:<br />
* The CVAR '''tdm_ai_show_conversationstate''' (when set to 1) draws the current conversation command and its execution state on all AI which are currently involved in conversations.<br />
* Another way to check if things go wrong is the console. During map load the number of valid conversations found in the map is verbosed to the console, so be sure to check if this number is right. If this number differs from the number you should have, you probably have your spawnargs wrong. Warnings might also be printed to the console if things go wrong during the execution of conversation commands.<br />
* The log file gives you some insight what is happening in the conversation code during map load and during the actual conversations. Open your <tt>darkmod.ini</tt> file and set <tt>LogClass_CONVERSATION</tt> to 1 to enable conversation logging. Also, be sure to enable the various log types (ERROR, DEBUG, WARNING and INFO) to see all the messages.<br />
<br />
{{editing}}</div>RJFerrethttps://wiki.thedarkmod.com/index.php?title=Conversations&diff=17818Conversations2014-07-07T20:59:55Z<p>RJFerret: /* Triggering a Conversation */</p>
<hr />
<div>Conversations between AI have a HUGE impact on player immersion, and they're not hard to do.<br />
<br />
If you have no way to record dialogue, you can always look through the vocal sets...it's quite possible to create short conversations with barks that already exist.<br />
<br />
== Overview ==<br />
All the info regarding a conversation is contained within a [[atdm:conversation_info]] entity. Each of these entities can define one or more conversations. There is a custom conversation editor GUI for [[DarkRadiant]] (on the map menu), which is the easiest way to make and edit them; but you can add these entities yourself and set the spawnargs manually if you wish. <br />
<br />
For instructions on how to use the conversation editor, see: [[Cutscenes Part 3: Lighting, Placing the Player, and Conversations]] or [[Conversation Tutorial]].<br />
<br />
Each conversation can have one or more ''Actors''. These are the AI which will participate in the conversation.<br />
<br />
Each conversation consists of a sequence of so-called ''Conversation Commands'', which are specific actions you can use to make the ''actors'' do what you want them to. Examples are "Talk", "Attack", "WalkToEntity", etc. You can add as many conversation commands as you like.<br />
<br />
=== Add a Conversation Info entity ===<br />
Right-click somewhere in the grid view and hit "Create Entity" which will open the dialog for selecting the [[Entity Class|entity classes]]. Go to Conversation and select '''[[atdm:conversation_info]]'''.<br />
<br />
(Note, make sure the entity isn't 'in the void' or you will get a leak in your map. Otherwise, it doesn't matter where the entity is placed.)<br />
<br />
=== Add the conversation spawnargs ===<br />
Once the entity is created you can start defining your conversation. The easiest way is to use the conversation editor. <br />
<br />
Here is an example of a simplistic "conversation" containing exactly one command:<br />
"conv_1_name" "Testconversation 1" // defines the name of the conversation (mandatory)<br />
"conv_1_actor_1" "atdm:ai_builder_guard_1" // first actor<br />
"conv_1_actor_2" "atdm:ai_builder_guard_2" // second actor<br />
<br />
// Here's the first conversation command (defined as ''cmd_1'')<br />
"conv_1_cmd_1_actor" "1" // Actor 1 takes this action<br />
"conv_1_cmd_1_type" "Talk" // the action is "Talk" (uppercase T is required)<br />
"conv_1_cmd_1_arg_1" "tdm_test_conversation_1_1" // play the sound shader: 'tdm_test_conversation_1_1'<br />
<br />
So basically, this conversation has a name ''Testconversation 1'', two actors (builder_guard_1 and 2) and lets the actor 1 play the sound shader ''tdm_test_conversation_1_1''.<br />
<br />
As you can see, the naming convention for the spawnargs is like this:<br />
conv_<number>_<key><br />
<br />
The purpose of ''<number>'' is to distinguish multiple conversations defined on the same conversation info entity. You can use a single entity for all the conversations in your map if you wish, although you'll probably want to keep them separate in order to trigger them at different times (see below). <br />
<br />
The <key> is then defining the properties and commands of this conversation. Each conversation can have multiple commands, that's why these spawnargs are equipped with indices as well ("conv_1_cmd_N_...").<br />
<br />
The above example is defining a command called ''Talk''. There are more ''conversation commands'' available, each having a varying number of arguments. See the section below for details.<br />
<br />
Each conversation ''must'' have a name and at least one actor and one command, otherwise the parser will flag the conversation as invalid and it will therefore be ignored.<br />
<br />
''Note:'' The <number> value is always numeric and starts with 1.<br />
<br />
== Spawnargs ==<br />
=== Conversation ===<br />
These spawnargs can be used to define properties that affect the conversation as a whole.<br />
<br />
The first two MUST be set by the mapper; the rest have defaults and only need to be changed if you want a non-standard result.<br />
<br />
The uppercase N indicates the conversation number (starting from 1).<br />
;'''conv_N_name''' (string)<br />
: defines the name of the conversation. This is a mandatory spawnarg, a conversation without a name will be ignored.<br />
;'''conv_N_actor_Y''' (entity name)<br />
: define the names of the AI participating in this conversation. At least one actor is required, otherwise the conversation is invalid.<br />
<br />
<br />
'''The following are optional:'''<br />
<br />
;'''conv_N_actors_must_be_within_talkdistance''' (1/0) default is 1<br />
: if set to "1", all actors are told to walk towards each other before the conversation actually starts.<br />
;'''conv_N_talk_distance''' (float) default is 60<br />
: defines the maximum distance AI should be away from each other while talking. When the spawnarg '''actors_must_be_within_talkdistance''' is set to 1, this distance tells the AI when to stop when walking towards each other.<br />
;'''conv_N_actors_always_face_each_other_while_talking''' (1/0) default is 1<br />
: if set to "1", all actors are facing each other while talking. The talker turns towards another actor (usually the actor 0 or 1), and all other actors (the listeners) turn to face the talker.<br />
;'''conv_N_max_play_count''' (int) default is -1<br />
: defines the maximum number of times this conversation is allowed to "play". After this number has been exhausted, the conversation won't be started anymore.<br />
;'''conv_N_cmd_Y_...'''<br />
: the conversation commands (see below). One conversation must have at least one and is allowed to have multiple conversation commands.<br />
<br />
=== Conversation Commands ===<br />
These spawnargs are used to tell the actors what to do during the conversation.<br />
<br />
The prefix <tt>conv_N_</tt> refers to the conversation these commands are associated with. The number M refers to the command number (starting at 1).<br />
;'''conv_N_cmd_M_actor''' (integer actor number, starting from 1)<br />
: defines which actor should perform this command. Use the "Actor Number" you assigned earlier. Note that the value of this spawnarg is a number X referring to the <tt>conv_N_actor_X</tt> definition above. You address a conversation's actor by this number, ''not'' by its name. ;'''conv_N_cmd_M_type''' (string == command type name)<br />
: defines the type of command you want to give (this is a mandatory spawnarg, each command must have a type). The most common is probably "Talk". See below for a list of available type names. ''Ex: "conv_1_cmd_1_type" "Talk" '' <br />
<br />
;'''conv_N_cmd_M_wait_until_finished''' (1/0), default is 1 (note: default is 0 in the editor)<br />
: defines whether the conversation should wait for the actor to complete this command before the next command is executed. Setting this to "0" allows to step over to the next command with nearly no time loss. This can be used to issue two or more commands at virtually the same time to an actor, so that the commands "Talk" and "PlayAnimOnce" are executed side-by-side by the same AI, for instance.<br />
Note: I set a single conversation for an AI to walk to an entity. This failed unless this spawnarg was set to 1 so possibly the last command in the list needs it?<br />
;'''conv_N_cmd_M_arg_L'''<br />
:defines the arguments of this conversation command. The actual arguments depend on the command type, each type is requiring a different amount of arguments, and some of them are optional. See below for a description of the command's arguments. The index L starts at the number 1, there is no upper limit imposed by the code.<br />
<br />
== Triggering a Conversation ==<br />
<br />
Now that your conversation is created, you need to trigger it.<br />
<br />
To trigger a conversation you need to create a ''target_tdm_startconversation'' entity. Give it the spawnarg "conversation" with the name of the conversation you want to start (ex "conversation" "Testcoversation 1") then target that entity from any trigger you like such as a trigger_once entity or [[Path Node|path node]] (as of TDM v2.02).<br />
<br />
== Conversation Commands ==<br />
The following is a list of available conversation commands:<br />
*'''WaitSeconds'''<br />
: Lets the actor wait the given amount of seconds. Note that the <tt>wait_until_finished</tt> property is not affecting this command (would be pointless).<br />
:*Argument 1: (float) The amount of seconds to wait.<br />
*'''WalkToActor'''<br />
: Lets the actor walk to another actor, which must be participating in this conversation.<br />
:* Argument 1: (integer) The actor number of the AI to walk to.<br />
:* Argument 2: (optional float) The distance at which the actor stops "before" the actor. This value is optional and defaults to 50.<br />
*'''WalkToPosition'''<br />
: Lets the actor walk to the given position.<br />
:* Argument 1: (vector) The world position to walk to (e.g. "-32 4 196").<br />
*'''WalkToEntity'''<br />
: Lets the actor walk to the given entity.<br />
:* Argument 1: (string) The name of the entity to walk to.<br />
:* Argument 2: (optional float) The distance at which the actor stops "before" the entity. This value is optional and defaults to 50.<br />
*'''StopMove'''<br />
: Tells the entity to stop its current movement (no arguments).<br />
*'''Talk'''<br />
: Lets the actor talk a given string.<br />
:* Argument 1: (string) The sound shader to play<br />
:* Argument 2: (optional string) The language string to display as subtitle in the <tt>#str_9NNNN</tt> format. Conversation strings should start in the 9xxxx number range and are defined in the strings/*.lang file. ''Note: this feature is not yet implemented''.<br />
*'''PlayAnimOnce'''<br />
: Lets the actor play an animation once.<br />
:* Argument 1: (string) the name of the animation to play (see the actor's [[modelDef]] file)<br />
:* Argument 2: (optional integer) the number of blendframes to use when switching anims. This is optional and defaults to 4.<br />
*'''PlayAnimCycle'''<br />
: Lets the actor play an animation over and over. Note that the property <tt>wait_until_finished</tt> is not allowed here, as this command never stops, so execution will immediately proceed to the next command.<br />
:* Argument 1: (string) the name of the animation to play (see the actor's [[modelDef]] file)<br />
:* Argument 2: (optional integer) the number of blendframes to use when switching anims. This is optional and defaults to 4.<br />
*'''ActivateTarget'''<br />
:Triggers the given entity.<br />
:* Argument 1: (string) the name of the entity to trigger.<br />
*'''LookAtActor'''<br />
:Lets the actor look at another actor (must be participating in the conversation).<br />
:* Argument 1: (integer) the actor number of the AI to look at.<br />
:* Argument 2: (optional float) the "look duration" in seconds, the head is turning back to its previous position afterwards. This is optional and defaults to 5 seconds.<br />
*'''LookAtPosition'''<br />
:Lets the actor look at the given position.<br />
:* Argument 1: (vector) the world position to look at (e.g. "-32 4 196").<br />
:* Argument 2: (optional float) the "look duration" in seconds, the head is turning back to its previous position afterwards. This is optional and defaults to 5 seconds.<br />
*'''LookAtEntity'''<br />
:Lets the actor look at the given entity.<br />
:* Argument 1: (string) the name of the entity to look at.<br />
:* Argument 2: (optional float) the "look duration" in seconds, the head is turning back to its previous position afterwards. This is optional and defaults to 5 seconds.<br />
*'''TurnToActor'''<br />
: Lets the actor turn towards the given actor, which must participate in this conversation too (the whole body is rotated towards the actor). This command has no duration, so the property <tt>wait_until_finished</tt> is effectless here.<br />
:* Argument 1: (integer) the actor number of the AI to turn towards.<br />
*'''TurnToPosition'''<br />
: Lets the actor turn towards the given position (the whole body is affected). This command has no duration, so the property <tt>wait_until_finished</tt> is effectless here.<br />
:* Argument 1: (vector) the position in world coordinates which the actor should turn towards (e.g. "-32 4 196").<br />
*'''TurnToEntity'''<br />
: Lets the actor turn towards the given entity (whole body is affected). This command has no duration, so the property <tt>wait_until_finished</tt> is effectless here.<br />
:* Argument 1: (string) the entity to turn towards.<br />
*'''AttackActor'''<br />
: Lets the actor attack the other actor (which must be partipicating in this conversation as well). This command has no duration, so the property <tt>wait_until_finished</tt> is effectless here.<br />
:* Argument 1: (integer) the actor number of the AI to attack.<br />
*'''AttackEntity'''<br />
: Lets the actor attack the given entity (which can be any other AI or any other player). This command has no duration, so the property <tt>wait_until_finished</tt> is effectless here.<br />
:* Argument 1: (string) the entity to attack (e.g. "player1").<br />
*'''InteractWithEntity'''<br />
: Lets the actor walk to an entity, play the "use" anim and trigger the entity's frobaction script. Doors will be opened, buttons be pushed, etc.<br />
:* Argument 1: (string) the entity to interact with.<br />
*'''RunScript'''<br />
: Runs a local or global script function. Local script functions (those defined on the actor's scriptobject) must not take any arguments, global scriptfunctions must take an <tt>entity</tt> as argument (the actor will be passed as "owner" to this global function). Note that if <tt>wait_until_finished</tt> is set to "1" the command will not finish until the script is completely done (i.e. non-terminating eachFrame loops within the script function would cause this command to last forever).<br />
:* Argument 1: (string) the name of the local or global script function.<br />
*'''WaitForActor'''<br />
: Lets the actor wait until the other actor (specified in the first argument) has finished executing his current conversation command. If the other actor is already done with his command, WaitForActor does nothing.<br />
:* Argument 1: (integer) the actor number of the AI to wait for.<br />
*'''WaitForAllActors'''<br />
: Lets the conversation wait until all actors are finished executing their commands. Afterwards the conversation is allowed to continue with the next command.<br />
:* no arguments<br />
<br />
== How to get AI to patrol after finishing a conversation ==<br />
<br />
''Sometimes you want AI to stay put until their conversation is triggered, and then start a regular patrol. Here's one way how(courtesy of grayman), see another below in Notes:''<br />
<br />
Guards Bob and Sam will have the conversation. Neither is targetted at any path_corners.<br />
<br />
When the conversation is over, you want Bob to start patrolling, starting with path_corner_1.<br />
<br />
When the conversation is over, you want Sam to start patrolling, starting with path_corner_2.<br />
<br />
A player-activated trigger fires the entity that starts the conversation.<br />
<br />
In the conversation, have these two steps at or near the end:<br />
<br />
Trigger the entity StartBobPatrol<br />
<br />
Trigger the entity StartSamPatrol<br />
<br />
"StartBobPatrol" is an atdm:target_changetarget with these spawnargs:<br />
<br />
"add" "path_corner_1"<br />
"target" "Bob"<br />
<br />
"StartSamPatrol" is an atdm:target_changetarget with these spawnargs:<br />
<br />
"add" "path_corner_2"<br />
"target" "Sam"<br />
<br />
When the conversation ends, both guards will go their separate ways.<br />
<br />
== Notes ==<br />
* It's possible to define conversations with only one actor. This can be used to let AI talk a single sentence or perform some other actions.<br />
* The flags <tt>actors_must_be_within_talkdistance</tt> and <tt>actors_always_face_each_other_while_talking</tt> have no effect when only one actor is present in the conversation. The flags are automatically set to 0 in the code.<br />
* Starting with 1.08, an actor who begins a conversation sitting on a path_waitfortrigger can be moved off that trigger at the end of the conversation by having the last step in the conversation activate a trigger_once whose target is the actor, and which has a 'delay' spawnarg set to at least 1 second. W/o the delay, the actor will ignore the activation and remain where they are.<br />
* Simpler to walk off might be to have the last command in your conversation trigger an atdm:target_changetarget. In that entity, give it these spawnargs: "target" "<name of AI who's leaving>" and "add" "<name of path_corner you want him to walk to>"<br />
<br />
== Volume of Custom Lines ==<br />
The soundshader files for unique lines control how far the sound reaches and volume, it's not set within the editor.<br />
minDistance 1<br />
maxDistance 25<br />
volume 1<br />
Regular AI spoken lines have maxDistance 25, yells 30.<br />
<br />
== Debugging Conversations ==<br />
There are several possibilities to debug conversations, in case something isn't working correctly:<br />
* The CVAR '''tdm_ai_show_conversationstate''' (when set to 1) draws the current conversation command and its execution state on all AI which are currently involved in conversations.<br />
* Another way to check if things go wrong is the console. During map load the number of valid conversations found in the map is verbosed to the console, so be sure to check if this number is right. If this number differs from the number you should have, you probably have your spawnargs wrong. Warnings might also be printed to the console if things go wrong during the execution of conversation commands.<br />
* The log file gives you some insight what is happening in the conversation code during map load and during the actual conversations. Open your <tt>darkmod.ini</tt> file and set <tt>LogClass_CONVERSATION</tt> to 1 to enable conversation logging. Also, be sure to enable the various log types (ERROR, DEBUG, WARNING and INFO) to see all the messages.<br />
<br />
{{editing}}</div>RJFerrethttps://wiki.thedarkmod.com/index.php?title=Conversations&diff=17817Conversations2014-07-07T20:59:35Z<p>RJFerret: /* Triggering a Conversation */ +path node</p>
<hr />
<div>Conversations between AI have a HUGE impact on player immersion, and they're not hard to do.<br />
<br />
If you have no way to record dialogue, you can always look through the vocal sets...it's quite possible to create short conversations with barks that already exist.<br />
<br />
== Overview ==<br />
All the info regarding a conversation is contained within a [[atdm:conversation_info]] entity. Each of these entities can define one or more conversations. There is a custom conversation editor GUI for [[DarkRadiant]] (on the map menu), which is the easiest way to make and edit them; but you can add these entities yourself and set the spawnargs manually if you wish. <br />
<br />
For instructions on how to use the conversation editor, see: [[Cutscenes Part 3: Lighting, Placing the Player, and Conversations]] or [[Conversation Tutorial]].<br />
<br />
Each conversation can have one or more ''Actors''. These are the AI which will participate in the conversation.<br />
<br />
Each conversation consists of a sequence of so-called ''Conversation Commands'', which are specific actions you can use to make the ''actors'' do what you want them to. Examples are "Talk", "Attack", "WalkToEntity", etc. You can add as many conversation commands as you like.<br />
<br />
=== Add a Conversation Info entity ===<br />
Right-click somewhere in the grid view and hit "Create Entity" which will open the dialog for selecting the [[Entity Class|entity classes]]. Go to Conversation and select '''[[atdm:conversation_info]]'''.<br />
<br />
(Note, make sure the entity isn't 'in the void' or you will get a leak in your map. Otherwise, it doesn't matter where the entity is placed.)<br />
<br />
=== Add the conversation spawnargs ===<br />
Once the entity is created you can start defining your conversation. The easiest way is to use the conversation editor. <br />
<br />
Here is an example of a simplistic "conversation" containing exactly one command:<br />
"conv_1_name" "Testconversation 1" // defines the name of the conversation (mandatory)<br />
"conv_1_actor_1" "atdm:ai_builder_guard_1" // first actor<br />
"conv_1_actor_2" "atdm:ai_builder_guard_2" // second actor<br />
<br />
// Here's the first conversation command (defined as ''cmd_1'')<br />
"conv_1_cmd_1_actor" "1" // Actor 1 takes this action<br />
"conv_1_cmd_1_type" "Talk" // the action is "Talk" (uppercase T is required)<br />
"conv_1_cmd_1_arg_1" "tdm_test_conversation_1_1" // play the sound shader: 'tdm_test_conversation_1_1'<br />
<br />
So basically, this conversation has a name ''Testconversation 1'', two actors (builder_guard_1 and 2) and lets the actor 1 play the sound shader ''tdm_test_conversation_1_1''.<br />
<br />
As you can see, the naming convention for the spawnargs is like this:<br />
conv_<number>_<key><br />
<br />
The purpose of ''<number>'' is to distinguish multiple conversations defined on the same conversation info entity. You can use a single entity for all the conversations in your map if you wish, although you'll probably want to keep them separate in order to trigger them at different times (see below). <br />
<br />
The <key> is then defining the properties and commands of this conversation. Each conversation can have multiple commands, that's why these spawnargs are equipped with indices as well ("conv_1_cmd_N_...").<br />
<br />
The above example is defining a command called ''Talk''. There are more ''conversation commands'' available, each having a varying number of arguments. See the section below for details.<br />
<br />
Each conversation ''must'' have a name and at least one actor and one command, otherwise the parser will flag the conversation as invalid and it will therefore be ignored.<br />
<br />
''Note:'' The <number> value is always numeric and starts with 1.<br />
<br />
== Spawnargs ==<br />
=== Conversation ===<br />
These spawnargs can be used to define properties that affect the conversation as a whole.<br />
<br />
The first two MUST be set by the mapper; the rest have defaults and only need to be changed if you want a non-standard result.<br />
<br />
The uppercase N indicates the conversation number (starting from 1).<br />
;'''conv_N_name''' (string)<br />
: defines the name of the conversation. This is a mandatory spawnarg, a conversation without a name will be ignored.<br />
;'''conv_N_actor_Y''' (entity name)<br />
: define the names of the AI participating in this conversation. At least one actor is required, otherwise the conversation is invalid.<br />
<br />
<br />
'''The following are optional:'''<br />
<br />
;'''conv_N_actors_must_be_within_talkdistance''' (1/0) default is 1<br />
: if set to "1", all actors are told to walk towards each other before the conversation actually starts.<br />
;'''conv_N_talk_distance''' (float) default is 60<br />
: defines the maximum distance AI should be away from each other while talking. When the spawnarg '''actors_must_be_within_talkdistance''' is set to 1, this distance tells the AI when to stop when walking towards each other.<br />
;'''conv_N_actors_always_face_each_other_while_talking''' (1/0) default is 1<br />
: if set to "1", all actors are facing each other while talking. The talker turns towards another actor (usually the actor 0 or 1), and all other actors (the listeners) turn to face the talker.<br />
;'''conv_N_max_play_count''' (int) default is -1<br />
: defines the maximum number of times this conversation is allowed to "play". After this number has been exhausted, the conversation won't be started anymore.<br />
;'''conv_N_cmd_Y_...'''<br />
: the conversation commands (see below). One conversation must have at least one and is allowed to have multiple conversation commands.<br />
<br />
=== Conversation Commands ===<br />
These spawnargs are used to tell the actors what to do during the conversation.<br />
<br />
The prefix <tt>conv_N_</tt> refers to the conversation these commands are associated with. The number M refers to the command number (starting at 1).<br />
;'''conv_N_cmd_M_actor''' (integer actor number, starting from 1)<br />
: defines which actor should perform this command. Use the "Actor Number" you assigned earlier. Note that the value of this spawnarg is a number X referring to the <tt>conv_N_actor_X</tt> definition above. You address a conversation's actor by this number, ''not'' by its name. ;'''conv_N_cmd_M_type''' (string == command type name)<br />
: defines the type of command you want to give (this is a mandatory spawnarg, each command must have a type). The most common is probably "Talk". See below for a list of available type names. ''Ex: "conv_1_cmd_1_type" "Talk" '' <br />
<br />
;'''conv_N_cmd_M_wait_until_finished''' (1/0), default is 1 (note: default is 0 in the editor)<br />
: defines whether the conversation should wait for the actor to complete this command before the next command is executed. Setting this to "0" allows to step over to the next command with nearly no time loss. This can be used to issue two or more commands at virtually the same time to an actor, so that the commands "Talk" and "PlayAnimOnce" are executed side-by-side by the same AI, for instance.<br />
Note: I set a single conversation for an AI to walk to an entity. This failed unless this spawnarg was set to 1 so possibly the last command in the list needs it?<br />
;'''conv_N_cmd_M_arg_L'''<br />
:defines the arguments of this conversation command. The actual arguments depend on the command type, each type is requiring a different amount of arguments, and some of them are optional. See below for a description of the command's arguments. The index L starts at the number 1, there is no upper limit imposed by the code.<br />
<br />
== Triggering a Conversation ==<br />
<br />
Now that your conversation is created, you need to trigger it.<br />
<br />
To trigger a conversation you need to create a ''target_tdm_startconversation'' entity. Give it the spawnarg "conversation" with the name of the conversation you want to start (ex "conversation" "Testcoversation 1") then target that entity from any trigger you like such as a trigger_once entity or [path node] (as of TDM v2.02).<br />
<br />
== Conversation Commands ==<br />
The following is a list of available conversation commands:<br />
*'''WaitSeconds'''<br />
: Lets the actor wait the given amount of seconds. Note that the <tt>wait_until_finished</tt> property is not affecting this command (would be pointless).<br />
:*Argument 1: (float) The amount of seconds to wait.<br />
*'''WalkToActor'''<br />
: Lets the actor walk to another actor, which must be participating in this conversation.<br />
:* Argument 1: (integer) The actor number of the AI to walk to.<br />
:* Argument 2: (optional float) The distance at which the actor stops "before" the actor. This value is optional and defaults to 50.<br />
*'''WalkToPosition'''<br />
: Lets the actor walk to the given position.<br />
:* Argument 1: (vector) The world position to walk to (e.g. "-32 4 196").<br />
*'''WalkToEntity'''<br />
: Lets the actor walk to the given entity.<br />
:* Argument 1: (string) The name of the entity to walk to.<br />
:* Argument 2: (optional float) The distance at which the actor stops "before" the entity. This value is optional and defaults to 50.<br />
*'''StopMove'''<br />
: Tells the entity to stop its current movement (no arguments).<br />
*'''Talk'''<br />
: Lets the actor talk a given string.<br />
:* Argument 1: (string) The sound shader to play<br />
:* Argument 2: (optional string) The language string to display as subtitle in the <tt>#str_9NNNN</tt> format. Conversation strings should start in the 9xxxx number range and are defined in the strings/*.lang file. ''Note: this feature is not yet implemented''.<br />
*'''PlayAnimOnce'''<br />
: Lets the actor play an animation once.<br />
:* Argument 1: (string) the name of the animation to play (see the actor's [[modelDef]] file)<br />
:* Argument 2: (optional integer) the number of blendframes to use when switching anims. This is optional and defaults to 4.<br />
*'''PlayAnimCycle'''<br />
: Lets the actor play an animation over and over. Note that the property <tt>wait_until_finished</tt> is not allowed here, as this command never stops, so execution will immediately proceed to the next command.<br />
:* Argument 1: (string) the name of the animation to play (see the actor's [[modelDef]] file)<br />
:* Argument 2: (optional integer) the number of blendframes to use when switching anims. This is optional and defaults to 4.<br />
*'''ActivateTarget'''<br />
:Triggers the given entity.<br />
:* Argument 1: (string) the name of the entity to trigger.<br />
*'''LookAtActor'''<br />
:Lets the actor look at another actor (must be participating in the conversation).<br />
:* Argument 1: (integer) the actor number of the AI to look at.<br />
:* Argument 2: (optional float) the "look duration" in seconds, the head is turning back to its previous position afterwards. This is optional and defaults to 5 seconds.<br />
*'''LookAtPosition'''<br />
:Lets the actor look at the given position.<br />
:* Argument 1: (vector) the world position to look at (e.g. "-32 4 196").<br />
:* Argument 2: (optional float) the "look duration" in seconds, the head is turning back to its previous position afterwards. This is optional and defaults to 5 seconds.<br />
*'''LookAtEntity'''<br />
:Lets the actor look at the given entity.<br />
:* Argument 1: (string) the name of the entity to look at.<br />
:* Argument 2: (optional float) the "look duration" in seconds, the head is turning back to its previous position afterwards. This is optional and defaults to 5 seconds.<br />
*'''TurnToActor'''<br />
: Lets the actor turn towards the given actor, which must participate in this conversation too (the whole body is rotated towards the actor). This command has no duration, so the property <tt>wait_until_finished</tt> is effectless here.<br />
:* Argument 1: (integer) the actor number of the AI to turn towards.<br />
*'''TurnToPosition'''<br />
: Lets the actor turn towards the given position (the whole body is affected). This command has no duration, so the property <tt>wait_until_finished</tt> is effectless here.<br />
:* Argument 1: (vector) the position in world coordinates which the actor should turn towards (e.g. "-32 4 196").<br />
*'''TurnToEntity'''<br />
: Lets the actor turn towards the given entity (whole body is affected). This command has no duration, so the property <tt>wait_until_finished</tt> is effectless here.<br />
:* Argument 1: (string) the entity to turn towards.<br />
*'''AttackActor'''<br />
: Lets the actor attack the other actor (which must be partipicating in this conversation as well). This command has no duration, so the property <tt>wait_until_finished</tt> is effectless here.<br />
:* Argument 1: (integer) the actor number of the AI to attack.<br />
*'''AttackEntity'''<br />
: Lets the actor attack the given entity (which can be any other AI or any other player). This command has no duration, so the property <tt>wait_until_finished</tt> is effectless here.<br />
:* Argument 1: (string) the entity to attack (e.g. "player1").<br />
*'''InteractWithEntity'''<br />
: Lets the actor walk to an entity, play the "use" anim and trigger the entity's frobaction script. Doors will be opened, buttons be pushed, etc.<br />
:* Argument 1: (string) the entity to interact with.<br />
*'''RunScript'''<br />
: Runs a local or global script function. Local script functions (those defined on the actor's scriptobject) must not take any arguments, global scriptfunctions must take an <tt>entity</tt> as argument (the actor will be passed as "owner" to this global function). Note that if <tt>wait_until_finished</tt> is set to "1" the command will not finish until the script is completely done (i.e. non-terminating eachFrame loops within the script function would cause this command to last forever).<br />
:* Argument 1: (string) the name of the local or global script function.<br />
*'''WaitForActor'''<br />
: Lets the actor wait until the other actor (specified in the first argument) has finished executing his current conversation command. If the other actor is already done with his command, WaitForActor does nothing.<br />
:* Argument 1: (integer) the actor number of the AI to wait for.<br />
*'''WaitForAllActors'''<br />
: Lets the conversation wait until all actors are finished executing their commands. Afterwards the conversation is allowed to continue with the next command.<br />
:* no arguments<br />
<br />
== How to get AI to patrol after finishing a conversation ==<br />
<br />
''Sometimes you want AI to stay put until their conversation is triggered, and then start a regular patrol. Here's one way how(courtesy of grayman), see another below in Notes:''<br />
<br />
Guards Bob and Sam will have the conversation. Neither is targetted at any path_corners.<br />
<br />
When the conversation is over, you want Bob to start patrolling, starting with path_corner_1.<br />
<br />
When the conversation is over, you want Sam to start patrolling, starting with path_corner_2.<br />
<br />
A player-activated trigger fires the entity that starts the conversation.<br />
<br />
In the conversation, have these two steps at or near the end:<br />
<br />
Trigger the entity StartBobPatrol<br />
<br />
Trigger the entity StartSamPatrol<br />
<br />
"StartBobPatrol" is an atdm:target_changetarget with these spawnargs:<br />
<br />
"add" "path_corner_1"<br />
"target" "Bob"<br />
<br />
"StartSamPatrol" is an atdm:target_changetarget with these spawnargs:<br />
<br />
"add" "path_corner_2"<br />
"target" "Sam"<br />
<br />
When the conversation ends, both guards will go their separate ways.<br />
<br />
== Notes ==<br />
* It's possible to define conversations with only one actor. This can be used to let AI talk a single sentence or perform some other actions.<br />
* The flags <tt>actors_must_be_within_talkdistance</tt> and <tt>actors_always_face_each_other_while_talking</tt> have no effect when only one actor is present in the conversation. The flags are automatically set to 0 in the code.<br />
* Starting with 1.08, an actor who begins a conversation sitting on a path_waitfortrigger can be moved off that trigger at the end of the conversation by having the last step in the conversation activate a trigger_once whose target is the actor, and which has a 'delay' spawnarg set to at least 1 second. W/o the delay, the actor will ignore the activation and remain where they are.<br />
* Simpler to walk off might be to have the last command in your conversation trigger an atdm:target_changetarget. In that entity, give it these spawnargs: "target" "<name of AI who's leaving>" and "add" "<name of path_corner you want him to walk to>"<br />
<br />
== Volume of Custom Lines ==<br />
The soundshader files for unique lines control how far the sound reaches and volume, it's not set within the editor.<br />
minDistance 1<br />
maxDistance 25<br />
volume 1<br />
Regular AI spoken lines have maxDistance 25, yells 30.<br />
<br />
== Debugging Conversations ==<br />
There are several possibilities to debug conversations, in case something isn't working correctly:<br />
* The CVAR '''tdm_ai_show_conversationstate''' (when set to 1) draws the current conversation command and its execution state on all AI which are currently involved in conversations.<br />
* Another way to check if things go wrong is the console. During map load the number of valid conversations found in the map is verbosed to the console, so be sure to check if this number is right. If this number differs from the number you should have, you probably have your spawnargs wrong. Warnings might also be printed to the console if things go wrong during the execution of conversation commands.<br />
* The log file gives you some insight what is happening in the conversation code during map load and during the actual conversations. Open your <tt>darkmod.ini</tt> file and set <tt>LogClass_CONVERSATION</tt> to 1 to enable conversation logging. Also, be sure to enable the various log types (ERROR, DEBUG, WARNING and INFO) to see all the messages.<br />
<br />
{{editing}}</div>RJFerrethttps://wiki.thedarkmod.com/index.php?title=Path_Nodes&diff=17816Path Nodes2014-07-07T20:58:19Z<p>RJFerret: /* How to use Path Nodes */ +triggering</p>
<hr />
<div>''originally written by Springheel''<br />
<br />
For more information on pathfinding, see [[Pathfinding]]. For more general info on getting your AI to patrol, see [[AI Patrol]].<br />
<br />
= What are Path Nodes? =<br />
<br />
Path entities (or path nodes) are the things that you use to make your AI move (patrol) around the map. Placing path nodes can take a little getting used to; hopefully this article will help (I'm far from an expert, but here's what I've discovered so far).<br />
<br />
There are lots of different kinds of path nodes. It can sometimes help to think of them as "travel nodes" (nodes that AI will travel to) and "behaviour nodes" (nodes that tell AI how to behave at a certain point). <br />
<br />
Although path nodes have a directional arrow in the editor, it has no impact on most nodes. Rotating the node does add a corresponding "angle" property to the entity (matching the direction of the arrow). Certain nodes (path_anim, path_wait, and path_turn, for example) are affected by the "angle" property, but most will ignore it.<br />
<br />
= How to use Path Nodes =<br />
<br />
Path nodes are placed like any other entity (RMB and select "add entity", then scroll to "paths"). They show up as a coloured box with an arrow in the editor (colour varies depending on config.)<br />
<br />
Path nodes are useless if they are not linked to another entity (either an AI or another node). In order to link them, you use the "target" property. This tells the AI what path node they should go to (or act on) next. If you type "target" "path_corner_1" in your AI property list, then your AI will walk to "path_corner_1" when the map starts. Without a "target" property, your AI will not go anywhere. Once you add a "target" property to either your AI or another node, you should see a colored line connecting the two entities.<br />
<br />
Behaviour nodes activate behaviour in order. In other words, if you want an AI to reach a path_corner, then turn to face a direction, then wait for a time, then play an animation, you need to link the nodes in that order. <br />
<br />
path_corner ---> path_turn ----> path_wait ----> path_cycleanim -----> next path_corner<br />
<br />
== Variation and Randomness ==<br />
<br />
It is also possible to target multiple nodes (using "target1", "target2" etc. spawn args). In this case, the AI will choose one of these nodes with equal probability. <br />
If the '''"chance"''' spawn arg (between 0 and 1) is set on a node, it defines the probability for the AI to choose this path node next when multiple path nodes are targetted. The chances at any point must not add to greater than 1, or it won't work properly. For example, if a path_corner targets two different nodes, you could set "chance" ".75" on one and "chance" ".25" on the other. This will result in AI choosing the first path 3/4 of the time.<br />
<br />
There are now two new spawnargs, '''"alert_idle_only"''' and '''"idle_only"''' that can be set on path nodes. The nodes are then only chosen when the AI is in that state. For example, if you set a path_corner as "idle_only", then the AI will no longer go to that path node when it has been alerted. This allows the mapper to set a complete set of alternate patrols and actions for AI who have been alerted (like sending them to guard important areas). (for info on how to use Objectives to alter paths, see [[Objectives#Using_Objectives_Creatively]])<br />
<br />
''Note that if an AI reaches a node that targets pathnodes that are unavailable (because they are idle_only, and the AI is alert, for example), the AI will stop and no longer proceed.''<br />
<br />
Nodes that make the AI walk to a specified location (currently the only one that does this is the path_corner) can have an '''"move_to_position_tolerance"''' spawn arg, which defines how close the AI has to be to the destination point to determine the position as reached. Normally, the AI considers the position reached as soon as it is inside its bounding box (most of our humanoid AI are using aas32, so the point would need to be within 16 units from the AI's origin). This is not always accurate enough, for example when a path_corner is placed in front of a chair where the AI is supposed to sit down, making the AI place half of their back next to the chair. Smaller numbers mean the AI must get closer, larger numbers are more forgiving.<br />
<br />
[Fidcal: I believe the accuracy spawnarg is replaced by the move_to_position_tolerance above. The following likely applies to the new spawnarg anyway.]<br />
Setting the accuracy spawn arg will change the horizontal size of the bounding box used for checking. If the accuracy is set to negative values (default is -1), the standard bounding box will be used as before.<br />
<br />
This spawnarg is available for all entities and can also affect AIs moving towards levers or buttons.<br />
<br />
== Triggering ==<br />
These path nodes will trigger their targets when AI affect them (as of TDM v2.02):<br />
<br />
* path_corner - triggers targets when node is reached<br />
* path_turn - triggers targets when turn is done<br />
* path_wait - triggers targets when wait is over<br />
* path_sit - triggers targets when sitting anim is done, including any final turn<br />
* path_sleep - triggers targets when lying down anim is done<br />
* path_anim - triggers targets when anim is done<br />
<br />
= Kinds of Path Nodes =<br />
<br />
== path_corner ==<br />
Probably the most common path node, this is a "travel node". AI will walk from their current position to this node in as straight a line as possible. This node must be on the ground and in an area AI can reach. See [[Pathfinding]] for more information on how to help AI go from one node to another.<br />
<br />
To make AI patrol an area, each path_corner node can target the next one in sequence. If AI reach a node that does not target anything, they will stop there and no longer move without player interaction. It is possible for two path_nodes to target each other, which means the AI will walk from one to the other and back again endlessly.<br />
<br />
A single entity (path node or AI) can target more than one path_corner; D3 will randomly choose between the targetted nodes. Use the following syntax: <br />
<br />
target path_corner_1<br />
target2 path_corner_2<br />
<br />
<br />
''(At the moment, targetting more than 2 path_corners from the same entity does not seem to work (possibly a DR bug).''<br />
<br />
In the example below, both A and B are path_corner nodes. On map start, the AI will walk to A, then turn and walk to B, then stop.<br />
<br />
[[image:pathfinding2.jpg]]<br />
<br />
Extra note: To make an AI run on patrol add the property/value : "run" "1" to a path_corner on the AI's patrol and the AI will run to it (then resume walking after it if the next path_corner does not have that property set.) <br />
<br />
'''Note that an AI will continue on to their next path_corner after a failed search. If you do not have at least one path_corner, the AI will stop wherever they are when their search is complete.'''<br />
<br />
'''Also note that if the AI is going to stop at a path_corner--perhaps to wait a spell--the path_corner origin should be kept at least 16 horizontal units away from monsterclip and worldspawn brushes. Otherwise, the stopping animation might not look right.'''<br />
<br />
== path_wait ==<br />
<br />
This is a behaviour node. It does not tell an AI to move anywhere. This node tells an AI to wait in an idle state for a given amount of time. Once that time is up, the AI will proceed to whatever the next target is (a path_wait with no target is pretty pointless). <br />
<br />
A path_wait node appears as a small orange box. It has a directional arrow, but that has no affect on which direction the AI faces in the first place. However, you can set the angle key on the path either by rotating the entity or by setting the key directly to make the AI turn and face this direction before starting to wait. '''Important:''' If the angle is 0 make sure it is actually on the entity and not just default.<br />
<br />
A path_wait node should have a "wait" property, with the number of seconds the AI should wait there before proceeding. It can also have a "wait_max" property which will vary the repeat time. So for example...<br />
<br />
* wait 30<br />
* wait_max 40 <br />
<br />
...will cause the AI to wait between 30 to 40 seconds before proceeding. If wait_max is set to 0, the AI will always wait exactly the time specified in wait before proceeding. If you set wait to 0, the AI will wait between 0 seconds and the time specified in wait_max. Default values are 2 seconds for wait, and 0 seconds for wait_max, so the AI will always wait exactly 2 seconds.<br />
<br />
In the following example, A and B are path_corners, and the small orange box is a path_wait entity. On map start, the AI will walk to A and wait there for the required amount of time, then turn and proceeds to B.<br />
<br />
[[image:pathfinding3.jpg]]<br />
<br />
Note that it does not matter '''where''' the path_wait node is placed. The AI does not actually follow the orange lines (this is not really intuitive, I know). The example below would cause the exact same behaviour as the example above--in both cases the AI will walk directly from A to B.<br />
<br />
[[image:pathfinding4.jpg]]<br />
<br />
<br />
<br />
Another useful example for path_wait is that of the stationary guard who turns to look in different directions periodically. This can be schematically represented (arrows indicate target links) as:<br />
<br />
AI -> path_corner1 -> path_wait1 -> path_wait2 -> path_corner1<br />
<br />
Example properties for the path_wait are:<br />
wait: 5 (minimum time to wait on action)<br />
wait_max: 10 (maximum time to wait on action)<br />
angle: 0 ('''Important''': this property is essential for proper function even if the angle is 0)<br />
<br />
<br />
The AI walks to or stands at the path_corner. The next action is to do what is indicated by the first path_wait. In this example, it tells the AI to face a particular direction for a certain period of time. This then targets a second path_wait which has the AI face a different direction for a certain period of time. To complete the cycle, the second path_wait then targets the original path_corner. The path_corners are necessary because again, the path_wait doesn't contain pathing or location information. Without the path_corner, if the AI is caused to wander (e.g. becomes alerted), it might not return to the original standing spot, and instead will do the look angles right where it stands. The path_corner assures the AI returns to its original position.<br />
<br />
== path_turn == <br />
<br />
This behaviour node tells an AI to turn in place to face a chosen direction. It does not make the AI walk anywhere. This is the one node where the directional arrow does seem to matter--the AI turns to face the same direction as the arrow. Alternately, you can use the property "angle" and the values below:<br />
<br />
* 0 = East (X)<br />
* 90 = North (Y)<br />
* 180 = West (-X)<br />
* 270 = South (-Y)<br />
* 360 = East(X)<br />
<br />
(Actually, to be more accurate, rotating the entity automatically adds the "angle" property to the entity. If you just leave the arrow facing the way it is when you create the entity, there will be no "angle" property, and therefore the AI will not turn.)<br />
<br />
== path_anim ==<br />
<br />
This is a behaviour node that makes the AI play an animation, once. When that animation is done, it proceeds to the next target (if any). This could be used to make an AI walk over to a bookshelf and play a 'reaching out' animation, for example. Other possibilities include peering through a window, picking a carrot off a table and eating it, or running to a spot and cowering. <br />
<br />
The syntax proper syntax is:<br />
<br />
anim [animation name]<br />
<br />
You can see the list of animations names here: [[Animation List]]. Do not use the name of the actual animation file. <br />
<br />
A path_anim can have only one animation, but it is possible for a single entity to target more than one path_anim. The AI will pick one of the path_anim nodes at random and play that animation.<br />
<br />
When you first create the path_anim entity, the directional arrow is meaningless. However, if you rotate the entity, the "angle" property is added to the entity and is updated based on which direction the arrow is pointing. That property indicates the direction the AI will face while playing the animation. '''This value appears to be necessary to make the animation work.'''<br />
<br />
Tip: Animation blending doesn't seem to do very much, so AI often "snap" into position from walking to playing the animation. For a more natural look, add a path_wait of a few seconds first, so AI transition to their idle pose before playing the animation.<br />
<br />
== path_lookat ==<br />
<br />
This does not stop the AI, but they will turn their head and look somewhere specific as they walk to their next target. For the next ''wait'' seconds, turn head to look at the entity given by the ''focus'' spawnarg (defaults to looking at the path_lookat entity itself). This is useful if you want to make sure an AI is looking at a specific spot (or away from a certain spot) during their patrol. Note the focus entity must not be obscured by monsterclip.<br />
<br />
== path_sit ==<br />
<br />
This is a behaviour node that makes the AI sit down at its current location. See [[Sitting Behaviour for AI]] for more information.<br />
<br />
== path_waitfortrigger ==<br />
<br />
Waits at a given place until triggered, then proceeds to the next target. This is useful if you want some control over exactly where the AI is when the players first see it.<br />
<br />
The "path_waitfortrigger" basically operates like a wall, blocking the AI from proceeding until triggered.<br />
<br />
Here are the steps for future reference. Let's say you want an AI to stand somewhere until a player triggers him, then you want him to walk to path_corner 1.<br />
<br />
1. Make a "path_waitfortrigger" pathnode, and have it target "path_corner_1".<br />
<br />
2. Have the AI target the "path_waitfortrigger" pathnode.<br />
<br />
3. Create a trigger_once entity, and target the AI.<br />
<br />
The AI will stand where they are at map start and behave as if there are no pathnodes set (ie, he plays idle animations and can be alerted). When the player goes through the trigger, the "path_waitfortrigger" is cleared and the AI will proceed to path_corner_1.<br />
<br />
I've tried a few different setups and gotten unusual results...more testing needed.<br />
<br />
== path_interact ==<br />
<br />
This lets the AI interact with an entity (for example a button) in a similar way to frobbing. This will only work for buttons etc, not for inventory items and moveables. The AI will stop and look at the entiy while interacting, but not walk to it, so a path_corner next to the entity is required. AI will use normal doors and elevators without needing a path_interact (confirmation needed). However, this could be used to make AI turn on lightswitches, open mechanical doors, etc.<br />
<br />
You need to add these spawnargs to the path_interact entity:<br />
<br />
ent <name of entity to be frobbed by AI><br />
<br />
target <next path entity (if any)><br />
<br />
<br />
= How to Make AI do Random Interesting Things (RIT) =<br />
<br />
''by Sotha''<br />
<br />
You can use the above to make individual AI seem to do Random Interesting Things (RIT) when entering a room. Note that it will work with basic dendritic AI, so you could have multiple AI's running in several rooms doing things.<br />
<br />
1) Build a room with RITs. A statue. A few chairs. Maybe a lit fireplace.<br />
<br />
2) On each RIT place the necessary interaction path_nodes to make an AI interact with them: path_corner to walk over to them; path_sit on each of the chairs, path_anims for warming hands at the fireplace and standing in front of the statue and pondering, etc (A, B & C in image).<br />
<br />
3) Place two path_waits (1 & 2 in image) on the ceiling of the room. (They could be anywhere in the room, but it is easiest to manage if they are in the ceiling.)<br />
<br />
4) Name one of the path_waits "enter_room_decide_what_to_do." (1) From that path_wait target each of the RIT path_corners. Set the path_wait "wait 0". so AI won't stop there. The idea is to use the path_wait as a simple decision making node. Be sure that the path_wait has no angle-spawnarg. If it does, the AI will turn towards the angle each time he targets the node.<br />
<br />
5) Name the other path_wait "exit_room_decide_what_to_do." (2) Make each RIT final path_node target this path_wait. Make the path_wait target other rooms with similar decision making path_waits.<br />
<br />
6) Done.<br />
<br />
[[Image:Rits.jpg]] <br />
<br />
AI will come into the room, select A, B or C at random, and then leave. Next time they enter, they'll again pick at random.<br />
<br />
This could be used to make servants to run around a mansion, cleaning, making food, taking sitting breaks, visit the toilet, etc. You could build room decision making network separately for different AI. Servants clean, cook and take breaks. Guards patrol, make random deviations once in a while, and of course take breaks. Controlling the RIT path_corner chance-spawnarg gives you control what RITs the AI do more likely.<br />
<br />
Please see the dedicated RIT network article for more details. [[RIT Networks]]<br />
<br />
<br />
= Switching from one Path network to another =<br />
<br />
Suppose you want to have an AI patrol outside a mansion for the first part of a mission, and then change his route to patrol in another location later?<br />
<br />
It is possible to change the "target" property on a path_corner by using ''atdm:target_changetarget.''<br />
<br />
Target the atdm:target_changetarget entity at the pathnode you wish to alter. Use the following spawnargs:<br />
<br />
"add" "[new path_corner]"<br />
and/or<br />
"remove" "[old path_corner]"<br />
<br />
Then add a trigger that targets the atdm:target_changetarget.<br />
<br />
When triggered, the new path_corner will be added and the old removed, sending the AI to a new path network. This no doubt has vast potential for variation and creativity that has yet to be explored. One simple example would be a "changing of the guard" moment, where some guards leave their posts and go to their barracks to sleep, while others take over for them.<br />
<br />
'''Other ideas:'''<br />
<br />
'''Doormen'''-- An AI (or the player) walks up to the door and knocks on it. AI inside is triggered to walk over to the door and open it, then go back to his regular duties.<br />
<br />
'''Abandon ship!''' -- When triggered, all AI drop what they're doing and start running for the exits.<br />
<br />
'''Lights out!''' -- At a specific time, all AI stop what they're doing and walk to their beds to go to sleep.<br />
<br />
'''Re-use, recycle''' -- AI that are stuck back in a portion of the map the player won't be coming back to could be told to walk to a new portion of the map and assume some job there.<br />
<br />
It''''s a trap!''' -- Player walks down a hall and hits a trigger that causes AI to quickly position themselves at the only exits.<br />
<br />
= Flee Points =<br />
<br />
<br />
Do NOT target the AI to a flee point; AI will automatically go to a flee point if in danger. Just make available path_flee_point entities at suitable places where you would like your AI to flee to.<br />
<br />
On the path_flee_point entity:<br />
<br />
"is_guarded", a fleeing AI, eg, a civilian, would give this preference (but it is up to the mapper to actually provide a guard there.)<br />
<br />
"team", only AI on this team would use this flee point, also required for "friendly" flee points per below.<br />
<br />
This is how the code works:<br />
* The AI tries to determine the nearest friendly (their team specified) guarded flee point and flee to it.<br />
* If there is no friendly guarded flee point, the AI tries to find the nearest friendly flee point (on friendly team) and run to it.<br />
* If this also fails, the AI tries to find an AAS area far from the enemy and run there.<br />
* If the enemy is still visible when the AI reaches his destination, he chooses the farthest friendly guarded flee point to run to, <br />
* if this fails, the farthest friendly flee point, <br />
* and if this also fails falls back to choosing an AAS area far from the enemy to run to.<br />
* So neither the priority nor the target spawn arg have any function here, it is not possible to weight the flee points. The AI will choose one automatically.<br />
<br />
A problem occurs when the AI doesn't find any appropriate flee points but also no AAS area that is far away enough from the enemy. In this case, he will just stand there. Maybe he should either cower and be afraid in this case or just run around like a mad chicken?<br />
<br />
Whether a fleeing AI passes on info to other AI as to the source of their alert (ie so armed guard would go to investigate to the right place whereas another civilian might also flee to the farthest point.)<br />
Yes, they do. The cry for help bark is propagated to other AI and carries information about the last alert position.<br />
<br />
Armed AI will also flee if their health points drop to a certain level? Where is that determined?<br />
This is determined by the health_critical spawn arg.<br />
<br />
= Untested Nodes =<br />
<br />
I have not personally tested the following, so I'm just going by their editor descriptions. They may or may not work as described.<br />
<br />
<br />
== path_cycleanim ==<br />
<br />
The AI stays in place and loops the selected animation, either for a specified amount of time (using the 'wait' property) or until triggered. Syntax needed.<br />
<br />
== path_hide ==<br />
<br />
Supposedly deactivates and stops rendering the AI. <br />
<br />
Turns out this doesn't work well with TDM...makes AI invisible but they still talk and occupy space. To remove an AI from the map, try grayman's approach:<br />
<br />
Create a [b]func_remove[/b] with this spawnarg:<br />
<br />
"target" "<AI's name>"<br />
<br />
At the point in his path where you want him to disappear, place a [b]trigger_once_entityname[/b] with these spawnargs:<br />
<br />
"entityname" "<AI's name>"<br />
"target" "<func_remove's name>"<br />
<br />
When the AI walks through the [b]trigger_once_entityname[/b], it recognizes him, triggers the [b]func_remove[/b], and that takes the AI out of the game.<br />
<br />
I wrapped the AI's final path corner in a trigger_once_entityname and gave the trigger the keyword pair "entityname <AI_name>". (The docs don't tell you about this key, but the game will error out if it's not there, and tell you it's missing. A classic "trial by error".)<br />
<br />
== path_show ==<br />
<br />
Starts rendering the AI. I would assume this one would be linked to a path_waitfortrigger, to create AI that spawn when triggered. This could be used to create the effect that an AI just came through a doorway or around a corner.<br />
<br />
== path_attack ==<br />
<br />
Used to script AI attacking a particular enemy, for scripted sequences I guess. AI will continue on to the next path entity if it kills the enemy.<br />
<br />
Questions: How do you define who the AI attacks?<br />
<br />
[Fidcal]: Just found this - "Character will attack the character specified by 'enemy' key. Character will go to next path when enemy dies or when activated." Not tested.<br />
<br />
<br />
<br />
{{tutorial-editing}}</div>RJFerrethttps://wiki.thedarkmod.com/index.php?title=Path_Nodes&diff=17815Path Nodes2014-07-07T20:54:33Z<p>RJFerret: /* path_corner */ language changed to be more specific/answer query</p>
<hr />
<div>''originally written by Springheel''<br />
<br />
For more information on pathfinding, see [[Pathfinding]]. For more general info on getting your AI to patrol, see [[AI Patrol]].<br />
<br />
= What are Path Nodes? =<br />
<br />
Path entities (or path nodes) are the things that you use to make your AI move (patrol) around the map. Placing path nodes can take a little getting used to; hopefully this article will help (I'm far from an expert, but here's what I've discovered so far).<br />
<br />
There are lots of different kinds of path nodes. It can sometimes help to think of them as "travel nodes" (nodes that AI will travel to) and "behaviour nodes" (nodes that tell AI how to behave at a certain point). <br />
<br />
Although path nodes have a directional arrow in the editor, it has no impact on most nodes. Rotating the node does add a corresponding "angle" property to the entity (matching the direction of the arrow). Certain nodes (path_anim, path_wait, and path_turn, for example) are affected by the "angle" property, but most will ignore it.<br />
<br />
= How to use Path Nodes =<br />
<br />
Path nodes are placed like any other entity (RMB and select "add entity", then scroll to "paths"). They show up as a coloured box with an arrow in the editor (colour varies depending on config.)<br />
<br />
Path nodes are useless if they are not linked to another entity (either an AI or another node). In order to link them, you use the "target" property. This tells the AI what path node they should go to (or act on) next. If you type "target" "path_corner_1" in your AI property list, then your AI will walk to "path_corner_1" when the map starts. Without a "target" property, your AI will not go anywhere. Once you add a "target" property to either your AI or another node, you should see a colored line connecting the two entities.<br />
<br />
Behaviour nodes activate behaviour in order. In other words, if you want an AI to reach a path_corner, then turn to face a direction, then wait for a time, then play an animation, you need to link the nodes in that order. <br />
<br />
path_corner ---> path_turn ----> path_wait ----> path_cycleanim -----> next path_corner<br />
<br />
== Variation and Randomness ==<br />
<br />
It is also possible to target multiple nodes (using "target1", "target2" etc. spawn args). In this case, the AI will choose one of these nodes with equal probability. <br />
If the '''"chance"''' spawn arg (between 0 and 1) is set on a node, it defines the probability for the AI to choose this path node next when multiple path nodes are targetted. The chances at any point must not add to greater than 1, or it won't work properly. For example, if a path_corner targets two different nodes, you could set "chance" ".75" on one and "chance" ".25" on the other. This will result in AI choosing the first path 3/4 of the time.<br />
<br />
There are now two new spawnargs, '''"alert_idle_only"''' and '''"idle_only"''' that can be set on path nodes. The nodes are then only chosen when the AI is in that state. For example, if you set a path_corner as "idle_only", then the AI will no longer go to that path node when it has been alerted. This allows the mapper to set a complete set of alternate patrols and actions for AI who have been alerted (like sending them to guard important areas). (for info on how to use Objectives to alter paths, see [[Objectives#Using_Objectives_Creatively]])<br />
<br />
''Note that if an AI reaches a node that targets pathnodes that are unavailable (because they are idle_only, and the AI is alert, for example), the AI will stop and no longer proceed.''<br />
<br />
Nodes that make the AI walk to a specified location (currently the only one that does this is the path_corner) can have an '''"move_to_position_tolerance"''' spawn arg, which defines how close the AI has to be to the destination point to determine the position as reached. Normally, the AI considers the position reached as soon as it is inside its bounding box (most of our humanoid AI are using aas32, so the point would need to be within 16 units from the AI's origin). This is not always accurate enough, for example when a path_corner is placed in front of a chair where the AI is supposed to sit down, making the AI place half of their back next to the chair. Smaller numbers mean the AI must get closer, larger numbers are more forgiving.<br />
<br />
[Fidcal: I believe the accuracy spawnarg is replaced by the move_to_position_tolerance above. The following likely applies to the new spawnarg anyway.]<br />
Setting the accuracy spawn arg will change the horizontal size of the bounding box used for checking. If the accuracy is set to negative values (default is -1), the standard bounding box will be used as before.<br />
<br />
This spawnarg is available for all entities and can also affect AIs moving towards levers or buttons.<br />
<br />
= Kinds of Path Nodes =<br />
<br />
== path_corner ==<br />
Probably the most common path node, this is a "travel node". AI will walk from their current position to this node in as straight a line as possible. This node must be on the ground and in an area AI can reach. See [[Pathfinding]] for more information on how to help AI go from one node to another.<br />
<br />
To make AI patrol an area, each path_corner node can target the next one in sequence. If AI reach a node that does not target anything, they will stop there and no longer move without player interaction. It is possible for two path_nodes to target each other, which means the AI will walk from one to the other and back again endlessly.<br />
<br />
A single entity (path node or AI) can target more than one path_corner; D3 will randomly choose between the targetted nodes. Use the following syntax: <br />
<br />
target path_corner_1<br />
target2 path_corner_2<br />
<br />
<br />
''(At the moment, targetting more than 2 path_corners from the same entity does not seem to work (possibly a DR bug).''<br />
<br />
In the example below, both A and B are path_corner nodes. On map start, the AI will walk to A, then turn and walk to B, then stop.<br />
<br />
[[image:pathfinding2.jpg]]<br />
<br />
Extra note: To make an AI run on patrol add the property/value : "run" "1" to a path_corner on the AI's patrol and the AI will run to it (then resume walking after it if the next path_corner does not have that property set.) <br />
<br />
'''Note that an AI will continue on to their next path_corner after a failed search. If you do not have at least one path_corner, the AI will stop wherever they are when their search is complete.'''<br />
<br />
'''Also note that if the AI is going to stop at a path_corner--perhaps to wait a spell--the path_corner origin should be kept at least 16 horizontal units away from monsterclip and worldspawn brushes. Otherwise, the stopping animation might not look right.'''<br />
<br />
== path_wait ==<br />
<br />
This is a behaviour node. It does not tell an AI to move anywhere. This node tells an AI to wait in an idle state for a given amount of time. Once that time is up, the AI will proceed to whatever the next target is (a path_wait with no target is pretty pointless). <br />
<br />
A path_wait node appears as a small orange box. It has a directional arrow, but that has no affect on which direction the AI faces in the first place. However, you can set the angle key on the path either by rotating the entity or by setting the key directly to make the AI turn and face this direction before starting to wait. '''Important:''' If the angle is 0 make sure it is actually on the entity and not just default.<br />
<br />
A path_wait node should have a "wait" property, with the number of seconds the AI should wait there before proceeding. It can also have a "wait_max" property which will vary the repeat time. So for example...<br />
<br />
* wait 30<br />
* wait_max 40 <br />
<br />
...will cause the AI to wait between 30 to 40 seconds before proceeding. If wait_max is set to 0, the AI will always wait exactly the time specified in wait before proceeding. If you set wait to 0, the AI will wait between 0 seconds and the time specified in wait_max. Default values are 2 seconds for wait, and 0 seconds for wait_max, so the AI will always wait exactly 2 seconds.<br />
<br />
In the following example, A and B are path_corners, and the small orange box is a path_wait entity. On map start, the AI will walk to A and wait there for the required amount of time, then turn and proceeds to B.<br />
<br />
[[image:pathfinding3.jpg]]<br />
<br />
Note that it does not matter '''where''' the path_wait node is placed. The AI does not actually follow the orange lines (this is not really intuitive, I know). The example below would cause the exact same behaviour as the example above--in both cases the AI will walk directly from A to B.<br />
<br />
[[image:pathfinding4.jpg]]<br />
<br />
<br />
<br />
Another useful example for path_wait is that of the stationary guard who turns to look in different directions periodically. This can be schematically represented (arrows indicate target links) as:<br />
<br />
AI -> path_corner1 -> path_wait1 -> path_wait2 -> path_corner1<br />
<br />
Example properties for the path_wait are:<br />
wait: 5 (minimum time to wait on action)<br />
wait_max: 10 (maximum time to wait on action)<br />
angle: 0 ('''Important''': this property is essential for proper function even if the angle is 0)<br />
<br />
<br />
The AI walks to or stands at the path_corner. The next action is to do what is indicated by the first path_wait. In this example, it tells the AI to face a particular direction for a certain period of time. This then targets a second path_wait which has the AI face a different direction for a certain period of time. To complete the cycle, the second path_wait then targets the original path_corner. The path_corners are necessary because again, the path_wait doesn't contain pathing or location information. Without the path_corner, if the AI is caused to wander (e.g. becomes alerted), it might not return to the original standing spot, and instead will do the look angles right where it stands. The path_corner assures the AI returns to its original position.<br />
<br />
== path_turn == <br />
<br />
This behaviour node tells an AI to turn in place to face a chosen direction. It does not make the AI walk anywhere. This is the one node where the directional arrow does seem to matter--the AI turns to face the same direction as the arrow. Alternately, you can use the property "angle" and the values below:<br />
<br />
* 0 = East (X)<br />
* 90 = North (Y)<br />
* 180 = West (-X)<br />
* 270 = South (-Y)<br />
* 360 = East(X)<br />
<br />
(Actually, to be more accurate, rotating the entity automatically adds the "angle" property to the entity. If you just leave the arrow facing the way it is when you create the entity, there will be no "angle" property, and therefore the AI will not turn.)<br />
<br />
== path_anim ==<br />
<br />
This is a behaviour node that makes the AI play an animation, once. When that animation is done, it proceeds to the next target (if any). This could be used to make an AI walk over to a bookshelf and play a 'reaching out' animation, for example. Other possibilities include peering through a window, picking a carrot off a table and eating it, or running to a spot and cowering. <br />
<br />
The syntax proper syntax is:<br />
<br />
anim [animation name]<br />
<br />
You can see the list of animations names here: [[Animation List]]. Do not use the name of the actual animation file. <br />
<br />
A path_anim can have only one animation, but it is possible for a single entity to target more than one path_anim. The AI will pick one of the path_anim nodes at random and play that animation.<br />
<br />
When you first create the path_anim entity, the directional arrow is meaningless. However, if you rotate the entity, the "angle" property is added to the entity and is updated based on which direction the arrow is pointing. That property indicates the direction the AI will face while playing the animation. '''This value appears to be necessary to make the animation work.'''<br />
<br />
Tip: Animation blending doesn't seem to do very much, so AI often "snap" into position from walking to playing the animation. For a more natural look, add a path_wait of a few seconds first, so AI transition to their idle pose before playing the animation.<br />
<br />
== path_lookat ==<br />
<br />
This does not stop the AI, but they will turn their head and look somewhere specific as they walk to their next target. For the next ''wait'' seconds, turn head to look at the entity given by the ''focus'' spawnarg (defaults to looking at the path_lookat entity itself). This is useful if you want to make sure an AI is looking at a specific spot (or away from a certain spot) during their patrol. Note the focus entity must not be obscured by monsterclip.<br />
<br />
== path_sit ==<br />
<br />
This is a behaviour node that makes the AI sit down at its current location. See [[Sitting Behaviour for AI]] for more information.<br />
<br />
== path_waitfortrigger ==<br />
<br />
Waits at a given place until triggered, then proceeds to the next target. This is useful if you want some control over exactly where the AI is when the players first see it.<br />
<br />
The "path_waitfortrigger" basically operates like a wall, blocking the AI from proceeding until triggered.<br />
<br />
Here are the steps for future reference. Let's say you want an AI to stand somewhere until a player triggers him, then you want him to walk to path_corner 1.<br />
<br />
1. Make a "path_waitfortrigger" pathnode, and have it target "path_corner_1".<br />
<br />
2. Have the AI target the "path_waitfortrigger" pathnode.<br />
<br />
3. Create a trigger_once entity, and target the AI.<br />
<br />
The AI will stand where they are at map start and behave as if there are no pathnodes set (ie, he plays idle animations and can be alerted). When the player goes through the trigger, the "path_waitfortrigger" is cleared and the AI will proceed to path_corner_1.<br />
<br />
I've tried a few different setups and gotten unusual results...more testing needed.<br />
<br />
== path_interact ==<br />
<br />
This lets the AI interact with an entity (for example a button) in a similar way to frobbing. This will only work for buttons etc, not for inventory items and moveables. The AI will stop and look at the entiy while interacting, but not walk to it, so a path_corner next to the entity is required. AI will use normal doors and elevators without needing a path_interact (confirmation needed). However, this could be used to make AI turn on lightswitches, open mechanical doors, etc.<br />
<br />
You need to add these spawnargs to the path_interact entity:<br />
<br />
ent <name of entity to be frobbed by AI><br />
<br />
target <next path entity (if any)><br />
<br />
<br />
= How to Make AI do Random Interesting Things (RIT) =<br />
<br />
''by Sotha''<br />
<br />
You can use the above to make individual AI seem to do Random Interesting Things (RIT) when entering a room. Note that it will work with basic dendritic AI, so you could have multiple AI's running in several rooms doing things.<br />
<br />
1) Build a room with RITs. A statue. A few chairs. Maybe a lit fireplace.<br />
<br />
2) On each RIT place the necessary interaction path_nodes to make an AI interact with them: path_corner to walk over to them; path_sit on each of the chairs, path_anims for warming hands at the fireplace and standing in front of the statue and pondering, etc (A, B & C in image).<br />
<br />
3) Place two path_waits (1 & 2 in image) on the ceiling of the room. (They could be anywhere in the room, but it is easiest to manage if they are in the ceiling.)<br />
<br />
4) Name one of the path_waits "enter_room_decide_what_to_do." (1) From that path_wait target each of the RIT path_corners. Set the path_wait "wait 0". so AI won't stop there. The idea is to use the path_wait as a simple decision making node. Be sure that the path_wait has no angle-spawnarg. If it does, the AI will turn towards the angle each time he targets the node.<br />
<br />
5) Name the other path_wait "exit_room_decide_what_to_do." (2) Make each RIT final path_node target this path_wait. Make the path_wait target other rooms with similar decision making path_waits.<br />
<br />
6) Done.<br />
<br />
[[Image:Rits.jpg]] <br />
<br />
AI will come into the room, select A, B or C at random, and then leave. Next time they enter, they'll again pick at random.<br />
<br />
This could be used to make servants to run around a mansion, cleaning, making food, taking sitting breaks, visit the toilet, etc. You could build room decision making network separately for different AI. Servants clean, cook and take breaks. Guards patrol, make random deviations once in a while, and of course take breaks. Controlling the RIT path_corner chance-spawnarg gives you control what RITs the AI do more likely.<br />
<br />
Please see the dedicated RIT network article for more details. [[RIT Networks]]<br />
<br />
<br />
= Switching from one Path network to another =<br />
<br />
Suppose you want to have an AI patrol outside a mansion for the first part of a mission, and then change his route to patrol in another location later?<br />
<br />
It is possible to change the "target" property on a path_corner by using ''atdm:target_changetarget.''<br />
<br />
Target the atdm:target_changetarget entity at the pathnode you wish to alter. Use the following spawnargs:<br />
<br />
"add" "[new path_corner]"<br />
and/or<br />
"remove" "[old path_corner]"<br />
<br />
Then add a trigger that targets the atdm:target_changetarget.<br />
<br />
When triggered, the new path_corner will be added and the old removed, sending the AI to a new path network. This no doubt has vast potential for variation and creativity that has yet to be explored. One simple example would be a "changing of the guard" moment, where some guards leave their posts and go to their barracks to sleep, while others take over for them.<br />
<br />
'''Other ideas:'''<br />
<br />
'''Doormen'''-- An AI (or the player) walks up to the door and knocks on it. AI inside is triggered to walk over to the door and open it, then go back to his regular duties.<br />
<br />
'''Abandon ship!''' -- When triggered, all AI drop what they're doing and start running for the exits.<br />
<br />
'''Lights out!''' -- At a specific time, all AI stop what they're doing and walk to their beds to go to sleep.<br />
<br />
'''Re-use, recycle''' -- AI that are stuck back in a portion of the map the player won't be coming back to could be told to walk to a new portion of the map and assume some job there.<br />
<br />
It''''s a trap!''' -- Player walks down a hall and hits a trigger that causes AI to quickly position themselves at the only exits.<br />
<br />
= Flee Points =<br />
<br />
<br />
Do NOT target the AI to a flee point; AI will automatically go to a flee point if in danger. Just make available path_flee_point entities at suitable places where you would like your AI to flee to.<br />
<br />
On the path_flee_point entity:<br />
<br />
"is_guarded", a fleeing AI, eg, a civilian, would give this preference (but it is up to the mapper to actually provide a guard there.)<br />
<br />
"team", only AI on this team would use this flee point, also required for "friendly" flee points per below.<br />
<br />
This is how the code works:<br />
* The AI tries to determine the nearest friendly (their team specified) guarded flee point and flee to it.<br />
* If there is no friendly guarded flee point, the AI tries to find the nearest friendly flee point (on friendly team) and run to it.<br />
* If this also fails, the AI tries to find an AAS area far from the enemy and run there.<br />
* If the enemy is still visible when the AI reaches his destination, he chooses the farthest friendly guarded flee point to run to, <br />
* if this fails, the farthest friendly flee point, <br />
* and if this also fails falls back to choosing an AAS area far from the enemy to run to.<br />
* So neither the priority nor the target spawn arg have any function here, it is not possible to weight the flee points. The AI will choose one automatically.<br />
<br />
A problem occurs when the AI doesn't find any appropriate flee points but also no AAS area that is far away enough from the enemy. In this case, he will just stand there. Maybe he should either cower and be afraid in this case or just run around like a mad chicken?<br />
<br />
Whether a fleeing AI passes on info to other AI as to the source of their alert (ie so armed guard would go to investigate to the right place whereas another civilian might also flee to the farthest point.)<br />
Yes, they do. The cry for help bark is propagated to other AI and carries information about the last alert position.<br />
<br />
Armed AI will also flee if their health points drop to a certain level? Where is that determined?<br />
This is determined by the health_critical spawn arg.<br />
<br />
= Untested Nodes =<br />
<br />
I have not personally tested the following, so I'm just going by their editor descriptions. They may or may not work as described.<br />
<br />
<br />
== path_cycleanim ==<br />
<br />
The AI stays in place and loops the selected animation, either for a specified amount of time (using the 'wait' property) or until triggered. Syntax needed.<br />
<br />
== path_hide ==<br />
<br />
Supposedly deactivates and stops rendering the AI. <br />
<br />
Turns out this doesn't work well with TDM...makes AI invisible but they still talk and occupy space. To remove an AI from the map, try grayman's approach:<br />
<br />
Create a [b]func_remove[/b] with this spawnarg:<br />
<br />
"target" "<AI's name>"<br />
<br />
At the point in his path where you want him to disappear, place a [b]trigger_once_entityname[/b] with these spawnargs:<br />
<br />
"entityname" "<AI's name>"<br />
"target" "<func_remove's name>"<br />
<br />
When the AI walks through the [b]trigger_once_entityname[/b], it recognizes him, triggers the [b]func_remove[/b], and that takes the AI out of the game.<br />
<br />
I wrapped the AI's final path corner in a trigger_once_entityname and gave the trigger the keyword pair "entityname <AI_name>". (The docs don't tell you about this key, but the game will error out if it's not there, and tell you it's missing. A classic "trial by error".)<br />
<br />
== path_show ==<br />
<br />
Starts rendering the AI. I would assume this one would be linked to a path_waitfortrigger, to create AI that spawn when triggered. This could be used to create the effect that an AI just came through a doorway or around a corner.<br />
<br />
== path_attack ==<br />
<br />
Used to script AI attacking a particular enemy, for scripted sequences I guess. AI will continue on to the next path entity if it kills the enemy.<br />
<br />
Questions: How do you define who the AI attacks?<br />
<br />
[Fidcal]: Just found this - "Character will attack the character specified by 'enemy' key. Character will go to next path when enemy dies or when activated." Not tested.<br />
<br />
<br />
<br />
{{tutorial-editing}}</div>RJFerrethttps://wiki.thedarkmod.com/index.php?title=Triggers&diff=17814Triggers2014-07-07T20:52:28Z<p>RJFerret: /* Triggering via Path Nodes */ +wikilink</p>
<hr />
<div>There are many different ways of triggering [[Entity|entities]], the Trigger entities themselves, as well as through [[Stim/Response]], [[Conversations]], Movers, [[Objectives]], and more. How the trigger occurs will typically dictate which manner you choose for your map. <br />
<br />
=Triggers=<br />
To create triggers that rely on boundaries (once, multiple and their derivations), you need to drag out a worldspawn brush, right-click, select "Create Entity". (They will not function if abutted against others.) Triggers need to be connected to their subjects, either via "Connect Selected Entities" menu option/shortcut key, or adding "Target", "Target0", "Target1" or subsequent "Target"# spawnargs. The triggers below are listed roughly by frequency of usage, with related triggers beneath.<br />
<br />
==trigger_once==<br />
When the origin of an entity is within the bounds of this entity, the target(s) will be triggered, then the trigger_once is removed. (Note, to resize the brush after creating the entity, select it then press Tab once.)<br />
<br />
==trigger_once_entityname==<br />
Similar to [[Triggers#trigger_once|trigger_once]], but may be set to only respond to the entity specified by the spawnarg, "entityname". Note the entity must move into the boundaries itself, not be moved by the player (AI walking themselves for example). (If you want something to happen based on the player dropping or placing an item somewhere, use the [[Objectives]] system instead.)<br />
<br />
==trigger_multiple==<br />
Similar to [[Triggers#trigger_once|trigger_once]] but will activate again and again, use "Wait" spawnarg to control how many seconds between triggerings. <br />
<br />
==trigger_entityname ==<br />
Similar to [[Triggers#trigger_multiple|trigger_multiple]] but only reacts to the entity defined by the "entityname" spawnarg.<br />
<br />
== trigger_facing ==<br />
Also similar to [[Triggers#trigger_multiple|trigger_multiple]], but requires the triggering entity to be within 30° of the specified "angle" spawnarg. For details see [[Trigger Facing]].<br />
<br />
==trigger_relay ==<br />
Most commonly used to trigger many targets, or do so after a delay (per the "delay" spawnarg). May be set to only work once (spawnarg "wait" "-1") or limit firing based upon how many seconds have passed. The "random" spawnarg may be used with "wait" to vary the firings. Very useful as the target of worldspawn, to trigger things at map start (since worldspawn currently only activate one "Target"), or as the target of Objectives.<br />
<br />
==trigger_count ==<br />
This will fire at it's targets upon a specific number of times being triggered itself, based upon the "count" spawnarg. If "count" "3" is set, it will do nothing until the third triggering. <br />
<br />
== trigger_timer ==<br />
This trigger will fire repeatedly every "wait" # seconds. The spawnarg "start_on" defines if it should do so at the start of the map, or wait to be triggered (defaults to 0, off at map start). Spawnarg "random" adds variability to the triggerings.<br />
<br />
== trigger_fade ==<br />
Will cause the display to fade or dissolve to a specified color. The spawnarg "fadeColor" specifies which color, and how transparent in RGBA (red, green, blue, and alpha, ranging from 0-1). Default is fade to black: "fadeColor" "0 0 0 1". To fade up from whatever, use alpha of 0, IE to fade up from black, "0 0 0 0". "fadeTime" controls how quickly the fade transpires.<br />
<br />
== trigger_hurt ==<br />
Applied to a worldspawn brush to define boundaries à la a [[Triggers#trigger_multiple|trigger_multiple]], by default it causes 10 points of damage/second to the activator (player or AI). It may be triggered on/off. The spawnarg, "delay" may be set to vary frequency of damage application. One of various "def_damage" may be specified, generally found in the root directory of the entities, or to see specific details, in the defs file, "damage.def". Note those referencing "triggerhurt" simply cause damage, while others feature additional effects such as push and knockbacks (launching the player away).<br />
<br />
If you need varying amount of damage based on proximity, the [[Stim/Response_Key/Values#Damage_Stim|Stim/Response]] system offers control of various types of falloff.<br />
<br />
== trigger_presize ==<br />
Akin to [[Triggers#trigger_multiple|trigger_multiple]] without the need of creating a brush first, and defaults to not being touched by players/AIs, but triggered by other entities/script.<br />
<br />
== trigger_touch ==<br />
Continuously checks if entities are touching, costly performance wise, probably done via [[Objectives]] more efficiently.<br />
<br />
=Triggering via Path Nodes=<br />
Several [[Path Nodes|path nodes]] will trigger their targets upon AI completing the associated node action (as of TDM v2.02). These include, path_corner (upon reaching), path_turn, path_wait, path_sit, path_sleep and path_anim.<br />
<br />
=Triggering Stim/Response=<br />
'''To Trigger Something Else:'''<br />
<br />
Any Response type may have an effect of "Trigger", in which another entity selected is triggered. Note the "Trigger" effect is all the way at the bottom of the drop down, which might not be displayed on screen (Toggle Effect is the last displayed on mine), you may cursor down or use the End key to get to Trigger.<br />
<br />
'''Be Triggered:'''<br />
<br />
Within the [[Stim/Response]] editor, add a response stim set to "Trigger", now when this entity is targeted, whatever specified effect will occur.<br />
<br />
An example would be to not have something able to be frobbed until something obscuring it is removed or opened. Make the response effect "Set Frobable" for the entity in question, and check "frobability" on. Now when the item is triggered, by a door, or frob response on something in front moved/picked up, it will become frobable.<br />
<br />
=Triggering via Conversation=<br />
The command, [[Conversations#Conversation Commands 2|ActivateTarget]] will trigger the specified entity at that time in the Conversation script.<br />
<br />
=Triggering via Doors, Buttons, Levers, Movers=<br />
[[Doors]] trigger their targets by default upon opening (spawnarg "trigger_on_open" "1"). They may also trigger when completely open by changing "trigger_when_opened" to 1 instead of the default 0, or when fully closed via "trigger_on_close". Note, those conditions on Buttons came from doors, so are counter-intuitive.<br />
<br />
=Triggering via Objectives=<br />
In the [[Objectives Editor]] you may select an entity to be triggered upon an objective succeeding or failing. Therefore all the possible objective conditions may become trigger events (knock out an AI, move an object away from another or to a spot, cause another objective to become visible, disappear or complete, etc.)<br />
<br />
=Triggering via Worldspawn=<br />
You may set "Target" on Worldspawn (usually at a trigger_relay since it only may target one entity currently) to cause things to be triggered at map start. If you use this to kill an AI or other affect with audio, note if in range of the player's start, it will be heard during the fade up from black.<br />
<br />
=Triggering via Lights=<br />
Lights trigger their target(s) both upon being extinguished and lit. This is useful to match window glow to actual light condition. Depending on the light, it may be tricky to set the targets however. A basic light entity can simply have target(s) spawnargs, but a candle, lamp or torch with attached flame entity, you need to use the "set" spawnarg. For example, "set target0 on flame" "EntityToBeTriggered".<br />
<br />
=Trigger a Script=<br />
Point any trigger at a target_callscriptfunction entity and give it the spawnarg, "call" ''ScriptFunctionName'', where ''ScriptFunctionName'' matches "void ''ScriptFunctionName''()" in the map's .script file. See [[Scripting_basics#Script_invocation|script invocation]] for more info.<br />
<br />
[[Category:Editing]]</div>RJFerrethttps://wiki.thedarkmod.com/index.php?title=Triggers&diff=17813Triggers2014-07-07T20:50:30Z<p>RJFerret: +path nodes section</p>
<hr />
<div>There are many different ways of triggering [[Entity|entities]], the Trigger entities themselves, as well as through [[Stim/Response]], [[Conversations]], Movers, [[Objectives]], and more. How the trigger occurs will typically dictate which manner you choose for your map. <br />
<br />
=Triggers=<br />
To create triggers that rely on boundaries (once, multiple and their derivations), you need to drag out a worldspawn brush, right-click, select "Create Entity". (They will not function if abutted against others.) Triggers need to be connected to their subjects, either via "Connect Selected Entities" menu option/shortcut key, or adding "Target", "Target0", "Target1" or subsequent "Target"# spawnargs. The triggers below are listed roughly by frequency of usage, with related triggers beneath.<br />
<br />
==trigger_once==<br />
When the origin of an entity is within the bounds of this entity, the target(s) will be triggered, then the trigger_once is removed. (Note, to resize the brush after creating the entity, select it then press Tab once.)<br />
<br />
==trigger_once_entityname==<br />
Similar to [[Triggers#trigger_once|trigger_once]], but may be set to only respond to the entity specified by the spawnarg, "entityname". Note the entity must move into the boundaries itself, not be moved by the player (AI walking themselves for example). (If you want something to happen based on the player dropping or placing an item somewhere, use the [[Objectives]] system instead.)<br />
<br />
==trigger_multiple==<br />
Similar to [[Triggers#trigger_once|trigger_once]] but will activate again and again, use "Wait" spawnarg to control how many seconds between triggerings. <br />
<br />
==trigger_entityname ==<br />
Similar to [[Triggers#trigger_multiple|trigger_multiple]] but only reacts to the entity defined by the "entityname" spawnarg.<br />
<br />
== trigger_facing ==<br />
Also similar to [[Triggers#trigger_multiple|trigger_multiple]], but requires the triggering entity to be within 30° of the specified "angle" spawnarg. For details see [[Trigger Facing]].<br />
<br />
==trigger_relay ==<br />
Most commonly used to trigger many targets, or do so after a delay (per the "delay" spawnarg). May be set to only work once (spawnarg "wait" "-1") or limit firing based upon how many seconds have passed. The "random" spawnarg may be used with "wait" to vary the firings. Very useful as the target of worldspawn, to trigger things at map start (since worldspawn currently only activate one "Target"), or as the target of Objectives.<br />
<br />
==trigger_count ==<br />
This will fire at it's targets upon a specific number of times being triggered itself, based upon the "count" spawnarg. If "count" "3" is set, it will do nothing until the third triggering. <br />
<br />
== trigger_timer ==<br />
This trigger will fire repeatedly every "wait" # seconds. The spawnarg "start_on" defines if it should do so at the start of the map, or wait to be triggered (defaults to 0, off at map start). Spawnarg "random" adds variability to the triggerings.<br />
<br />
== trigger_fade ==<br />
Will cause the display to fade or dissolve to a specified color. The spawnarg "fadeColor" specifies which color, and how transparent in RGBA (red, green, blue, and alpha, ranging from 0-1). Default is fade to black: "fadeColor" "0 0 0 1". To fade up from whatever, use alpha of 0, IE to fade up from black, "0 0 0 0". "fadeTime" controls how quickly the fade transpires.<br />
<br />
== trigger_hurt ==<br />
Applied to a worldspawn brush to define boundaries à la a [[Triggers#trigger_multiple|trigger_multiple]], by default it causes 10 points of damage/second to the activator (player or AI). It may be triggered on/off. The spawnarg, "delay" may be set to vary frequency of damage application. One of various "def_damage" may be specified, generally found in the root directory of the entities, or to see specific details, in the defs file, "damage.def". Note those referencing "triggerhurt" simply cause damage, while others feature additional effects such as push and knockbacks (launching the player away).<br />
<br />
If you need varying amount of damage based on proximity, the [[Stim/Response_Key/Values#Damage_Stim|Stim/Response]] system offers control of various types of falloff.<br />
<br />
== trigger_presize ==<br />
Akin to [[Triggers#trigger_multiple|trigger_multiple]] without the need of creating a brush first, and defaults to not being touched by players/AIs, but triggered by other entities/script.<br />
<br />
== trigger_touch ==<br />
Continuously checks if entities are touching, costly performance wise, probably done via [[Objectives]] more efficiently.<br />
<br />
=Triggering via Path Nodes=<br />
Several path nodes will trigger their targets upon AI completing the associated node action (as of TDM v2.02). These include, path_corner (upon reaching), path_turn, path_wait, path_sit, path_sleep and path_anim. <br />
<br />
=Triggering Stim/Response=<br />
'''To Trigger Something Else:'''<br />
<br />
Any Response type may have an effect of "Trigger", in which another entity selected is triggered. Note the "Trigger" effect is all the way at the bottom of the drop down, which might not be displayed on screen (Toggle Effect is the last displayed on mine), you may cursor down or use the End key to get to Trigger.<br />
<br />
'''Be Triggered:'''<br />
<br />
Within the [[Stim/Response]] editor, add a response stim set to "Trigger", now when this entity is targeted, whatever specified effect will occur.<br />
<br />
An example would be to not have something able to be frobbed until something obscuring it is removed or opened. Make the response effect "Set Frobable" for the entity in question, and check "frobability" on. Now when the item is triggered, by a door, or frob response on something in front moved/picked up, it will become frobable.<br />
<br />
=Triggering via Conversation=<br />
The command, [[Conversations#Conversation Commands 2|ActivateTarget]] will trigger the specified entity at that time in the Conversation script.<br />
<br />
=Triggering via Doors, Buttons, Levers, Movers=<br />
[[Doors]] trigger their targets by default upon opening (spawnarg "trigger_on_open" "1"). They may also trigger when completely open by changing "trigger_when_opened" to 1 instead of the default 0, or when fully closed via "trigger_on_close". Note, those conditions on Buttons came from doors, so are counter-intuitive.<br />
<br />
=Triggering via Objectives=<br />
In the [[Objectives Editor]] you may select an entity to be triggered upon an objective succeeding or failing. Therefore all the possible objective conditions may become trigger events (knock out an AI, move an object away from another or to a spot, cause another objective to become visible, disappear or complete, etc.)<br />
<br />
=Triggering via Worldspawn=<br />
You may set "Target" on Worldspawn (usually at a trigger_relay since it only may target one entity currently) to cause things to be triggered at map start. If you use this to kill an AI or other affect with audio, note if in range of the player's start, it will be heard during the fade up from black.<br />
<br />
=Triggering via Lights=<br />
Lights trigger their target(s) both upon being extinguished and lit. This is useful to match window glow to actual light condition. Depending on the light, it may be tricky to set the targets however. A basic light entity can simply have target(s) spawnargs, but a candle, lamp or torch with attached flame entity, you need to use the "set" spawnarg. For example, "set target0 on flame" "EntityToBeTriggered".<br />
<br />
=Trigger a Script=<br />
Point any trigger at a target_callscriptfunction entity and give it the spawnarg, "call" ''ScriptFunctionName'', where ''ScriptFunctionName'' matches "void ''ScriptFunctionName''()" in the map's .script file. See [[Scripting_basics#Script_invocation|script invocation]] for more info.<br />
<br />
[[Category:Editing]]</div>RJFerrethttps://wiki.thedarkmod.com/index.php?title=Fan_Missions_for_The_Dark_Mod&diff=17809Fan Missions for The Dark Mod2014-07-05T14:16:56Z<p>RJFerret: +Poets</p>
<hr />
<div>__NOTOC__<br />
{{infobox|<center>'''Big Ugly Disclaimer:'''</center><br> '''The Dark Mod''' team does not necessarily support or endorse content listed here, and only hosts missions listed on the [http://www.thedarkmod.com/ official TDM website]. This is a community maintained list, and an ongoing work in progress. Most of the mirror links in this list are dead or are for missions that are not 2.0 compliant. Mission entries which are suspected to violate copyright must be text-only, and cannot contain links. Report and/or remove links found in violation of this rule.}}<br />
<br />
<br />
* For details about editing this table, see [http://modetwo.net/darkmod/wiki/index.php?title=Fan_Missions_for_The_Dark_Mod#Editing_This_Table below].<br />
* For details about how to install Fan Missions please visit: [[Installing and Running Fan Missions]]<br />
* To sort by a different criterion, click the [[Image:Sort none.gif]] icon in the relevant column header.<br />
<br />
<br />
{|class="wikitable sortable" border=1 style="border-collapse: collapse;" cellspacing=0 cellpadding=2 width=100%<br />
|-<br />
!bgcolor=#d0d0e0 width="21%"|Fan Mission Title<br />
!bgcolor=#d0d0e0 width="12%"|Author(s)<br />
!bgcolor=#d0d0e0 width="9%" class="unsortable"|Links<br />
!bgcolor=#d0d0e0 width="5%"|First Release<br />
!bgcolor=#d0d0e0 width="4%"|Size (MB)<br />
!bgcolor=#d0d0e0 width="10%"|Series<br />
!bgcolor=#d0d0e0 width="13%"|Mission Type<br />
!bgcolor=#d0d0e0 width="6%"|Spiders and Undead<br />
|-<br />
<br />
<!--INSERT NEW MISSIONS BELOW THIS LINE--><br />
<br />
|-<br />
!align=left|{{TDM-FM|87|Poets and Peasants}}<br />
|Digi<br />
|{{Mirrorlink|https://drive.google.com/file/d/0B1HHvWAgbWGfTkI0SXFubXZucXM}}{{Forumlink|1=http://forums.thedarkmod.com/topic/16373-fan-mission-poets-peasants-by-digi-62914}}<br />
|2014-06-29<br />
|1<br />
|<br />
|Mansion/Estate FMs<br />
|<br />
|-<br />
<br />
<br />
|-<br />
!align=left|{{TDM-FM|85|A Reputation to Uphold}}<br />
|Springheel<br />
|{{Mirrorlink|http://www.mindplaces.com/follow.pk4}}{{Forumlink|1=http://forums.thedarkmod.com/topic/16204-fan-mission-a-reputation-to-uphold-by-springheel/}}<br />
|2014-04-18<br />
|25.5<br />
|Corbin<br />
|City Missions<br />
|<br />
|-<br />
<br />
<br />
|-<br />
!align=left|{{TDM-FM|86|Breaking out the Fence}}<br />
|Kyyrma<br />
|{{Mirrorlink|https://dl.dropboxusercontent.com/u/17706561/breakingout.pk4}}{{Forumlink|1=http://forums.thedarkmod.com/topic/16091-fan-mission-breaking-out-the-fence-17032014-by-kyyrma/}}<br />
|2014-03-17<br />
|11.6<br />
|In a Time of Need 2<br />
|City Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|84|A Noble Home}}<br />
|Goldwell, Bikerdude<br />
|{{Mirrorlink|http://www18.zippyshare.com/v/48473186/file.html}}{{Forumlink|1=http://forums.thedarkmod.com/topic/16085-fan-mission-80-a-noble-home-the-accountant-prologue-by-goldwell-bikerdude-20140314/}}<br />
|2014-03-14<br />
|23<br />
|The Accountant<br />
|Mansion/Estate FMs<br />
|<br />
|-<br />
<br />
<br />
|-<br />
!align=left|{{TDM-FM|83|Inn Business}}<br>(v.1.48, 2014/03/08)<br />
|RJFerret<br />
|{{Mirrorlink|https://drive.google.com/file/d/0B81T2ZXLPqhTYWVaODRiSExGeGc}} {{Forumlink|1=http://forums.thedarkmod.com/topic/16018-fan-mission-inn-business-by-rjferret-20140303/}}<br />
|2014-03-03<br />
|6<br />
|<br />
|Mansion/Estate FMs<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|82|William Steele 3: Cleighmoor}}<br />
|grayman<br />
|{{Forumlink|http://forums.thedarkmod.com/topic/16011-fan-mission-cleighmoor-by-grayman-201431/#entry338349/}}<br />
|2014-03-01<br />
|38<br />
|William Steele 3<br />
|Sewer / Prison<br />
|none<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|81|William Steele 2: Home Again}}<br />
|grayman<br />
|{{Forumlink|http://forums.thedarkmod.com/topic/15919-fan-mission-home-again-by-grayman-2014212/page__fromsearch__1}}<br />
|2014-02-12<br />
|26<br />
|William Steele 2<br />
|Thieves' Highway / Rooftop<br />
|none<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|80|The Gatehouse}}<br />
|Bikerdude Goldchocobo<br />
|{{Mirrorlink|http://www.southquarter.com/tdm/fms/gatehouse.pk4}} {{Forumlink|http://forums.thedarkmod.com/topic/15844-fan-mission-the-gatehouse-by-bikerdude-goldchocobo-20140114/}}<br />
|2014-01-29<br />
|100<br />
|Remake of Evilartist's Doom 3 mod<br />
|Castle/Fortress Missions<br />
|Ghosts<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|79|Window of Opportunity}}<br>(v.1.43, 2014/01/01)<br />
|RJFerret<br />
|{{Mirrorlink|https://drive.google.com/file/d/0B81T2ZXLPqhTWTMzQXZtMVFBSG8}} {{Forumlink|1=http://forums.thedarkmod.com/topic/15727-fan-mission-window-of-opportunity-by-rjferret-20140101/}}<br />
|2014-01-01<br />
|7<br />
|<br />
|Outdoor/caves<br />
|Spiders (not in short mode)<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|78|In A Time Of Need}}<br />
|kyyrma<br />
| {{Mirrorlink|http://www.mediafire.com/download/a97or40t1xrybh3/timeofneed_v1.zip}} {{Forumlink|http://forums.thedarkmod.com/topic/15354-fan-mission-in-a-time-of-need-by-kyyrma-20131112/}}<br />
|2013-11-12<br />
|5.6<br />
|In a Time of Need 1<br />
|Mansion/Estate FMs<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|76|Requiem}}<br />
|Moonbo<br />
| {{Mirrorlink|http://www.mediafire.com/download/l6o3vvj9y78hu89/requiem.pk4}} {{Forumlink|http://forums.thedarkmod.com/topic/15101-fan-mission-requiem-by-gelo-moonbo-fleisher-2013106/}}<br />
|2013-10-08<br />
|107.3<br />
|[http://www.amazon.com/Shadowcursed-ebook/dp/B00BYEW02M Shadowcursed]<br />
|Lost Civilizations<br />
|Undead<br />
|-<br />
<br />
<br />
|-<br />
!align=left|{{TDM-FM|75|Vengeance for a Thief Part 2}}<br />
|Sir Taffsalot<br />
| {{Mirrorlink|https://dl.dropboxusercontent.com/u/17706561/vfat2.pk4}} {{Forumlink|http://forums.thedarkmod.com/topic/15051-fan-mission-vengeance-for-a-thief-part-2-by-sir-taffsalot-06092013/}}<br />
|2013-09-06<br />
|22<br />
|VFAT 2 and CUC 13<br />
|Museum Missions<br />
|<br />
|-<br />
<br />
<br />
|-<br />
!align=left|{{TDM-FM|74|Lords and Legacy}}<br />
|Kvorning<br />
| {{Mirrorlink|https://dl.dropboxusercontent.com/u/17706561/lordsnlegacy.pk4}} {{Forumlink|http://forums.thedarkmod.com/topic/15016-fan-mission-lords-legacy-by-kvorning-20130830/}}<br />
|2013-08-30<br />
|45<br />
|<br />
|Thieves' Highway / Rooftop<br />
|<br />
|-<br />
<br />
<br />
|-<br />
!align=left|{{TDM-FM|72|Not An Ordinary Guest}}<br />
|Fieldmedic<br />
| {{Mirrorlink|https://dl.dropboxusercontent.com/u/17706561/naog.pk4}} {{Forumlink|http://forums.thedarkmod.com/topic/14965-fan-mission-not-an-ordinary-guest-by-fieldmedic-20130801/}}<br />
|2013-08-01<br />
|79.6<br />
|CUC 13<br />
|City Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|71|Penny Dreadful: Grail of Regrets}}<br />
|Melan<br />
| {{Forumlink|http://forums.thedarkmod.com/topic/14952-fan-mission-penny-dreadful-by-melan-20130728/}}<br />
|2013-07-27<br />
|74<br />
|Penny Dreadful 1<br />
|Horror FMs<br />
|Undead and Spiders<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|70|Solar Escape 1}}<br />
|Tr00pertj<br />
| {{Forumlink|http://forums.thedarkmod.com/topic/14944-fan-mission-solar-escape-1/}}<br />
|2013-07-22<br />
|6<br />
|<br />
|Mansion/Estate FMs<br />
|Undead<br />
|-<br />
<br />
<br />
|-<br />
!align=left|{{TDM-FM|69|The Lich Queen's Demise}}<br />
|Sotha<br />
|{{Mirrorlink|https://dl.dropboxusercontent.com/u/17706561/lich_queens_demise.pk4}} {{Forumlink|http://forums.thedarkmod.com/topic/14826-fan-mission-the-lich-queens-demise-by-sotha-20130520/unread/}}<br />
|2013-05-20<br />
|97.6<br />
|Thomas Porter 6 CUC 13 (Winner)<br />
|Horror FMs<br />
|Undead<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|77|Old Habits Rebuild}}<br />
|Obsttorte<br />
|{{Bloodgate|mc.pk4}} {{Mirrorlink|http://www.mediafire.com/download/u2gwucibh17c45a/oldhabits.pk4}} {{Forumlink|http://forums.thedarkmod.com/topic/14827-fan-mission-old-habits-rebuild-by-obsttorte-20052013/}}<br />
|2013-05-20<br />
|28.6<br />
|<br />
|Mansion/Estate FMs<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|68|The Builder's Blocks}}<br />
|Jesps<br />
|{{Mirrorlink|https://dl.dropboxusercontent.com/u/17706561/builders_blocks.pk4}} {{Forumlink|http://forums.thedarkmod.com/topic/14592-unusual-gameplay-contest-fm-the-builders-blocks-by-jesps/}}<br />
|2013-03-18<br />
|2.85<br />
|CUC 13<br />
|<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|67|Crystal Grave}} <br>(v.2.0, 2013/02/09)<br />
|ERH+ Bikerdude<br />
|{{Mirrorlink|https://dl.dropbox.com/u/17706561/crystalgravev2.pk4}} {{Forumlink|http://forums.thedarkmod.com/topic/14510-fan-mission-crystal-grave-v2-by-erh-and-bikerdude-20130209/unread/}}<br />
|2011-11-15<br />
|12.4<br />
|<br />
|Horror FMs<br />
|Undead<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|66|The Builder Roads}}<br />
|Obsttorte<br />
|{} {{Forumlink|http://forums.thedarkmod.com/topic/14449-fan-mission-the-builder-roads-by-obsttorte-20130119/}}<br />
|2013-01-19<br />
|?<br />
|<br />
|Horror FMs <br />
|Ghosts<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|65|William Steele 1: In the North}}<br />
|grayman<br />
|{{Bloodgate|ws1_north.pk4}} {{Forumlink|http://forums.thedarkmod.com/topic/14214-fan-mission-in-the-north-by-grayman-20121020/}}<br />
|2012-10-20<br />
|39.8<br />
|William Steele 1<br />
|Mansion/Estate FMs<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|64|Old Habits}}<br />
|Obsttorte<br />
|{{Bloodgate|mc.pk4}} {{Mirrorlink|http://www.mediafire.com/download.php?andes2xnsonssfj}} {{Forumlink|http://forums.thedarkmod.com/topic/14206-fan-mission-old-habits-by-obsttorte-20121019/}}<br />
|2012-10-19<br />
|12.8<br />
|<br />
|Mansion/Estate FMs<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|63|Deceptive Shadows}}<br />
|ShadowHide<br />
|{{Bloodgate|DeceptiveShadows.pk4}} {{Mirrorlink|http://www.sendspace.com/file/jzr9s7}} {{Forumlink|http://forums.thedarkmod.com/topic/14103-fan-mission-deceptive-shadows-by-shadowhide-16sep12/}}<br />
|2012-09-16<br />
|22.4<br />
|<br />
|Pagan/Outdoor Missions<br />
|Spiders<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|62|Vengeance for a Thief: Part 1}}<br />
|Sir Taffsalot <br />
|{{Bloodgate|VFAT1.pk4}} {{Mirrorlink|https://dl.dropbox.com/u/17706561/VFAT1.pk4}} {{Forumlink|http://forums.thedarkmod.com/topic/14068-fan-mission-vengeance-for-a-thief-part-1-by-sir-taffsalot-06092012/}}<br />
|2012-09-06<br />
|20.9<br />
|VFAT 1<br />
|Jail/Prison Missions<br />
|<br />
|-<br />
<br />
<br />
|-<br />
!align=left|{{TDM-FM|61|The Phrase Book}}<br />
|Sotha<br />
|{{Bloodgate|phrase_book.pk4}} {{Mirrorlink|http://dl.dropbox.com/u/17706561/phrase_book.pk4}} {{Forumlink|http://forums.thedarkmod.com/topic/13799-fan-mission-the-phrase-book-by-sotha-20120512/}}<br />
|2012-05-11<br />
|24<br />
|Thomas Porter 5<br />
|Thieves' Highway / Rooftop<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|60|In Remembrance of Him}}<br />
|RPGista<br />
|{{Bloodgate|remembrance.pk4}} {{Mirrorlink|http://dl.dropbox.com/u/17706561/remembrance.pk4}} {{Forumlink|http://forums.thedarkmod.com/topic/13749-fan-mission-in-remembrance-of-him-by-rpgista/}}<br />
|2012-04-22<br />
|27.6<br />
|CBC 12<br />
|City Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|59|Rightful Property}}<br />
|jysk<br />
|{{Bloodgate|rightful.pk4}} {{Mirrorlink|http://dl.dropbox.com/u/17706561/rightful1.1b.pk4}} {{Forumlink|http://forums.thedarkmod.com/topic/13711-fan-mission-rightful-property-by-jysk-20120413/}}<br />
|2012-04-12<br />
|22.5<br />
|CBC 12<br />
|Bank Jobs<br />
|Spiders<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|58|Sneak and Destroy}}<br />
|SeriousToni<br />
|{{Bloodgate|kneipe24.pk4}} {{Mirrorlink|http://minus.com/mVcf61n3G/1f}} {{Forumlink|http://forums.thedarkmod.com/topic/13706-fan-mission-sneak-destroy-by-serioustoni-beginners-contest-2012/}}<br />
|2012-04-11<br />
|158<br />
|CBC 12<br />
|City Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|56|House of Theo}}<br />
|Theothesnopp<br />
|{{Bloodgate|houseoftheo.pk4}} {{Mirrorlink|http://www.gamefront.com/files/21053391/houseoftheo__2__2.pk4}} {{Forumlink|http://forums.thedarkmod.com/topic/13242-fan-mission-house-of-theo/}}<br />
|2011-12-04<br />
|6.2<br />
|<br />
|Castle/Fortress Missions<br />
|<br />
|-<br />
<br />
<br />
|-<br />
!align=left|{{TDM-FM|53|Dragon's Claw}}<br />
|Bikerdude, Flanders (map assets)<br />
|{{Bloodgate|claw.pk4}}{{Mirrorlink|http://www.gamefront.com/files/20948800/claw.pk4}} {{Forumlink|http://forums.thedarkmod.com/topic/13181-fan-missiondragons-claw-by-b1k3rdude-31102011/}}<br />
|2011-10-31<br />
|98<br />
|HSC 11<br />
|City Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|52|A Night to Remember}}<br />
|Fieldmedic<br />
|{{Bloodgate|antr.pk4}}{{Mirrorlink|http://www.mediafire.com/?d4hch59m4nef3dc}} {{Forumlink|http://forums.thedarkmod.com/topic/13177-fan-mission-a-night-to-remember-by-fieldmedic-20111030/}}<br />
|2011-10-31<br />
|32<br />
|HSC 11<br />
|Mansion/Estate FMs<br />
|Ghosts<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|51|The Creeps}}<br />
|Mortem Desino<br />
|{{Bloodgate|thecreeps.pk4}}{{Mirrorlink|http://www.gamefront.com/files/20939925/thecreeps.pk4}} {{Forumlink|http://forums.thedarkmod.com/topic/13176-fan-mission-creeps-the-20111030-by-mortem-desino/}}<br />
|2011-10-30<br />
|61<br />
|HSC 11<br />
|Horror FMs<br />
|Ghosts<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|50|House in Blackbog Hollow}}<br />
|Stumpy<br />
|{{Bloodgate|blackbog.pk4}}{{Mirrorlink|http://www.bookofages.co.uk/doom3/mods/blackbog.html}} {{Forumlink|http://forums.thedarkmod.com/topic/13172-fan-mission-house-in-blackbog-hollow-by-stumpy-20111028/}}<br />
|2011-10-28<br />
|12<br />
|HSC 11<br />
|Horror FMs<br />
|Undead and Spiders<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|49|Let Sleeping Thieves Lie}}<br />
|Sir Taffsalot, Bikerdude<br />
|{{Bloodgate|lstl.pk4}}{{Mirrorlink|http://www.mediafire.com/?zkd1jn4lpwgioh9}} {{Forumlink|http://modetwo.net/darkmod/index.php?/topic/13153-let-sleeping-thieves-lie-by-sir-taffsalot-bikerdude-20102011/}}<br />
|2011-10-20<br />
|13<br />
|<br />
|Tombs, Catacombs & Crypts<br />
|Undead<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|48|Samhain Night}}<br />
|PranQster<br />
|{{Bloodgate|samhain.pk4}}{{Mirrorlink|http://jdchoate.mcn.org/games/darkmod/samhain.zip}} {{Forumlink|http://modetwo.net/darkmod/index.php?/topic/13127-fan-mission-samhain-night-on-bone-hill-by-pranqster-20111009/}}<br />
|2011-10-09<br />
|10<br />
|HSC 11<br />
|Horror FMs<br />
|Undead and Spiders<br />
|-<br />
<br />
<br />
|-<br />
!align=left|{{TDM-FM|47|A Score to Settle}}<br />
|Springheel<br />
|{{Bloodgate|score_to_settle.pk4}}{{Mirrorlink|http://www.mediafire.com/?f3o7hm4h4ew7o3l}} {{Forumlink|http://modetwo.net/darkmod/index.php?/topic/12894-fan-mission-%2348-a-score-to-settle-by-springheel-20110701/}}<br />
|2011-07-01<br />
|135<br />
|Corbin<br />
|City Missions<br />
|<br />
|-<br />
<br />
<br />
|-<br />
!align=left|{{TDM-FM|46|Siege Shop}}<br>(v3.0 2013/10/10)<br />
|PranQster and Lowenz<br />
|{{Bloodgate|siegeshop.pk4}}{{Mirrorlink|http://jdchoate.mcn.org/games/darkmod/siegeshop.pk4}} {{Forumlink|http://modetwo.net/darkmod/index.php?/topic/12874-fan-mission-the-siege-shop-by-pranqster-20110626/}}<br />
|2011-06-26<br />
|20.51<br />
|<br />
|Castle/Fortress Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|44|Alberic's Curse}}<br />
|Bikerdude<br />
|{{Bloodgate|alberic.pk4}} {{Mirrorlink|http://www.gamefront.com/files/20459738/alberic.pk4}} {{Forumlink|http://modetwo.net/darkmod/index.php?/topic/12850-fan-mission-alberics-curse-by-b1k3rdude-20062011/}}<br />
|2011-06-20<br />
|29<br />
|CSC 11 (Winner), T2 FM homage<br />
|Church/Cathedral<br />
|Undead and Spiders<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|45|Reap as you sow}}<br />
|Fieldmedic<br />
|{{Bloodgate|reap.pk4}} {{Forumlink|http://modetwo.net/darkmod/index.php?/topic/12849-fan-mission-reap-as-you-sow-by-fieldmedic-20110619/}}<br />
|2011-06-19<br />
|52<br />
|CSC 11<br />
|Daylight Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|43|Rake Off}}<br />
|Jesps<br />
|{{Bloodgate|rake_off.pk4}} {{Forumlink|http://modetwo.net/darkmod/index.php?/topic/12846-fm-rake-off-19-06-2011/}}<br />
|2011-06-19<br />
|8<br />
|CSC 11, Selis Woderose 2<br />
|Castle/Fortress Missions <br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|42|Winter Harvest}}<br>(v2.0 2011/07/24 with Bikerdude)<br />
|ShadowHide<br />
|{{Bloodgate|winterharvest.pk4}} {{Forumlink|http://modetwo.net/darkmod/index.php?/topic/12690-seasons-contest-entry-winter-harvest-by-shadowhide/}}<br />
|2011-05-08<br />
|10<br />
|CSC 11<br />
|Pagan/Outdoor Missions<br />
|Spiders<br />
|-<br />
<br />
<br />
|-<br />
!align=left|{{TDM-FM|41|Fiasco at Fauchard Street}}<br />
|Melan<br />
|{{Bloodgate|fauchard.pk4}} {{Mirrorlink|https://rapidshare.com/files/460141132/fauchard.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/12655-fan-mission-fiasco-at-fauchard-street-by-melan-20110501//}}<br />
|2011-05-01<br />
|62<br />
|Talbot 3<br />
|Thieves' Highway / Rooftop<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|40|Mandrasola}}<br />
|Sotha<br />
|{{Bloodgate|mandrasola.pk4}} {{Mirrorlink|http://www.mediafire.com/?2ox2nbhh796ne71}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/12575-fan-mission-mandrasola-by-sotha-20110410/}}<br />
|2011-04-10<br />
|10<br />
|Thomas Porter 0, CSC 11<br />
|City Missions<br />
|Undead<br />
|-<br />
<br />
|-<br />
!align=left|[http://www.gamefront.com/files/20167184/yantdm1.1.pk4 Q4 Conversion: Yan's Test]<br />
|Bikerdude<br />
|{{Mirrorlink|http://www.mediafire.com/?2nona089nzi00sv}} {{Mirrorlink|http://www.gamefront.com/files/20167184/yantdm1.1.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/12506-fan-mission-q4-map-conversion-yantdm1-280311/}}<br />
|2011-03-28<br />
|28<br />
|<br />
|<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|38|The Transaction}}<br />
|Sotha<br />
|{{Bloodgate|transaction.pk4}} {{Mirrorlink|http://www.mediafire.com/?ux7mx79wumnvcb6}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/12408-fan-mission-the-transaction-by-sotha-20110304/}}<br />
|2011-03-04<br />
|10<br />
|Thomas Porter 4<br />
|City Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|13|Return to the City}}<br>(v2.0 2011/03/01)<br />
|Melan, Bikerdude<br />
|{{Bloodgate|ReturnToTheCityV2.pk4}}{{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/10509-fan-mission-return-to-the-city-by-melan-20100110/}} {{Forumlink|1=http://www.ttlg.com/forums/showthread.php?t=130519/}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/12390-fan-mission-return-to-the-city-v2-01032011/}}<br />
|2010-01-10<br />
|26<br />
|Version 1.0, GCC 09 (Winner); Talbot 2<br />
|City Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|39|Lockdown}}<br />
|GameDevGoro Bikerdude Fidcal<br />
|{{Bloodgate|lockdown1_2_1.pk4}} {{Mirrorlink|http://www.fidcal.com/darkuser/missions/lockdown1_2_1.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/12064-fm-lockdown-part-1-by-gamedevgoro-and-bikerdude-20101224/}}<br />
|2010-12-25<br />
|3<br />
|Lockdown 1<br />
|City Missions<br />
|Undead<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|37|Flakebridge Monastery}}<br />
|Jesps<br />
|{{Bloodgate|flakebridge.pk4}} {{Mirrorlink|http://www.file-upload.net/download-3024426/flakebridge.pk4.html}} {{Mirrorlink|http://rapidshare.com/files/434997519/flakebridge.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/11991-fm-flakebridge-monastery-by-jesps/}}<br />
|2010-12-05<br />
|16<br />
|Selis Woderose 1<br />
|Church/Cathedral<br />
|Undead<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|36|Knighton Manor, The}}<br />
|Sotha<br />
|{{Bloodgate|knighton_manor.pk4}} {{Mirrorlink|http://www.mediafire.com/?xrdts3j4t2qxre2}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/11898-fan-mission-the-knighton-manor-by-sotha-20101109/page__view__getnewpost}}<br />
|2010-11-09<br />
|21<br />
|Thomas Porter 1<br />
|Mansion/Estate FMs<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|35|St Albans Cathedral}}<br>(v2.0 2014/06/11)<br />
|Bikerdude<br />
|{{Bloodgate|stac160.pk4}} [[http://www.bloodgate.com/fms/stac142.pk4 Classic]] {{Mirrorlink|http://www.filefront.com/17464439/stac141.pk4}}{{Forumlink|1=http://forums.thedarkmod.com/topic/16343-fan-mission-st-albans-cathedral-v20-11062014/}} {{Loot|FM:TDM_St_Alban's_Cathedral_-_Bikerdude}}<br />
|2010-11-01<br />
|67<br />
|St Alban<br />
|Church/Cathedral<br />
|Undead<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|33|Swing}}<br />
|Komag<br />
|{{Bloodgate|swing_v1.2.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/11660-vertigo-contest-entry-swing-by-komag-20100825/}} {{Loot|FM:TDM_Swing_-_Komag}}<br />
|2010-08-25<br />
|3<br />
|SVC 10<br />
|Platforming / Jumping<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|32|The Caduceus of St. Alban}}<br>(v.1.5.5 2010/08/26)<br />
|Bikerdude<br />
|{{bloodgate|stalban.pk4}} {{Mirrorlink|http://www.filefront.com/17237609/stalban.pk4/}}{{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/11644-the-caduceus-of-st-alban-vertical-fm-contest-entry-aug-8th-2010/}}<br />
|2010-08-23<br />
|11.3<br />
|SVC 10/St Alban<br />
|Church/Cathedral<br />
|Spiders<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|30|Somewhere Above the City}}<br>(v1.1 2010/08/27)<br />
|Grayman<br />
|{{Bloodgate|somewhere1.1.pk4}}{{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/11619-vertical-contest-mission-somewhere-above-the-city-by-grayman-aug-20-2010/}} {{Loot|FM:TDM_Somewhere_Above_the_City_-_grayman}}<br />
|2010-08-20<br />
|11<br />
|SVC 10<br />
|Tombs, Catacombs & Crypts<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|29|Betrayal}}<br>(v.1.1, 2010/09/01)<br />
|Fieldmedic<br />
|{{Bloodgate|betrayal.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/11605-betrayal-by-fieldmedic-20100817-summer-fm-vertical-contest-entry/}} {{Loot|FM:TDM_Awaiting_the_Storm_-_HappyCheeze}}<br />
|2010-08-17<br />
|12<br />
|SVC 10<br />
|Horror FMs<br />
|Undead<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|31|Rift, The}}<br />
|Baddcog<br />
|{{Bloodgate|rift.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/11599-vert-contest-mission-the-rift-by-baddcog-aug-15-2010/}}<br />
|2010-08-15<br />
|10<br />
|SVC 10<br />
|Lost Civilizations<br />
|Undead and Spiders<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|34|Illusionist's Tower}}<br />
|stumpy<br />
|{{Bloodgate|holetower.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/11541-illusionists-tower-by-stumpy-201085-summer-fm-vertical-contest-entry}} {{Forumlink|1=http://www.bookofages.co.uk/doom3/mods/holetower.html}} {{Loot|FM:TDM_Illusionist%27s_Tower_-_stumpy}}<br />
|2010-08-05<br />
|9<br />
|SVC 10<br />
|Horror FMs<br />
|Undead and Spiders<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|28|Mad's Mountain}}<br />
|Jesps<br />
|{{Bloodgate|madmountain.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/11510-fan-mission-mads-mountain-by-jesps-20100731}} {{Loot|FM:TDM_Lord_Dufford%27s_-_stumpy}}<br />
|2010-07-31<br />
|2<br />
|SVC 10<br />
|Tombs, Catacombs & Crypts<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|27|Glenham Tower, The}}<br />
|Sotha<br />
|{{Bloodgate|glenham_tower.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/11423-fan-mission-the-glenham-tower-by-sotha-20100717}}<br />
|2010-07-17<br />
|5<br />
|Thomas Porter 3, SVC 10 (Winner)<br />
|Horror FMs<br />
|Undead<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|25|Pandora's Box}}<br />
|Jesps, Fidcal<br />
|{{Bloodgate|pandoras_box.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/11381-fan-mission-pandoras-box-by-jesps20100711}} {{Loot|FM:TDM_Pandora%27s_Box_-_Jesps}}<br />
|2010-07-11<br />
|7<br />
|<br />
|Pirate Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|23|Beleaguered Fence, The}}<br />
|Sotha<br />
|{{Bloodgate|beleaguered_fence.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/11298-fan-mission-the-beleaguered-fence-by-sotha-20100623}} {{Loot|FM:TDM_The_Beleaguered_Fence_-_Sotha}}<br />
|2010-06-23<br />
|11<br />
|Thomas Porter 2<br />
|Jail/Prison Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|22|Special Delivery, A}}<br />
|Silencium18<br />
|{{Bloodgate|delivery.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/11247-fan-mission-a-special-delivery-by-silencium1820100612}} {{Loot|FM:TDM_A_Special_Delivery_-_Silencium18}}<br />
|2010-06-12<br />
|2<br />
|<br />
|Warehouse Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|21|Alchemist, The}}<br>(2010/06/04)<br />
|Sotha, Fidcal<br />
|{{Bloodgate|alchemist.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/11170-fan-mission-the-alchemist-by-sotha-fidcal20100601}} {{Loot|FM:TDM_The_Alchemist_-_Sotha_%26_Fidcal}}<br />
|2010-06-01<br />
|27<br />
|Thief's Den 4<br />
|City Missions<br />
|Undead<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|20|Awaiting The Storm}}<br />
|HappyCheeze<br />
|{{Bloodgate|storm.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/11095-fm-awaiting-the-storm-by-happycheeze-20200522}} {{Loot|FM:TDM_Awaiting_the_Storm_-_HappyCheeze}}<br />
|2010-05-22<br />
|4<br />
|<br />
|City Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|18|No Honor Among Thieves}}<br>(v.2.0, 2013/10/16)<br />
|Goldchocobo, RailGun, Mortem Desino<br />
|{{Mirrorlink|http://tinyurl.com/2a9mdcs}}{{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/10993-fan-mission-no-honor-among-thieves-20100429}} {{Loot|FM:TDM_No_Honor_Among_Thieves_-_Goldchocobo}}<br />
|2010-04-29<br />
|144<br />
|<br />
|Pagan/Outdoor Missions<br />
|Undead and Spiders<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|17|Heart of Lone Salvation, The}}<br>(v.2.0, 2010/04/12)<br />
|Fidcal, Baddcog<br />
|{{Bloodgate|heart.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/10878-fan-mission-the-heart-of-lone-salvation-by-fidcal-baddcog-20100402/}} {{Walkthrough|FM:TDM_The_Heart_of_Lone_Salvation_-_Fidcal_%26_Baddcog}} {{loot|FM:TDM_The_Heart_of_Lone_Salvation_-_Fidcal_%26_Baddcog}}<br />
|2010-04-02<br />
|41<br />
|Thief's Den 3<br />
|City Missions<br />
|Spiders<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|73|Lord Dufford's}}<br />
|stumpy<br />
|{{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/10868-fan-mission-lord-duffords-20100331}} {{Loot|FM:TDM_Lord_Dufford%27s_-_stumpy}}<br />
|2010-03-31<br />
|22<br />
|<br />
|City Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|16|Builder's Influence, The}}<br>(2010/03/23)<br />
|Railgun, Springheel<br />
|{{Bloodgate|builders_influence.pk4}} {{Mirrorlink|http://www.fidcal.com/darkuser/missions/builders_influence.pk4}}{{Forumlink|http://modetwo.net/darkmod/index.php?/topic/10811-fan-mission-the-builders-influence-20100320/}} {{Loot|FM:TDM_The_Builders_Influence_-_Railgun%26Springheel}}<br />
|2010-03-20<br />
|15<br />
|Corbin<br />
|Castle/Fortress Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|14|Business as Usual}}<br>(v2.0 2011/09/24)<br />
|Bikerdude<br />
|{{Bloodgate|business.pk4}}{{Mirrorlink|1=http://rapidshare.com/files/335299431/business.pk4.html}}{{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/10533-fan-mission-business-as-usual-by-b1k3rdude-14012010-christmas-fm-contest-entry/page__view__findpost__p__207055}}<br />
|2010-01-14<br />
|4<br />
|GCC 09<br />
|Sewer<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|12|Sons of Baltona 1, The}}<br />
|Carnage<br />
|{{Bloodgate|sons_of_baltona_1.pk4}} {{Mirrorlink|1=http://www.mediafire.com/?m4ywobjodm0}}{{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/10498-fan-mission-the-sons-of-baltona-1-by-carnage-20100109}}<br />
|2010-01-09<br />
|3<br />
|GCC 09 / Baltona 1<br />
|Mansion/Estate FMs<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|11|Living Expenses}}<br />
|Sonosuke<br />
|{{Bloodgate|living_expenses.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/10451-fm-living-expenses-by-sonosuke-2-jan-10/page__view__findpost__p__205386}}<br />
|2010-01-02<br />
|6<br />
|GCC 09<br />
|Mansion/Estate FMs<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|10|Trapped!}}<br />
|RailGun<br />
|{{Bloodgate|trapped.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/10442-fm-trapped-by-railgun-dec-30/page__view__findpost__p__205092}}<br />
|2009-12-30<br />
|6<br />
|<br />
|Jail/Prison Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|8|Parcel, The}}<br />
|Xonze<br />
|{{Bloodgate|parcel.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/10404-fm-the-parcel-by-xonze-dec-24/page__view__findpost__p__204459}}<br />
|2009-12-24<br />
|7<br />
|GCC 09<br />
|Mansion/Estate FMs<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|9|Too Late}}<br />
|Nielsen74<br />
|{{Bloodgate|too_late.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/10400-fm-too-late-by-nielsen74-24-dec-09/page__view__findpost__p__204396}}<br />
|2009-12-24<br />
|4<br />
|GCC 09<br />
|Warehouse Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|7|Thieves}}<br />
|Silencium, RailGun, Fidcal<br />
|{{Bloodgate|thieves.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/10286-fm-the-thieves-nov-2509/}}<br />
|2009-11-26<br />
|9<br />
|<br />
|City Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|6|Patently Dangerous}}<br>(v.2.0, 2013/10/08)<br />
|demagogue<br />
|{{Bloodgate|patently_dangerous.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/10125-fm-patently-dangerous-oct3109/page__view__findpost__p__199324/}}<br />
|2009-10-31<br />
|24<br />
|<br />
|City Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|5|Dark Mod Training Mission, The}}<br />
|TDM Team<br />
|{{Bloodgate|training_mission.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/9932-fm-training-mission-17-oct-09/}}<br />
|2009-10-17<br />
|6<br />
|<br />
|Training<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|2|Crown of Penitence, The}}<br />
|Jesps<br />
|{{Bloodgate|crow_of_penitence.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/9934-fm-crown-of-penitence-by-jesps-17-oct-09/}}<br />
|2009-10-16<br />
|12<br />
|<br />
|Mansion/Estate FMs<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|3|Chalice of Kings, The}}<br />
|Fidcal<br />
|{{Bloodgate|chalice.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/9935-fm-chalice-of-kings-by-fidcal-17-oct-09/}} {{Loot|FM:TDM_Chalice_of_Kings_-_Fidcal}}<br />
|2009-10-15<br />
|3<br />
|Thief's Den 2<br />
|Castle/Fortress Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|1|Outpost, The}}<br />
|angua, greebo<br />
|{{Bloodgate|outpost.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/9937-fm-the-outpost-by-angua-greebo-17-oct-09/}}<br />
|2008-12-23<br />
|2<br />
|<br />
|Castle/Fortress Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|15|Tears of Saint Lucia, The}}<br>(v.1.01, 2010/04/29)<br />
|TDM Team<br />
|{{Bloodgate|saintlucia.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/10579-fan-mission-the-tears-of-st-lucia-20081021/page__view__findpost__p__207972}} {{Loot|FM:TDM_The_Tears_of_Saint_Lucia_-_jdude}}<br />
|2008-10-21<br />
|18<br />
|<br />
|Church/Cathedral<br />
|Spiders<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|57|Closemouthed Shadows}}<br>(v.2.0, 2012/01/15)<br />
|LordSavage, Bikerdude<br />
|{{Bloodgate|closemouthed_shadows.pk4}} {{Forumlink|1=http://forums.thedarkmod.com/topic/13383-fan-mission-closemouthed-shadows-2008-reworked-for-tdm-107-20120115/}} <br />
|2008-09-21<br />
|2<br />
|Closemouthed Shadows 1<br />
|Mansion/Estate FMs<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|24|Thief's Den}}<br>(v.2.0, 2010/07/04)<br />
|Fidcal, greebo<br />
|{{Bloodgate|thiefs_den.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/11347-fan-mission-thiefs-den-re-release-by-fidcal20100704}} {{Walkthrough|FM:TDM_Thief's_Den_-_Fidcal}} {{Loot|FM:TDM_Thief%27s_Den_-_Fidcal}}<br />
|2008-01-18<br />
|3<br />
|Thief's Den 1<br />
|City Missions<br />
|<br />
|}<br />
<br />
If the aforementioned download links are down, [http://www.southquarter.com/downloads/missions_view.php South Quarter] has some TDM missions (-2011) as well as a link to it's TTLG forum thread. Just click the 'game column' to sort the list with TDM.<br />
<br />
To see a speculative list of Upcoming Fan Missions please visit: [[Upcoming Fan Missions]]<br />
<br />
<br />
<br />
'''Series Key'''<br />
<br />
GCC 09: Grand Christmas Contest 2009<br />
<br />
SVC 10: Summer Vertical Contest 2010<br />
<br />
CSC 11: Community Seasons Contest 2011<br />
<br />
HSC 11: Halloween Speed-Build Contest 2011<br />
<br />
CBC 12: Community Beginner Contest 2012<br />
<br />
CUC 13: Community Unusual Contest 2013<br />
<br />
<br />
'''Links Key'''<br />
<br />
{|class="wikitable" border=1 style="border-collapse: collapse;" cellspacing=0 cellpadding=2<br />
<br />
|-<br />
|[http://modetwo.net/darkmod/wiki/images/b/be/Icon_forum.png http://modetwo.net/darkmod/wiki/images/b/be/Icon_forum.png]<br />
|Link to discussion in Forums<br />
<br />
|-<br />
|{{Mirrorlink|}}<br />
|Misc. download mirror<br />
<br />
|-<br />
|{{Bloodgate|}}<br />
|Bloodgate download mirror<br />
<br />
|-<br />
|{{Loot|}}<br />
|Loot list<br />
<br />
|-<br />
|{{Walkthrough|}}<br />
|Walkthrough<br />
<br />
|}<br />
<br />
<br />
== Editing This Table ==<br />
* Please only include playable missions that are fully released, not those currently in development or testing. Tutorials, demos, prefabs, etc. should be listed elsewhere. <br />
* A mission title may be listed in plain text as a record of release, or preferably a link to an information page or primary direct download.<br />
* List by release date descending (newest at the top).<br />
* If a fan mission only has a single mirror/host please consider adding additional mirrors. <br />
{{general|sort=Fan Missions}}<br />
[[Category:Fan Missions]]</div>RJFerrethttps://wiki.thedarkmod.com/index.php?title=Doors&diff=17806Doors2014-06-25T02:07:38Z<p>RJFerret: /* Keys carried by AI */ +bind method</p>
<hr />
<div>{{todo}}<br />
''Written by Fidcal'' ''edit Baddcog''<br />
<br />
==Quick Summary==<br />
<br />
Quick way to get an unlocked door in your map:<br />
<br />
* Insert one of the prefab doors complete with handles and select its skin property and click the button to change its skin appearance to whatever you want. Set any other properties you need.<br />
<br />
Alternatively,<br />
<br />
* Create a door from the entity list<br />
* Use the "skin" spawnarg on the door to change its appearance. <br />
* Create a handle from the entity list<br />
* Add the ''door_handle'' property to the door and give it the name of the handle<br />
* To the door handle add the value frob_peer and use the name of the door.<br />
* To open clockwise, change the ''rotate'' property from <code>0 90 0</code> to <code>0 -90 0</code><br />
<br />
==Introduction==<br />
<br />
This tutorial explains how to put doors into your map using Dark Radiant, as well as adjust them and their properties.<br />
<br />
The rest of this tutorial assumes that you have a basic understanding of using DarkRadiant. If you haven't done so, please go read the [[Dark Radiant Must Know Basic Intro]] article first.<br />
<br />
Additionally:<br />
<br />
* Up, down, right, and left in Dark Radiant's ''top'' orthoview are regarded here as the standard map directions of North, South, East, and West where useful for clarity.<br />
* Where the term ''brush'' is used with a door it mostly also applies to a door made up of a group of brushes and/or patches.<br />
* Where the term ''door'' is used it often will also apply to any object you wish to rotate when frobbed, for instance an openable window, box lid, or even more exotic objects that the imaginative mapper might conceive like a signal, engine part, toy, or whatever. So long as it needs to turn or slide just a fixed amount when frobbed then return when frobbed again then the following applies.<br />
<br />
==Door types==<br />
<br />
All tangible objects in Dark Mod are ''entities'', having either a pre-made model shape or else brush/patch(es). So there are two ways to create a door in Dark Radiant: as a model door or a textured brush door (or a hybrid of the two).<br />
<br />
Models are ready made door objects but cannot within Dark Radiant (at the time of writing) be resized, rescaled, cropped or clipped whereas brushes are very flexible in that respect and can be worked into custom shapes for your map, including secret doors that blend into walls and other surfaces.<br />
<br />
Most of the current door models are found in two places along with the door handles.<br />
*Model Viewer: doors created from here will be static in the world and have no props other than material type.<br />
You can add any props to them to make them working doors. If nothing else it is a good place to view the different size and skin options for the doors.<br />
*Entity List: most of the door models can be found here. These doors have properties already assigned so they are ready to be used. Only one base door of each type is listed, create the size/hinge count door you want (2 hinge doors have a 'no hinge' skin). You can choose a skin for the door once it has been created in the editor with the "skin" spawnarg (use the model name of the door you want, taken from the model list, as its value). This is the easiest way to create a door. The same goes for door handles.<br />
<br />
Remember also that door functions may be applied to objects other than doors, such as openable windows, drawbridges, gates, etc. In fact, anything that needs a partial rotation or slide when frobbed then return when frobbed again, such as a signal device. Lockboxes and chests use similar properties.<br />
<br />
You can create one door/handle set and copy/paste it, but you need to take great care that all the name props are changed to match in each clone. Otherwise you get handles that fly off when a distant door moves, and handles that don't move.<br />
<br />
==Creating a Door==<br />
<br />
Put simply, to make a door you will be creating an 'entity with model' or 'entity with brush' or some variation thereof.<br />
<br />
===Creating a Model Door===<br />
<br />
There are several approaches to making a model door; the simplest is to create a door from the entity list; or create a door from the model viewer (good for static unusable prop doors).<br />
<br />
'''Entity List''':<br />
<br />
*Deselect everything in editor by hitting the Esc button<br />
*Right-click an ortho view and select Create Entity<br />
*Navigate to darkmod/movers/''atdm:door_...'', choose the door you want<br />
*Click Add<br />
*To change its appearance, add a "skin" spawnarg to the door, with the value being the model name of the door you want.<br />
<br />
You now have a workable door in your level.<br />
<br />
'''Model Viewer''':<br />
<br />
* Right click in the orthoview, select ''Create Model'' then <code>darkmod</code> and select a door.<br />
* Note that you can left drag the image in the ''Choose Model'' dialog to rotate it around.<br />
* Click [[Image:Button ok.png]] and you have a static door.<br />
* If you want to make it work (openable, frobbable) then:<br />
** Select the entity inspector,<br />
** Select the top classname line so it highlights<br />
** Select the func_static line in the input box ''below'' the properties window.<br />
** Edit <code>func_static</code> to <code>atdm:mover_door</code><br />
** Click {{check}} or press {{key-enter}}<br />
<br />
Alternatively you can do it the old way:<br />
<br />
* Create any temporary brush<br />
* Right click in orthoview and select <code>Create Entity</code> then <code>atdm:mover_door</code>.<br />
* Left lick the model name line in the entity inspector.<br />
* Below it on the ''Entity Inspector'' panel you should now see a button 'Choose Model'<br />
* Left click it, select a door model from the darkmod group.<br />
* Note that you can left drag the image in the ''Choose Model'' dialog to rotate it around.<br />
* The temporary brush was deleted.<br />
<br />
<br />
In all three instances, you now have a working door with default properties. <br />
<br />
Name your door by adding the prop (or modifing it) to name ''My_Door_1''. You can use any name that you feel is appropriate but all doors with handles attached ''must'' have their own specific name. Use the name My_Door_1 for your first attempt as it will be referenced when you get around to attaching handles (see below).<br />
<br />
To add a handle and other adjustments, see [[#Customising and Adjusting Door Properties]] below.<br />
<br />
===Creating a Textured Brush Door===<br />
<br />
'''Tip:''' If unsure of size then you might insert a temporary human AI first to get a sense of height.<br />
<br />
==== The simplest brush door: ====<br />
<br />
* Drag out a new brush to the size required, eg, a seven foot high door is 84" x 1.1 = about 90 units in Dark Radiant.<br />
* Give it a door texture from the texture browser (or wall texture for a secret door)<br />
* Right click in orthoview and select ''Create Entity'' then <code>atdm:mover_door</code><br />
<br />
You now have a working door but it will rotate around its center. To move the rotation point to where you want the door hinges to be:<br />
* Select the door and press 'v' to enter vertex editing mode. The door's origin will show up as a small green square in the middle of the brush.<br />
* In top-down orthoview, move the origin from the center to the corner of the brush. This is easiest in drag mode ('q'), although you can use translate mode ('w') by manually selecting the vertex first.<br />
<br />
==== Multi-brush doors: ====<br />
<br />
More complex multi-brush doors can be created using the [[Clipper]] tool, CSG, etc. - this is not covered in this tutorial. Then assign <code>atdm:mover_door</code> for that whole brush structure. Also you can collect various brushes positioned together in relation to one another as needed, select them all, then assign <code>atdm:mover_door</code> for the group. All the brushes will be children of the <code>atdm:mover_door</code> entity and will rotate and be frobbable, etc. as one unit, as one door. To add further brushes or even model shapes later see the section on [[#Adding handles and other items to doors]].<br />
<br />
Name your door by adding the prop (or modifing it) to name My_Door_1. You can use any name that you feel is appropriate but all doors with handles attached must have their own specific name. Use the name My_Door_1 for your first attempt as it will be referenced when you get around to attaching handles (see below). (repeated from above in case you didn't choose to create a model door)<br />
<br />
=== Double Doors ===<br />
Double doors are automatically recognised by the code when the doors are spawned. The prerequisite is that both doors are sharing/touching the same visportal. The spawnarg ''auto_setup_double_door'' (which defaults to "1") will take care of setting up the open/lock peer relationship between the two doors. The doors will open/close and lock/unlock along with each other as a result.<br />
<br />
What happens behind the scenes: the doors are adding each other to their internal open_peer and lock_peer list, which causes the double doors to perform the same action when frobbed or used.<br />
<br />
Note that ''auto_setup_double_door'' will not set the frob_peer relationship, i.e. each door will frob-highlight on its own without highlighting the other door. You'll need to add that spawnarg manually if you want to highlight the entire double door as one.<br />
<br />
==Customising and Adjusting Door Properties==<br />
<br />
Handles, lockplates, etc. can be added to doors and door properties can be adjusted for rotation, sliding, locking, and more.<br />
<br />
Some of the door models have hinge plates and lockboxes that are reskinnable with a good variety of skins.<br />
<br />
===Door handles and other door attachments===<br />
<br />
'''Summary: just add the property ''bind'' with the door's name to the attachment and position it where you want it on the door. If it's a ''atdm:mover_door_handle'' then it automatically will work as a handle but you can bind virtually anything.'''<br />
You can add handles and other items to doors such that they move correctly with the door whether rotating, sliding, or both and even if the door is not vertical such as a skylight or trapdoor.<br />
Handle models come in two types, ''single handles'' and ''double handles''. A single handle is one sided, this means the handle will be inside the door or outside the door, but not both. A double handle has a lever on the inside of the door and a handle on the outside of the door. Each has benefits.<br />
<br />
*'''''Single door handles''''':<br />
Single door handles can be used on a static door, a door that's just for show that no AI's or the player can use. In this case you should just create a door handle from the model viewer, it will be static and have no properties such as scripts. It is for looks only.<br />
<br />
I will call this ''multiple handles'', see more below.<br />
<br />
These can also be useful on brush doors created in the editor that may be very thin or very wide.<br />
<br />
*'''''Double door handles''''':<br />
These are models have have a handle inside and outside. The bonus is that they only use one entity. Maps are limited to about 4,000 entities but when you count lights, AI, sound speakers, ect... you can run out of entities quickly on a large map. If you plan on building a large map this is the way to go, even in a small map they have benefits, namely that you only have to attach one handle per door.<br />
<br />
Whether you decide to use a single handle or a double handle you must first follow the instructions below and attach one handle first. If you choose a double handle, follow the instructions below and you are done. If you choose a single handle type follow the instructions then also follow the ''multiple handle'' instructions for the second handle.<br />
<br />
Both single and double handle types can be found in two places. The model viewer which will create a static model good for show, you can manually add props to make them work OR you can look in the entity browser.<br />
Using a handle from the entity browser saves you a little bit of time as some props are already added, you just need to add the frob_peer names for the doors/handles and the door_handle name to the door.<br />
<br />
=== Adding a working model door handle===<br />
<br />
Quick summary:<br />
* Create a model or brush handle and make it an ''atdm:mover_door_handle'' entity.<br />
* Position it on your door. Use the opposite side from the door's multicolor X-Y-Z indicator (highlight the door to see it) if it's not obvious which side it goes on. <br />
* '''Bind''' the handle to the door (bind <doorname>)<br />
* It should now be a working handle though may need adjustments of rotation etc. see later. <br />
<br />
<br />
Important: read preceding section on door handle types and performance issues first.<br />
<br />
This works with both a model door and a brush door:<br />
<br />
'''Rotation''':<br />
* By default the door handle entity rotates ''anti-clockwise'' (looked at from the front) then springs back. A ''double handle'' model is OK but two singles (see ''Multiple door handles'' below) need more care as only one is the functioning entity and the other is just attached to it. So anti-clockwise is fine for a door with its hinge on the left and the handle on the right - the handle will rotate down then spring back. If you put the functioning door handle on the other side you will have to change the default ''rotate'' property from -45 0 0 to 45 0 0. '''''Therefore it is easier to generally put this handle on the side of the door where the hinge is on the left and the non-functioning attachment handle on the other side.'''''<br />
*If your door only needs one handle, eg, a cupboard door, and from outside its hinge is on the right then you will need to change the ''rotate'' property of the handle as described above.<br />
<br />
'''''The functioning handle entity:'''''<br />
* Create an entity door handle (movers folder) or create a brush or model handle and assign it the entity ''atdm:mover_door_handle''.<br />
* Position it where you wish on your door.<br />
* '''Bind''' the handle to the door, by adding the "bind" spawnarg to the handle.<br />
<br />
You now have a working door handle with default properties.<br />
<br />
*'''Multiple door handles''':<br />
Now that you've got a handle attached to one side of the door it is time to add one to the other side (unless you used a double handle).<br />
* Create the new handle. The single handles come in left and right persuasions. A door needs a left facing handle on one side and a right facing handle on the other, so if you have already added the left handle create a right handle and line it up on the other side of the door.<br />
* Name this handle. I prefer to keep a naming convention for each door and it's respective handles, it makes things alot easier. The door is named '''My_Door_1''', the first handle is named '''My_Handle_1''' so name the second handle '''My_Handle_1_1'''. This will make it stay with the first handle in the entity list. This is important to keep organized. If you name it My_Handle_2 then when you get to another door named My_Door_2 you'll be confused.<br />
* Place and '''bind''' that handle to your door.<br />
<br />
You now have two single door handles on either side of the door that rotate together as if they were physically attached.<br />
<br />
'''To add a brush to a brush door''':<br />
* Select the new brush ''and'' the brush door all together; ''the entity '''must''' be selected '''last'''.''<br />
* Use {{menu|Edit|Reparent primitives}}. This ensures the parent entity adopts the new item(s).<br />
* If you have trouble selecting them in the orthoview because other brushes, etc. get selected then try in the camera view or as a last resort move them temporarily to an open area (but keep them in the same positions relative to each other.) Use {{key-shift}}+{{LMB}} on new item(s) then {{key-shift}}+{{LMB}} on main entity. Once they are all selected, use the {{menu|Edit|Reparent primitives}}.<br />
<br />
'''To add ''model'' static items''': knockers, hinges, static handles etc. to a ''Model Door'':<br />
* Select item<br />
* Right click in orthoview and select ''Create Entity'' then <code>entity func_static</code><br />
* Position it where you wish on your door.<br />
* To synchronize this with your particular door you need to add the property ''bind'' and the individual door name to the brush entity. To do this...<br />
** Select the model door.<br />
** In the entity inspector, select the ''name'' line<br />
** Select the bottom line in the input box ''below'' the properties window.<br />
** Copy the name<br />
** Deselect the door with {{key-esc}}<br />
** Select the brush entity<br />
** Add a property "bind" to it.<br />
** Change the value of the property by pasting in the door name<br />
** Click {{check}} or press {{key-enter}}<br />
<br />
'''To add ''brush'' static items''': knockers, hinges, static handles to a Model Door:<br />
* This method is not ideal but it seems to work OK.<br />
* Select the brush.<br />
* Right click in orthoview and select Create Entity then ''atdm:mover_door_handle''<br />
* Position it where you wish on your door.<br />
<br />
To synchronize this with your particular door you need to add the property ''door_handle'' on the door, and give as the value the name of the brush you just created.<br />
<br />
This brush turns like a handle. To stop it:<br />
<br />
* Adding ''rotate 0 0 0'' or disabling the handle script won't help.<br />
* Add a real working handle (as in the section above ''To add a working model door handle...'' and it must be added LAST.)<br />
<br />
If you don't want too see a real working handle added maybe try another tiny brush with the handle function and hide it inside the door?<br />
<br />
===Locking Doors===<br />
<br />
To lock a door check the ''show inherited properties'' in the entity inspector for a ''atdm:mover_door'' entity and you should see the ''locked'' property. Select it and in the input box below the properties you can change its value:<br />
<br />
* 0 = unlocked (default)<br />
* 1 = locked<br />
<br />
If locked it will require an entity that is associated with it to be able to act as a key to unlock it.<br />
<br />
Currently door handles on locked doors will rotate when frobbed, they will bounce back though and the door will stay locked until unlocked.<br />
<br />
===Keys===<br />
<br />
Assigning specific keys to specific doors is simple.<br />
<br />
* It is recommended that you create an existing key entity. These keys have all required props, they just need to be named.<br />
<br />
Alternatively you can create a key from the Model Viewer and want it to be useable<br />
* Make sure it has the properties:<br />
useable 1 [so it can be used by the door]<br />
frobable 1<br />
inv_name <unique name><br />
inv_category Keys<br />
inv_target player1<br />
inv_icon guis/assets/hud/inventory_icons/<icon name><br />
inv_stackable 0 or 1 where 1 can be used on all copies of the same key so they show as one entry in the inventory with a total.<br />
<br />
Add to the door the property <code>used_by</code> with the name of the key as the value. Multiple keys can open the same door by using several <tt>used_by</tt> spawnargs:<br />
<br />
"used_by" "doorkey_1"<br />
"used_by1" "doorkey_2<br />
<br />
==== Keys carried by AI ====<br />
<br />
So you have a door and you have a guard Ai and you want the guard to be able to open/close/lock the door but you also want the player to be able to pickpocket the key. For more info on attaching key, props etc - see [[Attaching Props to AI]].<br />
<br />
*"def_attach6" "atdm:prop_silverkey" //the entity to spawn - in this case a key.<br />
*"pos_attach6" "belt_back_right" //where the key will spawn on the Ai.<br />
*"name_attach6" "door_key" //this gives 'attach6' arg the name "door_key" and is the name the arg "used_by" will need, eg: "used_by" "door_key"<br />
*"set inv_name on door_key" "Door key" //The name the key get when the play adds it to their inventory.<br />
*"set name on door_key" "door_key" //here it gets a name to be used in the map in general.<br />
<br />
Or simply:<br />
<br />
* load a key entity<br />
* position where you want it in relation to the AI, bind it to them<br />
* Add the spawnarg "bindToJoint" "Hips" (or other location, see AI for list)<br />
* adjust existing spawnargs accordingly (be sure the name and door's/chest's "used_by" match, if you aren't using a prefab chest w/key)<br />
<br />
====Master Key for Testing====<br />
<br />
By default, ALL locks can be opened by any key named ''key_master''. Just create a key in your map, name it ''key_master'' and it becomes a master key for use while testing. Add inv_map_start 1 to it so it is in the player inventory at game start. Remember to delete it when your mission is finished.<br />
<br />
===Lockpicks===<br />
''by Baddcog''<br />
<br />
There are two lock pick types.<br />
*'''s'''=snake<br />
*'''t'''=triangular<br />
<br />
A lock can be set with many pins. Each pin has a click sequence and each needs a designated lockpick type (see above). Keep in mind that the lockpicking in The Darkmod is much more involved than in T2 or T3. The player has to listen to sounds or watch a handle or lockbar to know when a lock is pin is picked.<br />
<br />
This means that authors can be very evil and really frustrate the player, in which case their missions will probably not be played. So be nice to the player and don't waste your time. Use simple locks for the most part and save complicated locks for important sections and to build tension. Don't make the player have 20 pins to pick all with different lockpicks. In most cases 1 or 2 pins will suffice and it isn't necessary to use both lockpicks on every lock.<br />
Also try to include a lock lever on lockboxes or chests, door handles will rotate as the pins are being picked. This gives the player visual clues to help with the picking (and essential in noisy environments where you can't hear the clicks.)<br />
IMO this system is a huge leap foward for lockpicking but also has the ability to completely frustrate the player as stated above. Keep this in mind when designing your lockpick systems.<br />
<br />
These props go on the door itself, or the lid of a chest, eg,<br />
*'''lock_pins''' 1327<br />
*'''lock_picktype''' stts<br />
<br />
The lock_pins property specifies how many pins each lockpicktype has.<br />
The lockpick_type property specifies how many times the player has to switch picks and which pick they have to use. You can see there must always be an equal number of lock_pins and lock_picktypes specified<br />
<br />
So looking at the example above we have lockpick_type s(snake), t(triangular), t(triangular), and s(snake). The player will have to use these lockpicks in this order. Once the snake lockpick's pins are open the player can advance to the triangular pick and so forth.<br />
5 is added to every click sequence so 5 is the minimum click pattern even if you set it to 0.<br />
In the example above the lockpins specify in order which pick types have how many pins, so the s pick has 1 + 5 = 6 clicks, the t pick has 8 and so on.<br />
The above is a difficult lock and to avoid annoying the player it is best only used rarely on a special lock like an important big vault door. Ordinary footlockers and common doors can be just 1 or 2 click sequences, eg, lock_pins 2 and lock_picktype t means the player uses one pick and listens for the end of one sequence of 7 clicks.<br />
<br />
lockpick_rotate - is placed on the door. It is the amount the visible rotating handle or pin rotates while picking. For a rotating handle or lockbar normally ignore this and leave the default. During lockpicking it oscillates and progresses to the normal full turn of the handle. Example 0 45 0.<br />
<br />
lockpick_translate - is placed on the door. It is the amount the visible handle or pin moves in a straight line while picking. Use this if you have eg, a lockbar that you want to move in a straight line and not rotate, eg sliding catch. Example 0 -5 0<br />
<br />
By default, doors are pickable. If you don't set up the above lockpick spawnargs then it can't be picked. So there is normally no need to enable lockpicking - just set up the above spawnargs. There is a ''pickable'' spawnarg set to 1 by default. If set to 0 then the door becomes unpickable. But hard to think of an application except in testing or perhaps a special custom situation where it is switched by script perhaps.<br />
<br />
===Open, Partially Open, or Closed Door at Game Start===<br />
<br />
By default, doors are closed at game start. If you want a door to be already open or partially open then do the following.<br />
<br />
'''Note well: Create all doors in their ''closed'' position. Adjust as follows and they will automatically be at the open position when game starts.'''<br />
<br />
Already Open Rotating Door:<br />
* Select the door.<br />
* Select the entity inspector<br />
* Check ''show inherited properties''<br />
* Select the ''open'' property<br />
* Edit the value to 1 in the input box below and tick the check button<br />
* The door will now be fully open at game start.<br />
<br />
* If you want it only partly open:<br />
* Make sure its ''open'' property is set to 1 as above.<br />
* Right click the entity inspector and select ''add property'' <br />
* Click the + sign on the left of the top line where atdm:mover_door is listed to open the folder. (if atdm:mover_door is not listed then the entity was likely changed from eg, func_static. If so, save the map and reload to update the add property list)<br />
* scroll down, select ''start_rotate'' then click {{ok}}<br />
* This adds it to the property list.<br />
* Now select ''start_rotate'' in the property list.<br />
* Edit the bottom line of the input box ''below'' the properties window to the angle you want in the same form as described in the ''Rotate Direction and Open Angle'' section. So for example, to have a door that has a fully open default ''rotate'' value of 0 90 0 to start only half open you would give it a ''start_rotate'' value of 0 45 0. <br />
* In a similar way add the property ''first_frob_open".<br />
* Set it to 1 and a partly open door should then open fully on the first frob.<br />
* Set it to 0 and a partly open door should close on the first frob.<br />
<br />
<br />
Already Open Sliding Door:<br />
* Select the door.<br />
* Select the entity inspector<br />
* Check ''show inherited properties''<br />
* Select the ''open'' property<br />
* Edit the value to 1 in the input box below and click {{check}} or press {{key-enter}}<br />
* The door will now be fully open at game start.<br />
<br />
* If you want it only partly open:<br />
* Right click the entity inspector and select ''add property'' <br />
* Make sure its ''open'' property is set to 1<br />
* Click the + sign on the left of the top line where atdm:mover_door is listed to open the folder.<br />
* scroll down, select ''start_position'' then click OK. (if atdm:mover_door is not listed then the entity was likely changed from eg, func_static. If so, save the map and reload to update the add property list)<br />
* This adds it to the property list.<br />
* Now select ''start_position'' in the property list.<br />
* Edit the bottom line of the input box ''below'' the properties window to the position you want in the same form as described in the ''Sliding (Translation) Amount and Direction'' section. So for example, to have a door that has a fully open default ''translate'' value of 0 50 0 to start only half open you would give it a ''start_position'' value of 0 25 0.<br />
* In a similar way add the property ''first_frob_open".<br />
* Set it to 1 and a partly open door should then open fully on the first frob.<br />
* Set it to 0 and a partly open door should close on the first frob.<br />
<br />
===Rotation Centre, Pivot, Hinge point===<br />
<br />
The centre of rotation of a door is at the origin point of its entity and the door rotates with reference to the orientation of that origin point, not the world map. See ''Rotate Direction...'' for more about that. This section only deals with the ''position'' of the rotation centre in the door.<br />
<br />
Model Door Centre of Rotation:<br><br />
The centre of rotation of a model door cannot be changed within Dark Radiant. Because a model door rotates around the centre 'spine' of its back edge this will cause clipping (penetration into solid) as in this example (where the door is set to open to 89 degrees for clarity):<BR>[[Image:modelClipping.jpg]]<BR> So care is needed with placement. You will not normally position a door right next to a wall as in the example but against a shallow frame so clipping will barely be noticeable but either way it can be fixed. You can correct it by adding a translation (see ''Sliding (Translation) Directions'') value of half the door width in the direction of the door handle. This will gently move the door out as it rotates to clear any solid on that side as in this diagram:<br><br />
[[Image:DoorClip.jpg]]<br><br />
Half a door width will typically be about 2. Any 'attachments' such as door handles will still synchronize with the door movement whether the door is rotating, sliding, or both.<br />
<br />
<br />
Brush Door Centre of Rotation:<br><br />
The centre of rotation of a brush door ''can'' be changed. The default origin point of a brush is at its centre. Therefore a default rotating brush door will rotate around its centre when you first create it. So, mappers will commonly need to move that rotation point to a corner or even to some other offset position for example, for an openable window using the door function.<br />
<br />
Put simply, to move the rotation point of a brush door you need to move the entity origin relative to the brush(es.)<br />
<br />
Moving the entity origin (centre of rotation) relative to a brush door:<br />
<br />
* Select the brush door<br />
* Select ''Vertices mode'' (default shortcut key is {{key|name=V}} or button on top toolbar 'Select Vertices')<br />
* Drag the door's entity origin to the point where you want the door to rotate. This should be on the corner on the leading edge side (the side to where the door is opening.) to avoid clipping as in this diagram....<br />
[[Image:getCorner.jpg]]<br />
* You should now find that door rotates around that point.<br />
<br />
===Rotate Direction and Open Angle===<br />
<br />
By default, rotating doors open anti-clockwise (viewed from above) by 90 degrees from the start orientation. If you want to change this edit the ''rotate'' property in the entity inspector. Don't confuse this ''rotate'' property with the ''rotation'' property. In the entity inspector remember that to see the inherited rotate property you must check the box 'Show inherited properties'.<br />
<br />
The three values shown in the rotate property are degrees from the closed position around Y Z X (absolute map axes Front, Top, Side views in DR's ortho view.)<br />
<br />
* Positive Y = Open clockwise (Dark Radiant grid front view, looking north)<br />
* Negative Y = Open anti-clockwise (Dark Radiant grid front view, looking north)<br />
<br />
* Positive Z = Open anti-clockwise (Dark Radiant grid top view, looking down)<br />
* Negative Z = Open clockwise (Dark Radiant grid top view, looking down)<br />
<br />
* Positive X = Open anti-clockwise (Dark Radiant grid side view, looking west)<br />
* Negative X = Open clockwise (Dark Radiant grid side view, looking west)<br />
<br />
There is a problem when you come to rotations that are not around the main Y Z X axes of the map, for instance a drawbridge that lowers down to the south east. You might think you can combine Y Z X values to get the result you want - and this can be done (for south east use 45 45 90) but it is a bit of a kludge and the drawbridge twists eccentrically as it lowers (though it arrives correctly!)<br />
<br />
The values are in the range -179 to +180. Positive values give an anti-clockwise opening rotation (looking down from above) and negative values give a clockwise opening rotation. The value 180 is unique in that it continues in an anti-clockwise rotation when closing rather than returning clockwise so might be used if you can think of some object that might need such a motion when frobbed!<br />
<br />
Edit the rotate value by selecting it and using the input box at the bottom and clicking the check(tick) button. That will change the angle the door will open to. Note that the line with the original default of 0 90 0 will still be there but your new entry will be added on a separate line and that is the one that will work in the game. CAUTION: when adjusting later make sure you have your new line selected and not the original! If you do it will appear to change but your first setting will remain unaltered.<br />
<br />
Examples:<br />
* 0 90 0 = Opens anti-clockwise round the entity's 'vertical' to 90 degrees - typical default vertical door.<br />
* 0 0 90 = Lowers a drawbridge from the entity 'vertical' to horizontal.<br />
* 0 0 -45 = Opens clockwise by 45 degrees viewed from the east side. This might suit a skylight in a sloping roof.<br />
<br />
'rotate' cannot be combined with translate motions (see [[#Sliding (Translation) Amount and Direction]]) in one door; you need to bind one door to another and link they by targetting one to the other. By that means you can produce exotic and useful motions. A door opening against an upward-sloping floor can thus have a ''lifting hinge'' and raise up slightly to clear the floor; a door can rotate towards you and slide back to one side very effectively.<br />
<br />
===Sliding (Translation) Amount and Direction===<br />
<br />
By default a Dark Mod door will rotate open. For most sliding doors you want to stop them rotating as well as make them slide. You cannot delete (remove) the ''rotate'' property - you have to set the ''rotate'' property to 0 0 0 to stop a door rotating (see ''Rotate Direction and Open Angle''.)<br />
<br />
Now edit the ''translate'' property value by selecting it (remember to have inherited properties box checked) and using the input box at the bottom and clicking the check(tick) button. That will change the distance the door will slide to. Note that the line with the original default of 0 0 0 will still be there but your new entry will be added on a separate line and that is the one that will work in the game. CAUTION: when adjusting later make sure you have your new line selected and not the original! If you do it will appear to change but your first setting will remain unaltered.<br />
<br />
Typically (but not always) you will want your sliding door to slide the width of the door. The three values in the translate property by default are 0 0 0 and are X Y Z ''absolute map'' values (irrespective of door orientation) where:<br />
<br />
* Positive X = Slide East (Right side of Dark Radiant grid in top view)<br />
* Negative X = Slide West (Left side of Dark Radiant grid in top view)<br />
* Positive Y = Slide North (top of Dark Radiant grid in top view)<br />
* Negative Y = Slide South (bottom of Dark Radiant grid in top view)<br />
* Positive Z = Slide Up (Top of Dark Radiant grid in side views)<br />
* Negative Z = Slide Down (Bottom of Dark Radiant grid in side views)<br />
<br />
So for a 50 unit wide door you want to slide fully to the east you would use 50 0 0 for the translate property values. A 100 unit portcullis sliding vertically up would need 0 0 100 to be fully raised.<br />
<br />
=== Doors Collision/Push Behaviour ===<br />
Doors push all entities by default, except for the player. Doors will also stop moving when anything blocks their movement. However, this default behaviour can be changed by setting appropriate spawnargs:<br />
<br />
Set '''push_player''' to '''1''' to let the player be pushed by this door:<br />
"push_player" "1" // Push the player too (default is off)<br />
<br />
By default '''stop_when_blocked''' is set to 1 and if a door is blocked by an entity then even if the entity is removed afterwards, the door stays where it is. The next frob will close the door.<br />
<br />
Set '''stop_when_blocked''' to '''0''' to prevent the door from ending the opening sequence when anything blocks its way. It will still pause - but continue to open if the block is removed.<br />
"stop_when_blocked" "0" // door keeps moving after being blocked (default is off)<br />
With this setting, doors will still stop at blocking entities (the player, for instance), but will continue to move when the entity moves out of the way.<br />
<br />
There is another spawnarg which stops a door pushing a moveable. Apply this to the ''moveable'', not the door...<br />
<br />
"notPushable" "1"<br />
<br />
===Door Sounds===<br />
<br />
The sound of doors opening and closing is set in the snd_open and snd_close properties. You can silence them by setting the following properties as shown:<br />
<br />
''snd_open nosound''<br><br />
''snd_close nosound''<br />
<br />
Don't just use a dash - as it seems to cause a sound of its own.<br />
<br />
The above sounds are triggered as the door begins to open (eg, unlatch sound) and when it finally closes (eg, slam). For special doors that need an ongoing sound, eg, a big stone slab that moves slowly, then use:<br />
<br />
''snd_move''<br />
The sound played as the door moves.<br />
<br />
''snd_locked''<br><br />
The sound played when a player or an AI tries to open a locked door.<br />
<br />
''snd_unlock string''<br><br />
The sound played when a door is unlocked.<br />
<br />
===Sound Propagation through Doors and Doorways===<br />
<br />
''This information will change significantly with the release of 2.0. See'' [[Controlling Sound Loss Across Portals]]<br />
<br />
<br />
The sound volume reduction to the player (ie, the sound the player hears) is fixed and constant in a cvar which adds a distance factor to the original sound. It is recommended that you do not change that because it will affect other FMs. Currently there is no way to change the way that sound to the player is reduced through doors and doorways.<br />
<br />
<br />
Sound propagation to AI, eg, impact sounds or guard yells is treated separately:<br />
<br />
Sound propagation to AI relies on visportals. For details study [[Sound Propagation: Part 1]] and [[Sound Propagation: Part 2]] as well as [[Visportals]] This tutorial will just cover the relevant sound and sound propagation ''properties'' of doors. If you set the ''show inherited properties'' box in the entity inspector you can see them as described here.<br />
<br />
Remember, the following have no effect on what the player hears through a door or doorway.<br />
<br />
''loss_open''<br><br />
Drop in sound volume in dB propagated to AI (not player) when going through an open door. (default 1dB)<br />
<br />
''loss_closed''<br><br />
Drop in sound volume in dB propagated to AI (not player) when going through a closed door. (default 15dB) You would want to set this very high to block all sound with a thick door but very low for a barred gate for example.<br />
<br />
''loss_double_open''<br><br />
Drop in sound volume in dB propagated to AI (not player) when going through double doors when only one is open. (default 1dB)<br />
<br />
There are also various sound properties for lockpicking:<br><br />
''snd_lockpick_pin_1 through 14'' and ''snd_lockpick_pin_success''<br />
<br />
===Speed of Door Opening and Closing===<br />
<br />
Rotating Door Speed:<br><br />
At the time of writing, the time a rotating door takes to open or close is set in the ''move_time'' property whatever its maximum open angle. So with rotation set at say 150 degrees the door just opens faster than at say 80 degrees. This is likely to be changed to a constant angular velocity so check to see if there a new property added if the following no longer works. The problem is that if an interruptable (see Extra Notes) door is frobbed while in motion it stops; another frob will reverse the motion - so even if the door is only open a crack it will still take the full time to close and vice versa.<br />
<br />
To change the time a rotating door takes to open or close, make sure the door is selected then...<br />
<br />
* Right click the entity inspector and check ''show inherited properties''<br />
* Scroll down, select ''move_time''<br />
* Edit the second line of the input box ''below'' the properties window to the time you want.<br />
* The time is in seconds and decimal fractions can be used.<br />
* The default is 1 second and if set to this then the door opens and closes in one second whatever the maximum open angle, great or small.<br />
<br />
<br />
Sliding Door Speed:<br><br />
The speed of a sliding door is set in the ''translate_speed'' property. To add this, make sure the door is selected then...<br />
<br />
* Right click the entity inspector and check ''show inherited properties''<br />
* Scroll down, select ''translate_speed''<br />
* Edit the second line of the input box ''below'' the properties window to the speed you want.<br />
* The speed is in Dark Radiant grid units per second.<br />
* The default is 0 and if set to this then the door slides open in one second whatever the distance, great or small.<br />
* CAUTION: If you later change the door back to a rotating door then delete the ''translate_speed'' property or ensure it is set to 0 as (at the time of writing but this will be fixed) a bug makes rotating doors open and close instantly. (Note: you can still mix sliding with rotating but check - this bug might only be if ''translate'' is set to 0 0 0)<br />
<br />
===Visportals and Doors===<br />
<br />
A visportal face surrounded by solid at its edges and in contact with a door is closed when the door is closed and enabled when the door is open. In most cases you will place a visportal in contact with a working door unless you can see through the door (such as a true glass door or barred gate*.) For full details see [[Visportals]].<br />
<br />
''*As of 2.0 it is possible to make visportals that remain transparent when closed for gates and windows. See'' [[Controlling Sound Loss Across Portals]]<br />
<br />
==Auto-Closing/Opening Doors==<br />
Doors that automatically close after being open for some time are easy to setup: Each frobmover entity supports these spawnargs:<br />
<br />
;"auto_close_time":Set this to something >= 0 to let the mover automatically close (again) after this time when being fully opened (measured in seconds). Defaults to -1, which means 'do not autoclose'. The event is also activated when the mover starts at the open position at map start.<br />
;"auto_open_time":"Set this to something >= 0 to let the mover automatically open (again) after this time when being fully closed (measured in seconds). Defaults to -1, which means 'do not autoopen'. The event is also activated when the mover starts at the closed position at map start.<br />
<br />
Old text:<br />
<br />
Note that auto-closing doors and AI closing doors behind them, is very much work in progress at the time of writing, so for now, this is another method that works. Check first if true AI closing of doors is working yet before bothering with this!<br />
<br />
I have one door that I particularly want the AI to close as there is a bit of frame lag inside if not. So I set this up and it works good as an auto-closing door - not as good as a true AI closing door as it will auto close when the player goes through as well but it does look very effective to see AI going through and closing the door behind them. Not tested exhaustively so I don't know if there could be any downside. Here's what to do....<br />
<br />
First a quick summary to make it more clear:<br />
<br />
'''''A trigger_relay is used both as a relay AND carries a stim. We put the trigger_relay with its stim in the path of the open door. The door has a response property. When it opens and contacts the stim its response is to send a signal back to the relay. The relay pauses then closes the door...'''''<br />
<br />
* First, optionally give your door a suitable name like autodoor1, whatever.<br />
* Copy that name to the clipboard.<br />
<br />
Next we need a relay with a delay:<br />
<br />
* Create entity > darkmod > trigger_relay<br />
<br />
* Place it roughly at the position the door will be at when open and to be on the safe side 3/4th of the way to the far end of the door (not the hinge end) to give max distance from the close door.<br />
<br />
* Add the property 'target' and paste in the door name you just copied.<br />
<br />
* Give the relay itself a name, eg, autoDoor_relay_1, and copy that name to the clipboard, you'll need that too in a bit.<br />
<br />
* Add the property delay and the value 3 - this is the delay in seconds before the door will close; 3 seems about right but 2 might be worth a try because to that 3 is added a random value between 0 to 0.5 seconds from the Time Interval we entered for the stim firings.<br />
<br />
* Add the property 'wait' and the value 3. This is the time before it can work again in seconds. If you set it too low then in theory the door might trigger again but in this situation I don't think it's possible. Too long, eg, one minute, and it won't work if the AI goes back through the door before then. If this value is -1 then the whole thing will only work ONCE so might be used for an AI who goes through once, closes it behind him, but you don't want it to be an autodoor thereafter.<br />
<br />
<br />
That's the relay, now we add a stim to it:<br />
<br />
* Still with the trigger relay selected, go to {{menu|Entity|Stim/Response}}<br />
<br />
* Custom stim tab.<br />
<br />
* Click Add stim type, select the new custom stim type you just made at the bottom of the list and type in eg, autoDoorStim at top right in the input box.<br />
<br />
* Click the stim tab and the little drop down arrow against the 'type' selector at bottom left and you should see your new custom stim name. Select it.<br />
<br />
* Select the new autoDoorStim in the list and on the right you need only type in the radius box 15.0 There is quite a lot of room for error. I had it working on 10 and also on 25. The value should be less than the distance to the closed door else it will trigger open! But no so small that the door might not reach it.<br />
<br />
* Select the check box for Time Interval and enter 500 (millisecs.) This is so it doesn't keep firing more frequently than is necessary. This stim will be firing all through your mission whether the door is used or not so if you had dozens of these then maybe it would affect performance. Too big a number and there may be a long delay before the door shuts - but it will be random depending on the next time the stim happens to fire. We'll control the delay we want more precisely later.<br />
<br />
* Click {{ok}} to confirm it.<br />
<br />
<br />
That's the stim set up, now for the response to it which is put on the door....<br />
<br />
* Select the doorm, then use {{menu|Entity|Stim/response}} and select the response tab.<br />
<br />
* Click the little drop down arrow against the 'type' selector at bottom left and you should see your new custom stim name. Select it.<br />
<br />
* Right click in the big ''Response Effects'' box on the bottom right of the panel.<br />
<br />
* Add New Effect and you should get a default 'Activate Response' response added to the list. Double click it.<br />
<br />
* In the Effect selector at the stop select 'Trigger'<br />
<br />
* in the Target box, paste in the name of the relay you copied or you can select it from the list at the little arrow.<br />
<br />
* Leave the Activator box empty.<br />
<br />
* Click {{apply}} and then {{ok}} on the main S & R panel bottom right.<br />
<br />
It should now work. No need to wait for an AI, just frob the door and watch it close itself. If not, check the position of the stim brush is close to where the door stops when open.<br />
<br />
==AI Door management==<br />
<br />
See also [[#Keys_carried_by_AI]] above.<br />
<br />
By default AI will open doors and close them behind them. Here are some spawnargs the mapper can use to modify that behaviour:<br />
<br />
;"ai_should_not_handle" :If set to 1, AI will not attempt to handle it and add it to the forbidden areas when closed (so that it doesn't try to path through). They might still walk through the door when it is open though. Useful if you have some special use door that you don't want the AI to operate.<br />
<br />
;"ai_should_not_close" :If set to 1, AI will not close the door behind them unless it obstructs them.<br />
<br />
;"canRemainOpen" :If set to 1, it's the same as "ai_should_not_close, with the added behavior that this is ignored if the door needs to be relocked, or the door is marked "shouldBeClosed". '''(This spawnarg is available starting in TDM 2.02.)'''<br />
<br />
<br />
To get AI to unlock/relock specific doors there are two methods currently:<br />
<br />
1. add the following spawnarg/value to the AI:<br />
<br />
;"can_unlock1" ''<doorname>''<br />
<br />
'''Do NOT use can_unlock_1.'''<br />
<br />
For additional doors on the same AI use ''can_unlock2 doorname'' etc.<br />
<br />
<br />
2. In the editor position an actual key that works for that door on the AI and also add to the key bind <AIname> and also bindToJoint LeftHips_Dummy (see other joints names elsewhere in wiki.) Currently, if the player pickpockets the key then the AI seeks an alternate route but otherwise does nothing (?) This may be upgraded in the future to better strategies.<br />
<br />
3. There is the possibility in the future of an additional method which would just use special attach spawnargs to make the above easier. The key would spawn at the correct position at game start. Watch this space.<br />
<br />
<br />
===Door Handling Positions===<br />
<br />
It is also possible to set custom door handling positions for the AI. This is especially useful when the standard routine that lets the AI choose their standing positions while opening and closing the door fails, leaving them circling around in front of the door helplessly.<br />
<br />
Place a movers > ''atdm:door_handling_position'' entity where you want the AI to stand while opening/closing the door from this side.<br />
<br />
On the door, you need to set the spawnarg "door_handle_position" "name_of_door_handling_position". You can also place a ''door_handling_position'' on each side of the door, and the AI will automatically choose the right one. In this case, you need to set spawnargs with "door_handle_position_1" etc., and the corresponding names of the ''door_handling_position'' entities on the door.<br />
<br />
The ''door_handling_position'' entities can also carry spawnargs that define the behaviour of the AI, which are useful for example for doors that can only be opened or locked from one side:<br />
<br />
'''"ai_no_open"''' If set to true, the AI will not try to open the door from this side (but will still walk through when the door is already open).<br />
<br />
'''"ai_no_close"''' If set to true, the AI will not attempt to close the door from this side.<br />
<br />
'''"ai_no_unlock"''' If set true, the AI will not be able to unlock the door from this side, but still use it when it is not locked.<br />
<br />
'''"ai_no_lock"''' If this is set true, the AI will not lock the door from this side.<br />
<br />
===Door Controllers===<br />
<br />
'''Available in TDM 2.02+'''<br />
<br />
You can design a door so it's operated by buttons or levers or switches (aka ''controllers''):<br />
<br />
1. Set up the door in the normal manner. It can be a rotating door, a sliding door, a locked door, etc.<br />
<br />
2. Turn off the "frobable" spawnarg on the door. ("frobable" "0")<br />
<br />
3. Create a controller on each side of the door. If you're setting up a locked door, there's no need to put any locking information on the controllers.<br />
<br />
4. Give each controller the door as a target. (Alternatively, you can give the door these spawnargs: "door_controller1" "<name of controller 1>", "door_controller2" "<name of controller 2>".)<br />
<br />
When the game starts, it will transfer any locking information from the door to the controllers.<br />
<br />
Both the player and any AI that wants to use the door will use the controllers to operate it. Any key, "can_unlock", or lockpick settings you would normally use at the door are now used at the controllers.<br />
<br />
Controllers and ''door_handling_position'' entities can be used on the same door, but in that situation the ''door_handling_position'' entities don't define where the AI stands to operate the door. They simply provide the "ai_no_*" spawnargs that define AI behavior on each side of the door.<br />
<br />
You can have a controller on only one side of the door. Note that, since the door is not frobable, the player and the AIs won't be able to operate the door from the non-controller side, even if that side has a ''door_handling_position'' entity.<br />
<br />
===AI locking doors behind them===<br />
<br />
If one AI is involved (no one else is in the queue), he'll lock it behind him if he had to unlock it in the first place.<br />
<br />
Prior to TDM 1.08, if more than one AI is using the door at the same time (there's a queue), the first AI unlocks the door, and the last AI through will only lock it if it's marked "should_always_be_locked" AND they have a "can_unlock" for that door or they have a key for that door. The last AI to use the door doesn't know that the first AI found it locked, because that info is kept per AI, and not per door. <br />
<br />
Starting in TDM 1.08, if the first AI in a door queue found the door locked, that information is remembered by the door and the last AI through uses it to relock the door, as long as they have a "can_unlock" for that door or they have a key for that door.<br />
<br />
In the rare case where a door is set up to use door-handling position entities (necessary for AI to use sliding doors), either or both of those entities can have the "ai_no_lock" spawnarg, which means AI aren't allowed to lock the door from that side.<br />
<br />
==Doors as Triggers==<br />
<br />
''by Ishtvan & greebo''<br />
<br />
Doors (or any binary frob mover, buttons, levers, etc) now have the option to [[Triggers|trigger]] their target on closing or opening. (For definition purposes, a button is defined as "closed" in the state when it starts out and "open" in the state you press it down to. I know that's a little non-intuitive, but it came from deriving from doors).<br />
<br />
New spawnargs on frob movers:<br />
;"trigger_on_open" :If set to 1, this binary mover will trigger its targets when it starts out completely closed and is opened.<br />
;"trigger_when_opened":If set to 1, this binary mover will trigger its targets when it is completely opened. Code defaults to 0.<br />
;"trigger_on_close":If set to 1, this binary mover will trigger its targets when it completely closes after being open.<br />
<br />
== Suspicious Doors ==<br />
<br />
If you give a door the spawnarg '''"shouldBeClosed" "1"''', then AI will treat it as suspicious if they find the door open.<br />
<br />
Doors with that spawnarg should work like this:<br />
<br />
- an AI opening the door knows he's not to become suspicious if he opened the door<br />
<br />
- nearby AI alerted by the open door will also not react if they can see the door, and can see the AI that opened it<br />
<br />
- AI who come upon the open door later probably won't be able to see the AI that opened it, so they'll treat it as suspicious<br />
<br />
- if the AI who opened the door comes upon the door later, and it's still open, and no one's touched it since he opened it, he'll see his name on the door and won't become suspicious. "Oh, crap. I forgot to close it earlier."<br />
<br />
- If an AI comes upon an open door that should be closed, he should close it whether he becomes suspicious or not.<br />
<br />
'''Post TDM 2.00:'''<br />
- AI turn to look at a door they see opening. The player can crack open a suspicious door to peek out w/o grabbing the attention of a nearby AI. After 5s, the AI will notice the cracked open door. Non-suspicious doors can be cracked open indefinitely w/o nearby AI noticing.<br />
<br />
==Skins: A Wide Variety of Door Textures==<br />
<br />
This is to remind you that as with many Dark Mod models, there is a wide range of extras skins (textures) available for door models. There are now several basic door entities of different sizes so choose your size first. Then enter the spawnarg: skin with any temporary value. Now select it and click the skin button at the bottom of Dark Radiant's Entity Inspector and you will find a large of range of skin textures from which to select to give you a choice of appearances for your door.<br />
<br />
<br />
<br />
==Extra Notes==<br />
The property ''interruptable'' determines whether a door can be stopped by frobbing while it is opening or closing. So by frobbing then frobbing again, the player can open a door to any position, eg, slightly ajar to peek through.<br />
<br />
''func_darkmod_door'' is no longer used (just in case you come across it in the Dark Mod forums or wiki.) '''<code>atdm:mover_door</code>''' is the entity to use.<br />
<br />
{{tutorial-editing}}</div>RJFerrethttps://wiki.thedarkmod.com/index.php?title=Triggers&diff=17804Triggers2014-06-21T15:14:18Z<p>RJFerret: /* Triggers */ abutment disfunction</p>
<hr />
<div>There are many different ways of triggering [[Entity|entities]], the Trigger entities themselves, as well as through [[Stim/Response]], [[Conversations]], Movers, [[Objectives]], and more. How the trigger occurs will typically dictate which manner you choose for your map. <br />
<br />
=Triggers=<br />
To create triggers that rely on boundaries (once, multiple and their derivations), you need to drag out a worldspawn brush, right-click, select "Create Entity". (They will not function if abutted against others.) Triggers need to be connected to their subjects, either via "Connect Selected Entities" menu option/shortcut key, or adding "Target", "Target0", "Target1" or subsequent "Target"# spawnargs. The triggers below are listed roughly by frequency of usage, with related triggers beneath.<br />
<br />
==trigger_once==<br />
When the origin of an entity is within the bounds of this entity, the target(s) will be triggered, then the trigger_once is removed. (Note, to resize the brush after creating the entity, select it then press Tab once.)<br />
<br />
==trigger_once_entityname==<br />
Similar to [[Triggers#trigger_once|trigger_once]], but may be set to only respond to the entity specified by the spawnarg, "entityname". Note the entity must move into the boundaries itself, not be moved by the player (AI walking themselves for example). (If you want something to happen based on the player dropping or placing an item somewhere, use the [[Objectives]] system instead.)<br />
<br />
==trigger_multiple==<br />
Similar to [[Triggers#trigger_once|trigger_once]] but will activate again and again, use "Wait" spawnarg to control how many seconds between triggerings. <br />
<br />
==trigger_entityname ==<br />
Similar to [[Triggers#trigger_multiple|trigger_multiple]] but only reacts to the entity defined by the "entityname" spawnarg.<br />
<br />
== trigger_facing ==<br />
Also similar to [[Triggers#trigger_multiple|trigger_multiple]], but requires the triggering entity to be within 30° of the specified "angle" spawnarg. For details see [[Trigger Facing]].<br />
<br />
==trigger_relay ==<br />
Most commonly used to trigger many targets, or do so after a delay (per the "delay" spawnarg). May be set to only work once (spawnarg "wait" "-1") or limit firing based upon how many seconds have passed. The "random" spawnarg may be used with "wait" to vary the firings. Very useful as the target of worldspawn, to trigger things at map start (since worldspawn currently only activate one "Target"), or as the target of Objectives.<br />
<br />
==trigger_count ==<br />
This will fire at it's targets upon a specific number of times being triggered itself, based upon the "count" spawnarg. If "count" "3" is set, it will do nothing until the third triggering. <br />
<br />
== trigger_timer ==<br />
This trigger will fire repeatedly every "wait" # seconds. The spawnarg "start_on" defines if it should do so at the start of the map, or wait to be triggered (defaults to 0, off at map start). Spawnarg "random" adds variability to the triggerings.<br />
<br />
== trigger_fade ==<br />
Will cause the display to fade or dissolve to a specified color. The spawnarg "fadeColor" specifies which color, and how transparent in RGBA (red, green, blue, and alpha, ranging from 0-1). Default is fade to black: "fadeColor" "0 0 0 1". To fade up from whatever, use alpha of 0, IE to fade up from black, "0 0 0 0". "fadeTime" controls how quickly the fade transpires.<br />
<br />
== trigger_hurt ==<br />
Applied to a worldspawn brush to define boundaries à la a [[Triggers#trigger_multiple|trigger_multiple]], by default it causes 10 points of damage/second to the activator (player or AI). It may be triggered on/off. The spawnarg, "delay" may be set to vary frequency of damage application. One of various "def_damage" may be specified, generally found in the root directory of the entities, or to see specific details, in the defs file, "damage.def". Note those referencing "triggerhurt" simply cause damage, while others feature additional effects such as push and knockbacks (launching the player away).<br />
<br />
If you need varying amount of damage based on proximity, the [[Stim/Response_Key/Values#Damage_Stim|Stim/Response]] system offers control of various types of falloff.<br />
<br />
== trigger_presize ==<br />
Akin to [[Triggers#trigger_multiple|trigger_multiple]] without the need of creating a brush first, and defaults to not being touched by players/AIs, but triggered by other entities/script.<br />
<br />
== trigger_touch ==<br />
Continuously checks if entities are touching, costly performance wise, probably done via [[Objectives]] more efficiently.<br />
<br />
=Triggering Stim/Response=<br />
'''To Trigger Something Else:'''<br />
<br />
Any Response type may have an effect of "Trigger", in which another entity selected is triggered. Note the "Trigger" effect is all the way at the bottom of the drop down, which might not be displayed on screen (Toggle Effect is the last displayed on mine), you may cursor down or use the End key to get to Trigger.<br />
<br />
'''Be Triggered:'''<br />
<br />
Within the [[Stim/Response]] editor, add a response stim set to "Trigger", now when this entity is targeted, whatever specified effect will occur.<br />
<br />
An example would be to not have something able to be frobbed until something obscuring it is removed or opened. Make the response effect "Set Frobable" for the entity in question, and check "frobability" on. Now when the item is triggered, by a door, or frob response on something in front moved/picked up, it will become frobable.<br />
<br />
=Triggering via Conversation=<br />
The command, [[Conversations#Conversation Commands 2|ActivateTarget]] will trigger the specified entity at that time in the Conversation script.<br />
<br />
=Triggering via Doors, Buttons, Levers, Movers=<br />
[[Doors]] trigger their targets by default upon opening (spawnarg "trigger_on_open" "1"). They may also trigger when completely open by changing "trigger_when_opened" to 1 instead of the default 0, or when fully closed via "trigger_on_close". Note, those conditions on Buttons came from doors, so are counter-intuitive.<br />
<br />
=Triggering via Objectives=<br />
In the [[Objectives Editor]] you may select an entity to be triggered upon an objective succeeding or failing. Therefore all the possible objective conditions may become trigger events (knock out an AI, move an object away from another or to a spot, cause another objective to become visible, disappear or complete, etc.)<br />
<br />
=Triggering via Worldspawn=<br />
You may set "Target" on Worldspawn (usually at a trigger_relay since it only may target one entity currently) to cause things to be triggered at map start. If you use this to kill an AI or other affect with audio, note if in range of the player's start, it will be heard during the fade up from black.<br />
<br />
=Triggering via Lights=<br />
Lights trigger their target(s) both upon being extinguished and lit. This is useful to match window glow to actual light condition. Depending on the light, it may be tricky to set the targets however. A basic light entity can simply have target(s) spawnargs, but a candle, lamp or torch with attached flame entity, you need to use the "set" spawnarg. For example, "set target0 on flame" "EntityToBeTriggered".<br />
<br />
=Trigger a Script=<br />
Point any trigger at a target_callscriptfunction entity and give it the spawnarg, "call" ''ScriptFunctionName'', where ''ScriptFunctionName'' matches "void ''ScriptFunctionName''()" in the map's .script file. See [[Scripting_basics#Script_invocation|script invocation]] for more info.<br />
<br />
[[Category:Editing]]</div>RJFerrethttps://wiki.thedarkmod.com/index.php?title=Skybox_Basics&diff=17803Skybox Basics2014-06-20T13:30:19Z<p>RJFerret: Redirecting blank page</p>
<hr />
<div>#REDIRECT [[Skybox_Basic_Details]]</div>RJFerrethttps://wiki.thedarkmod.com/index.php?title=Conversation_Tutorial&diff=17802Conversation Tutorial2014-06-17T10:43:40Z<p>RJFerret: /* Triggering */ revised usage lingo for 2.02</p>
<hr />
<div>Presumably your AI are pathing along, minding their own business, when you want them to interact, say something specific, or glance at one another. Here's how to set that up, step by step... ([[Conversations]] are more than just talk, they may control movement, animations, or other things.)<br />
<br />
<br />
= Triggering =<br />
First they have to run into a [[Triggers|trigger]] to initiate a "conversation", either as the target of a pathnode (once TDM 2.02 is available), another trigger entity, or a stim/response trigger, or equivalent.<br />
<br />
The trigger targets an "atdm:target_startconversation" entity (found in targets folder). That entity gets the spawnarg "conversation" "whatever" (substitute "whatever" with a label to identify this conversation compared to future ones in the list).<br />
<br />
=Sounds/Lines=<br />
Before you jump in, you will need to type in which soundshaders you will be using if you want them to talk. So if you haven't already picked your lines, pop in a temporary Speaker and get the names of the [[Sound_Folder_Structure|soundshaders]] you'll want to use.<br />
<br />
For example, I have an AI greet a horse with "tdm_ai_wench_greet_civilian_to_civilian", to which the horse whinnies via "animal_horse_idle", then she commiserates to it from, "tdm_ai_wench_idle". If you desire a specific line, or custom, you'll have to create your own soundshader (a text file listing an audiofile).<br />
<br />
=Conversation Editor window=<br />
Now enter the Conversation Editor (map menu), which will create an entity if you don't already have one, be sure it's not placed in the void!<br />
<br />
Click +Add down at the bottom to create a new conversation, then edit it. You'll notice toward the top, "Actors must be within talk distance" and "always facing", these cause them to move toward each other, and/or turn when the conversation is triggered, not that the conversation waits until they are in range. +Add an actor (you may have just one, or multiple AI interacting), it's/their names go here to identify who does what/when in the next step.<br />
<br />
Now in the bottom you may add commands, which run in sequence (generally). You may choose for one to not wait, in which case the next will occur perhaps before the current completes. This can be good to have AI talk more naturally overlapping, rather than a lengthy pause between each spoken line.<br />
<br />
Typical commands are "Talk" to say something (paste in a soundshader name you noted earlier), look at something or someone (including player1), wait a few seconds, etc. For example, my wench looks at the horse, says her line, the horse whinnies in reply, then she delivers her final line. That's it, now check to see how it works out in game.<br />
<br />
(Note: if you want to mute your AI generally, so they don't use their usual vocalizations the rest of the time (perhaps not making sense leading in or out of your conversation), change "def_vocal_set" to "atdm:ai_vocal_set_mute".)<br />
<br />
=See also=<br />
[[Conversations]]<br />
<br />
[[Cutscenes Part 3: Lighting, Placing the Player, and Conversations#Conversations]]<br />
<br />
[[Category:Tutorial]]</div>RJFerrethttps://wiki.thedarkmod.com/index.php?title=Scripting_basics&diff=17800Scripting basics2014-06-13T19:26:50Z<p>RJFerret: /* Script invocation */ +wikilinked triggers</p>
<hr />
<div>Doom 3 scripts are text files containing script code in a proprietary syntax. By convention, they are given a <tt>.script</tt> extension. Game-wide script files are located in the <tt>script</tt> directory, while map-specific script files are located in the same directory as the corresponding map.<br />
<br />
== Starting with scripting ==<br />
<br />
This article is an overview over the basics of scripting. If you are impatient and just want to implement a specific functionality, see [[My first map script]] for a start into scripting. <br />
<br />
== Syntax ==<br />
<br />
Doom 3 scripts have a vaguely C++-like syntax, though they are nowhere near as powerful as C++. They have standard braces-and-semicolons syntax, and a notion of "classes". Class members are defined inside a class declaration and defined separately, rather like C++. Unlike C++, there are no separate header files; everything goes into one script file.<br />
<br />
Doom 3 scripts have only a few data types:<br />
<br />
* <tt>float</tt> - A number, integer or floating point.<br />
* <tt>boolean</tt> - can be false or true.<br />
* <tt>string</tt> - A string (sequence of characters).<br />
* <tt>vector</tt> - Three numbers in one variable; useful for representing locations, velocities, etc.<br />
* <tt>entity</tt> - A reference to an entity (a pointer, in C++ parlance).<br />
<br />
Note the complete lack of a dedicated integer type (use <tt>float</tt> instead), or any ability to define complex data structures! If data structures are needed, they are typically created in the SDK and ''scriptevents'' (see below) are provided to allow scripts to manipulate them.<br />
<br />
For a more detailed specification of Doom 3 script syntax, see [http://www.modwiki.net/wiki/SCRIPT_%28file_format%29 Modwiki's SCRIPT file reference].<br />
<br />
=== The float data type ===<br />
All numeric values are stored in '''float''' data types, which is the only numeric type. Neither int, double nor short, unsigned or other numeric keywords known from C exist in D3 Scripting. Still, most of the operators are applicable, like ++, +, -, +=, *=, etc.<br />
<br />
=== The boolean data type ===<br />
The data type boolean can only hold two values, namely true or false (TRUE or FALSE work as well). Behind the scenes, this is just another float variable.<br />
<br />
Note: you can also use float as argument of conditional expressions, like this:<br />
float myFloat = 1; // this will evaluate to TRUE when used in conditional expr.<br />
if (myFloat) {<br />
// do something, <br />
}<br />
<br />
=== The string data type ===<br />
Strings hold sequences of characters, like the keys or values of entity spawnargs. Their use is quite intuitive, the + operator can be used to concatenate them:<br />
string myStr = $player1.getKey("name"); // Retrieve the value of the "name" spawnarg of the player entity<br />
myStr = "The name of player 1 is " + myStr + "\n";<br />
sys.println(myStr); // Print the text to the console<br />
<br />
=== The vector data type ===<br />
The data type vector implements a three-component vector. As arrays and their native operator [] is not implemented in D3 scripting, the elements of vectors are accessed like this:<br />
vector myVec; // declare a new vector<br />
myVec_x = 20;<br />
myVec_y = 0;<br />
myVec_z = 0;<br />
// myVec now holds the 3D vector <20,0,0><br />
Alternatively, you can assign a string to a vector variable, like this (the string gets converted correctly, but be sure to use '''single quotes'''):<br />
myVec = '0 10 0';<br />
As an example, the '''getOrigin()''' methods return a vector.<br />
<br />
=== The entity data type ===<br />
References to other entities are stored in the '''entity''' data type. Entities can be looked up by name, like this:<br />
entity myEnt; // declare myEnt to be of type entity<br />
myEnt = $player1; // Let myEnt refer to the player entity, which by convention has the name "player1".<br />
The entity data type can be compared to the pointers (that's also how they are stored internally) - there also exists a NULL entity, named '''$null_entity'''.<br />
<br />
=== The sys entity ===<br />
Script events always have to be called on an entity, like this:<br />
$player1.kill(); // kill the player<br />
However, there are a lot of scriptEvents which are unrelated to a specific entity, like cos(), sin(), spawn() and such. These "generic" events are invoked on the '''sys''' entity, like this:<br />
entity myLight = sys.spawn("light_moving"); // spawn a new light entity<br />
myLight.setOrigin($player1.getOrigin()); // move it to the point where the player is currently residing<br />
<br />
=== Script Events ===<br />
<br />
You can find a list of existing script events in the following two files:<br />
<br />
* scripts/doom_events.script<br />
* scripts/tdm_events.script<br />
<br />
demagogue: The Editing FAQ adds this information about script events.<br />
<br />
'''Q. What are script events (aka commands or functions)?'''<br />
<br />
'''A.''' A script event is a pre-made object that does something for you, usually to some game item you specify, just when you write it in your code (like $item.eventX(); does X to item). Sometimes it wants parameters or arguments to run (the stuff in parentheses) and will give an error if you don't put the arguments in the parentheses in exactly the way it wants, with the right number of them & right data types, etc. And some of them return values too, especially the "get" functions, which are handed over to a variable (e.g., X = getValue();, now X has the value. If X is an entity, you can even act on X as if it's the entity itself. Just be sure the data type of X and Value are the same, e.g. float, or string, or entity, etc, or you'll get an error).<br />
<br />
'''Q. What are some common or useful script events for editing?'''<br />
<br />
'''A.''' A list of all Doom3 and TDM script events are listed in two files (open with a text editor): scripts/doom_events.script, scripts/tdm_events.script. Proper syntax for the Doom3 events is here [http://www.modwiki.net/wiki/Script_events_%28Doom_3%29]. Note that TDM has some of its own script events, like setFrobable (in the tdm_events.script list). A quick list of common or useful script events good for editing is here: [[Script_Events_User-Friendly_List]], with syntax and description, and including TDM events. It doesn't list all script events and all details, just common & useful ones for actual mapping IMO.<br />
<br />
== Discovery (or, why is Doom 3 ignoring my script file?) ==<br />
<br />
Doom 3 will automatically find and load some kinds of files, such as .def files. However, it does not do the same for script files; if you merely create a .script file and place it in the <tt>script</tt> directory, Doom 3 will blithely ignore it.<br />
<br />
There are two ways to make Doom 3 use a script:<br />
<br />
* Place it in a map script. '''This is the recommended way for mappers'''. Map scripts are loaded when the corresponding map is loaded. They must be given the same name and placed in the same location as the corresponding map file, but with a .script extension instead of a .map extension. For example, the map script for <tt>maps/mydir/mymap.map</tt> must be called <tt>maps/mydir/mymap.script</tt>. Map scripts are used to implement map-specific behaviours; as such, mappers will often use them but mod coders typically won't.<br />
<br />
* There is only one script that Doom 3 loads for all maps. It's called <tt>script/tdm_main.script</tt>, and is loaded before the map-specific script. Since this script would be extremely long if it contained all the general-purpose script code in the ''entire mod'', we don't put any script code in <tt>tdm_main.script</tt> directly. Instead, we use <tt>#include</tt> directives to pull in scripts with different names. For example, <tt>tdm_events.script</tt> is <tt>#include</tt>d from <tt>tdm_main.script</tt>.<br />
<br />
Most of the TDM-specific scripts, including <tt>tdm_ai_base.script</tt>, are <tt>#include</tt>d from <tt>tdm_main.script</tt>. We could also put further <tt>#include</tt> directives into <tt>tdm_ai_base.script</tt>, and so on. As long as a script gets <tt>#include</tt>d at least once, it will get loaded in all maps. Note that you should be careful not to <tt>#include</tt> the same script twice, or Doom 3 will complain about multiple definitions - one common way to avoid accidental double-inclusion is to place so-called "inclusion guards" in your script file (C/C++ programmers will be familiar with this kind of preprocessor trickery):<br />
#ifndef __TDM_MOVERS__<br />
#define __TDM_MOVERS__<br />
<br />
// your code here will get included exactly once<br />
<br />
#endif //__TDM_MOVERS__<br />
<br />
== Script invocation ==<br />
<br />
'''TODO:''' Describe the various ways in which functions in script files can get called.<br />
<br />
{{infobox|The <tt>tdm_main</tt> function in <tt>script/tdm_main.script</tt> will be called right before the level starts to load. It's not recommended to put map-specific scripting in there. For map-specific script setup, use the map's own script file and place a <tt>void main()</tt> function in there, which will get called by the game.}}<br />
<br />
demagogue: The Editing FAQ has this entry for calling functions in scripts in-game.<br />
<br />
'''Q. How do I run a script in-game?'''<br />
<br />
'''A.''' A few common ways of calling a script object thread in-game are <br />
# creating a target_callscriptfunction entity with the spawnarg: "call" "<name of your script object>", then creating some other entity (such as a button or [[Triggers|trigger brush]]) that "targets" that entity; <br />
# creating a button with the property "state_change_callback" "<script object>", which runs the script when pushed or triggered, <br />
# Using [[Location_Settings#Script_calls]] to call a script when you enter or leave a location; <br />
# triggering a script with the [[Objectives_Editor]] when you fulfill or fail an objective (possibly a hidden objective only for triggering the script); <br />
# A script can call another thread in itself with the "thread" function; see the command in the link below. <br />
# An entity can call a script when it spawns. Add a property/value either in the .def file or as a spawnarg on the entity: "ScriptEvent void <script object>(<parameters>);". <br />
# The script "void main();" is always called at game start. So if you add code under that heading in your script file, it will run at game start. <br />
There are other methods too. (Note, if you call a persistent script, i.e., it runs all game, be especially sure to avoid performance hits, or make it non-persistent if possible, that is, you "kill" it at some point in the game so it doesn't hog resources.)<br />
<br />
== Interfacing with the SDK ==<br />
<br />
No language can operate usefully in a vacuum - at some point it needs to go out and do stuff.<br />
<br />
'''TODO:''' Describe the various ways in which the SDK can interface with Doom 3 scripts; scriptevents, scriptvars (instances of idScriptVar), etc.<br />
<br />
Vanilla Doom 3 script reference: http://www.modwiki.net/wiki/Script_events_%28Doom_3%29<br />
<br />
Also need refs for Dark Mod's scriptevents.<br />
<br />
== Things that don't exist in D3 scripting ==<br />
This is a non-comprehensive list of things that don't exist in D3 scripting, but may be expected or known from other languages.<br />
<br />
* structs<br />
* pointers (including dereference operators ->, *)<br />
* integers (use floats instead)<br />
* arrays (including the array operator[])<br />
* exceptions<br />
* "crashes" (you can call scriptEvents on any entity, even if that entity doesn't support it, the script won't crash).<br />
* char data types, which implies that const char* is also missing (use string instead)<br />
* private/public/protected<br />
* multiple inheritance<br />
<br />
== See also ==<br />
<br />
* [[My first map script]]<br />
<br />
{{scripting}}<br />
{{todo}}</div>RJFerrethttps://wiki.thedarkmod.com/index.php?title=Triggers&diff=17799Triggers2014-06-13T19:24:24Z<p>RJFerret: +script triggering</p>
<hr />
<div>There are many different ways of triggering [[Entity|entities]], the Trigger entities themselves, as well as through [[Stim/Response]], [[Conversations]], Movers, [[Objectives]], and more. How the trigger occurs will typically dictate which manner you choose for your map. <br />
<br />
=Triggers=<br />
To create triggers that rely on boundaries (once, multiple and their derivations), you need to drag out a worldspawn brush, right-click, select "Create Entity". They need to be connected to their subjects, either via "Connect Selected Entities" menu option/shortcut key, or adding "Target", "Target0", "Target1" or subsequent "Target"# spawnargs. The triggers below are listed roughly by frequency of usage, with related triggers beneath.<br />
<br />
==trigger_once==<br />
When the origin of an entity is within the bounds of this entity, the target(s) will be triggered, then the trigger_once is removed. (Note, to resize the brush after creating the entity, select it then press Tab once.)<br />
<br />
==trigger_once_entityname==<br />
Similar to [[Triggers#trigger_once|trigger_once]], but may be set to only respond to the entity specified by the spawnarg, "entityname". Note the entity must move into the boundaries itself, not be moved by the player (AI walking themselves for example). (If you want something to happen based on the player dropping or placing an item somewhere, use the [[Objectives]] system instead.)<br />
<br />
==trigger_multiple==<br />
Similar to [[Triggers#trigger_once|trigger_once]] but will activate again and again, use "Wait" spawnarg to control how many seconds between triggerings. <br />
<br />
==trigger_entityname ==<br />
Similar to [[Triggers#trigger_multiple|trigger_multiple]] but only reacts to the entity defined by the "entityname" spawnarg.<br />
<br />
== trigger_facing ==<br />
Also similar to [[Triggers#trigger_multiple|trigger_multiple]], but requires the triggering entity to be within 30° of the specified "angle" spawnarg. For details see [[Trigger Facing]].<br />
<br />
==trigger_relay ==<br />
Most commonly used to trigger many targets, or do so after a delay (per the "delay" spawnarg). May be set to only work once (spawnarg "wait" "-1") or limit firing based upon how many seconds have passed. The "random" spawnarg may be used with "wait" to vary the firings. Very useful as the target of worldspawn, to trigger things at map start (since worldspawn currently only activate one "Target"), or as the target of Objectives.<br />
<br />
==trigger_count ==<br />
This will fire at it's targets upon a specific number of times being triggered itself, based upon the "count" spawnarg. If "count" "3" is set, it will do nothing until the third triggering. <br />
<br />
== trigger_timer ==<br />
This trigger will fire repeatedly every "wait" # seconds. The spawnarg "start_on" defines if it should do so at the start of the map, or wait to be triggered (defaults to 0, off at map start). Spawnarg "random" adds variability to the triggerings.<br />
<br />
== trigger_fade ==<br />
Will cause the display to fade or dissolve to a specified color. The spawnarg "fadeColor" specifies which color, and how transparent in RGBA (red, green, blue, and alpha, ranging from 0-1). Default is fade to black: "fadeColor" "0 0 0 1". To fade up from whatever, use alpha of 0, IE to fade up from black, "0 0 0 0". "fadeTime" controls how quickly the fade transpires.<br />
<br />
== trigger_hurt ==<br />
Applied to a worldspawn brush to define boundaries à la a [[Triggers#trigger_multiple|trigger_multiple]], by default it causes 10 points of damage/second to the activator (player or AI). It may be triggered on/off. The spawnarg, "delay" may be set to vary frequency of damage application. One of various "def_damage" may be specified, generally found in the root directory of the entities, or to see specific details, in the defs file, "damage.def". Note those referencing "triggerhurt" simply cause damage, while others feature additional effects such as push and knockbacks (launching the player away).<br />
<br />
If you need varying amount of damage based on proximity, the [[Stim/Response_Key/Values#Damage_Stim|Stim/Response]] system offers control of various types of falloff.<br />
<br />
== trigger_presize ==<br />
Akin to [[Triggers#trigger_multiple|trigger_multiple]] without the need of creating a brush first, and defaults to not being touched by players/AIs, but triggered by other entities/script.<br />
<br />
== trigger_touch ==<br />
Continuously checks if entities are touching, costly performance wise, probably done via [[Objectives]] more efficiently.<br />
<br />
=Triggering Stim/Response=<br />
'''To Trigger Something Else:'''<br />
<br />
Any Response type may have an effect of "Trigger", in which another entity selected is triggered. Note the "Trigger" effect is all the way at the bottom of the drop down, which might not be displayed on screen (Toggle Effect is the last displayed on mine), you may cursor down or use the End key to get to Trigger.<br />
<br />
'''Be Triggered:'''<br />
<br />
Within the [[Stim/Response]] editor, add a response stim set to "Trigger", now when this entity is targeted, whatever specified effect will occur.<br />
<br />
An example would be to not have something able to be frobbed until something obscuring it is removed or opened. Make the response effect "Set Frobable" for the entity in question, and check "frobability" on. Now when the item is triggered, by a door, or frob response on something in front moved/picked up, it will become frobable.<br />
<br />
=Triggering via Conversation=<br />
The command, [[Conversations#Conversation Commands 2|ActivateTarget]] will trigger the specified entity at that time in the Conversation script.<br />
<br />
=Triggering via Doors, Buttons, Levers, Movers=<br />
[[Doors]] trigger their targets by default upon opening (spawnarg "trigger_on_open" "1"). They may also trigger when completely open by changing "trigger_when_opened" to 1 instead of the default 0, or when fully closed via "trigger_on_close". Note, those conditions on Buttons came from doors, so are counter-intuitive.<br />
<br />
=Triggering via Objectives=<br />
In the [[Objectives Editor]] you may select an entity to be triggered upon an objective succeeding or failing. Therefore all the possible objective conditions may become trigger events (knock out an AI, move an object away from another or to a spot, cause another objective to become visible, disappear or complete, etc.)<br />
<br />
=Triggering via Worldspawn=<br />
You may set "Target" on Worldspawn (usually at a trigger_relay since it only may target one entity currently) to cause things to be triggered at map start. If you use this to kill an AI or other affect with audio, note if in range of the player's start, it will be heard during the fade up from black.<br />
<br />
=Triggering via Lights=<br />
Lights trigger their target(s) both upon being extinguished and lit. This is useful to match window glow to actual light condition. Depending on the light, it may be tricky to set the targets however. A basic light entity can simply have target(s) spawnargs, but a candle, lamp or torch with attached flame entity, you need to use the "set" spawnarg. For example, "set target0 on flame" "EntityToBeTriggered".<br />
<br />
=Trigger a Script=<br />
Point any trigger at a target_callscriptfunction entity and give it the spawnarg, "call" ''ScriptFunctionName'', where ''ScriptFunctionName'' matches "void ''ScriptFunctionName''()" in the map's .script file. See [[Scripting_basics#Script_invocation|script invocation]] for more info.<br />
<br />
[[Category:Editing]]</div>RJFerrethttps://wiki.thedarkmod.com/index.php?title=LOD&diff=17792LOD2014-06-04T22:44:52Z<p>RJFerret: +example</p>
<hr />
<div>A '''Level of Detail''' (LOD) system can be used to bring more details to the screen while still speeding up rendering. See [http://en.wikipedia.org/wiki/Level_of_detail Wikipedia] for an introduction.<br />
<br />
== The new LOD System - Overview ==<br />
<br />
[[Image:TheDarkMod LOD System Overview.png]]<br />
<br />
SVG version of the above graphic [http://bloodgate.com/mirrors/tdm/TheDarkMod_LOD_System.svg here].<br />
<br />
{{infobox|Note: Fade in and fade out do '''only''' work on entities via ''[[alpha-fading]]'' (e.g. with alphatest materials and an alpha-channel in the texture that contains a range from 0..1.0). This is due to a deficit in the D3 engine and can only be fixed after D3 has gone open source.|bg=#f09090|fg=yellow}}<br />
<br />
== How to use LOD in your TDM map ==<br />
<br />
To enable the LOD system, use either one of the pre-made LOD-enabled entities in your map (most of these are defined in '''def/tdm_lod.def''') or set '''dist_check_period''' to a number greater than 0.<br />
<br />
Note: The '''dist_check_period''' spawnarg needs to be combined with one of "hide_distance" or "lod_X_distance" and "model_lod_X", "skin_lod_X" or "noshadows_lod_X" to have any effect!<br />
<br />
See also '''[[LOD Bias]]''' for how to hide individual entities depending on the menu setting.<br />
<br />
== GUI Setting ==<br />
<br />
There is a new GUI setting, called [[Object detail| '''Object detail''' ]]. You'll find it under <tt>'''Settings - Video - Advanced'''</tt>. It consist of multiple levels, where '''Normal''' is the default. Lower settings cause the LOD distances to shrink, meaning entities switch sooner to the low-quality version and vanish sooner. Higher settings are the opposite, increasing the quality, but may be decreasing the FPS.<br />
<br />
Mappers should design and test their map with the '''Normal''' setting on a typical modern PC (e.g. not too old and not high-end gaming rig either), and preferable also test on some slower and faster machines.<br />
<br />
== Entities ==<br />
<br />
Example entities:<br />
<br />
* atdm:nature_pine_skeleton (just the tree trunk)<br />
* atdm:nature_pine (Pine + particle leaves slowly swaying)<br />
* atdm:nature_tree_stump<br />
<br />
More can be found in the "Nature" folder with the DarkRadiant "Create entity" command.<br />
<br />
== Spawnargs ==<br />
<br />
=== min_lod_bias/max_lod_bias ===<br />
<br />
See [[LOD Bias]] for how to hide individual entities depending on the menu setting.<br />
<br />
=== hide_distance ===<br />
<br />
In D3 units. When set to a value > 0, then the entity will be hidden if it is further away than this distance from the player.<br />
<br />
Note: This might cause "popping", e.g. the entity will suddenly vanish or appear. See '''lod_fadeout_range''' for how to avoid this.<br />
<br />
The actual value used from this spawnarg is modified by the menu setting "Object detail", so make to sure to test with this setting at "Normal". Also see '''min_show_distance''':<br />
<br />
=== lod_normal_distance ===<br />
<br />
From TDM v1.05 onwards: This spawnarg defines a '''minimum''' distance from the player where the entity will ignore settings lower than '''Normal'''. This can be used to enforce a certain minimum distance so that players who set the detail level to '''Low''' or '''Lowest''' still do not experience entities popping in and out when being very close.<br />
<br />
If this spawnarg is not set, it defaults to '''500 units'''. Avoid setting this spawnarg too high or even equal or higher than "hide_distance". This would only result in the menu setting "Object detail" being fixed at "Normal", e.g. players could never lower the quality settings to achive better frame rates. Do so only in rare cases where important entities would otherwise vanish in front of the eyes of the player.<br />
<br />
Setting '''min_show_distance''' to very low values (e.g. 100 units) is ok for things that really should vanish close, like grass or small decals. Setting it to f.i. to 1000 for a big statue can avoid popping.<br />
<br />
=== lod_hide_probability ===<br />
<br />
If '''lod_hide_distance''' is true, this spawnarg controls what the probabiliy of this entity vanishing is. Values range from 0.0 (will never vanish) to 1.0 (will certainly vanish). Whether a particular entity vanishes is computed at map start, so an entity either stays or vanishes, but does not change during the map play time.<br />
<br />
Example:<br />
<br />
"lod_hide_probability" "0.2"<br />
<br />
If you place X identical entities, about 20% of them will vanish at the '''hide_distance''' and 80% will stay.<br />
<br />
This can be used to "thin out" forests at a distance without having them vanish completely.<br />
<br />
=== lod_X_distance ===<br />
<br />
In D3 units. Sets the distance from where on LOD X is used. Will be valid until the next defined lod_(X+1)_distance, or infinty if there is no further LOD distance set.<br />
<br />
To change the appearance of the entity inside this LOD, use the following spawnargs with a matching X:<br />
<br />
==== model_lod_X ====<br />
<br />
Set the model the entity displays inside this LOD. If not set, uses the model from LOD 0 e.g. the one from the "model" spawnarg.<br />
<br />
==== skin_lod_X ====<br />
<br />
Set the skin the entity displays uses this LOD. If not set, uses the skin from LOD 0 e.g. the one from the "skin" spawnarg.<br />
<br />
==== noshadows_lod_X ====<br />
<br />
Boolean. If set, the entity casts no shadows while in this LOD zone.<br />
<br />
==== lod_fadein_range ====<br />
<br />
{{infobox|Note: Fade in and fade out do only qwork via ''[[alpha-fading]]''. This can only be fixed after D3 has gone open source.|bg=#f09090|fg=yellow}}<br />
<br />
In D3 units. If set to non-zero, then the object will start hidden and begin to fade in at '''lod_1_distance''' - '''lod_fadein_range''' and be completely (100% opacity) visible at '''lod_1_distance'''. This can be used to create entities that only appear in some distance but not close up.<br />
<br />
==== lod_fadeout_range ====<br />
<br />
{{infobox|Note: Fade in and fade out do only qwork via ''[[alpha-fading]]''. This can only be fixed after D3 has gone open source.|bg=#f09090|fg=yellow}}<br />
<br />
In D3 units. If set to non-zero, then the object will not vanish suddenly at '''hide_distance''', but start to fade out and be completely invisible at '''hide_distance''' + '''lod_fadeoutrange'''. Defaults to 0.<br />
<br />
== Increasing the LOD steps ==<br />
<br />
The number of possible LOD steps is fixed in code and defined in '''game/misc.h''' as a constant. The current<br />
value is 7, meaning that there are 5 different rendering possibilities beside level 0 (the original) and level 6 (the object is hidden). That should be enough even for huge outdoor maps.<br />
<br />
== Performance ==<br />
<br />
Profiling showed that 3000 thinking entities consume about 7% CPU time. So if you use only a few hundred or thousand LOD entities, the performance of the extra thinking time is very small compared to the benefits of having only a few entities actually visible around the player. <br />
<br />
== Example ==<br />
<br />
At it's simplest, model, dist_check_period, hide_distance, lod_1_distance and model_lod_1 are used:<br />
[[File:Lod_test2.png|thumb|right|click for full size]]<br />
* '''model ''RegularModelName''''' -- point this to the fully detailed model<br />
* '''dist_check_period 0.5''' -- time in seconds between distance checks<br />
* '''hide_distance 400'''<br />
* '''lod_1_distance 100'''<br />
* '''model_lod_1 ''LessDetailedModelName''''' -- lower detail model<br />
* '''lod_2_distance 200''' -- (optional further step)<br />
* '''model_lod_2 ''LowerDetailModelName''''' -- even lower detail model (optional further step)<br />
<br />
== History ==<br />
<br />
Doom3 did not have any LOD system at all. The first steps of such a system were added in TDM by supporting a '''hide_distance''' spawnarg, which made entities hide or portals close once they were further away than this distance. The LOD system in TDM was totally rewritten for v1.04. <br />
<br />
=== Comparison ===<br />
<br />
Here we compare the new (v1.04) to the old system (until v1.02):<br />
<br />
* The old system had only two levels: 0 (original model), and 1 (entity is hidden)<br />
* Due to a typo, all thinking for the LOD entities happened in the first half of the interval. That means if you set the intervall to 1 s, all entities did their distance check between 0 and 0.5 seconds, and none between 0.5 and 1 second and so on. This lead to fluctuating frame rates.<br />
<br />
The new system:<br />
<br />
* Supports up to 7 levels (last is ''hide''), more can easily be done with a recompile<br />
* You can use less levels if you want<br />
* Thinking is distributed over the entire interval<br />
* makes scenes with thousands of entities possible<br />
* Can not only switch the model, but also change the skin (f.i. use less expensive glass shaders) and turn shadows off<br />
* Can hide only a fraction of all entities of the same class (''thinning out'')<br />
* Allows the player (via the settings menu) to control the quality vs. speed<br />
<br />
Note: The new system still works only for '''func_static''' (e.g. not for lights, AI etc)!<br />
<br />
== See also ==<br />
<br />
* [[LOD Bias]]<br />
* [[Creating LOD Models]] with only Gimp/Photoshop and DarkRadiant<br />
* [[List of LOD Models]]<br />
* [[SEED]] - Random entity placement and distant culling<br />
<br />
{{editing}} {{scripting}}</div>RJFerrethttps://wiki.thedarkmod.com/index.php?title=Conversations&diff=17744Conversations2014-04-28T12:52:08Z<p>RJFerret: /* Volume of Custom Lines */</p>
<hr />
<div>Conversations between AI have a HUGE impact on player immersion, and they're not hard to do.<br />
<br />
If you have no way to record dialogue, you can always look through the vocal sets...it's quite possible to create short conversations with barks that already exist.<br />
<br />
== Overview ==<br />
All the info regarding a conversation is contained within a [[atdm:conversation_info]] entity. Each of these entities can define one or more conversations. There is a custom conversation editor GUI for [[DarkRadiant]] (on the map menu), which is the easiest way to make and edit them; but you can add these entities yourself and set the spawnargs manually if you wish. <br />
<br />
For instructions on how to use the conversation editor, see: [[Cutscenes Part 3: Lighting, Placing the Player, and Conversations]] or [[Conversation Tutorial]].<br />
<br />
Each conversation can have one or more ''Actors''. These are the AI which will participate in the conversation.<br />
<br />
Each conversation consists of a sequence of so-called ''Conversation Commands'', which are specific actions you can use to make the ''actors'' do what you want them to. Examples are "Talk", "Attack", "WalkToEntity", etc. You can add as many conversation commands as you like.<br />
<br />
=== Add a Conversation Info entity ===<br />
Right-click somewhere in the grid view and hit "Create Entity" which will open the dialog for selecting the [[Entity Class|entity classes]]. Go to Conversation and select '''[[atdm:conversation_info]]'''.<br />
<br />
(Note, make sure the entity isn't 'in the void' or you will get a leak in your map. Otherwise, it doesn't matter where the entity is placed.)<br />
<br />
=== Add the conversation spawnargs ===<br />
Once the entity is created you can start defining your conversation. The easiest way is to use the conversation editor. <br />
<br />
Here is an example of a simplistic "conversation" containing exactly one command:<br />
"conv_1_name" "Testconversation 1" // defines the name of the conversation (mandatory)<br />
"conv_1_actor_1" "atdm:ai_builder_guard_1" // first actor<br />
"conv_1_actor_2" "atdm:ai_builder_guard_2" // second actor<br />
<br />
// Here's the first conversation command (defined as ''cmd_1'')<br />
"conv_1_cmd_1_actor" "1" // Actor 1 takes this action<br />
"conv_1_cmd_1_type" "Talk" // the action is "Talk" (uppercase T is required)<br />
"conv_1_cmd_1_arg_1" "tdm_test_conversation_1_1" // play the sound shader: 'tdm_test_conversation_1_1'<br />
<br />
So basically, this conversation has a name ''Testconversation 1'', two actors (builder_guard_1 and 2) and lets the actor 1 play the sound shader ''tdm_test_conversation_1_1''.<br />
<br />
As you can see, the naming convention for the spawnargs is like this:<br />
conv_<number>_<key><br />
<br />
The purpose of ''<number>'' is to distinguish multiple conversations defined on the same conversation info entity. You can use a single entity for all the conversations in your map if you wish, although you'll probably want to keep them separate in order to trigger them at different times (see below). <br />
<br />
The <key> is then defining the properties and commands of this conversation. Each conversation can have multiple commands, that's why these spawnargs are equipped with indices as well ("conv_1_cmd_N_...").<br />
<br />
The above example is defining a command called ''Talk''. There are more ''conversation commands'' available, each having a varying number of arguments. See the section below for details.<br />
<br />
Each conversation ''must'' have a name and at least one actor and one command, otherwise the parser will flag the conversation as invalid and it will therefore be ignored.<br />
<br />
''Note:'' The <number> value is always numeric and starts with 1.<br />
<br />
== Spawnargs ==<br />
=== Conversation ===<br />
These spawnargs can be used to define properties that affect the conversation as a whole.<br />
<br />
The first two MUST be set by the mapper; the rest have defaults and only need to be changed if you want a non-standard result.<br />
<br />
The uppercase N indicates the conversation number (starting from 1).<br />
;'''conv_N_name''' (string)<br />
: defines the name of the conversation. This is a mandatory spawnarg, a conversation without a name will be ignored.<br />
;'''conv_N_actor_Y''' (entity name)<br />
: define the names of the AI participating in this conversation. At least one actor is required, otherwise the conversation is invalid.<br />
<br />
<br />
'''The following are optional:'''<br />
<br />
;'''conv_N_actors_must_be_within_talkdistance''' (1/0) default is 1<br />
: if set to "1", all actors are told to walk towards each other before the conversation actually starts.<br />
;'''conv_N_talk_distance''' (float) default is 60<br />
: defines the maximum distance AI should be away from each other while talking. When the spawnarg '''actors_must_be_within_talkdistance''' is set to 1, this distance tells the AI when to stop when walking towards each other.<br />
;'''conv_N_actors_always_face_each_other_while_talking''' (1/0) default is 1<br />
: if set to "1", all actors are facing each other while talking. The talker turns towards another actor (usually the actor 0 or 1), and all other actors (the listeners) turn to face the talker.<br />
;'''conv_N_max_play_count''' (int) default is -1<br />
: defines the maximum number of times this conversation is allowed to "play". After this number has been exhausted, the conversation won't be started anymore.<br />
;'''conv_N_cmd_Y_...'''<br />
: the conversation commands (see below). One conversation must have at least one and is allowed to have multiple conversation commands.<br />
<br />
=== Conversation Commands ===<br />
These spawnargs are used to tell the actors what to do during the conversation.<br />
<br />
The prefix <tt>conv_N_</tt> refers to the conversation these commands are associated with. The number M refers to the command number (starting at 1).<br />
;'''conv_N_cmd_M_actor''' (integer actor number, starting from 1)<br />
: defines which actor should perform this command. Use the "Actor Number" you assigned earlier. Note that the value of this spawnarg is a number X referring to the <tt>conv_N_actor_X</tt> definition above. You address a conversation's actor by this number, ''not'' by its name. ;'''conv_N_cmd_M_type''' (string == command type name)<br />
: defines the type of command you want to give (this is a mandatory spawnarg, each command must have a type). The most common is probably "Talk". See below for a list of available type names. ''Ex: "conv_1_cmd_1_type" "Talk" '' <br />
<br />
;'''conv_N_cmd_M_wait_until_finished''' (1/0), default is 1 (note: default is 0 in the editor)<br />
: defines whether the conversation should wait for the actor to complete this command before the next command is executed. Setting this to "0" allows to step over to the next command with nearly no time loss. This can be used to issue two or more commands at virtually the same time to an actor, so that the commands "Talk" and "PlayAnimOnce" are executed side-by-side by the same AI, for instance.<br />
Note: I set a single conversation for an AI to walk to an entity. This failed unless this spawnarg was set to 1 so possibly the last command in the list needs it?<br />
;'''conv_N_cmd_M_arg_L'''<br />
:defines the arguments of this conversation command. The actual arguments depend on the command type, each type is requiring a different amount of arguments, and some of them are optional. See below for a description of the command's arguments. The index L starts at the number 1, there is no upper limit imposed by the code.<br />
<br />
== Triggering a Conversation ==<br />
<br />
Now that your conversation is created, you need to trigger it.<br />
<br />
To trigger a conversation you need to create a ''target_tdm_startconversation'' entity. Give it the spawnarg "conversation" with the name of the conversation you want to start (ex "conversation" "Testcoversation 1") then target that entity from any trigger you like such as a trigger_once entity.<br />
<br />
== Conversation Commands ==<br />
The following is a list of available conversation commands:<br />
*'''WaitSeconds'''<br />
: Lets the actor wait the given amount of seconds. Note that the <tt>wait_until_finished</tt> property is not affecting this command (would be pointless).<br />
:*Argument 1: (float) The amount of seconds to wait.<br />
*'''WalkToActor'''<br />
: Lets the actor walk to another actor, which must be participating in this conversation.<br />
:* Argument 1: (integer) The actor number of the AI to walk to.<br />
:* Argument 2: (optional float) The distance at which the actor stops "before" the actor. This value is optional and defaults to 50.<br />
*'''WalkToPosition'''<br />
: Lets the actor walk to the given position.<br />
:* Argument 1: (vector) The world position to walk to (e.g. "-32 4 196").<br />
*'''WalkToEntity'''<br />
: Lets the actor walk to the given entity.<br />
:* Argument 1: (string) The name of the entity to walk to.<br />
:* Argument 2: (optional float) The distance at which the actor stops "before" the entity. This value is optional and defaults to 50.<br />
*'''StopMove'''<br />
: Tells the entity to stop its current movement (no arguments).<br />
*'''Talk'''<br />
: Lets the actor talk a given string.<br />
:* Argument 1: (string) The sound shader to play<br />
:* Argument 2: (optional string) The language string to display as subtitle in the <tt>#str_9NNNN</tt> format. Conversation strings should start in the 9xxxx number range and are defined in the strings/*.lang file. ''Note: this feature is not yet implemented''.<br />
*'''PlayAnimOnce'''<br />
: Lets the actor play an animation once.<br />
:* Argument 1: (string) the name of the animation to play (see the actor's [[modelDef]] file)<br />
:* Argument 2: (optional integer) the number of blendframes to use when switching anims. This is optional and defaults to 4.<br />
*'''PlayAnimCycle'''<br />
: Lets the actor play an animation over and over. Note that the property <tt>wait_until_finished</tt> is not allowed here, as this command never stops, so execution will immediately proceed to the next command.<br />
:* Argument 1: (string) the name of the animation to play (see the actor's [[modelDef]] file)<br />
:* Argument 2: (optional integer) the number of blendframes to use when switching anims. This is optional and defaults to 4.<br />
*'''ActivateTarget'''<br />
:Triggers the given entity.<br />
:* Argument 1: (string) the name of the entity to trigger.<br />
*'''LookAtActor'''<br />
:Lets the actor look at another actor (must be participating in the conversation).<br />
:* Argument 1: (integer) the actor number of the AI to look at.<br />
:* Argument 2: (optional float) the "look duration" in seconds, the head is turning back to its previous position afterwards. This is optional and defaults to 5 seconds.<br />
*'''LookAtPosition'''<br />
:Lets the actor look at the given position.<br />
:* Argument 1: (vector) the world position to look at (e.g. "-32 4 196").<br />
:* Argument 2: (optional float) the "look duration" in seconds, the head is turning back to its previous position afterwards. This is optional and defaults to 5 seconds.<br />
*'''LookAtEntity'''<br />
:Lets the actor look at the given entity.<br />
:* Argument 1: (string) the name of the entity to look at.<br />
:* Argument 2: (optional float) the "look duration" in seconds, the head is turning back to its previous position afterwards. This is optional and defaults to 5 seconds.<br />
*'''TurnToActor'''<br />
: Lets the actor turn towards the given actor, which must participate in this conversation too (the whole body is rotated towards the actor). This command has no duration, so the property <tt>wait_until_finished</tt> is effectless here.<br />
:* Argument 1: (integer) the actor number of the AI to turn towards.<br />
*'''TurnToPosition'''<br />
: Lets the actor turn towards the given position (the whole body is affected). This command has no duration, so the property <tt>wait_until_finished</tt> is effectless here.<br />
:* Argument 1: (vector) the position in world coordinates which the actor should turn towards (e.g. "-32 4 196").<br />
*'''TurnToEntity'''<br />
: Lets the actor turn towards the given entity (whole body is affected). This command has no duration, so the property <tt>wait_until_finished</tt> is effectless here.<br />
:* Argument 1: (string) the entity to turn towards.<br />
*'''AttackActor'''<br />
: Lets the actor attack the other actor (which must be partipicating in this conversation as well). This command has no duration, so the property <tt>wait_until_finished</tt> is effectless here.<br />
:* Argument 1: (integer) the actor number of the AI to attack.<br />
*'''AttackEntity'''<br />
: Lets the actor attack the given entity (which can be any other AI or any other player). This command has no duration, so the property <tt>wait_until_finished</tt> is effectless here.<br />
:* Argument 1: (string) the entity to attack (e.g. "player1").<br />
*'''InteractWithEntity'''<br />
: Lets the actor walk to an entity, play the "use" anim and trigger the entity's frobaction script. Doors will be opened, buttons be pushed, etc.<br />
:* Argument 1: (string) the entity to interact with.<br />
*'''RunScript'''<br />
: Runs a local or global script function. Local script functions (those defined on the actor's scriptobject) must not take any arguments, global scriptfunctions must take an <tt>entity</tt> as argument (the actor will be passed as "owner" to this global function). Note that if <tt>wait_until_finished</tt> is set to "1" the command will not finish until the script is completely done (i.e. non-terminating eachFrame loops within the script function would cause this command to last forever).<br />
:* Argument 1: (string) the name of the local or global script function.<br />
*'''WaitForActor'''<br />
: Lets the actor wait until the other actor (specified in the first argument) has finished executing his current conversation command. If the other actor is already done with his command, WaitForActor does nothing.<br />
:* Argument 1: (integer) the actor number of the AI to wait for.<br />
*'''WaitForAllActors'''<br />
: Lets the conversation wait until all actors are finished executing their commands. Afterwards the conversation is allowed to continue with the next command.<br />
:* no arguments<br />
<br />
== How to get AI to patrol after finishing a conversation ==<br />
<br />
''Sometimes you want AI to stay put until their conversation is triggered, and then start a regular patrol. Here's one way how(courtesy of grayman), see another below in Notes:''<br />
<br />
Guards Bob and Sam will have the conversation. Neither is targetted at any path_corners.<br />
<br />
When the conversation is over, you want Bob to start patrolling, starting with path_corner_1.<br />
<br />
When the conversation is over, you want Sam to start patrolling, starting with path_corner_2.<br />
<br />
A player-activated trigger fires the entity that starts the conversation.<br />
<br />
In the conversation, have these two steps at or near the end:<br />
<br />
Trigger the entity StartBobPatrol<br />
<br />
Trigger the entity StartSamPatrol<br />
<br />
"StartBobPatrol" is an atdm:target_changetarget with these spawnargs:<br />
<br />
"add" "path_corner_1"<br />
"target" "Bob"<br />
<br />
"StartSamPatrol" is an atdm:target_changetarget with these spawnargs:<br />
<br />
"add" "path_corner_2"<br />
"target" "Sam"<br />
<br />
When the conversation ends, both guards will go their separate ways.<br />
<br />
== Notes ==<br />
* It's possible to define conversations with only one actor. This can be used to let AI talk a single sentence or perform some other actions.<br />
* The flags <tt>actors_must_be_within_talkdistance</tt> and <tt>actors_always_face_each_other_while_talking</tt> have no effect when only one actor is present in the conversation. The flags are automatically set to 0 in the code.<br />
* Starting with 1.08, an actor who begins a conversation sitting on a path_waitfortrigger can be moved off that trigger at the end of the conversation by having the last step in the conversation activate a trigger_once whose target is the actor, and which has a 'delay' spawnarg set to at least 1 second. W/o the delay, the actor will ignore the activation and remain where they are.<br />
* Simpler to walk off might be to have the last command in your conversation trigger an atdm:target_changetarget. In that entity, give it these spawnargs: "target" "<name of AI who's leaving>" and "add" "<name of path_corner you want him to walk to>"<br />
<br />
== Volume of Custom Lines ==<br />
The soundshader files for unique lines control how far the sound reaches and volume, it's not set within the editor.<br />
minDistance 1<br />
maxDistance 25<br />
volume 1<br />
Regular AI spoken lines have maxDistance 25, yells 30.<br />
<br />
== Debugging Conversations ==<br />
There are several possibilities to debug conversations, in case something isn't working correctly:<br />
* The CVAR '''tdm_ai_show_conversationstate''' (when set to 1) draws the current conversation command and its execution state on all AI which are currently involved in conversations.<br />
* Another way to check if things go wrong is the console. During map load the number of valid conversations found in the map is verbosed to the console, so be sure to check if this number is right. If this number differs from the number you should have, you probably have your spawnargs wrong. Warnings might also be printed to the console if things go wrong during the execution of conversation commands.<br />
* The log file gives you some insight what is happening in the conversation code during map load and during the actual conversations. Open your <tt>darkmod.ini</tt> file and set <tt>LogClass_CONVERSATION</tt> to 1 to enable conversation logging. Also, be sure to enable the various log types (ERROR, DEBUG, WARNING and INFO) to see all the messages.<br />
<br />
{{editing}}</div>RJFerrethttps://wiki.thedarkmod.com/index.php?title=Conversations&diff=17742Conversations2014-04-27T16:26:44Z<p>RJFerret: +volume</p>
<hr />
<div>Conversations between AI have a HUGE impact on player immersion, and they're not hard to do.<br />
<br />
If you have no way to record dialogue, you can always look through the vocal sets...it's quite possible to create short conversations with barks that already exist.<br />
<br />
== Overview ==<br />
All the info regarding a conversation is contained within a [[atdm:conversation_info]] entity. Each of these entities can define one or more conversations. There is a custom conversation editor GUI for [[DarkRadiant]] (on the map menu), which is the easiest way to make and edit them; but you can add these entities yourself and set the spawnargs manually if you wish. <br />
<br />
For instructions on how to use the conversation editor, see: [[Cutscenes Part 3: Lighting, Placing the Player, and Conversations]] or [[Conversation Tutorial]].<br />
<br />
Each conversation can have one or more ''Actors''. These are the AI which will participate in the conversation.<br />
<br />
Each conversation consists of a sequence of so-called ''Conversation Commands'', which are specific actions you can use to make the ''actors'' do what you want them to. Examples are "Talk", "Attack", "WalkToEntity", etc. You can add as many conversation commands as you like.<br />
<br />
=== Add a Conversation Info entity ===<br />
Right-click somewhere in the grid view and hit "Create Entity" which will open the dialog for selecting the [[Entity Class|entity classes]]. Go to Conversation and select '''[[atdm:conversation_info]]'''.<br />
<br />
(Note, make sure the entity isn't 'in the void' or you will get a leak in your map. Otherwise, it doesn't matter where the entity is placed.)<br />
<br />
=== Add the conversation spawnargs ===<br />
Once the entity is created you can start defining your conversation. The easiest way is to use the conversation editor. <br />
<br />
Here is an example of a simplistic "conversation" containing exactly one command:<br />
"conv_1_name" "Testconversation 1" // defines the name of the conversation (mandatory)<br />
"conv_1_actor_1" "atdm:ai_builder_guard_1" // first actor<br />
"conv_1_actor_2" "atdm:ai_builder_guard_2" // second actor<br />
<br />
// Here's the first conversation command (defined as ''cmd_1'')<br />
"conv_1_cmd_1_actor" "1" // Actor 1 takes this action<br />
"conv_1_cmd_1_type" "Talk" // the action is "Talk" (uppercase T is required)<br />
"conv_1_cmd_1_arg_1" "tdm_test_conversation_1_1" // play the sound shader: 'tdm_test_conversation_1_1'<br />
<br />
So basically, this conversation has a name ''Testconversation 1'', two actors (builder_guard_1 and 2) and lets the actor 1 play the sound shader ''tdm_test_conversation_1_1''.<br />
<br />
As you can see, the naming convention for the spawnargs is like this:<br />
conv_<number>_<key><br />
<br />
The purpose of ''<number>'' is to distinguish multiple conversations defined on the same conversation info entity. You can use a single entity for all the conversations in your map if you wish, although you'll probably want to keep them separate in order to trigger them at different times (see below). <br />
<br />
The <key> is then defining the properties and commands of this conversation. Each conversation can have multiple commands, that's why these spawnargs are equipped with indices as well ("conv_1_cmd_N_...").<br />
<br />
The above example is defining a command called ''Talk''. There are more ''conversation commands'' available, each having a varying number of arguments. See the section below for details.<br />
<br />
Each conversation ''must'' have a name and at least one actor and one command, otherwise the parser will flag the conversation as invalid and it will therefore be ignored.<br />
<br />
''Note:'' The <number> value is always numeric and starts with 1.<br />
<br />
== Spawnargs ==<br />
=== Conversation ===<br />
These spawnargs can be used to define properties that affect the conversation as a whole.<br />
<br />
The first two MUST be set by the mapper; the rest have defaults and only need to be changed if you want a non-standard result.<br />
<br />
The uppercase N indicates the conversation number (starting from 1).<br />
;'''conv_N_name''' (string)<br />
: defines the name of the conversation. This is a mandatory spawnarg, a conversation without a name will be ignored.<br />
;'''conv_N_actor_Y''' (entity name)<br />
: define the names of the AI participating in this conversation. At least one actor is required, otherwise the conversation is invalid.<br />
<br />
<br />
'''The following are optional:'''<br />
<br />
;'''conv_N_actors_must_be_within_talkdistance''' (1/0) default is 1<br />
: if set to "1", all actors are told to walk towards each other before the conversation actually starts.<br />
;'''conv_N_talk_distance''' (float) default is 60<br />
: defines the maximum distance AI should be away from each other while talking. When the spawnarg '''actors_must_be_within_talkdistance''' is set to 1, this distance tells the AI when to stop when walking towards each other.<br />
;'''conv_N_actors_always_face_each_other_while_talking''' (1/0) default is 1<br />
: if set to "1", all actors are facing each other while talking. The talker turns towards another actor (usually the actor 0 or 1), and all other actors (the listeners) turn to face the talker.<br />
;'''conv_N_max_play_count''' (int) default is -1<br />
: defines the maximum number of times this conversation is allowed to "play". After this number has been exhausted, the conversation won't be started anymore.<br />
;'''conv_N_cmd_Y_...'''<br />
: the conversation commands (see below). One conversation must have at least one and is allowed to have multiple conversation commands.<br />
<br />
=== Conversation Commands ===<br />
These spawnargs are used to tell the actors what to do during the conversation.<br />
<br />
The prefix <tt>conv_N_</tt> refers to the conversation these commands are associated with. The number M refers to the command number (starting at 1).<br />
;'''conv_N_cmd_M_actor''' (integer actor number, starting from 1)<br />
: defines which actor should perform this command. Use the "Actor Number" you assigned earlier. Note that the value of this spawnarg is a number X referring to the <tt>conv_N_actor_X</tt> definition above. You address a conversation's actor by this number, ''not'' by its name. ;'''conv_N_cmd_M_type''' (string == command type name)<br />
: defines the type of command you want to give (this is a mandatory spawnarg, each command must have a type). The most common is probably "Talk". See below for a list of available type names. ''Ex: "conv_1_cmd_1_type" "Talk" '' <br />
<br />
;'''conv_N_cmd_M_wait_until_finished''' (1/0), default is 1 (note: default is 0 in the editor)<br />
: defines whether the conversation should wait for the actor to complete this command before the next command is executed. Setting this to "0" allows to step over to the next command with nearly no time loss. This can be used to issue two or more commands at virtually the same time to an actor, so that the commands "Talk" and "PlayAnimOnce" are executed side-by-side by the same AI, for instance.<br />
Note: I set a single conversation for an AI to walk to an entity. This failed unless this spawnarg was set to 1 so possibly the last command in the list needs it?<br />
;'''conv_N_cmd_M_arg_L'''<br />
:defines the arguments of this conversation command. The actual arguments depend on the command type, each type is requiring a different amount of arguments, and some of them are optional. See below for a description of the command's arguments. The index L starts at the number 1, there is no upper limit imposed by the code.<br />
<br />
== Triggering a Conversation ==<br />
<br />
Now that your conversation is created, you need to trigger it.<br />
<br />
To trigger a conversation you need to create a ''target_tdm_startconversation'' entity. Give it the spawnarg "conversation" with the name of the conversation you want to start (ex "conversation" "Testcoversation 1") then target that entity from any trigger you like such as a trigger_once entity.<br />
<br />
== Conversation Commands ==<br />
The following is a list of available conversation commands:<br />
*'''WaitSeconds'''<br />
: Lets the actor wait the given amount of seconds. Note that the <tt>wait_until_finished</tt> property is not affecting this command (would be pointless).<br />
:*Argument 1: (float) The amount of seconds to wait.<br />
*'''WalkToActor'''<br />
: Lets the actor walk to another actor, which must be participating in this conversation.<br />
:* Argument 1: (integer) The actor number of the AI to walk to.<br />
:* Argument 2: (optional float) The distance at which the actor stops "before" the actor. This value is optional and defaults to 50.<br />
*'''WalkToPosition'''<br />
: Lets the actor walk to the given position.<br />
:* Argument 1: (vector) The world position to walk to (e.g. "-32 4 196").<br />
*'''WalkToEntity'''<br />
: Lets the actor walk to the given entity.<br />
:* Argument 1: (string) The name of the entity to walk to.<br />
:* Argument 2: (optional float) The distance at which the actor stops "before" the entity. This value is optional and defaults to 50.<br />
*'''StopMove'''<br />
: Tells the entity to stop its current movement (no arguments).<br />
*'''Talk'''<br />
: Lets the actor talk a given string.<br />
:* Argument 1: (string) The sound shader to play<br />
:* Argument 2: (optional string) The language string to display as subtitle in the <tt>#str_9NNNN</tt> format. Conversation strings should start in the 9xxxx number range and are defined in the strings/*.lang file. ''Note: this feature is not yet implemented''.<br />
*'''PlayAnimOnce'''<br />
: Lets the actor play an animation once.<br />
:* Argument 1: (string) the name of the animation to play (see the actor's [[modelDef]] file)<br />
:* Argument 2: (optional integer) the number of blendframes to use when switching anims. This is optional and defaults to 4.<br />
*'''PlayAnimCycle'''<br />
: Lets the actor play an animation over and over. Note that the property <tt>wait_until_finished</tt> is not allowed here, as this command never stops, so execution will immediately proceed to the next command.<br />
:* Argument 1: (string) the name of the animation to play (see the actor's [[modelDef]] file)<br />
:* Argument 2: (optional integer) the number of blendframes to use when switching anims. This is optional and defaults to 4.<br />
*'''ActivateTarget'''<br />
:Triggers the given entity.<br />
:* Argument 1: (string) the name of the entity to trigger.<br />
*'''LookAtActor'''<br />
:Lets the actor look at another actor (must be participating in the conversation).<br />
:* Argument 1: (integer) the actor number of the AI to look at.<br />
:* Argument 2: (optional float) the "look duration" in seconds, the head is turning back to its previous position afterwards. This is optional and defaults to 5 seconds.<br />
*'''LookAtPosition'''<br />
:Lets the actor look at the given position.<br />
:* Argument 1: (vector) the world position to look at (e.g. "-32 4 196").<br />
:* Argument 2: (optional float) the "look duration" in seconds, the head is turning back to its previous position afterwards. This is optional and defaults to 5 seconds.<br />
*'''LookAtEntity'''<br />
:Lets the actor look at the given entity.<br />
:* Argument 1: (string) the name of the entity to look at.<br />
:* Argument 2: (optional float) the "look duration" in seconds, the head is turning back to its previous position afterwards. This is optional and defaults to 5 seconds.<br />
*'''TurnToActor'''<br />
: Lets the actor turn towards the given actor, which must participate in this conversation too (the whole body is rotated towards the actor). This command has no duration, so the property <tt>wait_until_finished</tt> is effectless here.<br />
:* Argument 1: (integer) the actor number of the AI to turn towards.<br />
*'''TurnToPosition'''<br />
: Lets the actor turn towards the given position (the whole body is affected). This command has no duration, so the property <tt>wait_until_finished</tt> is effectless here.<br />
:* Argument 1: (vector) the position in world coordinates which the actor should turn towards (e.g. "-32 4 196").<br />
*'''TurnToEntity'''<br />
: Lets the actor turn towards the given entity (whole body is affected). This command has no duration, so the property <tt>wait_until_finished</tt> is effectless here.<br />
:* Argument 1: (string) the entity to turn towards.<br />
*'''AttackActor'''<br />
: Lets the actor attack the other actor (which must be partipicating in this conversation as well). This command has no duration, so the property <tt>wait_until_finished</tt> is effectless here.<br />
:* Argument 1: (integer) the actor number of the AI to attack.<br />
*'''AttackEntity'''<br />
: Lets the actor attack the given entity (which can be any other AI or any other player). This command has no duration, so the property <tt>wait_until_finished</tt> is effectless here.<br />
:* Argument 1: (string) the entity to attack (e.g. "player1").<br />
*'''InteractWithEntity'''<br />
: Lets the actor walk to an entity, play the "use" anim and trigger the entity's frobaction script. Doors will be opened, buttons be pushed, etc.<br />
:* Argument 1: (string) the entity to interact with.<br />
*'''RunScript'''<br />
: Runs a local or global script function. Local script functions (those defined on the actor's scriptobject) must not take any arguments, global scriptfunctions must take an <tt>entity</tt> as argument (the actor will be passed as "owner" to this global function). Note that if <tt>wait_until_finished</tt> is set to "1" the command will not finish until the script is completely done (i.e. non-terminating eachFrame loops within the script function would cause this command to last forever).<br />
:* Argument 1: (string) the name of the local or global script function.<br />
*'''WaitForActor'''<br />
: Lets the actor wait until the other actor (specified in the first argument) has finished executing his current conversation command. If the other actor is already done with his command, WaitForActor does nothing.<br />
:* Argument 1: (integer) the actor number of the AI to wait for.<br />
*'''WaitForAllActors'''<br />
: Lets the conversation wait until all actors are finished executing their commands. Afterwards the conversation is allowed to continue with the next command.<br />
:* no arguments<br />
<br />
== How to get AI to patrol after finishing a conversation ==<br />
<br />
''Sometimes you want AI to stay put until their conversation is triggered, and then start a regular patrol. Here's one way how(courtesy of grayman), see another below in Notes:''<br />
<br />
Guards Bob and Sam will have the conversation. Neither is targetted at any path_corners.<br />
<br />
When the conversation is over, you want Bob to start patrolling, starting with path_corner_1.<br />
<br />
When the conversation is over, you want Sam to start patrolling, starting with path_corner_2.<br />
<br />
A player-activated trigger fires the entity that starts the conversation.<br />
<br />
In the conversation, have these two steps at or near the end:<br />
<br />
Trigger the entity StartBobPatrol<br />
<br />
Trigger the entity StartSamPatrol<br />
<br />
"StartBobPatrol" is an atdm:target_changetarget with these spawnargs:<br />
<br />
"add" "path_corner_1"<br />
"target" "Bob"<br />
<br />
"StartSamPatrol" is an atdm:target_changetarget with these spawnargs:<br />
<br />
"add" "path_corner_2"<br />
"target" "Sam"<br />
<br />
When the conversation ends, both guards will go their separate ways.<br />
<br />
== Notes ==<br />
* It's possible to define conversations with only one actor. This can be used to let AI talk a single sentence or perform some other actions.<br />
* The flags <tt>actors_must_be_within_talkdistance</tt> and <tt>actors_always_face_each_other_while_talking</tt> have no effect when only one actor is present in the conversation. The flags are automatically set to 0 in the code.<br />
* Starting with 1.08, an actor who begins a conversation sitting on a path_waitfortrigger can be moved off that trigger at the end of the conversation by having the last step in the conversation activate a trigger_once whose target is the actor, and which has a 'delay' spawnarg set to at least 1 second. W/o the delay, the actor will ignore the activation and remain where they are.<br />
* Simpler to walk off might be to have the last command in your conversation trigger an atdm:target_changetarget. In that entity, give it these spawnargs: "target" "<name of AI who's leaving>" and "add" "<name of path_corner you want him to walk to>"<br />
<br />
== Volume of Custom Lines ==<br />
The soundshader files for unique lines control how far the sound reaches and volume, it's not set within the editor.<br />
* minDistance<br />
* maxDistance<br />
* volume<br />
Regular AI spoken lines are 25 dB, yells 30.<br />
<br />
== Debugging Conversations ==<br />
There are several possibilities to debug conversations, in case something isn't working correctly:<br />
* The CVAR '''tdm_ai_show_conversationstate''' (when set to 1) draws the current conversation command and its execution state on all AI which are currently involved in conversations.<br />
* Another way to check if things go wrong is the console. During map load the number of valid conversations found in the map is verbosed to the console, so be sure to check if this number is right. If this number differs from the number you should have, you probably have your spawnargs wrong. Warnings might also be printed to the console if things go wrong during the execution of conversation commands.<br />
* The log file gives you some insight what is happening in the conversation code during map load and during the actual conversations. Open your <tt>darkmod.ini</tt> file and set <tt>LogClass_CONVERSATION</tt> to 1 to enable conversation logging. Also, be sure to enable the various log types (ERROR, DEBUG, WARNING and INFO) to see all the messages.<br />
<br />
{{editing}}</div>RJFerrethttps://wiki.thedarkmod.com/index.php?title=Triggers&diff=17722Triggers2014-03-29T17:14:58Z<p>RJFerret: /* trigger_presize */ +descript per forum thread</p>
<hr />
<div>There are many different ways of triggering [[Entity|entities]], the Trigger entities themselves, as well as through [[Stim/Response]], [[Conversations]], Movers, [[Objectives]], and more. How the trigger occurs will typically dictate which manner you choose for your map. <br />
<br />
=Triggers=<br />
To create triggers that rely on boundaries (once, multiple and their derivations), you need to drag out a worldspawn brush, right-click, select "Create Entity". They need to be connected to their subjects, either via "Connect Selected Entities" menu option/shortcut key, or adding "Target", "Target0", "Target1" or subsequent "Target"# spawnargs. The triggers below are listed roughly by frequency of usage, with related triggers beneath.<br />
<br />
==trigger_once==<br />
When the origin of an entity is within the bounds of this entity, the target(s) will be triggered, then the trigger_once is removed. (Note, to resize the brush after creating the entity, select it then press Tab once.)<br />
<br />
==trigger_once_entityname==<br />
Similar to [[Triggers#trigger_once|trigger_once]], but may be set to only respond to the entity specified by the spawnarg, "entityname". Note the entity must move into the boundaries itself, not be moved by the player (AI walking themselves for example). (If you want something to happen based on the player dropping or placing an item somewhere, use the [[Objectives]] system instead.)<br />
<br />
==trigger_multiple==<br />
Similar to [[Triggers#trigger_once|trigger_once]] but will activate again and again, use "Wait" spawnarg to control how many seconds between triggerings. <br />
<br />
==trigger_entityname ==<br />
Similar to [[Triggers#trigger_multiple|trigger_multiple]] but only reacts to the entity defined by the "entityname" spawnarg.<br />
<br />
== trigger_facing ==<br />
Also similar to [[Triggers#trigger_multiple|trigger_multiple]], but requires the triggering entity to be within 30° of the specified "angle" spawnarg. For details see [[Trigger Facing]].<br />
<br />
==trigger_relay ==<br />
Most commonly used to trigger many targets, or do so after a delay (per the "delay" spawnarg). May be set to only work once (spawnarg "wait" "-1") or limit firing based upon how many seconds have passed. The "random" spawnarg may be used with "wait" to vary the firings. Very useful as the target of worldspawn, to trigger things at map start (since worldspawn currently only activate one "Target"), or as the target of Objectives.<br />
<br />
==trigger_count ==<br />
This will fire at it's targets upon a specific number of times being triggered itself, based upon the "count" spawnarg. If "count" "3" is set, it will do nothing until the third triggering. <br />
<br />
== trigger_timer ==<br />
This trigger will fire repeatedly every "wait" # seconds. The spawnarg "start_on" defines if it should do so at the start of the map, or wait to be triggered (defaults to 0, off at map start). Spawnarg "random" adds variability to the triggerings.<br />
<br />
== trigger_fade ==<br />
Will cause the display to fade or dissolve to a specified color. The spawnarg "fadeColor" specifies which color, and how transparent in RGBA (red, green, blue, and alpha, ranging from 0-1). Default is fade to black: "fadeColor" "0 0 0 1". To fade up from whatever, use alpha of 0, IE to fade up from black, "0 0 0 0". "fadeTime" controls how quickly the fade transpires.<br />
<br />
== trigger_hurt ==<br />
Applied to a worldspawn brush to define boundaries à la a [[Triggers#trigger_multiple|trigger_multiple]], by default it causes 10 points of damage/second to the activator (player or AI). It may be triggered on/off. The spawnarg, "delay" may be set to vary frequency of damage application. One of various "def_damage" may be specified, generally found in the root directory of the entities, or to see specific details, in the defs file, "damage.def". Note those referencing "triggerhurt" simply cause damage, while others feature additional effects such as push and knockbacks (launching the player away).<br />
<br />
If you need varying amount of damage based on proximity, the [[Stim/Response_Key/Values#Damage_Stim|Stim/Response]] system offers control of various types of falloff.<br />
<br />
== trigger_presize ==<br />
Akin to [[Triggers#trigger_multiple|trigger_multiple]] without the need of creating a brush first, and defaults to not being touched by players/AIs, but triggered by other entities/script.<br />
<br />
== trigger_touch ==<br />
Continuously checks if entities are touching, costly performance wise, probably done via [[Objectives]] more efficiently.<br />
<br />
=Triggering Stim/Response=<br />
'''To Trigger Something Else:'''<br />
<br />
Any Response type may have an effect of "Trigger", in which another entity selected is triggered. Note the "Trigger" effect is all the way at the bottom of the drop down, which might not be displayed on screen (Toggle Effect is the last displayed on mine), you may cursor down or use the End key to get to Trigger.<br />
<br />
'''Be Triggered:'''<br />
<br />
Within the [[Stim/Response]] editor, add a response stim set to "Trigger", now when this entity is targeted, whatever specified effect will occur.<br />
<br />
An example would be to not have something able to be frobbed until something obscuring it is removed or opened. Make the response effect "Set Frobable" for the entity in question, and check "frobability" on. Now when the item is triggered, by a door, or frob response on something in front moved/picked up, it will become frobable.<br />
<br />
=Triggering via Conversation=<br />
The command, [[Conversations#Conversation Commands 2|ActivateTarget]] will trigger the specified entity at that time in the Conversation script.<br />
<br />
=Triggering via Doors, Buttons, Levers, Movers=<br />
[[Doors]] trigger their targets by default upon opening (spawnarg "trigger_on_open" "1"). They may also trigger when completely open by changing "trigger_when_opened" to 1 instead of the default 0, or when fully closed via "trigger_on_close". Note, those conditions on Buttons came from doors, so are counter-intuitive.<br />
<br />
=Triggering via Objectives=<br />
In the [[Objectives Editor]] you may select an entity to be triggered upon an objective succeeding or failing. Therefore all the possible objective conditions may become trigger events (knock out an AI, move an object away from another or to a spot, cause another objective to become visible, disappear or complete, etc.)<br />
<br />
=Triggering via Worldspawn=<br />
You may set "Target" on Worldspawn (usually at a trigger_relay since it only may target one entity currently) to cause things to be triggered at map start. If you use this to kill an AI or other affect with audio, note if in range of the player's start, it will be heard during the fade up from black.<br />
<br />
=Triggering via Lights=<br />
Lights trigger their target(s) both upon being extinguished and lit. This is useful to match window glow to actual light condition. Depending on the light, it may be tricky to set the targets however. A basic light entity can simply have target(s) spawnargs, but a candle, lamp or torch with attached flame entity, you need to use the "set" spawnarg. For example, "set target0 on flame" "EntityToBeTriggered".<br />
<br />
[[Category:Editing]]</div>RJFerrethttps://wiki.thedarkmod.com/index.php?title=Atdm:target_callobjectfunction&diff=17712Atdm:target callobjectfunction2014-03-21T01:31:31Z<p>RJFerret: /* Door locks */ removed as didn't work</p>
<hr />
<div>== Introduction ==<br />
<br />
The entity '''atdm::target_callobjectfunction''' is a useful entity to call one script object function on multiple entities.<br />
<br />
The main difference between this entity and [[atdm:target_postscriptevent]] is as follows:<br />
<br />
* atdm:target_callobjectfunction only works on entities that have a script object associated with them<br />
* atdm:target_callobjectfunction can only call functions defined in that script object (general script events like "Off" are not supported? check this)<br />
* atdm:target_postscriptevent cannot (yet) call object functions as a fallback<br />
<br />
Currently it is a bit difficult to know when to use which of these two entities. They will hopefully be merged into one target entity soon.<br />
<br />
== Usage ==<br />
<br />
This entity is very useful to manipulte [[combined light entities]].<br />
<br />
== Spawnargs ==<br />
<br />
The following spawnargs can be used on this entity:<br />
<br />
=== call ===<br />
<br />
The '''call''' spawnarg gives the name of the script object function to call. Examples are:<br />
<br />
* "LightsOff", "LightsOn", "LightsToggle" (for lights)<br />
<br />
and so on. A full list of available events can be found in the files <code>script/doom_events.script</code> and <code>script/tdm_events.script</code>.<br />
<br />
=== delay (float, default: 0) ===<br />
<br />
The '''delay''' spawnarg specifies an initial delay in seconds, before the first call will be done.<br />
<br />
=== wait (float, default: 0) ===<br />
<br />
The '''wait''' spawnarg specifies the delay in seconds between each subsequent call (e.g. between one and the next target).<br />
<br />
== Examples ==<br />
=== Lights ===<br />
See the map test/trigger_teleport.map for an example on how to turn lights on/off.<br />
== See also ==<br />
*[[Script Events User-Friendly List]]<br />
<br />
{{editing}}</div>RJFerrethttps://wiki.thedarkmod.com/index.php?title=Atdm:target_callobjectfunction&diff=17709Atdm:target callobjectfunction2014-03-20T17:50:51Z<p>RJFerret: +example doorlocks, see also</p>
<hr />
<div>== Introduction ==<br />
<br />
The entity '''atdm::target_callobjectpfunction''' is a useful entity to call one script object function on multiple entities.<br />
<br />
The main difference between this entity and [[atdm:target_postscriptevent]] is as follows:<br />
<br />
* atdm:target_callobjectfunction only works on entity that have a script object associated with them<br />
* atdm:target_callobjectfunction can only call functions defined in that script object (general script events like "Off" are not supported? check this)<br />
* atdm:target_postscriptevent cannot (yet) call object functions as a fallback<br />
<br />
Currently it is a bit difficult to know when to use which of these two entities, they will hopefully be merged into one target entity soon.<br />
<br />
== Usage ==<br />
<br />
This entity is very useful to manipulte [[combined light entities]].<br />
<br />
== Spawnargs ==<br />
<br />
The following spawnargs can be used on this entity:<br />
<br />
=== call ===<br />
<br />
The '''call''' spawnarg gives the name of the script object function to call. Examples are:<br />
<br />
* "LightsOff", "LightsOn", "LightsToggle" (for lights)<br />
<br />
and so on. A full list of available events can be found in the files <code>script/doom_events.script</code> and <code>script/tdm_events.script</code>.<br />
<br />
=== delay (float, default: 0) ===<br />
<br />
The '''delay''' spawnarg specifies an initial delay in seconds, before the first call will be done.<br />
<br />
=== wait (float, default: 0) ===<br />
<br />
The '''wait''' spawnarg specifies the delay in seconds between each subsequent call (e.g. between one and the next target).<br />
<br />
== Examples ==<br />
=== Lights ===<br />
See the map test/trigger_teleport.map for an example on how to turn lights on/off.<br />
=== Door locks ===<br />
To lock a door, trigger the target_callobjectfunction with these two spawnargs:<br />
*"target" "name_of_door"<br />
*"call" "Lock"<br />
<br />
== See also ==<br />
*[[Script Events User-Friendly List]]<br />
<br />
{{editing}}</div>RJFerrethttps://wiki.thedarkmod.com/index.php?title=Stim/Response_Key/Values&diff=17708Stim/Response Key/Values2014-03-19T03:47:45Z<p>RJFerret: +see also</p>
<hr />
<div>'''Note:''' ''There is now a stim/response editor accessed via the Dark Radiant entity menu which makes it easier to set these key/values. The editor settings will be shown below next to their equivalent key/values (work in progress.)''<br />
<br />
<br />
I added two new key/vals to stim response, and figured I would document them all here including the new ones.<br />
<br />
In all of these, N is the number of the stim on the entity. It starts at 1 and goes up. Be aware of any stims that are defined on the entity in other places, like in the def file or in something inherited by it. Stims on the entity itself must start counting from the last one of these, so if the def file has 1 stim, the entitydef in the map would start at number 2.<br />
<br />
== Keys that can be used to set up both stims and responses ==<br />
Key: '''sr_class_N'''<br />
Set to "S" for stim, "R" for response.<br />
<br />
Key: '''sr_type_N'''<br />
Type of stim (e.g. STIM_WATER). See /script/darkmod_stim_response.script for a complete list of stim types.<br />
<br />
Key: '''sr_state_N'''<br />
Set to "1" for enabled, "0" for disabled. This may be altered later with scripting.<br />
<br />
Key: '''sr_chance_N'''<br />
Probability for this stim/response to fire/react. Set this to 0.3 if you want to have a 30% chance.<br />
<br />
== Stim only ==<br />
Key: '''sr_use_bounds_N'''<br />
Set to "1" if you want to use the bounds of the entity as the basis for the intersection test. "0" (the default) uses a sphere centered on the entity origin.<br />
<br />
Key: '''sr_radius_N'''<br />
Radius of the stim in doomunits. NOTE: If you set sr_use_bounds to "1", the radius is applied as an expansion of the entity bounding box in all directions. So if you select use bounds and set the radius to "0", this makes the stimmed region exactly equal to the stim bounds.<br />
<br />
Key: '''sr_radius_final_N'''<br />
Final radius of the stim (i.e. the radius at the end of its lifetime). While the stim is active, the radius will linearly change within the [sr_radius..sr_radius_final] interval. The start value is defined by sr_radius, the end value by this spawnarg. Note that sr_radius_final is not necessarily larger than the sr_radius value, it's also possible to let a stim shrink. For this spawnarg to work, the '''sr_duration''' value must be greater than zero.<br />
<br />
Key: '''sr_magnitude_N''' (float)<br />
The maximum magnitude of the stim at zero distance. If the responding entity's origin is exactly at the origin of the stimming entity (which is not always possible due to the collision boxes), this magnitude value is passed to the response effect scripts.<br />
<br />
Key: '''sr_falloffexponent_N''' (float)<br />
The falloff exponent determining the magnitude in dependency of the distance. There is no limitation to this value, although only a few make sense.<br />
<br />
0 = no falloff (magnitude is constantly at maximum value over the whole radius)<br />
<br />
1 = linear falloff<br />
<br />
2 = quadratic falloff<br />
<br />
3 = etc.<br />
<br />
The higher the number, the faster the magnitude is decreasing with the distance. The magnitude is reaching zero as soon as the distance of the responding object is greater than or equal to the stim radius, except for falloffexponent = 0 (no falloff). Negative values are allowed as well, this way it should be possible to actually increase the magnitude of a stim with larger distance. Don't know if that makes sense, though and I haven't tested it either.<br />
<br />
For documentation purposes, this function is used to determine the actual magnitude: '''m(dist) = m0*[ 1 - dist/radius]^falloffExponent''' (math functions seem to be disabled for this wiki)<br />
<br />
Key: '''sr_duration_N'''<br />
This specifies how long the stim is active before it gets disabled. If this is key is empty, the stim has infinite lifetime (apart from being disabled by scripts and such).<br />
<br />
Key: '''sr_time_interval_N'''<br />
When this stim is active, the firings will be spread out by this many milliseconds. So a stim with sr_time_interval = 500 will fire every half second when active. Used for optimization for stims that don't have to be checked that often.<br />
<br />
Key: '''sr_max_fire_count_N''' (default: -1)<br />
This specifies the maximum number of stim firings that are possible for this stim. The default is -1 which means that it can be fired infinitely often. With each firing, the counter is decreased. When it reaches zero, the stim is entirely ignored from then on. Currently there is no way to reactivate a stim whose max_fire_count has been depleted. Stims that fail because of their '''sr_chance_N''' spawnarg decrease the counter as well.<br />
<br />
Key: '''sr_timer_time_N''' (Format: hhhh:mm:ss:ms, for example: 0:3:20:0 which means 3 minutes and 20 secs) ''(s & r editor = Activation Timer.)''<br />
This can be used to enable the stim after a certain amount of time. Depending on the '''sr_timer_waitforstart''' key the timer is started on spawn or on a "StartTimer" event. Use this to setup a stim that has its '''sr_state_N''' set to 0 at start and gets enabled after a certain amount of time. This is only effective if the sr_state is 0 (disabled) by the time this timer is elapsing ''(s & r editor = Active checkbox.)''<br />
<br />
Key: '''sr_timer_waitforstart_N''' (0 or 1, default is 0)<br />
If this key is TRUE = "1", the timer has to be started by a StartTimer script event or the according response effect. If this is set to 0, the timer starts on spawning this entity (beware: the entities might be spawned quite some time before the map is actually started, on my testmap it sometimes took up to 20 seconds before the player is spawned, so this is not a very reliable measure).<br />
<br />
Key: '''sr_timer_type_N''' | possible values: "RELOAD" or "SINGLESHOT" (default)<br />
When this is set to RELOAD, the timer is reactivated after the stim has been fired. This can be used to setup sophisticated time intervals. I intend to draw a graph explaining this, so if this is not yet in the wiki, you can bug greebo to do this. :)<br />
<br />
Key: '''sr_bounds_mins_N''' and '''sr_bounds_maxs_N''' (Type: Vector, default is "0 0 0")<br />
These two vectors define the bounding box of the stim. This is measured relatively to the stim origin (which might be moving), not the entity origin. A vector pair of '''-10 -10 -50''' and '''10 10 150''' defines a primarily vertical stim area.<br />
<br />
Key: '''sr_velocity_N''' (type: Vector, default: "0 0 ")<br />
This defines the velocity of the stim in units per second. A vector of '''0 0 -10''' let's the stim move downward for 10 units per second for the stim duration time.<br />
<br />
== Response only ==<br />
Key: '''sr_chance_timeout_N'''<br />
Many stims like the water arrow stim are firing rapidly multiple times a second, distorting the "effective" probability of a response going off. Use this to give the response a timeout before it can be evaluated again after a failed probability check.<br />
<br />
Key: '''sr_random_effects_N'''<br />
If this spawnarg contains non-zero values, exactly this number of random response effects is chosen from the available ones. So, if you set sr_random_effects to 2 and there are 5 effects available, two are randomly chosen (may also be one of them twice). If only one effect is available, just this one is fired twice.<br />
<br />
Key: '''sr_script_<STIM TYPE>'''<br />
First off, the name of this key: <STIM TYPE> should be replaced with the string name of one of the stim types. For example, sr_script_STIM_WATER defines the script to call in respone to a water stim. Apparently there can only be one of these per stim type. <STIM TYPE> can either be the name as a string (in case of default stims) or the number:<br />
sr_script_STIM_WATER<br />
sr_script_2<br />
Both of which will have the same meaning, assuming that the water stim has the number two.<br />
<br />
The value this key contains the name of the script function to call. If it's a local script, you must put it in the form of "<script object name>::<local function>" otherwise "<global function name>" works as well.<br />
<br />
== Important note about writing response scripts ==<br />
There's some subtlety about writing these response scriptfunctions. Global scriptfunctions must take two arguments: an entity argument and int threadnum argument. The first argument is the entity that was stimmed. Local response functions (those on the entity being stimmed) should not have the entity argument, only taking one argument, the threadnum. This is because the entity being stimmed is the same as the entity running the script, so the argument is passed implicitly as the "self" entity, just like the "this" pointer is passed implicitly in C++.<br />
<br />
<br />
== Examples ==<br />
=== Damage Stim ===<br />
<br />
An entity has a STIM_DAMAGE with a magnitude of 100 and a linear falloff (1). The further you're away from the stim origin, the smaller the magnitude gets.<br />
<br />
Once an entity with a response to STIM_DAMAGE comes into range and the stim fires, the magnitude is passed on to the response entity. The response entity needs to have a response effect defined for the DAMAGE stim, which tells the code which damage entityDef (e.g. ''atdm:damage_simple'') it should use and which entity should be damaged (this should be ''_SELF'' by default).<br />
<br />
So, an example response setup can be found on the player:<br />
<br />
<br />
// The damage response<br />
"sr_class_3" "R"<br />
"sr_type_3" "STIM_DAMAGE"<br />
"sr_state_3" "1"<br />
"sr_effect_3_1" "effect_damage"<br />
"sr_effect_3_1_arg1" "_SELF"<br />
"sr_effect_3_1_arg2" "atdm:damage_simple"<br />
<br />
<br />
As soon as the player comes into the range of a damage stim, the distance-based magnitude is passed over and the code multiplies this magnitude with the "damage" value defined in atdm:damage_simple. E.g. if a magnitude of 30 is passed, the atdm:damage_simple's value of 10 ends up at 300 => insta-death.<br />
<br />
If you want to have a constant magnitude which is not depending on the distance, you need to define a 0 falloff on the stim.<br />
<br />
=== Remove torch damage if extinguished with water ===<br />
If you have hot torches/ovens that damage the player if too close, but shouldn't if extinguished, first copy the name of the entity that has the damage stim. Then use the Stim/Response editor to add a Water Response, effect "Deactivate Stim", pasting/selecting the entity with the damage stim, and "Damage". (One would want a Fire Response, "Activate Stim" if they wished damage to return if reignited.)<br />
<br />
==See Also==<br />
*[[Stim/Response]] overview<br />
*[[Triggers]]<br />
<br />
[[Category:Editing]]</div>RJFerrethttps://wiki.thedarkmod.com/index.php?title=Triggers&diff=17707Triggers2014-03-19T03:31:10Z<p>RJFerret: /* trigger_hurt */ +info per request for info in forums</p>
<hr />
<div>There are many different ways of triggering [[Entity|entities]], the Trigger entities themselves, as well as through [[Stim/Response]], [[Conversations]], Movers, [[Objectives]], and more. How the trigger occurs will typically dictate which manner you choose for your map. <br />
<br />
=Triggers=<br />
To create triggers that rely on boundaries (once, multiple and their derivations), you need to drag out a worldspawn brush, right-click, select "Create Entity". They need to be connected to their subjects, either via "Connect Selected Entities" menu option/shortcut key, or adding "Target", "Target0", "Target1" or subsequent "Target"# spawnargs. The triggers below are listed roughly by frequency of usage, with related triggers beneath.<br />
<br />
==trigger_once==<br />
When the origin of an entity is within the bounds of this entity, the target(s) will be triggered, then the trigger_once is removed. (Note, to resize the brush after creating the entity, select it then press Tab once.)<br />
<br />
==trigger_once_entityname==<br />
Similar to [[Triggers#trigger_once|trigger_once]], but may be set to only respond to the entity specified by the spawnarg, "entityname". Note the entity must move into the boundaries itself, not be moved by the player (AI walking themselves for example). (If you want something to happen based on the player dropping or placing an item somewhere, use the [[Objectives]] system instead.)<br />
<br />
==trigger_multiple==<br />
Similar to [[Triggers#trigger_once|trigger_once]] but will activate again and again, use "Wait" spawnarg to control how many seconds between triggerings. <br />
<br />
==trigger_entityname ==<br />
Similar to [[Triggers#trigger_multiple|trigger_multiple]] but only reacts to the entity defined by the "entityname" spawnarg.<br />
<br />
== trigger_facing ==<br />
Also similar to [[Triggers#trigger_multiple|trigger_multiple]], but requires the triggering entity to be within 30° of the specified "angle" spawnarg. For details see [[Trigger Facing]].<br />
<br />
==trigger_relay ==<br />
Most commonly used to trigger many targets, or do so after a delay (per the "delay" spawnarg). May be set to only work once (spawnarg "wait" "-1") or limit firing based upon how many seconds have passed. The "random" spawnarg may be used with "wait" to vary the firings. Very useful as the target of worldspawn, to trigger things at map start (since worldspawn currently only activate one "Target"), or as the target of Objectives.<br />
<br />
==trigger_count ==<br />
This will fire at it's targets upon a specific number of times being triggered itself, based upon the "count" spawnarg. If "count" "3" is set, it will do nothing until the third triggering. <br />
<br />
== trigger_timer ==<br />
This trigger will fire repeatedly every "wait" # seconds. The spawnarg "start_on" defines if it should do so at the start of the map, or wait to be triggered (defaults to 0, off at map start). Spawnarg "random" adds variability to the triggerings.<br />
<br />
== trigger_fade ==<br />
Will cause the display to fade or dissolve to a specified color. The spawnarg "fadeColor" specifies which color, and how transparent in RGBA (red, green, blue, and alpha, ranging from 0-1). Default is fade to black: "fadeColor" "0 0 0 1". To fade up from whatever, use alpha of 0, IE to fade up from black, "0 0 0 0". "fadeTime" controls how quickly the fade transpires.<br />
<br />
== trigger_hurt ==<br />
Applied to a worldspawn brush to define boundaries à la a [[Triggers#trigger_multiple|trigger_multiple]], by default it causes 10 points of damage/second to the activator (player or AI). It may be triggered on/off. The spawnarg, "delay" may be set to vary frequency of damage application. One of various "def_damage" may be specified, generally found in the root directory of the entities, or to see specific details, in the defs file, "damage.def". Note those referencing "triggerhurt" simply cause damage, while others feature additional effects such as push and knockbacks (launching the player away).<br />
<br />
If you need varying amount of damage based on proximity, the [[Stim/Response_Key/Values#Damage_Stim|Stim/Response]] system offers control of various types of falloff.<br />
<br />
== trigger_presize ==<br />
(needs experienced write-up)<br />
<br />
== trigger_touch ==<br />
Continuously checks if entities are touching, costly performance wise, probably done via [[Objectives]] more efficiently.<br />
<br />
=Triggering Stim/Response=<br />
'''To Trigger Something Else:'''<br />
<br />
Any Response type may have an effect of "Trigger", in which another entity selected is triggered. Note the "Trigger" effect is all the way at the bottom of the drop down, which might not be displayed on screen (Toggle Effect is the last displayed on mine), you may cursor down or use the End key to get to Trigger.<br />
<br />
'''Be Triggered:'''<br />
<br />
Within the [[Stim/Response]] editor, add a response stim set to "Trigger", now when this entity is targeted, whatever specified effect will occur.<br />
<br />
An example would be to not have something able to be frobbed until something obscuring it is removed or opened. Make the response effect "Set Frobable" for the entity in question, and check "frobability" on. Now when the item is triggered, by a door, or frob response on something in front moved/picked up, it will become frobable.<br />
<br />
=Triggering via Conversation=<br />
The command, [[Conversations#Conversation Commands 2|ActivateTarget]] will trigger the specified entity at that time in the Conversation script.<br />
<br />
=Triggering via Doors, Buttons, Levers, Movers=<br />
[[Doors]] trigger their targets by default upon opening (spawnarg "trigger_on_open" "1"). They may also trigger when completely open by changing "trigger_when_opened" to 1 instead of the default 0, or when fully closed via "trigger_on_close". Note, those conditions on Buttons came from doors, so are counter-intuitive.<br />
<br />
=Triggering via Objectives=<br />
In the [[Objectives Editor]] you may select an entity to be triggered upon an objective succeeding or failing. Therefore all the possible objective conditions may become trigger events (knock out an AI, move an object away from another or to a spot, cause another objective to become visible, disappear or complete, etc.)<br />
<br />
=Triggering via Worldspawn=<br />
You may set "Target" on Worldspawn (usually at a trigger_relay since it only may target one entity currently) to cause things to be triggered at map start. If you use this to kill an AI or other affect with audio, note if in range of the player's start, it will be heard during the fade up from black.<br />
<br />
=Triggering via Lights=<br />
Lights trigger their target(s) both upon being extinguished and lit. This is useful to match window glow to actual light condition. Depending on the light, it may be tricky to set the targets however. A basic light entity can simply have target(s) spawnargs, but a candle, lamp or torch with attached flame entity, you need to use the "set" spawnarg. For example, "set target0 on flame" "EntityToBeTriggered".<br />
<br />
[[Category:Editing]]</div>RJFerrethttps://wiki.thedarkmod.com/index.php?title=Triggers&diff=17702Triggers2014-03-12T23:18:16Z<p>RJFerret: /* trigger_once */ +language change per Grayman's: http://forums.thedarkmod.com/topic/16070-help-with-completing-conversation/page__view__findpost__p__340094</p>
<hr />
<div>There are many different ways of triggering [[Entity|entities]], the Trigger entities themselves, as well as through [[Stim/Response]], [[Conversations]], Movers, [[Objectives]], and more. How the trigger occurs will typically dictate which manner you choose for your map. <br />
<br />
=Triggers=<br />
To create triggers that rely on boundaries (once, multiple and their derivations), you need to drag out a worldspawn brush, right-click, select "Create Entity". They need to be connected to their subjects, either via "Connect Selected Entities" menu option/shortcut key, or adding "Target", "Target0", "Target1" or subsequent "Target"# spawnargs. The triggers below are listed roughly by frequency of usage, with related triggers beneath.<br />
<br />
==trigger_once==<br />
When the origin of an entity is within the bounds of this entity, the target(s) will be triggered, then the trigger_once is removed. (Note, to resize the brush after creating the entity, select it then press Tab once.)<br />
<br />
==trigger_once_entityname==<br />
Similar to [[Triggers#trigger_once|trigger_once]], but may be set to only respond to the entity specified by the spawnarg, "entityname". Note the entity must move into the boundaries itself, not be moved by the player (AI walking themselves for example). (If you want something to happen based on the player dropping or placing an item somewhere, use the [[Objectives]] system instead.)<br />
<br />
==trigger_multiple==<br />
Similar to [[Triggers#trigger_once|trigger_once]] but will activate again and again, use "Wait" spawnarg to control how many seconds between triggerings. <br />
<br />
==trigger_entityname ==<br />
Similar to [[Triggers#trigger_multiple|trigger_multiple]] but only reacts to the entity defined by the "entityname" spawnarg.<br />
<br />
== trigger_facing ==<br />
Also similar to [[Triggers#trigger_multiple|trigger_multiple]], but requires the triggering entity to be within 30° of the specified "angle" spawnarg. For details see [[Trigger Facing]].<br />
<br />
==trigger_relay ==<br />
Most commonly used to trigger many targets, or do so after a delay (per the "delay" spawnarg). May be set to only work once (spawnarg "wait" "-1") or limit firing based upon how many seconds have passed. The "random" spawnarg may be used with "wait" to vary the firings. Very useful as the target of worldspawn, to trigger things at map start (since worldspawn currently only activate one "Target"), or as the target of Objectives.<br />
<br />
==trigger_count ==<br />
This will fire at it's targets upon a specific number of times being triggered itself, based upon the "count" spawnarg. If "count" "3" is set, it will do nothing until the third triggering. <br />
<br />
== trigger_timer ==<br />
This trigger will fire repeatedly every "wait" # seconds. The spawnarg "start_on" defines if it should do so at the start of the map, or wait to be triggered (defaults to 0, off at map start). Spawnarg "random" adds variability to the triggerings.<br />
<br />
== trigger_fade ==<br />
Will cause the display to fade or dissolve to a specified color. The spawnarg "fadeColor" specifies which color, and how transparent in RGBA (red, green, blue, and alpha, ranging from 0-1). Default is fade to black: "fadeColor" "0 0 0 1". To fade up from whatever, use alpha of 0, IE to fade up from black, "0 0 0 0". "fadeTime" controls how quickly the fade transpires.<br />
<br />
== trigger_hurt ==<br />
(needs experienced write-up, compare with stim/response damage please)<br />
<br />
== trigger_presize ==<br />
(needs experienced write-up)<br />
<br />
== trigger_touch ==<br />
Continuously checks if entities are touching, costly performance wise, probably done via [[Objectives]] more efficiently.<br />
<br />
=Triggering Stim/Response=<br />
'''To Trigger Something Else:'''<br />
<br />
Any Response type may have an effect of "Trigger", in which another entity selected is triggered. Note the "Trigger" effect is all the way at the bottom of the drop down, which might not be displayed on screen (Toggle Effect is the last displayed on mine), you may cursor down or use the End key to get to Trigger.<br />
<br />
'''Be Triggered:'''<br />
<br />
Within the [[Stim/Response]] editor, add a response stim set to "Trigger", now when this entity is targeted, whatever specified effect will occur.<br />
<br />
An example would be to not have something able to be frobbed until something obscuring it is removed or opened. Make the response effect "Set Frobable" for the entity in question, and check "frobability" on. Now when the item is triggered, by a door, or frob response on something in front moved/picked up, it will become frobable.<br />
<br />
=Triggering via Conversation=<br />
The command, [[Conversations#Conversation Commands 2|ActivateTarget]] will trigger the specified entity at that time in the Conversation script.<br />
<br />
=Triggering via Doors, Buttons, Levers, Movers=<br />
[[Doors]] trigger their targets by default upon opening (spawnarg "trigger_on_open" "1"). They may also trigger when completely open by changing "trigger_when_opened" to 1 instead of the default 0, or when fully closed via "trigger_on_close". Note, those conditions on Buttons came from doors, so are counter-intuitive.<br />
<br />
=Triggering via Objectives=<br />
In the [[Objectives Editor]] you may select an entity to be triggered upon an objective succeeding or failing. Therefore all the possible objective conditions may become trigger events (knock out an AI, move an object away from another or to a spot, cause another objective to become visible, disappear or complete, etc.)<br />
<br />
=Triggering via Worldspawn=<br />
You may set "Target" on Worldspawn (usually at a trigger_relay since it only may target one entity currently) to cause things to be triggered at map start. If you use this to kill an AI or other affect with audio, note if in range of the player's start, it will be heard during the fade up from black.<br />
<br />
=Triggering via Lights=<br />
Lights trigger their target(s) both upon being extinguished and lit. This is useful to match window glow to actual light condition. Depending on the light, it may be tricky to set the targets however. A basic light entity can simply have target(s) spawnargs, but a candle, lamp or torch with attached flame entity, you need to use the "set" spawnarg. For example, "set target0 on flame" "EntityToBeTriggered".<br />
<br />
[[Category:Editing]]</div>RJFerrethttps://wiki.thedarkmod.com/index.php?title=Objectives&diff=17700Objectives2014-03-12T14:56:01Z<p>RJFerret: /* Using Objectives Creatively */ +harm script</p>
<hr />
<div>{{Original_Reference|Ishtvan|4121}} ''additions by greebo''<br />
<br />
This article covers details of the objectives system. Note that mappers can use <br />
DarkRadiant's [[Objectives Editor]] to make it easier to create objectives.<br />
<br />
The objectives system exists to determine when the player has completed the mission. At the highest level, a mission consists of a list of objectives to be completed and boolean logic to determine when the mission has succeeded or failed based on which of the objectives are complete. At the objective level, an objective consists of individual components and boolean logic to determine when the objective is completed or failed. At the component level, each component has a type, a specifier, and arguments. These will be explained fully in the components section.<br />
<br />
= Mission =<br />
Objectives are stored by entities named [[target_tdm_addobjectives]]. Your mission can have several of these but typically you will only want one for all your objectives.<br />
<br />
By default these entities self-trigger (activates themselves) at mission start. If you need to delay this and activate it later (via any trigger entity that can have a target spawnarg) then add the spawnarg ''wait_for_trigger'' with a value of 1.<br />
<br />
When triggered, these entities add objectives to the mission based on their spawnargs.<br />
<br />
Spawnargs governing mission level behavior may be entered on any target_addobjectives. Non-empty spawnargs will be overwritten by the most recently triggered target_addobjectives (FM authors may want to do this if they add an objective later on and want to change the mission success logic to include that objective, for example). The following is a list of the mission-level spawnargs and what they mean:<br />
<br />
== Success/Failure Logic ==<br />
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.<br />
<br />
=== Default Logic ===<br />
*;<tt>mission_logic_success</tt> (string) <br />
:A string of boolean logic applied to individual objective states to determine if the mission succeeds. AND, OR, NOT and parenthesis are available. The FM author can construct strings using these and the integer index for an objective. For example: "1 OR (NOT(2) AND 3)" would complete the mission if either objective 1 is true, or if 2 is false and 3 is true. By default, a mission succeeds when all mandatory objectives are completed.<br />
<br />
*;<tt>mission_logic_failure</tt> (string) <br />
:Boolean logic applied to individual objective component states to determine if the mission has failed. By default, if any mandatory objective fails, the mission fails.<br />
<br />
=== Difficulty Dependent Logic ===<br />
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):<br />
<br />
*;<tt>mission_logic_success_diff_N</tt> (string) <br />
:Defines the success logic for the difficulty level N (override the default logic), e.g. "1 AND 2 AND 3".<br />
*;<tt>mission_logic_failure_diff_N</tt> (string) <br />
:Defines the failure logic for the difficulty level N (override the default logic). When this condition is fulfilled, the mission has failed.<br />
<br />
If specific logic is not specified for a certain difficulty level, the default spawnargs (without _diff_*) will be used.<br />
<br />
= Objectives =<br />
Objectives added by the target_addobjectives each have a unique integer index, starting with objective 1, the first objective. The spawnargs associated with an objective are prefixed in the following manner:<br />
obj<objective index>_<spawnarg name><br />
Example: ''obj3_desc''<br />
<br />
The spawnargs (minus prefix) and meanings for objective attributes are listed below. Each objective also includes a list of components and their attributes, which will be covered in the next section.<br />
<br />
*;<tt>objN_desc</tt> (string) <br />
: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. The default value is an empty string.<br />
<br />
*;<tt>objN_state</tt> (int) Defines the state of the objective at map start. <br />
:'''Possible Objective States:'''<br />
:* 0 = STATE_INCOMPLETE<br />
:* 1 = STATE_COMPLETE<br />
:* 2 = STATE_INVALID<br />
:* 3 = STATE_FAILED<br />
:Code defaults to 0 = incomplete.<br />
<br />
*;<tt>objN_mandatory</tt> (1/0) <br />
:Set to 0 for optional objective that doesn't fail the mission if you fail it. Objective must be completed to complete the mission if 1. Code defaults to 1.<br />
<br />
*;<tt>objN_irreversible</tt> (1/0) <br />
: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.<br />
<br />
*;<tt>objN_ongoing</tt> (1/0) <br />
:If true, this objective is not marked as complete and the player is not informed that it's complete until the end of the mission. Typically used for "do not kill" type objectives, because technically they would be complete right from the beginning, but we don't want to mark them off or tell the player they're complete right at the beginning. Could also be used for "have some item with you when you complete the mission." Code defaults to 0.<br />
<br />
*;<tt>objN_visible</tt> (1/0) <br />
: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 another 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.<br />
<br />
*;<tt>objN_difficulty</tt> (integer)<br />
:Space delimited list of difficulty levels that should include this objective. For example, "2 3" would enable this objective at difficulty levels 2 and 3, but not for other difficulty levels. Default value is empty - the objective applies to all difficulty levels.<br />
:''Note:'' When the objective is not active for a given difficutly, it is invalidated and hidden, but it still exists, so the numbering of the next objective should still increase by 1. E.g., objective 5 only appears on hard difficulty, but you still have to call the next objective objective 6, you can't call it objective 5 only appearing on easy or medium difficulty.<br />
<br />
*;<tt>objN_enabling_objs</tt> (space-delimited integers) <br />
:This is a list of objectives which must 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.<br />
<br />
*;<tt>objN_script_complete</tt> (string)<br />
*;<tt>objN_script_failed</tt> (string)<br />
: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.<br />
<br />
*;<tt>objN_target_complete</tt> (string)<br />
*;<tt>objN_target_failed</tt> (string)<br />
:Name of a target entity to [[Triggers|trigger]] when this objective is completed or failed, similar to the completion/failure script. Only one entity name is allowed here. If you need to trigger multiple entities on objective state change, use a [[Triggers#trigger_relay|trigger_relay]] entity.<br />
<br />
*;<tt>objN_logic_success</tt> (string)<br />
:Boolean logic applied to individual objective component states to determine if the objective is complete. The same boolean logic options are available as in the mission-level logic described above. By default, all of the components must be true to complete the objective. In other words, all components are ANDed together (1 AND 2 AND 3...).<br />
*;<tt>objN_logic_failure</tt> (string)<br />
:Boolean logic applied to individual objective component states to determine if the objective is failed. By default, if an objective is ongoing, and any opponent becomes false, that objective will fail.<br />
<br />
= Objective Components =<br />
Each objective has an associated list of components and spawnargs defining the attributes of those components. These component spawnargs associated with a given objective are prefixed in the following manner:<br />
obj<objective index>_<component index>_<spawnarg name><br />
Example: ''obj1_2_state''<br />
<br />
In the following, the index N defines the objective number and M refers to the component number. Programmers beware that both numbers start from the value 1.<br />
<br />
*;<tt>objN_M_state</tt> (1/0) <br />
:Defines the state of the component at map start, which can only be "1" (complete) or "0" (incomplete). Code defaults to 0.<br />
<br />
*;<tt>objN_M_player_responsible</tt> (1/0) <br />
:When true, the player must be responsible for the events that satisfy this component. Events the player is not responsible for are not counted. (e.g., the player kills an AI vs. another AI killing an AI). Code defaults to 1.<br />
<br />
*;<tt>objN_M_not</tt> (1/0) <br />
:Code defaults to 0. If true, this component is logically NOTed, so when the conditions described by the type and speifiers are not met, the component state is true, and when they are met, it is false.<br />
<br />
*;<tt>objN_M_irreversible</tt> (1/0) <br />
:When the component state changes from its initial state, it will stay in its new state regardless of what happens later. (There is a script event to "unlatch" a latched objective component if needed). Code defaults to 0.<br />
<br />
*;<tt>objN_M_type</tt> (string) <br />
:Defines the type of this objective component. See the section [[#Component_Types|Component Types]] below for detailed information.<br />
:'''Possible 'Objective Component' Types:'''<br />
:* kill (also includes non-living things being destroyed)<br />
:* ko<br />
:* ai_find_item (not implemented)<br />
:* ai_find_body (not implemented)<br />
:* alert<br />
:* destroy (inanimate item destroyed ("killed"))<br />
:* item (picked up or dropped an inventory item)<br />
:* pickpocket (inventory item acquired from conscious AI)<br />
:* 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)<br />
:* custom (custom component that is set true/false by a map script)<br />
:These components are triggered every N milliseconds by a system clock:<br />
:* custom_clocked (runs a custom map script that should check something and set the objective)<br />
:* info_location (Item A at info_location area B) - TODO: more information needed<br />
:* distance (distance between the origin of entity X and that of entity Y)<br />
<br />
Any component can have up to two specifiers, each of which can carry a value. Here, K refers to the number of the specifier, e.g. ("obj2_1_spec4" "name").<br />
*;<tt>objN_M_specK</tt> (string) <br />
:'''Specification Methods:'''<br />
: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). See the section [[#Specifiers|Specifiers]] below for a detailed description.<br />
:'''The following apply to both AIs and items:'''<br />
:* none<br />
:* name (name of entity)<br />
:* overall (overall count of something: kills, loot, kos, etc)<br />
:* group (inventory group)<br />
:* classname (soft/scripting classname)<br />
:* spawnclass (hard / SDK classname, e.g. "idPlayer")<br />
:'''The following specification methods apply only to AI:'''<br />
:* ai_type (human, beast, undead, bot, etc)<br />
:* ai_team (mapper defined team of the AI)<br />
:* ai_innocence (For distinguishing noncombatants)<br />
<br />
*;<tt>objN_M_spec_valK</tt><br />
:Value that the Kth specifier should match in order to count towards this component. (E.g., an entity name if we specify by name.)<br />
<br />
*;<tt>objN_M_args</tt> (space-delimited string) <br />
:'''Integer and String Arguments:'''<br />
: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.<br />
<br />
*;<tt>objN_M_clock_interval</tt> (float/seconds)<br />
:For clocked components like "custom_clocked" this determines how often they are updated. The value is to be set in seconds.<br />
<br />
== Component Types ==<br />
=== AI-Related Components ===<br />
The following specifiers are termed "Standard AI Specifiers": All specifiers minus the <tt>group</tt> specifier.<br />
<br />
;*<tt>kill</tt><br />
:An AI must be killed to satisfy this component.<br />
:'''SDK Name''': COMP_KILL<br />
:'''Number of Specificatons''': 1 (object that must be killed)<br />
:'''Applicable Specifiers''': Standard AI Specifiers<br />
:'''Expected Arguments''': int (number of kills required)<br />
<br />
;*<tt>ko</tt> (Knockout)<br />
:An AI must be knocked out by any means (gas, blackjack, other).<br />
:'''SDK Name''': COMP_KO<br />
:'''Number of Specificatons''': 1 (AI that must be KO'd)<br />
:'''Applicable Specifiers''': Standard AI Specifiers<br />
:'''Expected Arguments''': int (number of KOs required)<br />
<br />
;*<tt>ai_find_item</tt><br />
:''not yet implemented''<br />
:'''SDK Name''': COMP_AI_FIND_ITEM<br />
:'''Number of Specificatons''': --<br />
:'''Applicable Specifiers''': --<br />
:'''Expected Arguments''': --<br />
<br />
;*<tt>ai_find_body</tt><br />
:''not yet implemented'' An AI must find a body. Currently, the specifiers apply to the bodies found, and any AI finding the bodies triggers this component. Future revisions might add another specifier for the AI that finds the body.<br />
:'''SDK Name''': COMP_AI_FIND_BODY<br />
:'''Number of Specificatons''': 1 (Type of body that must be found)<br />
:'''Applicable Specifiers''': Standard AI Specifiers<br />
:'''Expected Arguments''': int (number of bodies that must be found)<br />
<br />
;*<tt>alert</tt><br />
:True if an AI or type of AI is alerted. Use the player_responsible flag to determine if this should count alerts not caused by the player's actions (e.g., enemy AI being sighted)<br />
:'''SDK Name''': COMP_ALERT<br />
:'''Number of Specificatons''': 1 (AI that must be alerted)<br />
:'''Applicable Specifiers''': Standard AI Specifiers<br />
:'''Expected Arguments''': int (number of alerts required), int (minimum alert level that counts: 1-5 with 5 being the combat state)<br />
<br />
=== Non-AI Components ===<br />
<br />
;*<tt>destroy</tt><br />
:An inanimate item must be destroyed (damage it until its health is lower than zero).<br />
:'''SDK Name''': COMP_DESTROY<br />
:'''Number of Specificatons''': 1 (item to be destroyed)<br />
:'''Applicable Specifiers''': all<br />
:'''Expected Arguments''': int (number of items to be destroyed)<br />
<br />
;*<tt>item</tt><br />
:Completed when the player has this inventory item or loot.<br />
:'''SDK Name''': COMP_ITEM<br />
:'''Number of Specificatons''': 1 (item the player must have)<br />
:'''Applicable Specifiers''': All except AI type, team and innocence.<br />
:'''Expected Arguments''': int (number of items to have, 1 by default)<br />
<br />
;*<tt>pickpocket</tt><br />
:An inventory item must be taken from a conscious AI. Note that it doesn't matter what happens to the item after it is pickpocketed. It could be destroyed or dropped, but as long as it was originally pickpocketed, it counts.<br />
:'''SDK Name''': COMP_PICKPOCKET<br />
:'''Number of Specificatons''': 1 (Item the player must pickpocket)<br />
:'''Applicable Specifiers''': All except AI type, team and innocence<br />
:'''Expected Arguments''': int (number of items to pickpocket, 1 by default)<br />
<br />
;*<tt>location</tt> Object in location brush (using info_tdm_objective_location brush)<br />
:A particular item must be in a particular location, defined by an info_objective_location brush. For optimization reasons, the entity or entities to be checked must also have this spawnarg: "objective_ent" set to "1". NOTE: Multiple objects in a single location are not counted up for this component, this is a single-shot objective. If you want the player to put more than one object in a location, you must currently create several of these components, specifying by name, and OR them together in the objective logic.<br />
:'''SDK Name''': COMP_LOCATION<br />
:'''Number of Specificatons''': 2 (object entity to check, location entity to check)<br />
:'''Applicable Specifiers''': For the object to check, all specifiers apply, but multiple objects are not counted up. Typically the objects will be specified by name. For the location to check, it will either be specified by name or by group.<br />
:'''Expected Arguments''': None (if both specifiers match, the objective is completed).<br />
<br />
;*<tt>info_location</tt> Object in location area (using info_location entities)<br />
:A particular item must be in a particular location, defined by an info_location area (see vanilla D3 documentation for info_location). Multiple objects in a single location are not counted up for this component, this is a single-shot objective. If you want the player to put more than one object in a location, you must currently create several of these components, specifying by name, and OR them together in the objective logic.<br />
:This check is done periodically. Set spawnarg <tt>clock_interval</tt> to the time in seconds between periodic checks.<br />
:'''SDK Name''': COMP_INFO_LOCATION<br />
:'''Number of Specificatons''': 2 (object entity to check, location entity to check)<br />
:'''Applicable Specifiers''': For the object to check, all specifiers apply, but multiple objects are not counted up. Typically the objects will be specified by name. For the location to check, it will either be specified by name or by group.<br />
:'''Expected Arguments''': None (if both specifiers match, the objective is completed).<br />
<br />
;*<tt>custom</tt><br />
:This custom objective component is only changed when an external script changes it. Otherwise it does nothing.<br />
:'''SDK Name''': COMP_CUSTOM_ASYNC<br />
:'''Number of Specificatons''': none<br />
:'''Applicable Specifiers''': none<br />
:'''Expected Arguments''': none<br />
<br />
;*<tt>custom_clocked</tt><br />
:This component calls a custom script periodically to check some condition. When run, the script is expected to this component true or false based on the custom check. This objective component could also be used as a convenient method to periodically call a script that has nothing to do with objectives.<br />
:Set spawnarg <tt>clock_interval</tt> to the time in seconds between periodic calls of the script.<br />
:'''SDK Name''': COMP_CUSTOM_CLOCKED<br />
:'''Number of Specificatons''': none<br />
:'''Applicable Specifiers''': none<br />
:'''Expected Arguments''': string (name of the script to call periodically)<br />
<br />
;*<tt>distance</tt><br />
:Two entities must be sufficiently close to eachother to satisfy this component. The distance check is done between the origin of the first object and that of the second object. If this distance is below the input maximum distance, the component is set to true.<br />
:This check is done periodically. Set spawnarg "clock_interval" to the time in seconds between periodic checks.<br />
:'''SDK Name''': COMP_DISTANCE<br />
:'''Number of Specificatons''': none (see arguments below)<br />
:'''Applicable Specifiers''': none<br />
:'''Expected Arguments''': string (name of first entity), string (name of second entity), int (maximum distance in doom units)<br />
<br />
;*<tt>readable_opened</tt><br />
:''available since TDM 1.02''<br />
:The player must open a named readable to satisfy this component. This doesn't refer to a specific page, just opening the readable is enough.<br />
:'''SDK Name''': COMP_READABLE_OPENED<br />
:'''Number of Specificatons''': 1 (The name of the readable)<br />
:'''Applicable Specifiers''': name<br />
:'''Expected Arguments''': none<br />
<br />
;*<tt>readable_closed</tt><br />
:''available since TDM 1.02''<br />
:The player must close a named readable to satisfy this component. This doesn't check whether the player has finished reading all pages, just closing the previously opened readable is enough.<br />
:'''SDK Name''': COMP_READABLE_CLOSED<br />
:'''Number of Specificatons''': 1 (The name of the readable)<br />
:'''Applicable Specifiers''': name<br />
:'''Expected Arguments''': none<br />
<br />
;*<tt>readable_page_reached</tt><br />
:''available since TDM 1.02''<br />
:The player must open/read a specific page of a named readable to fulfil this component. Scrolling to the page is enough to trigger this event.<br />
:'''SDK Name''': COMP_READABLE_PAGE_REACHED<br />
:'''Number of Specificatons''': 1 (The name of the readable)<br />
:'''Applicable Specifiers''': name<br />
:'''Expected Arguments''': int (the page number which should be reached, the number 1 refers to the first page)<br />
<br />
== Specifiers ==<br />
;*<tt>none</tt> <br />
:No specifier. Component will be completed as soon as any event of that component type happens. (E.g., if you set a KO component type, with specifier none, it would be set to true as soon as soon as the player KO's anyone). This is the default specifier if none is entered. Not very useful, except for blanket "don't do this" objectives. Even then, it is better to use "overall" described below.<br />
:'''SDK Name''': SPEC_NONE<br />
:'''Specifier Argument Type Expected''': No spec argument needed since we don't have to match anything.<br />
<br />
;*<tt>name</tt> <br />
:Name of the entity<br />
:'''SDK Name''': SPEC_NAME<br />
:'''Specifier Argument Type Expected''': string<br />
<br />
;*<tt>overall</tt> <br />
:In the context of inventory item objectives, this refers to overall loot. In the context of AI objectives, this refers to all AI, regardless of team, type, etc.<br />
:'''SDK Name''': SPEC_OVERALL<br />
:'''Specifier Argument Type Expected''': No spec argument needed since we don't have to match anything.<br />
<br />
;*<tt>Group</tt> <br />
:For inventory items, the item's <tt>inv_name</tt> spawnarg value will be used here. For example, if you want the player to get 5 flashbombs, you would use this with group equal to the <tt>inv_name</tt> of flashbombs. As opposed to getting a specific flashbomb in the map, where you would use the <tt>name</tt> specifier instead. If an inventory item is loot, the loot group is used here instead (e.g., <tt>loot_gold</tt>).<br />
:Group is also used for other component types as a convenient way to group things, such as info_objective_location or info_location entities checked by COMP_LOCATION and COMP_INFO_LOCATION, respectively.<br />
:'''SDK Name''': SPEC_GROUP<br />
:'''Specifier Argument Type Expected''': string<br />
:'''Loot group names:''' <tt>loot_gold</tt>, <tt>loot_goods</tt>, <tt>loot_jewels</tt> and <tt>loot_total</tt><br />
<br />
;*<tt>Classname</tt> <br />
:The entityDef classname of the entity. For example: atdm:ai_builder_guard<br />
:'''SDK Name''': SPEC_CLASSNAME<br />
:'''Specifier Argument Type Expected''': string<br />
<br />
;*<tt>Spawnclass</tt> <br />
: The SDK classname of the entity. For example: idAI<br />
:'''SDK Name''': SPEC_SPAWNCLASS<br />
:'''Specifier Argument Type Expected''': string<br />
<br />
;*<tt>ai_type</tt> <br />
:Type of AI: human, beast, undead, steambot, etc. (reads m_AIType in the SDK, which is set by the "type" spawnarg on idActors. Not sure if this is implemented yet).<br />
:'''SDK Name''': SPEC_AI_TYPE<br />
:'''Specifier Argument Type Expected''': int<br />
<br />
;*<tt>ai_team</tt> <br />
:The AI's team integer. This can be set up by the mapper to put AI on arbitrary teams. Mapper can also team up AI for objective purposes, and use this team specifier as a fast way of saying "KO any of these 5 AI." Alternatively, one could use the name specifier and put in multiple components for each of those 5 AI, then OR all the components in the objective success logic. Making a new team may save time over that method.<br />
:'''SDK Name''': SPEC_AI_TEAM<br />
:'''Specifier Argument Type Expected''': int<br />
<br />
;*<tt>ai_innocence</tt> <br />
:Differentiates between combatants and non-combatants. A value of 1 = non-combatant, a value of 0 => non-combatant, or otherwise not deemed "innocent" by the FM author.<br />
:'''SDK Name''': SPEC_AI_INNOCENCE<br />
:'''Specifier Argument Type Expected''': int (1 = innocent, 0 = not)<br />
<br />
= Objective Conditions =<br />
With the campaign code added to TDM 1.06 a new set of spawnargs can be used to let objectives depend on those in a previous mission. These spawnargs are starting with the <tt>obj_condition</tt> prefix.<br />
<br />
Each condition defines the "source" mission and the source objective by number, plus the state of the source objective. It also needs to specify the "target" objective (which is always in the current mission) by number and which action to take. Right now, three different actions are supported: <br />
* Change Objective State (complete, failed, etc.)<br />
* Change the Objective's Visibility (hide or show)<br />
* Change the Objective's Mandatory Flag<br />
<br />
== Syntax ==<br />
<br />
*;<tt>obj_condition_N_src_mission</tt> (integer) <br />
:Defines the source mission the condition depends on. The integer is 0-based, i.e. the first mission has the number 0. The placeholder N is the number of the condition.<br />
<br />
*;<tt>obj_condition_N_src_obj</tt> (integer) <br />
:Defines the number of the source objective in the source mission. The integer is 0-based, i.e. the first objective has the number 0. The placeholder N is the number of the condition.<br />
<br />
*;<tt>obj_condition_N_src_state</tt> (integer) <br />
:Defines the state the source objective needs to be in for this condition to apply. The value can be in the same range as the objN_state spawnarg above:<br />
:* 0 = STATE_INCOMPLETE<br />
:* 1 = STATE_COMPLETE<br />
:* 2 = STATE_INVALID<br />
:* 3 = STATE_FAILED<br />
<br />
*;<tt>obj_condition_N_target_obj</tt> (integer) <br />
:Defines the number of the target objective in the current mission. The integer is 0-based, i.e. the first objective has the number 0. The placeholder N is the number of the condition.<br />
<br />
*;<tt>obj_condition_N_type</tt> (string) <br />
:Defines the action to take if the condition applies. There are three possible action types available:<br />
:* "changestate" Change the state of the target objective.<br />
:* "changevisibility" Change the visibility of the target objective.<br />
:* "changemandatory" Change the mandatory flag of the target objective.<br />
:The combination of this "type" spawnarg and the "value" spawnarg below defines exactly what action is performed on the target objective.<br />
<br />
*;<tt>obj_condition_N_value</tt> (integer) <br />
:The meaning and possible values of this spawnarg depend on the "type" spawnarg above. It is used as "parameter" or "argument" for the above action, e.g. the "changevisibility" action needs to know whether to show or hide the target objective. The possible values are listed below:<br />
:* For type "changestate"<br />
:** 0: set to incomplete<br />
:** 1: set to complete<br />
:** 2: set to invalid<br />
:** 3: set to failed<br />
:* For type "changevisibility"<br />
:** 0: set to invisible<br />
:** 1: set to visible<br />
:* For type "changemandatory"<br />
:** 0: clear mandatory flag<br />
:** 1: set mandatory flag<br />
<br />
= Conclusion =<br />
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.<br />
<br />
= Using Objectives Creatively =<br />
<br />
==A method for using objectives to change AI patrols when alert.==<br />
<br />
This works beautifully. The AI are placed at the seats just like in the card player prefab. Each player have "sitting 1" so they sit down at map start. AI's have no targets.<br />
<br />
Then I have one unseen objective per player:<br />
Objective component is only "AI is alerted", with the single entity card playing AI name. I can set the minimum alert level required for the AI to react. I set that to 3, so if the AI search actively, he won't be playing cards anymore, but goes patrolling instead.<br />
Basically the objective component says: "Alert entity cardgamer1 1 times to a minimum alert level of 3."<br />
<br />
And when that gets satisfied, the objective has completion target gopatrol_start, which is an ordinary trigger_once. This in turn targets a func_static which gives all the cardgamers new targets to their patrol routes. <br />
<br />
This is done as follows: Choose any kind of func_static. Open it in the Stim&Response editor. Add response trigger. Add an effect to this response. Choose "Add Target." Put in the entity box the name of the AI. Put in the target box the name of the path_node where the AI should go.<br />
<br />
When I make one objective for each player, alerting any single one of them will make everyone of them to go for patrol. And once the trigger_once is gone, further alerting of the AI has no effect.<br />
<br />
==A way to replace AI when others are knocked out or killed.==<br />
<br />
Have spare AIs isolated in an inaccessible place either of your map, or room off in the void, targeting a path_waitfortrigger which then carries on their path. Have the AI subject to substitution on a unique team in your map (or identify another way), as well as the spare AIs. An objective is set up like the usual fail if you knock out or kill an AI, but not visible, set to the appropriate team. I found I needed multiple Objective Components, the first no knock/no kill set to an amount of one. Then two and three, etc. Take note of what objective number the objective is and plan on not altering that. Set the failure target to a trigger relay, which targets as many trigger_counts as you have replacement AI. That's it for setting up the objective part.<br />
<br />
Add the aforementioned trigger relay, trigger_counts, and a target_setobjective_state. Setup the target_setobjective_state with "Obj_id0" #, where # is the objective number noted earlier, and set "obj_state" to "0". Add a matching number of atdm:teleport (in target/) as trigger_counts, each teleport targeting one of the stored AI. The first trigger_count is set to 1, and targets the first teleport and AI (to release it from the path_waitfortrigger). The second trigger_count is set to 2, and targets the next teleport and AI, etc. The trigger_relay targets all the trigger_counts and the target_setobjective_state.<br />
<br />
So when the initial AI is knocked out or killed, the objective failure triggers the relay. It in turns increments the counts and resets the objective to work again. The first count activates the teleport and triggers the AI to move off it's path_waitfortrigger on to the next path node. Test and voilà!<br />
<br />
==Having the player place multiple interchangeable items in varied places.==<br />
<br />
In "{{TDM-FM|83|Inn Business}}", the player has to place a number of markers in any of several places. However it was key to not permit multiple markers being placed in the same place, and not all places are required, between half and two-thirds so there's flexibility for various players and their styles.<br />
<br />
An "item is in location" with "group identifier" component was used, so each spot (info_tdm_objective_location) had the same spawnarg "objective_group", "drops". Also "interval" was set to "0.3", with no noticeable performance issue while being responsive enough for player feedback. These locations were separate enough, but limited in size, to meet the restrictions below.<br />
<br />
So a number of objectives matching the number of inventory items were made, with several components. <br />
* let the target entity ''marker1'' be at location 0 of ''drops''<br />
* Do NOT let the entity ''marker1'' and ''marker2'' get within 150 units (check interval 0.3)<br />
* Do NOT let the entity ''marker1'' and ''marker3'' get within 150 units (check interval 0.3)<br />
* Do NOT let the entity ''marker1'' and ''marker4'' get within 150 units (check interval 0.3)<br />
* etc., depending how many marker entities there are<br />
<br />
The other objectives were set up the same way but for their own ''marker#''. (IE, don't let 2 and 1 get within..., don't let 2 and 3, etc.) In this manner, the objective checks if the marker is within the area, but unchecks if the maker rolls out or is removed by the player, and rechecks when they put it back in. <br />
<br />
Finally, another objective was created to complete when all had been placed which is not visible but irreversible. It has Enabling Objectives of the former objectives AND together. IE, "9 AND 10 AND 11 AND 12" if there are four. It has a completion target of a [[Triggers#trigger_relay|trigger relay]] entity which targeted several "atdm:target_setobjective_visibility" to turn off all the marker objectives and enable other mission specific things.<br />
<br />
The components match the markers, again using the group identifier:<br />
* let the target entity ''marker1'' be at location 0 of ''drops''<br />
* let the target entity ''marker2'' be at location 0 of ''drops''<br />
* let the target entity ''marker#etc...'' be at location 0 of ''drops''<br />
<br />
So if all the marker objectives are complete (all items dropped in separate spots), then this completes and fires the trigger, which removes all the marker objectives from display (which the player had for feedback of progress) and moves on with objectives, perhaps displaying a dummy completed objective "All markers placed."<br />
<br />
Note: It's important for the marker objective numbers in the objective editor not to change, or update the non visible completion objective AND logic accordingly.<br />
<br />
== Don't hurt AI script ==<br />
<br />
To have a mission fail if an AI is simply hurt (not just knocked out/killed), this script may be used:<br />
<br />
void checkHarm()<br />
{<br />
float JackHealth = $Jack.getHealth();<br />
float JillHealth = $Jill.getHealth();<br><br />
while(1)<br />
{<br><br />
if(JackHealth - $Jack.getHealth() > 1)<br />
{<br />
$FailHarmObjective.activate($player1);<br />
}<br><br />
if(JillHealth - $Jill.getHealth() > 1)<br />
{<br />
$FailHarmObjective.activate($player1);<br />
}<br><br />
sys.wait(1);<br />
}<br />
}<br />
<br />
You would just need to add one variable/if statement for each AI to be affected and run it from the start of the level (i.e. in the void main just have a line that says "thread checkHarm()"). The "FailHarmObjective" is an actual entity in the map which would then fail the relevant objective.<br />
<br />
<br />
[[Category:Editing]]<br />
[[Category:Tutorial]]</div>RJFerrethttps://wiki.thedarkmod.com/index.php?title=Triggers&diff=17696Triggers2014-03-10T14:08:12Z<p>RJFerret: /* Triggering Stim/Response */ +Trigger</p>
<hr />
<div>There are many different ways of triggering [[Entity|entities]], the Trigger entities themselves, as well as through [[Stim/Response]], [[Conversations]], Movers, [[Objectives]], and more. How the trigger occurs will typically dictate which manner you choose for your map. <br />
<br />
=Triggers=<br />
To create triggers that rely on boundaries (once, multiple and their derivations), you need to drag out a worldspawn brush, right-click, select "Create Entity". They need to be connected to their subjects, either via "Connect Selected Entities" menu option/shortcut key, or adding "Target", "Target0", "Target1" or subsequent "Target"# spawnargs. The triggers below are listed roughly by frequency of usage, with related triggers beneath.<br />
<br />
==trigger_once==<br />
When the origin of an entity enters the bounds of this entity, the target(s) will be triggered one time only. (Note, to resize the brush after creating the entity, select it then press Tab once.)<br />
<br />
==trigger_once_entityname==<br />
Similar to [[Triggers#trigger_once|trigger_once]], but may be set to only respond to the entity specified by the spawnarg, "entityname". Note the entity must move into the boundaries itself, not be moved by the player (AI walking themselves for example). (If you want something to happen based on the player dropping or placing an item somewhere, use the [[Objectives]] system instead.)<br />
<br />
==trigger_multiple==<br />
Similar to [[Triggers#trigger_once|trigger_once]] but will activate again and again, use "Wait" spawnarg to control how many seconds between triggerings. <br />
<br />
==trigger_entityname ==<br />
Similar to [[Triggers#trigger_multiple|trigger_multiple]] but only reacts to the entity defined by the "entityname" spawnarg.<br />
<br />
== trigger_facing ==<br />
Also similar to [[Triggers#trigger_multiple|trigger_multiple]], but requires the triggering entity to be within 30° of the specified "angle" spawnarg. For details see [[Trigger Facing]].<br />
<br />
==trigger_relay ==<br />
Most commonly used to trigger many targets, or do so after a delay (per the "delay" spawnarg). May be set to only work once (spawnarg "wait" "-1") or limit firing based upon how many seconds have passed. The "random" spawnarg may be used with "wait" to vary the firings. Very useful as the target of worldspawn, to trigger things at map start (since worldspawn currently only activate one "Target"), or as the target of Objectives.<br />
<br />
==trigger_count ==<br />
This will fire at it's targets upon a specific number of times being triggered itself, based upon the "count" spawnarg. If "count" "3" is set, it will do nothing until the third triggering. <br />
<br />
== trigger_timer ==<br />
This trigger will fire repeatedly every "wait" # seconds. The spawnarg "start_on" defines if it should do so at the start of the map, or wait to be triggered (defaults to 0, off at map start). Spawnarg "random" adds variability to the triggerings.<br />
<br />
== trigger_fade ==<br />
Will cause the display to fade or dissolve to a specified color. The spawnarg "fadeColor" specifies which color, and how transparent in RGBA (red, green, blue, and alpha, ranging from 0-1). Default is fade to black: "fadeColor" "0 0 0 1". To fade up from whatever, use alpha of 0, IE to fade up from black, "0 0 0 0". "fadeTime" controls how quickly the fade transpires.<br />
<br />
== trigger_hurt ==<br />
(needs experienced write-up, compare with stim/response damage please)<br />
<br />
== trigger_presize ==<br />
(needs experienced write-up)<br />
<br />
== trigger_touch ==<br />
Continuously checks if entities are touching, costly performance wise, probably done via [[Objectives]] more efficiently.<br />
<br />
=Triggering Stim/Response=<br />
'''To Trigger Something Else:'''<br />
<br />
Any Response type may have an effect of "Trigger", in which another entity selected is triggered. Note the "Trigger" effect is all the way at the bottom of the drop down, which might not be displayed on screen (Toggle Effect is the last displayed on mine), you may cursor down or use the End key to get to Trigger.<br />
<br />
'''Be Triggered:'''<br />
<br />
Within the [[Stim/Response]] editor, add a response stim set to "Trigger", now when this entity is targeted, whatever specified effect will occur.<br />
<br />
An example would be to not have something able to be frobbed until something obscuring it is removed or opened. Make the response effect "Set Frobable" for the entity in question, and check "frobability" on. Now when the item is triggered, by a door, or frob response on something in front moved/picked up, it will become frobable.<br />
<br />
=Triggering via Conversation=<br />
The command, [[Conversations#Conversation Commands 2|ActivateTarget]] will trigger the specified entity at that time in the Conversation script.<br />
<br />
=Triggering via Doors, Buttons, Levers, Movers=<br />
[[Doors]] trigger their targets by default upon opening (spawnarg "trigger_on_open" "1"). They may also trigger when completely open by changing "trigger_when_opened" to 1 instead of the default 0, or when fully closed via "trigger_on_close". Note, those conditions on Buttons came from doors, so are counter-intuitive.<br />
<br />
=Triggering via Objectives=<br />
In the [[Objectives Editor]] you may select an entity to be triggered upon an objective succeeding or failing. Therefore all the possible objective conditions may become trigger events (knock out an AI, move an object away from another or to a spot, cause another objective to become visible, disappear or complete, etc.)<br />
<br />
=Triggering via Worldspawn=<br />
You may set "Target" on Worldspawn (usually at a trigger_relay since it only may target one entity currently) to cause things to be triggered at map start. If you use this to kill an AI or other affect with audio, note if in range of the player's start, it will be heard during the fade up from black.<br />
<br />
=Triggering via Lights=<br />
Lights trigger their target(s) both upon being extinguished and lit. This is useful to match window glow to actual light condition. Depending on the light, it may be tricky to set the targets however. A basic light entity can simply have target(s) spawnargs, but a candle, lamp or torch with attached flame entity, you need to use the "set" spawnarg. For example, "set target0 on flame" "EntityToBeTriggered".<br />
<br />
[[Category:Editing]]</div>RJFerrethttps://wiki.thedarkmod.com/index.php?title=Dead_Bodies&diff=17695Dead Bodies2014-03-10T12:38:49Z<p>RJFerret: formatting (bullets not indented)</p>
<hr />
<div>To create a dead body in your mission where there isn't an existing ragdoll, here are two methods:<br />
<br />
==by killing an AI at map start==<br />
<br />
Create entity > darkmod > ragdoll then select the one you want. Place it approximately where you want it to fall. You can't pose it like in Thief as far as I know so it falls like a ragdoll.<br />
<br />
Though, you can move it around in-game (use cvar g_dragEntity 1), and then use the saveRagdolls console command to write the ragdoll position out to the map file.<br />
<br />
If a ragdoll doesn't exist (for example, animals/bots), one solution is to kill the AI at map start.<br />
# Create the appropriate entity<br />
# Add "Target" spawnarg to that entity from any worldspawn brush or patch (control k doesn't work with worldspawn, have to type it manually...now all worldspawn show the entity as target)<br />
# Setup a "Trigger" response via the entity Stim/Response panel<br />
# Add a "Response Effect" of "Kill", selecting the entity name as the target<br />
Note the entity will go through the death anim, so don't have the player start be in earshot at start.<br />
<br />
==by creating a new def file to include with FM==<br />
<br />
Copy/paste the following into a .def file saved in the def folder of your FM. Substitute "whatever" with your actual item (horse, lanternbot, whatever).<br />
<br />
entityDef atdm:env_ragdoll_whatever<br />
{<br />
"inherit" "atdm:env_ragdoll_base"<br />
"editor_displayFolder" "Ragdolls/Bodies"<br />
"editor_ragdoll" "1"<br />
"editor_usage" "Ragdoll for whatever"<br />
"bleed" "1"<br />
"sleep" "1"<br />
"smoke_wound_flesh" "bloodwound.smoke"<br />
"model" whatever's model within quotation marks<br />
"articulatedFigure" I used the same as model, not sure where to get this<br />
"snd_bounce" copy same sound from whatever (again in quotes)<br />
}<br />
<br />
==Adjust how a ragdoll lays==<br />
* Save a backup copy of the map because doom rewrites your map and fixes ALL ragdolls.<br />
* In game, drag the ragdoll around until you get a nice position.<br />
* In the console enter saveRagdolls<br />
* doom rewrites your map.<br />
* When you replay the map ALL ragdolls will now have position spawnargs added for every joint. These are WORLD coordinates so you cannot thereafter easily move that posed ragdoll elsewhere in the editor. I mean, you can still drag it around in-game and use saveRagdolls again but you can't just take a saved ragdoll in the editor and move it to the left - it will still start at the saveRagdoll position (you can fiddle with the spawnargs.)<br />
<br />
<br />
[[Category:Editing]]</div>RJFerrethttps://wiki.thedarkmod.com/index.php?title=Dead_Bodies&diff=17694Dead Bodies2014-03-10T12:37:53Z<p>RJFerret: +ragdoll positioning</p>
<hr />
<div>To create a dead body in your mission where there isn't an existing ragdoll, here are two methods:<br />
<br />
==by killing an AI at map start==<br />
<br />
Create entity > darkmod > ragdoll then select the one you want. Place it approximately where you want it to fall. You can't pose it like in Thief as far as I know so it falls like a ragdoll.<br />
<br />
Though, you can move it around in-game (use cvar g_dragEntity 1), and then use the saveRagdolls console command to write the ragdoll position out to the map file.<br />
<br />
If a ragdoll doesn't exist (for example, animals/bots), one solution is to kill the AI at map start.<br />
# Create the appropriate entity<br />
# Add "Target" spawnarg to that entity from any worldspawn brush or patch (control k doesn't work with worldspawn, have to type it manually...now all worldspawn show the entity as target)<br />
# Setup a "Trigger" response via the entity Stim/Response panel<br />
# Add a "Response Effect" of "Kill", selecting the entity name as the target<br />
Note the entity will go through the death anim, so don't have the player start be in earshot at start.<br />
<br />
==by creating a new def file to include with FM==<br />
<br />
Copy/paste the following into a .def file saved in the def folder of your FM. Substitute "whatever" with your actual item (horse, lanternbot, whatever).<br />
<br />
entityDef atdm:env_ragdoll_whatever<br />
{<br />
"inherit" "atdm:env_ragdoll_base"<br />
"editor_displayFolder" "Ragdolls/Bodies"<br />
"editor_ragdoll" "1"<br />
"editor_usage" "Ragdoll for whatever"<br />
"bleed" "1"<br />
"sleep" "1"<br />
"smoke_wound_flesh" "bloodwound.smoke"<br />
"model" whatever's model within quotation marks<br />
"articulatedFigure" I used the same as model, not sure where to get this<br />
"snd_bounce" copy same sound from whatever (again in quotes)<br />
}<br />
<br />
==Adjust how a ragdoll lays==<br />
* Save a backup copy of the map because doom rewrites your map and fixes ALL ragdolls.<br />
* In game, drag the ragdoll around until you get a nice position.<br />
* In the console enter saveRagdolls<br />
* doom rewrites your map.<br />
* When you replay the map ALL ragdolls will now have position spawnargs added for every joint. These are WORLD coordinates so you cannot thereafter easily move that posed ragdoll elsewhere in the editor. I mean, you can still drag it around in-game and use saveRagdolls again but you can't just take a saved ragdoll in the editor and move it to the left - it will still start at the saveRagdoll position (you can fiddle with the spawnargs.)<br />
<br />
<br />
[[Category:Editing]]</div>RJFerrethttps://wiki.thedarkmod.com/index.php?title=DarkRadiant_Tips_and_Tricks&diff=17692DarkRadiant Tips and Tricks2014-03-09T20:18:12Z<p>RJFerret: +searching</p>
<hr />
<div>== Rendering Performance == <br />
For large maps the rendering performance of DarkRadiant can be poor, depending on your system. Use this to give DarkRadiant a small powerup: <br />
<br />
Got to {{menu|Edit|Preferences}} and then select <code>Orthoview</code> and make sure the '''Update Views on Camera Move''' is unchecked.<br />
<br />
Disabling this option will stop camera movement from triggering an update of the orthoviews, which is expensive.<br />
<br />
==Centering Camera in Ortho views ==<br />
Sometimes you try to resize a brush in an ortho view and your mouse pointer hits the edge of a window. This will zoom you far away very quickly and probably resize your brush very large. This happens to me alot.<br />
<br />
An easy way to get back to where you started is to first hit {{Ctrl-Z}}, this will undo the mistaken brush size so you can try again.<br />
<br />
Next hit {{Ctrl-Tab}}, this will cycle your view to the next view (top, front, side). If you were in the top view you want to {{Ctrl-Tab}} 3 times. This will take you back to the top view and you will be recentered on the selected brush. The brush you were working on is still selected because you only {{Ctrl-Z}}'ed once and you didn't hit escape.<br />
<br />
This is also an easy way to center your front view in on an object you have selected in your top view.<br />
<br />
{{darkradiant|sort=Tips and Tricks}}<br />
<br />
== Tips for Organization == <br />
Try to avoid using very small grid sizes for walls which are on the outside sides of your map. I prefer using no less than a grid size of 4 or larger. By doing this it makes it a lot easier to prevent and find leaks than if you are using a very small grid size.<br />
<br />
== Layers ==<br />
One should always try and utilize the layer function in DarkRadiant. As one's map grows, the perfromance of DarkRadiant will shrink and by being able to isolate the area you are working on you can improve performance for both your computer and yourself!<br />
<br />
== Searching ==<br />
<br />
To search for items (models, entities, sounds, animations, etc.), open the chooser, if the tree is open, click the - symbol to close it (changes to +) and press shift-right-arrow which will open the entire tree. Now type your search term, a box pops up and it will scroll as it finds matches, press up/down arrow to move through other matches.</div>RJFerrethttps://wiki.thedarkmod.com/index.php?title=Triggers&diff=17691Triggers2014-03-09T04:22:13Z<p>RJFerret: /* Triggering Stim/Response */ +triggering frobability example</p>
<hr />
<div>There are many different ways of triggering [[Entity|entities]], the Trigger entities themselves, as well as through [[Stim/Response]], [[Conversations]], Movers, [[Objectives]], and more. How the trigger occurs will typically dictate which manner you choose for your map. <br />
<br />
=Triggers=<br />
To create triggers that rely on boundaries (once, multiple and their derivations), you need to drag out a worldspawn brush, right-click, select "Create Entity". They need to be connected to their subjects, either via "Connect Selected Entities" menu option/shortcut key, or adding "Target", "Target0", "Target1" or subsequent "Target"# spawnargs. The triggers below are listed roughly by frequency of usage, with related triggers beneath.<br />
<br />
==trigger_once==<br />
When the origin of an entity enters the bounds of this entity, the target(s) will be triggered one time only. (Note, to resize the brush after creating the entity, select it then press Tab once.)<br />
<br />
==trigger_once_entityname==<br />
Similar to [[Triggers#trigger_once|trigger_once]], but may be set to only respond to the entity specified by the spawnarg, "entityname". Note the entity must move into the boundaries itself, not be moved by the player (AI walking themselves for example). (If you want something to happen based on the player dropping or placing an item somewhere, use the [[Objectives]] system instead.)<br />
<br />
==trigger_multiple==<br />
Similar to [[Triggers#trigger_once|trigger_once]] but will activate again and again, use "Wait" spawnarg to control how many seconds between triggerings. <br />
<br />
==trigger_entityname ==<br />
Similar to [[Triggers#trigger_multiple|trigger_multiple]] but only reacts to the entity defined by the "entityname" spawnarg.<br />
<br />
== trigger_facing ==<br />
Also similar to [[Triggers#trigger_multiple|trigger_multiple]], but requires the triggering entity to be within 30° of the specified "angle" spawnarg. For details see [[Trigger Facing]].<br />
<br />
==trigger_relay ==<br />
Most commonly used to trigger many targets, or do so after a delay (per the "delay" spawnarg). May be set to only work once (spawnarg "wait" "-1") or limit firing based upon how many seconds have passed. The "random" spawnarg may be used with "wait" to vary the firings. Very useful as the target of worldspawn, to trigger things at map start (since worldspawn currently only activate one "Target"), or as the target of Objectives.<br />
<br />
==trigger_count ==<br />
This will fire at it's targets upon a specific number of times being triggered itself, based upon the "count" spawnarg. If "count" "3" is set, it will do nothing until the third triggering. <br />
<br />
== trigger_timer ==<br />
This trigger will fire repeatedly every "wait" # seconds. The spawnarg "start_on" defines if it should do so at the start of the map, or wait to be triggered (defaults to 0, off at map start). Spawnarg "random" adds variability to the triggerings.<br />
<br />
== trigger_fade ==<br />
Will cause the display to fade or dissolve to a specified color. The spawnarg "fadeColor" specifies which color, and how transparent in RGBA (red, green, blue, and alpha, ranging from 0-1). Default is fade to black: "fadeColor" "0 0 0 1". To fade up from whatever, use alpha of 0, IE to fade up from black, "0 0 0 0". "fadeTime" controls how quickly the fade transpires.<br />
<br />
== trigger_hurt ==<br />
(needs experienced write-up, compare with stim/response damage please)<br />
<br />
== trigger_presize ==<br />
(needs experienced write-up)<br />
<br />
== trigger_touch ==<br />
Continuously checks if entities are touching, costly performance wise, probably done via [[Objectives]] more efficiently.<br />
<br />
=Triggering Stim/Response=<br />
Within the [[Stim/Response]] editor, add a response stim set to "Trigger", now when this entity is targeted, whatever specified effect will occur.<br />
<br />
An example would be to not have something able to be frobbed until something obscuring it is removed or opened. Make the response effect "Set Frobable" for the entity in question, and check "frobability" on. Now when the item is triggered, by a door, or frob response on something in front moved/picked up, it will become frobable.<br />
<br />
=Triggering via Conversation=<br />
The command, [[Conversations#Conversation Commands 2|ActivateTarget]] will trigger the specified entity at that time in the Conversation script.<br />
<br />
=Triggering via Doors, Buttons, Levers, Movers=<br />
[[Doors]] trigger their targets by default upon opening (spawnarg "trigger_on_open" "1"). They may also trigger when completely open by changing "trigger_when_opened" to 1 instead of the default 0, or when fully closed via "trigger_on_close". Note, those conditions on Buttons came from doors, so are counter-intuitive.<br />
<br />
=Triggering via Objectives=<br />
In the [[Objectives Editor]] you may select an entity to be triggered upon an objective succeeding or failing. Therefore all the possible objective conditions may become trigger events (knock out an AI, move an object away from another or to a spot, cause another objective to become visible, disappear or complete, etc.)<br />
<br />
=Triggering via Worldspawn=<br />
You may set "Target" on Worldspawn (usually at a trigger_relay since it only may target one entity currently) to cause things to be triggered at map start. If you use this to kill an AI or other affect with audio, note if in range of the player's start, it will be heard during the fade up from black.<br />
<br />
=Triggering via Lights=<br />
Lights trigger their target(s) both upon being extinguished and lit. This is useful to match window glow to actual light condition. Depending on the light, it may be tricky to set the targets however. A basic light entity can simply have target(s) spawnargs, but a candle, lamp or torch with attached flame entity, you need to use the "set" spawnarg. For example, "set target0 on flame" "EntityToBeTriggered".<br />
<br />
[[Category:Editing]]</div>RJFerrethttps://wiki.thedarkmod.com/index.php?title=Fan_Missions_for_The_Dark_Mod&diff=17690Fan Missions for The Dark Mod2014-03-08T16:03:53Z<p>RJFerret: Inn Business patch</p>
<hr />
<div>__NOTOC__<br />
{{infobox|<center>'''Big Ugly Disclaimer:'''</center><br> '''The Dark Mod''' team does not necessarily support or endorse content listed here, and only hosts missions listed on the [http://www.thedarkmod.com/ official TDM website]. This is a community maintained list, and an ongoing work in progress. Most of the mirror links in this list are dead or are for missions that are not 2.0 compliant. Mission entries which are suspected to violate copyright must be text-only, and cannot contain links. Report and/or remove links found in violation of this rule.}}<br />
<br />
<br />
* For details about editing this table, see [http://modetwo.net/darkmod/wiki/index.php?title=Fan_Missions_for_The_Dark_Mod#Editing_This_Table below].<br />
* For details about how to install Fan Missions please visit: [[Installing and Running Fan Missions]]<br />
* To sort by a different criterion, click the [[Image:Sort none.gif]] icon in the relevant column header.<br />
<br />
<br />
{|class="wikitable sortable" border=1 style="border-collapse: collapse;" cellspacing=0 cellpadding=2 width=100%<br />
|-<br />
!bgcolor=#d0d0e0 width="21%"|Fan Mission Title<br />
!bgcolor=#d0d0e0 width="12%"|Author(s)<br />
!bgcolor=#d0d0e0 width="9%" class="unsortable"|Links<br />
!bgcolor=#d0d0e0 width="5%"|First Release<br />
!bgcolor=#d0d0e0 width="4%"|Size (MB)<br />
!bgcolor=#d0d0e0 width="10%"|Series<br />
!bgcolor=#d0d0e0 width="13%"|Mission Type<br />
!bgcolor=#d0d0e0 width="6%"|Spiders and Undead<br />
|-<br />
<br />
<!--INSERT NEW MISSIONS BELOW THIS LINE--><br />
|-<br />
!align=left|{{TDM-FM|83|Inn Business}}<br>(v.1.48, 2014/03/08)<br />
|RJFerret<br />
|{{Mirrorlink|https://drive.google.com/file/d/0B81T2ZXLPqhTYWVaODRiSExGeGc}} {{Forumlink|1=http://forums.thedarkmod.com/topic/16018-fan-mission-inn-business-by-rjferret-20140303/}}<br />
|2014-03-03<br />
|6<br />
|<br />
|Mansion/Estate FMs<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|82|William Steele 3: Cleighmoor}}<br />
|grayman<br />
|{{Forumlink|http://forums.thedarkmod.com/topic/16011-fan-mission-cleighmoor-by-grayman-201431/#entry338349/}}<br />
|2014-03-01<br />
|38<br />
|William Steele 3<br />
|Sewer / Prison<br />
|none<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|81|William Steele 2: Home Again}}<br />
|grayman<br />
|{{Forumlink|http://forums.thedarkmod.com/topic/15919-fan-mission-home-again-by-grayman-2014212/page__fromsearch__1}}<br />
|2014-02-12<br />
|26<br />
|William Steele 2<br />
|Thieves' Highway / Rooftop<br />
|none<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|80|The Gatehouse}}<br />
|Bikerdude Goldchocobo<br />
|{{Mirrorlink|http://www.southquarter.com/tdm/fms/gatehouse.pk4}} {{Forumlink|http://forums.thedarkmod.com/topic/15844-fan-mission-the-gatehouse-by-bikerdude-goldchocobo-20140114/}}<br />
|2014-01-29<br />
|100<br />
|Remake of Evilartist's Doom 3 mod<br />
|Castle/Fortress Missions<br />
|Ghosts<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|79|Window of Opportunity}}<br>(v.1.43, 2014/01/01)<br />
|RJFerret<br />
|{{Mirrorlink|https://drive.google.com/file/d/0B81T2ZXLPqhTWTMzQXZtMVFBSG8}} {{Forumlink|1=http://forums.thedarkmod.com/topic/15727-fan-mission-window-of-opportunity-by-rjferret-20140101/}}<br />
|2014-01-01<br />
|7<br />
|<br />
|Outdoor/caves<br />
|Spiders (not in short mode)<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|78|In A Time Of Need}}<br />
|kyyrma<br />
| {{Mirrorlink|http://www.mediafire.com/download/a97or40t1xrybh3/timeofneed_v1.zip}} {{Forumlink|http://forums.thedarkmod.com/topic/15354-fan-mission-in-a-time-of-need-by-kyyrma-20131112/}}<br />
|2013-11-12<br />
|5.6<br />
|<br />
|Mansion/Estate FMs<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|76|Requiem}}<br />
|Moonbo<br />
| {{Mirrorlink|http://www.mediafire.com/download/l6o3vvj9y78hu89/requiem.pk4}} {{Forumlink|http://forums.thedarkmod.com/topic/15101-fan-mission-requiem-by-gelo-moonbo-fleisher-2013106/}}<br />
|2013-10-08<br />
|107.3<br />
|[http://www.amazon.com/Shadowcursed-ebook/dp/B00BYEW02M Shadowcursed]<br />
|Lost Civilizations<br />
|Undead<br />
|-<br />
<br />
<br />
|-<br />
!align=left|{{TDM-FM|75|Vengeance for a Thief Part 2}}<br />
|Sir Taffsalot<br />
| {{Mirrorlink|https://dl.dropboxusercontent.com/u/17706561/vfat2.pk4}} {{Forumlink|http://forums.thedarkmod.com/topic/15051-fan-mission-vengeance-for-a-thief-part-2-by-sir-taffsalot-06092013/}}<br />
|2013-09-06<br />
|22<br />
|VFAT 2 and CUC 13<br />
|Museum Missions<br />
|<br />
|-<br />
<br />
<br />
|-<br />
!align=left|{{TDM-FM|74|Lords and Legacy}}<br />
|Kvorning<br />
| {{Mirrorlink|https://dl.dropboxusercontent.com/u/17706561/lordsnlegacy.pk4}} {{Forumlink|http://forums.thedarkmod.com/topic/15016-fan-mission-lords-legacy-by-kvorning-20130830/}}<br />
|2013-08-30<br />
|45<br />
|<br />
|Thieves' Highway / Rooftop<br />
|<br />
|-<br />
<br />
<br />
|-<br />
!align=left|{{TDM-FM|72|Not An Ordinary Guest}}<br />
|Fieldmedic<br />
| {{Mirrorlink|https://dl.dropboxusercontent.com/u/17706561/naog.pk4}} {{Forumlink|http://forums.thedarkmod.com/topic/14965-fan-mission-not-an-ordinary-guest-by-fieldmedic-20130801/}}<br />
|2013-08-01<br />
|79.6<br />
|CUC 13<br />
|City Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|71|Penny Dreadful: Grail of Regrets}}<br />
|Melan<br />
| {{Forumlink|http://forums.thedarkmod.com/topic/14952-fan-mission-penny-dreadful-by-melan-20130728/}}<br />
|2013-07-27<br />
|74<br />
|Penny Dreadful 1<br />
|Horror FMs<br />
|Undead and Spiders<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|70|Solar Escape 1}}<br />
|Tr00pertj<br />
| {{Forumlink|http://forums.thedarkmod.com/topic/14944-fan-mission-solar-escape-1/}}<br />
|2013-07-22<br />
|6<br />
|<br />
|Mansion/Estate FMs<br />
|Undead<br />
|-<br />
<br />
<br />
|-<br />
!align=left|{{TDM-FM|69|The Lich Queen's Demise}}<br />
|Sotha<br />
|{{Mirrorlink|https://dl.dropboxusercontent.com/u/17706561/lich_queens_demise.pk4}} {{Forumlink|http://forums.thedarkmod.com/topic/14826-fan-mission-the-lich-queens-demise-by-sotha-20130520/unread/}}<br />
|2013-05-20<br />
|97.6<br />
|Thomas Porter 6 CUC 13<br />
|Horror FMs<br />
|Undead<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|77|Old Habits Rebuild}}<br />
|Obsttorte<br />
|{{Bloodgate|mc.pk4}} {{Mirrorlink|http://www.mediafire.com/download/u2gwucibh17c45a/oldhabits.pk4}} {{Forumlink|http://forums.thedarkmod.com/topic/14827-fan-mission-old-habits-rebuild-by-obsttorte-20052013/}}<br />
|2013-05-20<br />
|28.6<br />
|<br />
|Mansion/Estate FMs<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|68|The Builder's Blocks}}<br />
|Jesps<br />
|{{Mirrorlink|https://dl.dropboxusercontent.com/u/17706561/builders_blocks.pk4}} {{Forumlink|http://forums.thedarkmod.com/topic/14592-unusual-gameplay-contest-fm-the-builders-blocks-by-jesps/}}<br />
|2013-03-18<br />
|2.85<br />
|CUC 13<br />
|<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|67|Crystal Grave}} <br>(v.2.0, 2013/02/09)<br />
|ERH+ Bikerdude<br />
|{{Mirrorlink|https://dl.dropbox.com/u/17706561/crystalgravev2.pk4}} {{Forumlink|http://forums.thedarkmod.com/topic/14510-fan-mission-crystal-grave-v2-by-erh-and-bikerdude-20130209/unread/}}<br />
|2011-11-15<br />
|12.4<br />
|<br />
|Horror FMs<br />
|Undead<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|66|The Builder Roads}}<br />
|Obsttorte<br />
|{} {{Forumlink|http://forums.thedarkmod.com/topic/14449-fan-mission-the-builder-roads-by-obsttorte-20130119/}}<br />
|2013-01-19<br />
|?<br />
|<br />
|Horror FMs <br />
|Ghosts<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|65|William Steele 1: In the North}}<br />
|grayman<br />
|{{Bloodgate|ws1_north.pk4}} {{Forumlink|http://forums.thedarkmod.com/topic/14214-fan-mission-in-the-north-by-grayman-20121020/}}<br />
|2012-10-20<br />
|39.8<br />
|William Steele 1<br />
|Mansion/Estate FMs<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|64|Old Habits}}<br />
|Obsttorte<br />
|{{Bloodgate|mc.pk4}} {{Mirrorlink|http://www.mediafire.com/download.php?andes2xnsonssfj}} {{Forumlink|http://forums.thedarkmod.com/topic/14206-fan-mission-old-habits-by-obsttorte-20121019/}}<br />
|2012-10-19<br />
|12.8<br />
|<br />
|Mansion/Estate FMs<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|63|Deceptive Shadows}}<br />
|ShadowHide<br />
|{{Bloodgate|DeceptiveShadows.pk4}} {{Mirrorlink|http://www.sendspace.com/file/jzr9s7}} {{Forumlink|http://forums.thedarkmod.com/topic/14103-fan-mission-deceptive-shadows-by-shadowhide-16sep12/}}<br />
|2012-09-16<br />
|22.4<br />
|<br />
|Pagan/Outdoor Missions<br />
|Spiders<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|62|Vengeance for a Thief: Part 1}}<br />
|Sir Taffsalot <br />
|{{Bloodgate|VFAT1.pk4}} {{Mirrorlink|https://dl.dropbox.com/u/17706561/VFAT1.pk4}} {{Forumlink|http://forums.thedarkmod.com/topic/14068-fan-mission-vengeance-for-a-thief-part-1-by-sir-taffsalot-06092012/}}<br />
|2012-09-06<br />
|20.9<br />
|VFAT 1<br />
|Jail/Prison Missions<br />
|<br />
|-<br />
<br />
<br />
|-<br />
!align=left|{{TDM-FM|61|The Phrase Book}}<br />
|Sotha<br />
|{{Bloodgate|phrase_book.pk4}} {{Mirrorlink|http://dl.dropbox.com/u/17706561/phrase_book.pk4}} {{Forumlink|http://forums.thedarkmod.com/topic/13799-fan-mission-the-phrase-book-by-sotha-20120512/}}<br />
|2012-05-11<br />
|24<br />
|Thomas Porter 5<br />
|Thieves' Highway / Rooftop<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|60|In Remembrance of Him}}<br />
|RPGista<br />
|{{Bloodgate|remembrance.pk4}} {{Mirrorlink|http://dl.dropbox.com/u/17706561/remembrance.pk4}} {{Forumlink|http://forums.thedarkmod.com/topic/13749-fan-mission-in-remembrance-of-him-by-rpgista/}}<br />
|2012-04-22<br />
|27.6<br />
|CBC 12<br />
|City Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|59|Rightful Property}}<br />
|jysk<br />
|{{Bloodgate|rightful.pk4}} {{Mirrorlink|http://dl.dropbox.com/u/17706561/rightful1.1b.pk4}} {{Forumlink|http://forums.thedarkmod.com/topic/13711-fan-mission-rightful-property-by-jysk-20120413/}}<br />
|2012-04-12<br />
|22.5<br />
|CBC 12<br />
|Bank Jobs<br />
|Spiders<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|58|Sneak and Destroy}}<br />
|SeriousToni<br />
|{{Bloodgate|kneipe24.pk4}} {{Mirrorlink|http://minus.com/mVcf61n3G/1f}} {{Forumlink|http://forums.thedarkmod.com/topic/13706-fan-mission-sneak-destroy-by-serioustoni-beginners-contest-2012/}}<br />
|2012-04-11<br />
|158<br />
|CBC 12<br />
|City Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|56|House of Theo}}<br />
|Theothesnopp<br />
|{{Bloodgate|houseoftheo.pk4}} {{Mirrorlink|http://www.gamefront.com/files/21053391/houseoftheo__2__2.pk4}} {{Forumlink|http://forums.thedarkmod.com/topic/13242-fan-mission-house-of-theo/}}<br />
|2011-12-04<br />
|6.2<br />
|<br />
|Castle/Fortress Missions<br />
|<br />
|-<br />
<br />
<br />
|-<br />
!align=left|{{TDM-FM|53|Dragon's Claw}}<br />
|Bikerdude, Flanders (map assets)<br />
|{{Bloodgate|claw.pk4}}{{Mirrorlink|http://www.gamefront.com/files/20948800/claw.pk4}} {{Forumlink|http://forums.thedarkmod.com/topic/13181-fan-missiondragons-claw-by-b1k3rdude-31102011/}}<br />
|2011-10-31<br />
|98<br />
|HSC 11<br />
|City Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|52|A Night to Remember}}<br />
|Fieldmedic<br />
|{{Bloodgate|antr.pk4}}{{Mirrorlink|http://www.mediafire.com/?d4hch59m4nef3dc}} {{Forumlink|http://forums.thedarkmod.com/topic/13177-fan-mission-a-night-to-remember-by-fieldmedic-20111030/}}<br />
|2011-10-31<br />
|32<br />
|HSC 11<br />
|Mansion/Estate FMs<br />
|Ghosts<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|51|The Creeps}}<br />
|Mortem Desino<br />
|{{Bloodgate|thecreeps.pk4}}{{Mirrorlink|http://www.gamefront.com/files/20939925/thecreeps.pk4}} {{Forumlink|http://forums.thedarkmod.com/topic/13176-fan-mission-creeps-the-20111030-by-mortem-desino/}}<br />
|2011-10-30<br />
|61<br />
|HSC 11<br />
|Horror FMs<br />
|Ghosts<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|50|House in Blackbog Hollow}}<br />
|Stumpy<br />
|{{Bloodgate|blackbog.pk4}}{{Mirrorlink|http://www.bookofages.co.uk/doom3/mods/blackbog.html}} {{Forumlink|http://forums.thedarkmod.com/topic/13172-fan-mission-house-in-blackbog-hollow-by-stumpy-20111028/}}<br />
|2011-10-28<br />
|12<br />
|HSC 11<br />
|Horror FMs<br />
|Undead and Spiders<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|49|Let Sleeping Thieves Lie}}<br />
|Sir Taffsalot, Bikerdude<br />
|{{Bloodgate|lstl.pk4}}{{Mirrorlink|http://www.mediafire.com/?zkd1jn4lpwgioh9}} {{Forumlink|http://modetwo.net/darkmod/index.php?/topic/13153-let-sleeping-thieves-lie-by-sir-taffsalot-bikerdude-20102011/}}<br />
|2011-10-20<br />
|13<br />
|<br />
|Tombs, Catacombs & Crypts<br />
|Undead<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|48|Samhain Night}}<br />
|PranQster<br />
|{{Bloodgate|samhain.pk4}}{{Mirrorlink|http://jdchoate.mcn.org/games/darkmod/samhain.zip}} {{Forumlink|http://modetwo.net/darkmod/index.php?/topic/13127-fan-mission-samhain-night-on-bone-hill-by-pranqster-20111009/}}<br />
|2011-10-09<br />
|10<br />
|HSC 11<br />
|Horror FMs<br />
|Undead and Spiders<br />
|-<br />
<br />
<br />
|-<br />
!align=left|{{TDM-FM|47|A Score to Settle}}<br />
|Springheel<br />
|{{Bloodgate|score_to_settle.pk4}}{{Mirrorlink|http://www.mediafire.com/?f3o7hm4h4ew7o3l}} {{Forumlink|http://modetwo.net/darkmod/index.php?/topic/12894-fan-mission-%2348-a-score-to-settle-by-springheel-20110701/}}<br />
|2011-07-01<br />
|135<br />
|<br />
|City Missions<br />
|<br />
|-<br />
<br />
<br />
|-<br />
!align=left|{{TDM-FM|46|Siege Shop}}<br>(v3.0 2013/10/10)<br />
|PranQster and Lowenz<br />
|{{Bloodgate|siegeshop.pk4}}{{Mirrorlink|http://jdchoate.mcn.org/games/darkmod/siegeshop.pk4}} {{Forumlink|http://modetwo.net/darkmod/index.php?/topic/12874-fan-mission-the-siege-shop-by-pranqster-20110626/}}<br />
|2011-06-26<br />
|20.51<br />
|<br />
|Castle/Fortress Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|44|Alberic's Curse}}<br />
|Bikerdude<br />
|{{Bloodgate|alberic.pk4}} {{Mirrorlink|http://www.gamefront.com/files/20459738/alberic.pk4}} {{Forumlink|http://modetwo.net/darkmod/index.php?/topic/12850-fan-mission-alberics-curse-by-b1k3rdude-20062011/}}<br />
|2011-06-20<br />
|29<br />
|CSC 11 (Winner), T2 FM homage<br />
|Church/Cathedral<br />
|Undead and Spiders<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|45|Reap as you sow}}<br />
|Fieldmedic<br />
|{{Bloodgate|reap.pk4}} {{Forumlink|http://modetwo.net/darkmod/index.php?/topic/12849-fan-mission-reap-as-you-sow-by-fieldmedic-20110619/}}<br />
|2011-06-19<br />
|52<br />
|CSC 11<br />
|Daylight Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|43|Rake Off}}<br />
|Jesps<br />
|{{Bloodgate|rake_off.pk4}} {{Forumlink|http://modetwo.net/darkmod/index.php?/topic/12846-fm-rake-off-19-06-2011/}}<br />
|2011-06-19<br />
|8<br />
|CSC 11, Selis Woderose 2<br />
|Castle/Fortress Missions <br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|42|Winter Harvest}}<br>(v2.0 2011/07/24 with Bikerdude)<br />
|ShadowHide<br />
|{{Bloodgate|winterharvest.pk4}} {{Forumlink|http://modetwo.net/darkmod/index.php?/topic/12690-seasons-contest-entry-winter-harvest-by-shadowhide/}}<br />
|2011-05-08<br />
|10<br />
|CSC 11<br />
|Pagan/Outdoor Missions<br />
|Spiders<br />
|-<br />
<br />
<br />
|-<br />
!align=left|{{TDM-FM|41|Fiasco at Fauchard Street}}<br />
|Melan<br />
|{{Bloodgate|fauchard.pk4}} {{Mirrorlink|https://rapidshare.com/files/460141132/fauchard.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/12655-fan-mission-fiasco-at-fauchard-street-by-melan-20110501//}}<br />
|2011-05-01<br />
|62<br />
|Talbot 3<br />
|Thieves' Highway / Rooftop<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|40|Mandrasola}}<br />
|Sotha<br />
|{{Bloodgate|mandrasola.pk4}} {{Mirrorlink|http://www.mediafire.com/?2ox2nbhh796ne71}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/12575-fan-mission-mandrasola-by-sotha-20110410/}}<br />
|2011-04-10<br />
|10<br />
|Thomas Porter 0, CSC 11<br />
|City Missions<br />
|Undead<br />
|-<br />
<br />
|-<br />
!align=left|[http://www.gamefront.com/files/20167184/yantdm1.1.pk4 Q4 Conversion: Yan's Test]<br />
|Bikerdude<br />
|{{Mirrorlink|http://www.mediafire.com/?2nona089nzi00sv}} {{Mirrorlink|http://www.gamefront.com/files/20167184/yantdm1.1.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/12506-fan-mission-q4-map-conversion-yantdm1-280311/}}<br />
|2011-03-28<br />
|28<br />
|<br />
|<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|38|The Transaction}}<br />
|Sotha<br />
|{{Bloodgate|transaction.pk4}} {{Mirrorlink|http://www.mediafire.com/?ux7mx79wumnvcb6}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/12408-fan-mission-the-transaction-by-sotha-20110304/}}<br />
|2011-03-04<br />
|10<br />
|Thomas Porter 4<br />
|City Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|13|Return to the City}}<br>(v2.0 2011/03/01)<br />
|Melan, Bikerdude<br />
|{{Bloodgate|ReturnToTheCityV2.pk4}}{{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/10509-fan-mission-return-to-the-city-by-melan-20100110/}} {{Forumlink|1=http://www.ttlg.com/forums/showthread.php?t=130519/}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/12390-fan-mission-return-to-the-city-v2-01032011/}}<br />
|2010-01-10<br />
|26<br />
|Version 1.0, GCC 09 (Winner); Talbot 2<br />
|City Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|39|Lockdown}}<br />
|GameDevGoro Bikerdude Fidcal<br />
|{{Bloodgate|lockdown1_2_1.pk4}} {{Mirrorlink|http://www.fidcal.com/darkuser/missions/lockdown1_2_1.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/12064-fm-lockdown-part-1-by-gamedevgoro-and-bikerdude-20101224/}}<br />
|2010-12-25<br />
|3<br />
|Lockdown 1<br />
|City Missions<br />
|Undead<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|37|Flakebridge Monastery}}<br />
|Jesps<br />
|{{Bloodgate|flakebridge.pk4}} {{Mirrorlink|http://www.file-upload.net/download-3024426/flakebridge.pk4.html}} {{Mirrorlink|http://rapidshare.com/files/434997519/flakebridge.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/11991-fm-flakebridge-monastery-by-jesps/}}<br />
|2010-12-05<br />
|16<br />
|Selis Woderose 1<br />
|Church/Cathedral<br />
|Undead<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|36|Knighton Manor, The}}<br />
|Sotha<br />
|{{Bloodgate|knighton_manor.pk4}} {{Mirrorlink|http://www.mediafire.com/?xrdts3j4t2qxre2}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/11898-fan-mission-the-knighton-manor-by-sotha-20101109/page__view__getnewpost}}<br />
|2010-11-09<br />
|21<br />
|Thomas Porter 1<br />
|Mansion/Estate FMs<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|35|St Albans Cathedral}}<br>(v1.6 2011/03/13)<br />
|Bikerdude<br />
|{{Bloodgate|stac160.pk4}} [[http://www.bloodgate.com/fms/stac142.pk4 Classic]] {{Mirrorlink|http://www.filefront.com/17464439/stac141.pk4}}{{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/11872-fan-mission-st-albans-cathedral-01112010/}} {{Loot|FM:TDM_St_Alban's_Cathedral_-_Bikerdude}}<br />
|2010-11-01<br />
|67<br />
|St Alban<br />
|Church/Cathedral<br />
|Undead<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|33|Swing}}<br />
|Komag<br />
|{{Bloodgate|swing_v1.2.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/11660-vertigo-contest-entry-swing-by-komag-20100825/}} {{Loot|FM:TDM_Swing_-_Komag}}<br />
|2010-08-25<br />
|3<br />
|SVC 10<br />
|Platforming / Jumping<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|32|The Caduceus of St. Alban}}<br>(v.1.5.5 2010/08/26)<br />
|Bikerdude<br />
|{{bloodgate|stalban.pk4}} {{Mirrorlink|http://www.filefront.com/17237609/stalban.pk4/}}{{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/11644-the-caduceus-of-st-alban-vertical-fm-contest-entry-aug-8th-2010/}}<br />
|2010-08-23<br />
|11.3<br />
|SVC 10/St Alban<br />
|Church/Cathedral<br />
|Spiders<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|30|Somewhere Above the City}}<br>(v1.1 2010/08/27)<br />
|Grayman<br />
|{{Bloodgate|somewhere1.1.pk4}}{{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/11619-vertical-contest-mission-somewhere-above-the-city-by-grayman-aug-20-2010/}} {{Loot|FM:TDM_Somewhere_Above_the_City_-_grayman}}<br />
|2010-08-20<br />
|11<br />
|SVC 10<br />
|Tombs, Catacombs & Crypts<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|29|Betrayal}}<br>(v.1.1, 2010/09/01)<br />
|Fieldmedic<br />
|{{Bloodgate|betrayal.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/11605-betrayal-by-fieldmedic-20100817-summer-fm-vertical-contest-entry/}} {{Loot|FM:TDM_Awaiting_the_Storm_-_HappyCheeze}}<br />
|2010-08-17<br />
|12<br />
|SVC 10<br />
|Horror FMs<br />
|Undead<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|31|Rift, The}}<br />
|Baddcog<br />
|{{Bloodgate|rift.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/11599-vert-contest-mission-the-rift-by-baddcog-aug-15-2010/}}<br />
|2010-08-15<br />
|10<br />
|SVC 10<br />
|Lost Civilizations<br />
|Undead and Spiders<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|34|Illusionist's Tower}}<br />
|stumpy<br />
|{{Bloodgate|holetower.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/11541-illusionists-tower-by-stumpy-201085-summer-fm-vertical-contest-entry}} {{Forumlink|1=http://www.bookofages.co.uk/doom3/mods/holetower.html}} {{Loot|FM:TDM_Illusionist%27s_Tower_-_stumpy}}<br />
|2010-08-05<br />
|9<br />
|SVC 10<br />
|Horror FMs<br />
|Undead and Spiders<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|28|Mad's Mountain}}<br />
|Jesps<br />
|{{Bloodgate|madmountain.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/11510-fan-mission-mads-mountain-by-jesps-20100731}} {{Loot|FM:TDM_Lord_Dufford%27s_-_stumpy}}<br />
|2010-07-31<br />
|2<br />
|SVC 10<br />
|Tombs, Catacombs & Crypts<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|27|Glenham Tower, The}}<br />
|Sotha<br />
|{{Bloodgate|glenham_tower.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/11423-fan-mission-the-glenham-tower-by-sotha-20100717}}<br />
|2010-07-17<br />
|5<br />
|Thomas Porter 3, SVC 10 (Winner)<br />
|Horror FMs<br />
|Undead<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|25|Pandora's Box}}<br />
|Jesps, Fidcal<br />
|{{Bloodgate|pandoras_box.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/11381-fan-mission-pandoras-box-by-jesps20100711}} {{Loot|FM:TDM_Pandora%27s_Box_-_Jesps}}<br />
|2010-07-11<br />
|7<br />
|<br />
|Pirate Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|23|Beleaguered Fence, The}}<br />
|Sotha<br />
|{{Bloodgate|beleaguered_fence.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/11298-fan-mission-the-beleaguered-fence-by-sotha-20100623}} {{Loot|FM:TDM_The_Beleaguered_Fence_-_Sotha}}<br />
|2010-06-23<br />
|11<br />
|Thomas Porter 2<br />
|Jail/Prison Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|22|Special Delivery, A}}<br />
|Silencium18<br />
|{{Bloodgate|delivery.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/11247-fan-mission-a-special-delivery-by-silencium1820100612}} {{Loot|FM:TDM_A_Special_Delivery_-_Silencium18}}<br />
|2010-06-12<br />
|2<br />
|<br />
|Warehouse Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|21|Alchemist, The}}<br>(2010/06/04)<br />
|Sotha, Fidcal<br />
|{{Bloodgate|alchemist.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/11170-fan-mission-the-alchemist-by-sotha-fidcal20100601}} {{Loot|FM:TDM_The_Alchemist_-_Sotha_%26_Fidcal}}<br />
|2010-06-01<br />
|27<br />
|Thief's Den 4<br />
|City Missions<br />
|Undead<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|20|Awaiting The Storm}}<br />
|HappyCheeze<br />
|{{Bloodgate|storm.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/11095-fm-awaiting-the-storm-by-happycheeze-20200522}} {{Loot|FM:TDM_Awaiting_the_Storm_-_HappyCheeze}}<br />
|2010-05-22<br />
|4<br />
|<br />
|City Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|18|No Honor Among Thieves}}<br>(v.2.0, 2013/10/16)<br />
|Goldchocobo, RailGun, Mortem Desino<br />
|{{Mirrorlink|http://tinyurl.com/2a9mdcs}}{{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/10993-fan-mission-no-honor-among-thieves-20100429}} {{Loot|FM:TDM_No_Honor_Among_Thieves_-_Goldchocobo}}<br />
|2010-04-29<br />
|144<br />
|<br />
|Pagan/Outdoor Missions<br />
|Undead and Spiders<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|17|Heart of Lone Salvation, The}}<br>(v.2.0, 2010/04/12)<br />
|Fidcal, Baddcog<br />
|{{Bloodgate|heart.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/10878-fan-mission-the-heart-of-lone-salvation-by-fidcal-baddcog-20100402/}} {{Walkthrough|FM:TDM_The_Heart_of_Lone_Salvation_-_Fidcal_%26_Baddcog}} {{loot|FM:TDM_The_Heart_of_Lone_Salvation_-_Fidcal_%26_Baddcog}}<br />
|2010-04-02<br />
|41<br />
|Thief's Den 3<br />
|City Missions<br />
|Spiders<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|73|Lord Dufford's}}<br />
|stumpy<br />
|{{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/10868-fan-mission-lord-duffords-20100331}} {{Loot|FM:TDM_Lord_Dufford%27s_-_stumpy}}<br />
|2010-03-31<br />
|22<br />
|<br />
|City Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|16|Builder's Influence, The}}<br>(2010/03/23)<br />
|Railgun, Springheel<br />
|{{Bloodgate|builders_influence.pk4}} {{Mirrorlink|http://www.fidcal.com/darkuser/missions/builders_influence.pk4}}{{Forumlink|http://modetwo.net/darkmod/index.php?/topic/10811-fan-mission-the-builders-influence-20100320/}} {{Loot|FM:TDM_The_Builders_Influence_-_Railgun%26Springheel}}<br />
|2010-03-20<br />
|15<br />
|<br />
|Castle/Fortress Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|14|Business as Usual}}<br>(v2.0 2011/09/24)<br />
|Bikerdude<br />
|{{Bloodgate|business.pk4}}{{Mirrorlink|1=http://rapidshare.com/files/335299431/business.pk4.html}}{{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/10533-fan-mission-business-as-usual-by-b1k3rdude-14012010-christmas-fm-contest-entry/page__view__findpost__p__207055}}<br />
|2010-01-14<br />
|4<br />
|GCC 09<br />
|Sewer<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|12|Sons of Baltona 1, The}}<br />
|Carnage<br />
|{{Bloodgate|sons_of_baltona_1.pk4}} {{Mirrorlink|1=http://www.mediafire.com/?m4ywobjodm0}}{{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/10498-fan-mission-the-sons-of-baltona-1-by-carnage-20100109}}<br />
|2010-01-09<br />
|3<br />
|GCC 09 / Baltona 1<br />
|Mansion/Estate FMs<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|11|Living Expenses}}<br />
|Sonosuke<br />
|{{Bloodgate|living_expenses.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/10451-fm-living-expenses-by-sonosuke-2-jan-10/page__view__findpost__p__205386}}<br />
|2010-01-02<br />
|6<br />
|GCC 09<br />
|Mansion/Estate FMs<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|10|Trapped!}}<br />
|RailGun<br />
|{{Bloodgate|trapped.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/10442-fm-trapped-by-railgun-dec-30/page__view__findpost__p__205092}}<br />
|2009-12-30<br />
|6<br />
|<br />
|Jail/Prison Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|8|Parcel, The}}<br />
|Xonze<br />
|{{Bloodgate|parcel.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/10404-fm-the-parcel-by-xonze-dec-24/page__view__findpost__p__204459}}<br />
|2009-12-24<br />
|7<br />
|GCC 09<br />
|Mansion/Estate FMs<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|9|Too Late}}<br />
|Nielsen74<br />
|{{Bloodgate|too_late.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/10400-fm-too-late-by-nielsen74-24-dec-09/page__view__findpost__p__204396}}<br />
|2009-12-24<br />
|4<br />
|GCC 09<br />
|Warehouse Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|7|Thieves}}<br />
|Silencium, RailGun, Fidcal<br />
|{{Bloodgate|thieves.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/10286-fm-the-thieves-nov-2509/}}<br />
|2009-11-26<br />
|9<br />
|<br />
|City Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|6|Patently Dangerous}}<br>(v.2.0, 2013/10/08)<br />
|demagogue<br />
|{{Bloodgate|patently_dangerous.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/10125-fm-patently-dangerous-oct3109/page__view__findpost__p__199324/}}<br />
|2009-10-31<br />
|24<br />
|<br />
|City Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|5|Dark Mod Training Mission, The}}<br />
|TDM Team<br />
|{{Bloodgate|training_mission.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/9932-fm-training-mission-17-oct-09/}}<br />
|2009-10-17<br />
|6<br />
|<br />
|Training<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|2|Crown of Penitence, The}}<br />
|Jesps<br />
|{{Bloodgate|crow_of_penitence.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/9934-fm-crown-of-penitence-by-jesps-17-oct-09/}}<br />
|2009-10-16<br />
|12<br />
|<br />
|Mansion/Estate FMs<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|3|Chalice of Kings, The}}<br />
|Fidcal<br />
|{{Bloodgate|chalice.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/9935-fm-chalice-of-kings-by-fidcal-17-oct-09/}} {{Loot|FM:TDM_Chalice_of_Kings_-_Fidcal}}<br />
|2009-10-15<br />
|3<br />
|Thief's Den 2<br />
|Castle/Fortress Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|1|Outpost, The}}<br />
|angua, greebo<br />
|{{Bloodgate|outpost.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/9937-fm-the-outpost-by-angua-greebo-17-oct-09/}}<br />
|2008-12-23<br />
|2<br />
|<br />
|Castle/Fortress Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|15|Tears of Saint Lucia, The}}<br>(v.1.01, 2010/04/29)<br />
|TDM Team<br />
|{{Bloodgate|saintlucia.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/10579-fan-mission-the-tears-of-st-lucia-20081021/page__view__findpost__p__207972}} {{Loot|FM:TDM_The_Tears_of_Saint_Lucia_-_jdude}}<br />
|2008-10-21<br />
|18<br />
|<br />
|Church/Cathedral<br />
|Spiders<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|57|Closemouthed Shadows}}<br>(v.2.0, 2012/01/15)<br />
|LordSavage, Bikerdude<br />
|{{Bloodgate|closemouthed_shadows.pk4}} {{Forumlink|1=http://forums.thedarkmod.com/topic/13383-fan-mission-closemouthed-shadows-2008-reworked-for-tdm-107-20120115/}} <br />
|2008-09-21<br />
|2<br />
|Closemouthed Shadows 1<br />
|Mansion/Estate FMs<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|24|Thief's Den}}<br>(v.2.0, 2010/07/04)<br />
|Fidcal, greebo<br />
|{{Bloodgate|thiefs_den.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/11347-fan-mission-thiefs-den-re-release-by-fidcal20100704}} {{Walkthrough|FM:TDM_Thief's_Den_-_Fidcal}} {{Loot|FM:TDM_Thief%27s_Den_-_Fidcal}}<br />
|2008-01-18<br />
|3<br />
|Thief's Den 1<br />
|City Missions<br />
|<br />
|}<br />
<br />
If the aforementioned download links are down, [http://www.southquarter.com/downloads/missions_view.php South Quarter] has some TDM missions (-2011) as well as a link to it's TTLG forum thread. Just click the 'game column' to sort the list with TDM.<br />
<br />
To see a speculative list of Upcoming Fan Missions please visit: [[Upcoming Fan Missions]]<br />
<br />
<br />
<br />
'''Series Key'''<br />
<br />
GCC 09: Grand Christmas Contest 2009<br />
<br />
SVC 10: Summer Vertical Contest 2010<br />
<br />
CSC 11: Community Seasons Contest 2011<br />
<br />
HSC 11: Halloween Speed-Build Contest 2011<br />
<br />
CBC 12: Community Beginner Contest 2012<br />
<br />
CUC 13: Community Unusual Contest 2013<br />
<br />
<br />
'''Links Key'''<br />
<br />
{|class="wikitable" border=1 style="border-collapse: collapse;" cellspacing=0 cellpadding=2<br />
<br />
|-<br />
|[http://modetwo.net/darkmod/wiki/images/b/be/Icon_forum.png http://modetwo.net/darkmod/wiki/images/b/be/Icon_forum.png]<br />
|Link to discussion in Forums<br />
<br />
|-<br />
|{{Mirrorlink|}}<br />
|Misc. download mirror<br />
<br />
|-<br />
|{{Bloodgate|}}<br />
|Bloodgate download mirror<br />
<br />
|-<br />
|{{Loot|}}<br />
|Loot list<br />
<br />
|-<br />
|{{Walkthrough|}}<br />
|Walkthrough<br />
<br />
|}<br />
<br />
<br />
== Editing This Table ==<br />
* Please only include playable missions that are fully released, not those currently in development or testing. Tutorials, demos, prefabs, etc. should be listed elsewhere. <br />
* A mission title may be listed in plain text as a record of release, or preferably a link to an information page or primary direct download.<br />
* List by release date descending (newest at the top).<br />
* If a fan mission only has a single mirror/host please consider adding additional mirrors. <br />
{{general|sort=Fan Missions}}<br />
[[Category:Fan Missions]]</div>RJFerrethttps://wiki.thedarkmod.com/index.php?title=Stim/Response&diff=17687Stim/Response2014-03-07T03:15:50Z<p>RJFerret: /* Stim/Response Key/Value Definitions */ +not just key/values, examples are there too</p>
<hr />
<div>This article describes how the stim/response system works for '''The Dark Mod'''. The name is taken from the Dromed Stim/Response system. However this does '''not''' mean that you should assume any other similarities. The system was described to me (sparhawk) and I coded it accordingly, but I have no Dromed experience, beyond some '''very''' simple maps, without any special features. I never got beyond the "Create a room and texture it" stage. :)<br />
So while this system may be similar on how it works as seen by the users, you can't assume that this is is more then a fleeting similarity as defined by it's common requirements.<br />
<br />
== How does it work? ==<br />
<br />
The general concept is pretty easy to understand. The mapper populates his map with entities. Each of these entities can be either a kind of actor (a stim) or an actee (the response). Any entity can be both at the same time, however stims don't affect the owner itself. So if the entity carries a stim and it triggers, it will not act on himself, even if the entity has a response for that stim.<br />
Stims and responses are defined by numbers. '''The Dark Mod''' already defines some very common stims (like water) and reserves numbers for them. For a complete list you should take a look at tdm_stim_response.script in the script folder. You will notice that there is one stim named USER. This stim has no special meaning. Instead it defines the lowest number that users can use for themselves. So if you define new stims to be used in your maps, you should use USER+N for your individual stims. All numbers below USER are assumed to be known stims and may trigger specific actions if needed, which possibly includes specific SDK support code.<br />
<br />
As explained above, stims and responses are identified by their id's (the numbers). Whenever a stim is active, the system evaluates all stims and checks if appropriate responses are within its reach. A response is identified by having the same id as the stim. When such a response is found, the response is triggered and a script action is executed for it. If the response doesn't have a script action associated, nothing will happen, but this is usually a waste of CPU, unless the response is coded in C++ directly in the SDK.<br />
One major difference between stims and responses is that responses have an action associated with them, while stims don't.<br />
<br />
Stims and responses can be enabled and disabled at runtime. This is not only a feature, it is very important for the health of the system. If stims are not destroyed after they are used up, they will take up memory and hog your machine down over time. Also accumulating stims will cause the system to respond slower over time as more and more stims have to be tested. For example: The arrows (like the water arrow) will spawn an entity that carries the water stim when the arrow explodes. If that stim is not destroyed, it will continue to fire. Once a water arrow is exploded it doesn't makes sense though to keep it running, so it has to be destroyed. However, there is no definite rule when a stim has to be destroyed because it depends on its actual usage. Some stims may run throughout the game and others should be destroyed after they are used up.<br />
<br />
== How to set it up? ==<br />
<br />
Bascially there are several methods to create a stim/response. The most obvious one is to add it in the SDK code, but this is probably the least preferred. For all practical purposes, stims and responses should be added either via scripting or the map editor, without the need of coding in the SDK environment.<br />
<br />
== Configuring Stims/Responses in DarkRadiant ==<br />
Since release 0.9.0 [[DarkRadiant]] is capable of setting up stims and responses via a graphical interface. To open the Stim/Response Editor, select your entity and choose the command from the menu:<br />
<br />
[http://img296.imageshack.us/img296/8965/srmenudf9.jpg http://img296.imageshack.us/img296/8965/srmenudf9.th.jpg]<br />
<br />
The Stim/Response Editor will pop up and allow you to define stims and responses for your entity. I'll go briefly over the properties of stims and responses in the following sections.<br />
<br />
=== Stims ===<br />
A Stim is the equivalent to DromEd's Source and can be of various types (Frob, Heal, Damage, Trigger, Sound, Visual, Communication, whatever). Each stim can be either active or inactive, which can be controlled via ticking the checkbox "Active" accordingly.<br />
<br />
Most stims need to have a '''radius''' defined, that specifies their action area. The radius is measured in Doom Units and its value depends on the purpose of your stim. A torchflame for example has a Fire Stim with a radius of 10, which is fairly small (~25 cm, ~10 inches). One can also set up a stim whose radius is growing during the stim's lifetime, by setting '''radius_final''' (this requires a non-zero '''duration''' being set on the stim).<br />
<br />
The second important parameter is the '''magnitude''' of the stim. For instance, the fire stim of a torch is supposed to have a smaller magnitude than a lava stream.<br />
<br />
The magnitude can be either constant over the whole stim range or follow a certain falloff function as defined by the '''falloff exponent'''. A falloffexponent of 0 means that the magnitude is constant over the whole range, which is the default: <br />
<br />
* 0 = no falloff (magnitude is constantly at maximum value over the whole radius)<br />
* 1 = linear falloff<br />
* 2 = quadratic falloff<br />
* 3 = etc.<br />
<br />
The higher the number, the faster the magnitude is decreasing with the distance. The magnitude is reaching zero as soon as the distance of the responding object is greater than or equal to the stim radius, except for falloffexponent = 0 (no falloff). Negative values are allowed as well, making it possible to actually increase the magnitude of a stim with larger distance < radius. Don't know if that makes sense, though, and I haven't tested it either.<br />
<br />
== Stim/Response Key/Value Definitions ==<br />
These can be found here: [[Stim/Response Key/Values]] (with examples also)<br />
<br />
[[Category:Tutorial]]<br />
[[Category:Editing]]</div>RJFerrethttps://wiki.thedarkmod.com/index.php?title=Stim/Response_Key/Values&diff=17686Stim/Response Key/Values2014-03-07T03:13:08Z<p>RJFerret: /* Example: Damage Stim */ +water extinguishing removes damaging</p>
<hr />
<div>'''Note:''' ''There is now a stim/response editor accessed via the Dark Radiant entity menu which makes it easier to set these key/values. The editor settings will be shown below next to their equivalent key/values (work in progress.)''<br />
<br />
<br />
I added two new key/vals to stim response, and figured I would document them all here including the new ones.<br />
<br />
In all of these, N is the number of the stim on the entity. It starts at 1 and goes up. Be aware of any stims that are defined on the entity in other places, like in the def file or in something inherited by it. Stims on the entity itself must start counting from the last one of these, so if the def file has 1 stim, the entitydef in the map would start at number 2.<br />
<br />
== Keys that can be used to set up both stims and responses ==<br />
Key: '''sr_class_N'''<br />
Set to "S" for stim, "R" for response.<br />
<br />
Key: '''sr_type_N'''<br />
Type of stim (e.g. STIM_WATER). See /script/darkmod_stim_response.script for a complete list of stim types.<br />
<br />
Key: '''sr_state_N'''<br />
Set to "1" for enabled, "0" for disabled. This may be altered later with scripting.<br />
<br />
Key: '''sr_chance_N'''<br />
Probability for this stim/response to fire/react. Set this to 0.3 if you want to have a 30% chance.<br />
<br />
== Stim only ==<br />
Key: '''sr_use_bounds_N'''<br />
Set to "1" if you want to use the bounds of the entity as the basis for the intersection test. "0" (the default) uses a sphere centered on the entity origin.<br />
<br />
Key: '''sr_radius_N'''<br />
Radius of the stim in doomunits. NOTE: If you set sr_use_bounds to "1", the radius is applied as an expansion of the entity bounding box in all directions. So if you select use bounds and set the radius to "0", this makes the stimmed region exactly equal to the stim bounds.<br />
<br />
Key: '''sr_radius_final_N'''<br />
Final radius of the stim (i.e. the radius at the end of its lifetime). While the stim is active, the radius will linearly change within the [sr_radius..sr_radius_final] interval. The start value is defined by sr_radius, the end value by this spawnarg. Note that sr_radius_final is not necessarily larger than the sr_radius value, it's also possible to let a stim shrink. For this spawnarg to work, the '''sr_duration''' value must be greater than zero.<br />
<br />
Key: '''sr_magnitude_N''' (float)<br />
The maximum magnitude of the stim at zero distance. If the responding entity's origin is exactly at the origin of the stimming entity (which is not always possible due to the collision boxes), this magnitude value is passed to the response effect scripts.<br />
<br />
Key: '''sr_falloffexponent_N''' (float)<br />
The falloff exponent determining the magnitude in dependency of the distance. There is no limitation to this value, although only a few make sense.<br />
<br />
0 = no falloff (magnitude is constantly at maximum value over the whole radius)<br />
<br />
1 = linear falloff<br />
<br />
2 = quadratic falloff<br />
<br />
3 = etc.<br />
<br />
The higher the number, the faster the magnitude is decreasing with the distance. The magnitude is reaching zero as soon as the distance of the responding object is greater than or equal to the stim radius, except for falloffexponent = 0 (no falloff). Negative values are allowed as well, this way it should be possible to actually increase the magnitude of a stim with larger distance. Don't know if that makes sense, though and I haven't tested it either.<br />
<br />
For documentation purposes, this function is used to determine the actual magnitude: '''m(dist) = m0*[ 1 - dist/radius]^falloffExponent''' (math functions seem to be disabled for this wiki)<br />
<br />
Key: '''sr_duration_N'''<br />
This specifies how long the stim is active before it gets disabled. If this is key is empty, the stim has infinite lifetime (apart from being disabled by scripts and such).<br />
<br />
Key: '''sr_time_interval_N'''<br />
When this stim is active, the firings will be spread out by this many milliseconds. So a stim with sr_time_interval = 500 will fire every half second when active. Used for optimization for stims that don't have to be checked that often.<br />
<br />
Key: '''sr_max_fire_count_N''' (default: -1)<br />
This specifies the maximum number of stim firings that are possible for this stim. The default is -1 which means that it can be fired infinitely often. With each firing, the counter is decreased. When it reaches zero, the stim is entirely ignored from then on. Currently there is no way to reactivate a stim whose max_fire_count has been depleted. Stims that fail because of their '''sr_chance_N''' spawnarg decrease the counter as well.<br />
<br />
Key: '''sr_timer_time_N''' (Format: hhhh:mm:ss:ms, for example: 0:3:20:0 which means 3 minutes and 20 secs) ''(s & r editor = Activation Timer.)''<br />
This can be used to enable the stim after a certain amount of time. Depending on the '''sr_timer_waitforstart''' key the timer is started on spawn or on a "StartTimer" event. Use this to setup a stim that has its '''sr_state_N''' set to 0 at start and gets enabled after a certain amount of time. This is only effective if the sr_state is 0 (disabled) by the time this timer is elapsing ''(s & r editor = Active checkbox.)''<br />
<br />
Key: '''sr_timer_waitforstart_N''' (0 or 1, default is 0)<br />
If this key is TRUE = "1", the timer has to be started by a StartTimer script event or the according response effect. If this is set to 0, the timer starts on spawning this entity (beware: the entities might be spawned quite some time before the map is actually started, on my testmap it sometimes took up to 20 seconds before the player is spawned, so this is not a very reliable measure).<br />
<br />
Key: '''sr_timer_type_N''' | possible values: "RELOAD" or "SINGLESHOT" (default)<br />
When this is set to RELOAD, the timer is reactivated after the stim has been fired. This can be used to setup sophisticated time intervals. I intend to draw a graph explaining this, so if this is not yet in the wiki, you can bug greebo to do this. :)<br />
<br />
Key: '''sr_bounds_mins_N''' and '''sr_bounds_maxs_N''' (Type: Vector, default is "0 0 0")<br />
These two vectors define the bounding box of the stim. This is measured relatively to the stim origin (which might be moving), not the entity origin. A vector pair of '''-10 -10 -50''' and '''10 10 150''' defines a primarily vertical stim area.<br />
<br />
Key: '''sr_velocity_N''' (type: Vector, default: "0 0 ")<br />
This defines the velocity of the stim in units per second. A vector of '''0 0 -10''' let's the stim move downward for 10 units per second for the stim duration time.<br />
<br />
== Response only ==<br />
Key: '''sr_chance_timeout_N'''<br />
Many stims like the water arrow stim are firing rapidly multiple times a second, distorting the "effective" probability of a response going off. Use this to give the response a timeout before it can be evaluated again after a failed probability check.<br />
<br />
Key: '''sr_random_effects_N'''<br />
If this spawnarg contains non-zero values, exactly this number of random response effects is chosen from the available ones. So, if you set sr_random_effects to 2 and there are 5 effects available, two are randomly chosen (may also be one of them twice). If only one effect is available, just this one is fired twice.<br />
<br />
Key: '''sr_script_<STIM TYPE>'''<br />
First off, the name of this key: <STIM TYPE> should be replaced with the string name of one of the stim types. For example, sr_script_STIM_WATER defines the script to call in respone to a water stim. Apparently there can only be one of these per stim type. <STIM TYPE> can either be the name as a string (in case of default stims) or the number:<br />
sr_script_STIM_WATER<br />
sr_script_2<br />
Both of which will have the same meaning, assuming that the water stim has the number two.<br />
<br />
The value this key contains the name of the script function to call. If it's a local script, you must put it in the form of "<script object name>::<local function>" otherwise "<global function name>" works as well.<br />
<br />
== Important note about writing response scripts ==<br />
There's some subtlety about writing these response scriptfunctions. Global scriptfunctions must take two arguments: an entity argument and int threadnum argument. The first argument is the entity that was stimmed. Local response functions (those on the entity being stimmed) should not have the entity argument, only taking one argument, the threadnum. This is because the entity being stimmed is the same as the entity running the script, so the argument is passed implicitly as the "self" entity, just like the "this" pointer is passed implicitly in C++.<br />
<br />
<br />
== Examples ==<br />
=== Damage Stim ===<br />
<br />
An entity has a STIM_DAMAGE with a magnitude of 100 and a linear falloff (1). The further you're away from the stim origin, the smaller the magnitude gets.<br />
<br />
Once an entity with a response to STIM_DAMAGE comes into range and the stim fires, the magnitude is passed on to the response entity. The response entity needs to have a response effect defined for the DAMAGE stim, which tells the code which damage entityDef (e.g. ''atdm:damage_simple'') it should use and which entity should be damaged (this should be ''_SELF'' by default).<br />
<br />
So, an example response setup can be found on the player:<br />
<br />
<br />
// The damage response<br />
"sr_class_3" "R"<br />
"sr_type_3" "STIM_DAMAGE"<br />
"sr_state_3" "1"<br />
"sr_effect_3_1" "effect_damage"<br />
"sr_effect_3_1_arg1" "_SELF"<br />
"sr_effect_3_1_arg2" "atdm:damage_simple"<br />
<br />
<br />
As soon as the player comes into the range of a damage stim, the distance-based magnitude is passed over and the code multiplies this magnitude with the "damage" value defined in atdm:damage_simple. E.g. if a magnitude of 30 is passed, the atdm:damage_simple's value of 10 ends up at 300 => insta-death.<br />
<br />
If you want to have a constant magnitude which is not depending on the distance, you need to define a 0 falloff on the stim.<br />
<br />
=== Remove torch damage if extinguished with water ===<br />
If you have hot torches/ovens that damage the player if too close, but shouldn't if extinguished, first copy the name of the entity that has the damage stim. Then use the Stim/Response editor to add a Water Response, effect "Deactivate Stim", pasting/selecting the entity with the damage stim, and "Damage". (One would want a Fire Response, "Activate Stim" if they wished damage to return if reignited.)<br />
<br />
<br />
[[Category:Editing]]</div>RJFerrethttps://wiki.thedarkmod.com/index.php?title=Objectives&diff=17685Objectives2014-03-07T02:44:12Z<p>RJFerret: /* Using Objectives Creatively */ +multiple marked areas example</p>
<hr />
<div>{{Original_Reference|Ishtvan|4121}} ''additions by greebo''<br />
<br />
This article covers details of the objectives system. Note that mappers can use <br />
DarkRadiant's [[Objectives Editor]] to make it easier to create objectives.<br />
<br />
The objectives system exists to determine when the player has completed the mission. At the highest level, a mission consists of a list of objectives to be completed and boolean logic to determine when the mission has succeeded or failed based on which of the objectives are complete. At the objective level, an objective consists of individual components and boolean logic to determine when the objective is completed or failed. At the component level, each component has a type, a specifier, and arguments. These will be explained fully in the components section.<br />
<br />
= Mission =<br />
Objectives are stored by entities named [[target_tdm_addobjectives]]. Your mission can have several of these but typically you will only want one for all your objectives.<br />
<br />
By default these entities self-trigger (activates themselves) at mission start. If you need to delay this and activate it later (via any trigger entity that can have a target spawnarg) then add the spawnarg ''wait_for_trigger'' with a value of 1.<br />
<br />
When triggered, these entities add objectives to the mission based on their spawnargs.<br />
<br />
Spawnargs governing mission level behavior may be entered on any target_addobjectives. Non-empty spawnargs will be overwritten by the most recently triggered target_addobjectives (FM authors may want to do this if they add an objective later on and want to change the mission success logic to include that objective, for example). The following is a list of the mission-level spawnargs and what they mean:<br />
<br />
== Success/Failure Logic ==<br />
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.<br />
<br />
=== Default Logic ===<br />
*;<tt>mission_logic_success</tt> (string) <br />
:A string of boolean logic applied to individual objective states to determine if the mission succeeds. AND, OR, NOT and parenthesis are available. The FM author can construct strings using these and the integer index for an objective. For example: "1 OR (NOT(2) AND 3)" would complete the mission if either objective 1 is true, or if 2 is false and 3 is true. By default, a mission succeeds when all mandatory objectives are completed.<br />
<br />
*;<tt>mission_logic_failure</tt> (string) <br />
:Boolean logic applied to individual objective component states to determine if the mission has failed. By default, if any mandatory objective fails, the mission fails.<br />
<br />
=== Difficulty Dependent Logic ===<br />
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):<br />
<br />
*;<tt>mission_logic_success_diff_N</tt> (string) <br />
:Defines the success logic for the difficulty level N (override the default logic), e.g. "1 AND 2 AND 3".<br />
*;<tt>mission_logic_failure_diff_N</tt> (string) <br />
:Defines the failure logic for the difficulty level N (override the default logic). When this condition is fulfilled, the mission has failed.<br />
<br />
If specific logic is not specified for a certain difficulty level, the default spawnargs (without _diff_*) will be used.<br />
<br />
= Objectives =<br />
Objectives added by the target_addobjectives each have a unique integer index, starting with objective 1, the first objective. The spawnargs associated with an objective are prefixed in the following manner:<br />
obj<objective index>_<spawnarg name><br />
Example: ''obj3_desc''<br />
<br />
The spawnargs (minus prefix) and meanings for objective attributes are listed below. Each objective also includes a list of components and their attributes, which will be covered in the next section.<br />
<br />
*;<tt>objN_desc</tt> (string) <br />
: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. The default value is an empty string.<br />
<br />
*;<tt>objN_state</tt> (int) Defines the state of the objective at map start. <br />
:'''Possible Objective States:'''<br />
:* 0 = STATE_INCOMPLETE<br />
:* 1 = STATE_COMPLETE<br />
:* 2 = STATE_INVALID<br />
:* 3 = STATE_FAILED<br />
:Code defaults to 0 = incomplete.<br />
<br />
*;<tt>objN_mandatory</tt> (1/0) <br />
:Set to 0 for optional objective that doesn't fail the mission if you fail it. Objective must be completed to complete the mission if 1. Code defaults to 1.<br />
<br />
*;<tt>objN_irreversible</tt> (1/0) <br />
: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.<br />
<br />
*;<tt>objN_ongoing</tt> (1/0) <br />
:If true, this objective is not marked as complete and the player is not informed that it's complete until the end of the mission. Typically used for "do not kill" type objectives, because technically they would be complete right from the beginning, but we don't want to mark them off or tell the player they're complete right at the beginning. Could also be used for "have some item with you when you complete the mission." Code defaults to 0.<br />
<br />
*;<tt>objN_visible</tt> (1/0) <br />
: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 another 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.<br />
<br />
*;<tt>objN_difficulty</tt> (integer)<br />
:Space delimited list of difficulty levels that should include this objective. For example, "2 3" would enable this objective at difficulty levels 2 and 3, but not for other difficulty levels. Default value is empty - the objective applies to all difficulty levels.<br />
:''Note:'' When the objective is not active for a given difficutly, it is invalidated and hidden, but it still exists, so the numbering of the next objective should still increase by 1. E.g., objective 5 only appears on hard difficulty, but you still have to call the next objective objective 6, you can't call it objective 5 only appearing on easy or medium difficulty.<br />
<br />
*;<tt>objN_enabling_objs</tt> (space-delimited integers) <br />
:This is a list of objectives which must 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.<br />
<br />
*;<tt>objN_script_complete</tt> (string)<br />
*;<tt>objN_script_failed</tt> (string)<br />
: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.<br />
<br />
*;<tt>objN_target_complete</tt> (string)<br />
*;<tt>objN_target_failed</tt> (string)<br />
:Name of a target entity to [[Triggers|trigger]] when this objective is completed or failed, similar to the completion/failure script. Only one entity name is allowed here. If you need to trigger multiple entities on objective state change, use a [[Triggers#trigger_relay|trigger_relay]] entity.<br />
<br />
*;<tt>objN_logic_success</tt> (string)<br />
:Boolean logic applied to individual objective component states to determine if the objective is complete. The same boolean logic options are available as in the mission-level logic described above. By default, all of the components must be true to complete the objective. In other words, all components are ANDed together (1 AND 2 AND 3...).<br />
*;<tt>objN_logic_failure</tt> (string)<br />
:Boolean logic applied to individual objective component states to determine if the objective is failed. By default, if an objective is ongoing, and any opponent becomes false, that objective will fail.<br />
<br />
= Objective Components =<br />
Each objective has an associated list of components and spawnargs defining the attributes of those components. These component spawnargs associated with a given objective are prefixed in the following manner:<br />
obj<objective index>_<component index>_<spawnarg name><br />
Example: ''obj1_2_state''<br />
<br />
In the following, the index N defines the objective number and M refers to the component number. Programmers beware that both numbers start from the value 1.<br />
<br />
*;<tt>objN_M_state</tt> (1/0) <br />
:Defines the state of the component at map start, which can only be "1" (complete) or "0" (incomplete). Code defaults to 0.<br />
<br />
*;<tt>objN_M_player_responsible</tt> (1/0) <br />
:When true, the player must be responsible for the events that satisfy this component. Events the player is not responsible for are not counted. (e.g., the player kills an AI vs. another AI killing an AI). Code defaults to 1.<br />
<br />
*;<tt>objN_M_not</tt> (1/0) <br />
:Code defaults to 0. If true, this component is logically NOTed, so when the conditions described by the type and speifiers are not met, the component state is true, and when they are met, it is false.<br />
<br />
*;<tt>objN_M_irreversible</tt> (1/0) <br />
:When the component state changes from its initial state, it will stay in its new state regardless of what happens later. (There is a script event to "unlatch" a latched objective component if needed). Code defaults to 0.<br />
<br />
*;<tt>objN_M_type</tt> (string) <br />
:Defines the type of this objective component. See the section [[#Component_Types|Component Types]] below for detailed information.<br />
:'''Possible 'Objective Component' Types:'''<br />
:* kill (also includes non-living things being destroyed)<br />
:* ko<br />
:* ai_find_item (not implemented)<br />
:* ai_find_body (not implemented)<br />
:* alert<br />
:* destroy (inanimate item destroyed ("killed"))<br />
:* item (picked up or dropped an inventory item)<br />
:* pickpocket (inventory item acquired from conscious AI)<br />
:* 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)<br />
:* custom (custom component that is set true/false by a map script)<br />
:These components are triggered every N milliseconds by a system clock:<br />
:* custom_clocked (runs a custom map script that should check something and set the objective)<br />
:* info_location (Item A at info_location area B) - TODO: more information needed<br />
:* distance (distance between the origin of entity X and that of entity Y)<br />
<br />
Any component can have up to two specifiers, each of which can carry a value. Here, K refers to the number of the specifier, e.g. ("obj2_1_spec4" "name").<br />
*;<tt>objN_M_specK</tt> (string) <br />
:'''Specification Methods:'''<br />
: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). See the section [[#Specifiers|Specifiers]] below for a detailed description.<br />
:'''The following apply to both AIs and items:'''<br />
:* none<br />
:* name (name of entity)<br />
:* overall (overall count of something: kills, loot, kos, etc)<br />
:* group (inventory group)<br />
:* classname (soft/scripting classname)<br />
:* spawnclass (hard / SDK classname, e.g. "idPlayer")<br />
:'''The following specification methods apply only to AI:'''<br />
:* ai_type (human, beast, undead, bot, etc)<br />
:* ai_team (mapper defined team of the AI)<br />
:* ai_innocence (For distinguishing noncombatants)<br />
<br />
*;<tt>objN_M_spec_valK</tt><br />
:Value that the Kth specifier should match in order to count towards this component. (E.g., an entity name if we specify by name.)<br />
<br />
*;<tt>objN_M_args</tt> (space-delimited string) <br />
:'''Integer and String Arguments:'''<br />
: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.<br />
<br />
*;<tt>objN_M_clock_interval</tt> (float/seconds)<br />
:For clocked components like "custom_clocked" this determines how often they are updated. The value is to be set in seconds.<br />
<br />
== Component Types ==<br />
=== AI-Related Components ===<br />
The following specifiers are termed "Standard AI Specifiers": All specifiers minus the <tt>group</tt> specifier.<br />
<br />
;*<tt>kill</tt><br />
:An AI must be killed to satisfy this component.<br />
:'''SDK Name''': COMP_KILL<br />
:'''Number of Specificatons''': 1 (object that must be killed)<br />
:'''Applicable Specifiers''': Standard AI Specifiers<br />
:'''Expected Arguments''': int (number of kills required)<br />
<br />
;*<tt>ko</tt> (Knockout)<br />
:An AI must be knocked out by any means (gas, blackjack, other).<br />
:'''SDK Name''': COMP_KO<br />
:'''Number of Specificatons''': 1 (AI that must be KO'd)<br />
:'''Applicable Specifiers''': Standard AI Specifiers<br />
:'''Expected Arguments''': int (number of KOs required)<br />
<br />
;*<tt>ai_find_item</tt><br />
:''not yet implemented''<br />
:'''SDK Name''': COMP_AI_FIND_ITEM<br />
:'''Number of Specificatons''': --<br />
:'''Applicable Specifiers''': --<br />
:'''Expected Arguments''': --<br />
<br />
;*<tt>ai_find_body</tt><br />
:''not yet implemented'' An AI must find a body. Currently, the specifiers apply to the bodies found, and any AI finding the bodies triggers this component. Future revisions might add another specifier for the AI that finds the body.<br />
:'''SDK Name''': COMP_AI_FIND_BODY<br />
:'''Number of Specificatons''': 1 (Type of body that must be found)<br />
:'''Applicable Specifiers''': Standard AI Specifiers<br />
:'''Expected Arguments''': int (number of bodies that must be found)<br />
<br />
;*<tt>alert</tt><br />
:True if an AI or type of AI is alerted. Use the player_responsible flag to determine if this should count alerts not caused by the player's actions (e.g., enemy AI being sighted)<br />
:'''SDK Name''': COMP_ALERT<br />
:'''Number of Specificatons''': 1 (AI that must be alerted)<br />
:'''Applicable Specifiers''': Standard AI Specifiers<br />
:'''Expected Arguments''': int (number of alerts required), int (minimum alert level that counts: 1-5 with 5 being the combat state)<br />
<br />
=== Non-AI Components ===<br />
<br />
;*<tt>destroy</tt><br />
:An inanimate item must be destroyed (damage it until its health is lower than zero).<br />
:'''SDK Name''': COMP_DESTROY<br />
:'''Number of Specificatons''': 1 (item to be destroyed)<br />
:'''Applicable Specifiers''': all<br />
:'''Expected Arguments''': int (number of items to be destroyed)<br />
<br />
;*<tt>item</tt><br />
:Completed when the player has this inventory item or loot.<br />
:'''SDK Name''': COMP_ITEM<br />
:'''Number of Specificatons''': 1 (item the player must have)<br />
:'''Applicable Specifiers''': All except AI type, team and innocence.<br />
:'''Expected Arguments''': int (number of items to have, 1 by default)<br />
<br />
;*<tt>pickpocket</tt><br />
:An inventory item must be taken from a conscious AI. Note that it doesn't matter what happens to the item after it is pickpocketed. It could be destroyed or dropped, but as long as it was originally pickpocketed, it counts.<br />
:'''SDK Name''': COMP_PICKPOCKET<br />
:'''Number of Specificatons''': 1 (Item the player must pickpocket)<br />
:'''Applicable Specifiers''': All except AI type, team and innocence<br />
:'''Expected Arguments''': int (number of items to pickpocket, 1 by default)<br />
<br />
;*<tt>location</tt> Object in location brush (using info_tdm_objective_location brush)<br />
:A particular item must be in a particular location, defined by an info_objective_location brush. For optimization reasons, the entity or entities to be checked must also have this spawnarg: "objective_ent" set to "1". NOTE: Multiple objects in a single location are not counted up for this component, this is a single-shot objective. If you want the player to put more than one object in a location, you must currently create several of these components, specifying by name, and OR them together in the objective logic.<br />
:'''SDK Name''': COMP_LOCATION<br />
:'''Number of Specificatons''': 2 (object entity to check, location entity to check)<br />
:'''Applicable Specifiers''': For the object to check, all specifiers apply, but multiple objects are not counted up. Typically the objects will be specified by name. For the location to check, it will either be specified by name or by group.<br />
:'''Expected Arguments''': None (if both specifiers match, the objective is completed).<br />
<br />
;*<tt>info_location</tt> Object in location area (using info_location entities)<br />
:A particular item must be in a particular location, defined by an info_location area (see vanilla D3 documentation for info_location). Multiple objects in a single location are not counted up for this component, this is a single-shot objective. If you want the player to put more than one object in a location, you must currently create several of these components, specifying by name, and OR them together in the objective logic.<br />
:This check is done periodically. Set spawnarg <tt>clock_interval</tt> to the time in seconds between periodic checks.<br />
:'''SDK Name''': COMP_INFO_LOCATION<br />
:'''Number of Specificatons''': 2 (object entity to check, location entity to check)<br />
:'''Applicable Specifiers''': For the object to check, all specifiers apply, but multiple objects are not counted up. Typically the objects will be specified by name. For the location to check, it will either be specified by name or by group.<br />
:'''Expected Arguments''': None (if both specifiers match, the objective is completed).<br />
<br />
;*<tt>custom</tt><br />
:This custom objective component is only changed when an external script changes it. Otherwise it does nothing.<br />
:'''SDK Name''': COMP_CUSTOM_ASYNC<br />
:'''Number of Specificatons''': none<br />
:'''Applicable Specifiers''': none<br />
:'''Expected Arguments''': none<br />
<br />
;*<tt>custom_clocked</tt><br />
:This component calls a custom script periodically to check some condition. When run, the script is expected to this component true or false based on the custom check. This objective component could also be used as a convenient method to periodically call a script that has nothing to do with objectives.<br />
:Set spawnarg <tt>clock_interval</tt> to the time in seconds between periodic calls of the script.<br />
:'''SDK Name''': COMP_CUSTOM_CLOCKED<br />
:'''Number of Specificatons''': none<br />
:'''Applicable Specifiers''': none<br />
:'''Expected Arguments''': string (name of the script to call periodically)<br />
<br />
;*<tt>distance</tt><br />
:Two entities must be sufficiently close to eachother to satisfy this component. The distance check is done between the origin of the first object and that of the second object. If this distance is below the input maximum distance, the component is set to true.<br />
:This check is done periodically. Set spawnarg "clock_interval" to the time in seconds between periodic checks.<br />
:'''SDK Name''': COMP_DISTANCE<br />
:'''Number of Specificatons''': none (see arguments below)<br />
:'''Applicable Specifiers''': none<br />
:'''Expected Arguments''': string (name of first entity), string (name of second entity), int (maximum distance in doom units)<br />
<br />
;*<tt>readable_opened</tt><br />
:''available since TDM 1.02''<br />
:The player must open a named readable to satisfy this component. This doesn't refer to a specific page, just opening the readable is enough.<br />
:'''SDK Name''': COMP_READABLE_OPENED<br />
:'''Number of Specificatons''': 1 (The name of the readable)<br />
:'''Applicable Specifiers''': name<br />
:'''Expected Arguments''': none<br />
<br />
;*<tt>readable_closed</tt><br />
:''available since TDM 1.02''<br />
:The player must close a named readable to satisfy this component. This doesn't check whether the player has finished reading all pages, just closing the previously opened readable is enough.<br />
:'''SDK Name''': COMP_READABLE_CLOSED<br />
:'''Number of Specificatons''': 1 (The name of the readable)<br />
:'''Applicable Specifiers''': name<br />
:'''Expected Arguments''': none<br />
<br />
;*<tt>readable_page_reached</tt><br />
:''available since TDM 1.02''<br />
:The player must open/read a specific page of a named readable to fulfil this component. Scrolling to the page is enough to trigger this event.<br />
:'''SDK Name''': COMP_READABLE_PAGE_REACHED<br />
:'''Number of Specificatons''': 1 (The name of the readable)<br />
:'''Applicable Specifiers''': name<br />
:'''Expected Arguments''': int (the page number which should be reached, the number 1 refers to the first page)<br />
<br />
== Specifiers ==<br />
;*<tt>none</tt> <br />
:No specifier. Component will be completed as soon as any event of that component type happens. (E.g., if you set a KO component type, with specifier none, it would be set to true as soon as soon as the player KO's anyone). This is the default specifier if none is entered. Not very useful, except for blanket "don't do this" objectives. Even then, it is better to use "overall" described below.<br />
:'''SDK Name''': SPEC_NONE<br />
:'''Specifier Argument Type Expected''': No spec argument needed since we don't have to match anything.<br />
<br />
;*<tt>name</tt> <br />
:Name of the entity<br />
:'''SDK Name''': SPEC_NAME<br />
:'''Specifier Argument Type Expected''': string<br />
<br />
;*<tt>overall</tt> <br />
:In the context of inventory item objectives, this refers to overall loot. In the context of AI objectives, this refers to all AI, regardless of team, type, etc.<br />
:'''SDK Name''': SPEC_OVERALL<br />
:'''Specifier Argument Type Expected''': No spec argument needed since we don't have to match anything.<br />
<br />
;*<tt>Group</tt> <br />
:For inventory items, the item's <tt>inv_name</tt> spawnarg value will be used here. For example, if you want the player to get 5 flashbombs, you would use this with group equal to the <tt>inv_name</tt> of flashbombs. As opposed to getting a specific flashbomb in the map, where you would use the <tt>name</tt> specifier instead. If an inventory item is loot, the loot group is used here instead (e.g., <tt>loot_gold</tt>).<br />
:Group is also used for other component types as a convenient way to group things, such as info_objective_location or info_location entities checked by COMP_LOCATION and COMP_INFO_LOCATION, respectively.<br />
:'''SDK Name''': SPEC_GROUP<br />
:'''Specifier Argument Type Expected''': string<br />
:'''Loot group names:''' <tt>loot_gold</tt>, <tt>loot_goods</tt>, <tt>loot_jewels</tt> and <tt>loot_total</tt><br />
<br />
;*<tt>Classname</tt> <br />
:The entityDef classname of the entity. For example: atdm:ai_builder_guard<br />
:'''SDK Name''': SPEC_CLASSNAME<br />
:'''Specifier Argument Type Expected''': string<br />
<br />
;*<tt>Spawnclass</tt> <br />
: The SDK classname of the entity. For example: idAI<br />
:'''SDK Name''': SPEC_SPAWNCLASS<br />
:'''Specifier Argument Type Expected''': string<br />
<br />
;*<tt>ai_type</tt> <br />
:Type of AI: human, beast, undead, steambot, etc. (reads m_AIType in the SDK, which is set by the "type" spawnarg on idActors. Not sure if this is implemented yet).<br />
:'''SDK Name''': SPEC_AI_TYPE<br />
:'''Specifier Argument Type Expected''': int<br />
<br />
;*<tt>ai_team</tt> <br />
:The AI's team integer. This can be set up by the mapper to put AI on arbitrary teams. Mapper can also team up AI for objective purposes, and use this team specifier as a fast way of saying "KO any of these 5 AI." Alternatively, one could use the name specifier and put in multiple components for each of those 5 AI, then OR all the components in the objective success logic. Making a new team may save time over that method.<br />
:'''SDK Name''': SPEC_AI_TEAM<br />
:'''Specifier Argument Type Expected''': int<br />
<br />
;*<tt>ai_innocence</tt> <br />
:Differentiates between combatants and non-combatants. A value of 1 = non-combatant, a value of 0 => non-combatant, or otherwise not deemed "innocent" by the FM author.<br />
:'''SDK Name''': SPEC_AI_INNOCENCE<br />
:'''Specifier Argument Type Expected''': int (1 = innocent, 0 = not)<br />
<br />
= Objective Conditions =<br />
With the campaign code added to TDM 1.06 a new set of spawnargs can be used to let objectives depend on those in a previous mission. These spawnargs are starting with the <tt>obj_condition</tt> prefix.<br />
<br />
Each condition defines the "source" mission and the source objective by number, plus the state of the source objective. It also needs to specify the "target" objective (which is always in the current mission) by number and which action to take. Right now, three different actions are supported: <br />
* Change Objective State (complete, failed, etc.)<br />
* Change the Objective's Visibility (hide or show)<br />
* Change the Objective's Mandatory Flag<br />
<br />
== Syntax ==<br />
<br />
*;<tt>obj_condition_N_src_mission</tt> (integer) <br />
:Defines the source mission the condition depends on. The integer is 0-based, i.e. the first mission has the number 0. The placeholder N is the number of the condition.<br />
<br />
*;<tt>obj_condition_N_src_obj</tt> (integer) <br />
:Defines the number of the source objective in the source mission. The integer is 0-based, i.e. the first objective has the number 0. The placeholder N is the number of the condition.<br />
<br />
*;<tt>obj_condition_N_src_state</tt> (integer) <br />
:Defines the state the source objective needs to be in for this condition to apply. The value can be in the same range as the objN_state spawnarg above:<br />
:* 0 = STATE_INCOMPLETE<br />
:* 1 = STATE_COMPLETE<br />
:* 2 = STATE_INVALID<br />
:* 3 = STATE_FAILED<br />
<br />
*;<tt>obj_condition_N_target_obj</tt> (integer) <br />
:Defines the number of the target objective in the current mission. The integer is 0-based, i.e. the first objective has the number 0. The placeholder N is the number of the condition.<br />
<br />
*;<tt>obj_condition_N_type</tt> (string) <br />
:Defines the action to take if the condition applies. There are three possible action types available:<br />
:* "changestate" Change the state of the target objective.<br />
:* "changevisibility" Change the visibility of the target objective.<br />
:* "changemandatory" Change the mandatory flag of the target objective.<br />
:The combination of this "type" spawnarg and the "value" spawnarg below defines exactly what action is performed on the target objective.<br />
<br />
*;<tt>obj_condition_N_value</tt> (integer) <br />
:The meaning and possible values of this spawnarg depend on the "type" spawnarg above. It is used as "parameter" or "argument" for the above action, e.g. the "changevisibility" action needs to know whether to show or hide the target objective. The possible values are listed below:<br />
:* For type "changestate"<br />
:** 0: set to incomplete<br />
:** 1: set to complete<br />
:** 2: set to invalid<br />
:** 3: set to failed<br />
:* For type "changevisibility"<br />
:** 0: set to invisible<br />
:** 1: set to visible<br />
:* For type "changemandatory"<br />
:** 0: clear mandatory flag<br />
:** 1: set mandatory flag<br />
<br />
= Conclusion =<br />
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.<br />
<br />
= Using Objectives Creatively =<br />
<br />
==A method for using objectives to change AI patrols when alert.==<br />
<br />
This works beautifully. The AI are placed at the seats just like in the card player prefab. Each player have "sitting 1" so they sit down at map start. AI's have no targets.<br />
<br />
Then I have one unseen objective per player:<br />
Objective component is only "AI is alerted", with the single entity card playing AI name. I can set the minimum alert level required for the AI to react. I set that to 3, so if the AI search actively, he won't be playing cards anymore, but goes patrolling instead.<br />
Basically the objective component says: "Alert entity cardgamer1 1 times to a minimum alert level of 3."<br />
<br />
And when that gets satisfied, the objective has completion target gopatrol_start, which is an ordinary trigger_once. This in turn targets a func_static which gives all the cardgamers new targets to their patrol routes. <br />
<br />
This is done as follows: Choose any kind of func_static. Open it in the Stim&Response editor. Add response trigger. Add an effect to this response. Choose "Add Target." Put in the entity box the name of the AI. Put in the target box the name of the path_node where the AI should go.<br />
<br />
When I make one objective for each player, alerting any single one of them will make everyone of them to go for patrol. And once the trigger_once is gone, further alerting of the AI has no effect.<br />
<br />
==A way to replace AI when others are knocked out or killed.==<br />
<br />
Have spare AIs isolated in an inaccessible place either of your map, or room off in the void, targeting a path_waitfortrigger which then carries on their path. Have the AI subject to substitution on a unique team in your map (or identify another way), as well as the spare AIs. An objective is set up like the usual fail if you knock out or kill an AI, but not visible, set to the appropriate team. I found I needed multiple Objective Components, the first no knock/no kill set to an amount of one. Then two and three, etc. Take note of what objective number the objective is and plan on not altering that. Set the failure target to a trigger relay, which targets as many trigger_counts as you have replacement AI. That's it for setting up the objective part.<br />
<br />
Add the aforementioned trigger relay, trigger_counts, and a target_setobjective_state. Setup the target_setobjective_state with "Obj_id0" #, where # is the objective number noted earlier, and set "obj_state" to "0". Add a matching number of atdm:teleport (in target/) as trigger_counts, each teleport targeting one of the stored AI. The first trigger_count is set to 1, and targets the first teleport and AI (to release it from the path_waitfortrigger). The second trigger_count is set to 2, and targets the next teleport and AI, etc. The trigger_relay targets all the trigger_counts and the target_setobjective_state.<br />
<br />
So when the initial AI is knocked out or killed, the objective failure triggers the relay. It in turns increments the counts and resets the objective to work again. The first count activates the teleport and triggers the AI to move off it's path_waitfortrigger on to the next path node. Test and voilà!<br />
<br />
==Having the player place multiple interchangeable items in varied places.==<br />
<br />
In "{{TDM-FM|83|Inn Business}}", the player has to place a number of markers in any of several places. However it was key to not permit multiple markers being placed in the same place, and not all places are required, between half and two-thirds so there's flexibility for various players and their styles.<br />
<br />
An "item is in location" with "group identifier" component was used, so each spot (info_tdm_objective_location) had the same spawnarg "objective_group", "drops". Also "interval" was set to "0.3", with no noticeable performance issue while being responsive enough for player feedback. These locations were separate enough, but limited in size, to meet the restrictions below.<br />
<br />
So a number of objectives matching the number of inventory items were made, with several components. <br />
* let the target entity ''marker1'' be at location 0 of ''drops''<br />
* Do NOT let the entity ''marker1'' and ''marker2'' get within 150 units (check interval 0.3)<br />
* Do NOT let the entity ''marker1'' and ''marker3'' get within 150 units (check interval 0.3)<br />
* Do NOT let the entity ''marker1'' and ''marker4'' get within 150 units (check interval 0.3)<br />
* etc., depending how many marker entities there are<br />
<br />
The other objectives were set up the same way but for their own ''marker#''. (IE, don't let 2 and 1 get within..., don't let 2 and 3, etc.) In this manner, the objective checks if the marker is within the area, but unchecks if the maker rolls out or is removed by the player, and rechecks when they put it back in. <br />
<br />
Finally, another objective was created to complete when all had been placed which is not visible but irreversible. It has Enabling Objectives of the former objectives AND together. IE, "9 AND 10 AND 11 AND 12" if there are four. It has a completion target of a [[Triggers#trigger_relay|trigger relay]] entity which targeted several "atdm:target_setobjective_visibility" to turn off all the marker objectives and enable other mission specific things.<br />
<br />
The components match the markers, again using the group identifier:<br />
* let the target entity ''marker1'' be at location 0 of ''drops''<br />
* let the target entity ''marker2'' be at location 0 of ''drops''<br />
* let the target entity ''marker#etc...'' be at location 0 of ''drops''<br />
<br />
So if all the marker objectives are complete (all items dropped in separate spots), then this completes and fires the trigger, which removes all the marker objectives from display (which the player had for feedback of progress) and moves on with objectives, perhaps displaying a dummy completed objective "All markers placed."<br />
<br />
Note: It's important for the marker objective numbers in the objective editor not to change, or update the non visible completion objective AND logic accordingly.<br />
<br />
<br />
[[Category:Editing]]<br />
[[Category:Tutorial]]</div>RJFerrethttps://wiki.thedarkmod.com/index.php?title=Relighting_Lights&diff=17682Relighting Lights2014-03-06T19:24:59Z<p>RJFerret: /* See also */ +wikilink</p>
<hr />
<div>==Overview==<br />
<br />
Starting with '''[[What%27s_new_in_TDM_1.06|v1.06]]''', TDM supports AI relighting lights. A previous version of TDM supported this in a rudimentary way, but interim versions lost that capability.<br />
<br />
In general, the human AI in TDM notice when a light that's been on suddenly goes out. They might simply comment on this, or they might try to relight the light. The mapper has control over which lights can be relit, which arouse suspicion when they've gone out, and which can be ignored. This gives the mapper another tool to enhance the atmosphere of their map.<br />
<br />
The code for this was kindly contributed by '''grayman'''.<br />
<br />
==AI Spawnargs==<br />
<br />
Most lights in TDM can be relit if they go out. However, it's not in the player's interest if every wall torch they douse with a water arrow gets relit a moment later by a passing AI. For the player's benefit, TDM uses AI spawnargs to control relight behavior.<br />
<br />
* '''chanceNoticeLight:''' The probability that an AI will comment that a light has gone out. (From 0.0 to 1.0)<br />
* '''canLightTorches:''' Whether an AI can relight doused flames. (1 = yes, 0 = no)<br />
* '''canOperateSwitchLights:''' Whether an AI can turn on electric lights that have gone out. (1 = yes, 0 = no)<br />
* '''chanceLightTorches:''' Once an AI has passed the ''chanceNoticeLight'' check, this is the probability that he'll try to relight a doused flame. (From 0.0 to 1.0) <br />
* '''chanceOperateSwitchLights:''' Once an AI has passed the ''chanceNoticeLight'' check, this is the probability that he'll try to turn on an electric light that has gone out. (From 0.0 to 1.0) <br />
<br />
The default settings for these spawnargs on human AI are:<br />
<br />
<pre><br />
chanceNoticeLight 0.9<br />
<br />
canLightTorches 1<br />
<br />
canOperateSwitchLights 1<br />
<br />
chanceLightTorches 0.4<br />
<br />
chanceOperateSwitchLights 0.7<br />
</pre><br />
<br />
In all cases but one, if an AI fails to make a relight attempt, he'll ignore the light for at least 15 seconds. The exception is when he doesn't have a direct line of sight to the light. See the '''Line of Sight''' section below.<br />
<br />
Certain AI override these defaults. For example, revenants and zombies couldn't care less when lights go out, so their ''chanceNoticeLight'' spawnarg is set to 0.<br />
<br />
When you add an AI to your map, override these defaults as needed to change the AI's relight behavior.<br />
<br />
==Light Spawnargs==<br />
<br />
Lights use these spawnargs to define how they're treated by the AI:<br />
<br />
* '''shouldBeOn:''' Controls AI response to a light going out. (0, 1, or 2. See description below.)<br />
* '''AIUse:''' Set to AIUSE_LIGHTSOURCE for light sources.<br />
* '''lightType:''' Set to AIUSE_LIGHTTYPE_TORCH for flames or AIUSE_LIGHTTYPE_ELECTRIC for electric lights.<br />
<br />
The default settings for these spawnargs are:<br />
<br />
<pre><br />
shouldBeOn 0<br />
<br />
AIUse AIUSE_LIGHTSOURCE<br />
<br />
lightType AIUSE_LIGHTTYPE_TORCH (for flames)<br />
<br />
lightType AIUSE_LIGHTTYPE_ELECTRIC (for electrics)<br />
</pre><br />
<br />
==shouldBeOn==<br />
<br />
A light's ''shouldBeOn'' spawnarg defines how AI will respond to its going out.<br />
<br />
* '''0''' - Comment that the light has gone out, but don't relight it.<br />
* '''1''' - Comment that the light has gone out, and try to relight it. If discovered w/in 10 seconds of when it went out, increase suspicion that an intruder might be present.<br />
* '''2''' - Comment that the light has gone out, and try to relight it. Increase suspicion that an intruder might be present.<br />
<br />
''shouldBeOn'' can be set on light holders. For example, a candle is a candle flame entity bound to a candle model. The candle entity is what you place in your map, and since you can't directly change the ''shouldBeOn'' spawnarg on the flame, you need to set it on the candle. This is true for all compound entities that spawn lights, from candles to fireplaces.<br />
<br />
If you want AI to completely ignore a light (not even comment when it goes out), put the following spawnarg on it:<br />
AI_USE ""<br />
<br />
==Light Switches==<br />
<br />
Some lights, for example the desk lamp, are turned on/off by frobbing them directly. For lights that have a switch, AI will use the switch. If more than one switch can turn a light on/off, AI will use the nearest. Though AI need a direct line of sight to the light to notice that it's out, they don't need a direct line of sight to a switch. The switch can be behind a door, around a corner, or even on a different floor. Wherever it is, if AI can walk to it, they'll use it.<br />
<br />
==Height of Light==<br />
<br />
When a light is high off the floor (or ground), AI reach up to perform the relight. For the animation to look as real as possible, don't place relightable lights more than 100 off the floor. AI will not try to relight lights higher than that. The same applies to switches: a switch more than 100 off the floor won't be used.<br />
<br />
==Relight Position==<br />
<br />
If you find that relight positions determined by TDM aren't working--perhaps you have a complex light design--you can use a ''relight_position'' entity (darkmod/Lights/atdm:relight_position).<br />
<br />
Place this at the spot where you want the AI to stand when relighting. One requirement is that its horizontal distance from the light be no more than 68. Link it to the light by adding a ''target'' spawnarg on the light, with its value set to the name of the ''relight_position''. You can define multiple relight positions (''target1'', ''target2'', etc.) and TDM will select the one that's nearest to the AI at relight time.<br />
<br />
You can't assign a ''relight_position'' to a movable light, for example a candle. If you pick the light up, or knock it over, the relight position won't change. Because of this, TDM will ignore all ''relight_positions'' targeted by the light, and will instead determine a relight standing position based on where the movable light currently is.<br />
<br />
==Line of Sight==<br />
<br />
If an AI doesn't have direct line of sight (LOS) to a light that's out, he won't apply the "wait 15 seconds" rule. This lets him comment on a light the moment he establishes LOS, and it also lets him deal with situations where--because of the AI's orientation to the light--something surrounding it is momentarily blocking LOS. For example, LOS to a flame entity inside the basket of a gothic wall torch might hit a basket tine on one attempt (fail), and pass between tines the next (pass). Moving the light entity slightly (especially up) should increase the odds of establishing LOS in these cases. <br />
<br />
==Unreachable Lights==<br />
<br />
When a light can't be reached to be turned back on, we don't want patrolling AI to incessantly comment on the light being out. Over time, the number of comments will dwindle, then stop.<br />
<br />
==AI Don't Need a Torch==<br />
<br />
An AI that isn't carrying a torch can still relight doused flames. New animations allow him to pull a tinderbox from his belt to get the job done.<br />
<br />
== Electric Lights ==<br />
<br />
If you construct an electric light using the basic light entity (''light'') and an electric light model, the AI won't try to relight it if it goes out. This may or may not change in a future rev.<br />
<br />
If you want AI to notice that an electric light has gone out, use one of the electric light entities in '''darkmod/Lights/Switchable/Electric/Flickering/'''. These entities use both lit and unlit model skins to match the light state, which makes them preferable to roll-your-own electric lights.<br />
<br />
== See also ==<br />
<br />
* [[Electric Lights]]<br />
* [[Light Properties]]<br />
<br />
{{ai}} {{editing}}</div>RJFerrethttps://wiki.thedarkmod.com/index.php?title=Light_Properties&diff=17681Light Properties2014-03-06T19:23:49Z<p>RJFerret: /* Further reading */ +wikilink/formatting</p>
<hr />
<div>'''''NOTE: <br>This is a first-draft article. It has not yet undergone quality control, so take information with a grain of salt <br> as it is subject to change '''''<br />
<br />
== Introduction == <br />
<br />
For Doom 3 (and subsequently, The Dark Mod), there are 4 different types of lights at our disposal. Each has their own advantages and drawbacks, and hopefully this article will help to familiarize The Dark Mod hopefuls with their use. For information on creating lights and a lot of other useful information, see [[A - Z Beginner Full Guide Start Here!]]<br />
<br />
*<br />
<br />
{{clear}}<br />
<br />
==Light Volume Properties==<br />
<br />
=== Point Light ===<br />
<br />
A point light is the default light (also the default for fog). No option must be checked to make a light a point light. A point light casts light, and subsequently shadows in all directions evenly, falling off after a distance defined by the light texture. This works best for most small indoor and outdoor lighting, like lamps, candles, fireplaces etc. For this reason, it is going to be the most used type.<br />
<br />
* Note, a misconception about Point Light is that they project spherically. The box shaped bounding volume in Dark Radiant is no mere simplification, it is the literal area affected by the light for calculation purposes. Point Light volumes should be perceived as cylindrical prisms that on one axis are shaped by the silhouette of the [[Light_Properties#Lighting_Textures | projection texture]] (think of a stack of cheese cut with a cookie cutter) and the other axis (z-axis) traditionally determines the distance from origin brightness (usually vertical... or how tall you make your cheese stack) with the LightFalloffImage.<br />
<br />
=== Projected Light ===<br />
<br />
Projected light is just as the name suggests. It is probably more intuitive and easier to use than a parallel light and is better for things like projecting a window-shaped light on the floor of a room or a spotlight on a wall. To make one, select projected instead of the default omni option at the top of the light inspector. <br />
<br />
This creates a triangular prism as the bounding box for the light (instead of a rectangular prism like a regular light), with the point ending right at the entity itself. This can be rotated using any of the XYZ rotation buttons or manually using DarkRadiant’s rotation tool (shortcut R). <br />
<br />
You can also manipulate the projected light via the vertices (shortcut V to enable vertices dragging). By dragging the vertices in the center of the projected square, you can lengthen and change the angle of the projection while keeping the projected square the same size. To resize the projection, use the two side vertices in the correct XYZ grid view. Making the bounding box flat against a surface (like a floor) is usually unnecessary (for example, making a moonlight window light on a floor or wall), because with shadows enabled and making the projection long enough to intersect the plane on which the shadow is to be cast, the full shadow will be cast (its simple geometry and just requires minor toying). <br />
<br />
As with all the lights, projected lights have a full range of color and texture options to let the mapper find just the effect they need, allowing you to create a great atmosphere for your map.<br />
<br />
<br />
=== Parallel Light ===<br />
<br />
A light is said to be parallel when the parallel checkbox is checked in the light inspector. It is subject to all the same options as a point light, but it has a few distinct differences. A parallel light tends to not care exactly where the entity itself is placed. The most important thing is where the light_center vertex is placed and where the light entities bounding box intersects with elements in your map. <br />
<br />
The light_center vertex starts right in the middle of the entity. The main difference between the parallel and point lights is that a parallel light does not radiate from the origin around the entity itself. What controls the direction that shadows are cast is the placement of the light_center vertex. Shadows will run parallel (hence the name) to a line between this vertices and the light entity itself. As such, this makes it an excellent choice for sunlight or moonlight. As such, it has some of the elements of a point light and a projected light, it can seem to radiate in a circle (if you use the appropriate texture) whilst casting a shadow in any direction preferred. <br />
<br />
Switch to Vertex mode in [[DarkRadiant]] to drag the light_center vertex of your selected light entity.<br />
<br />
Posted by Greebo: Also, note that a parallel light will only light surfaces "matching" the direction of the "light vector" <br>(origin minus light_center). All other surfaces will stay completely unlit, therefore it should be combined with an ambient light to <br>achieve good lighting effects. [http://modetwo.net/darkmod/index.php?s=&showtopic=8091&view=findpost&p=159842]<br />
<br />
What this means is, you can draw a line from the center vertex to the light entity's origin and on from there, and only objects in the direction of that line will be lit. The light won't light 4 walls of a room and the floor, it would only light one of the walls or the floor (or ceiling)<br />
<br />
==== Troubleshooting Parallel Lights ====<br />
<br />
''I added a parallel light but I can’t see any light at all!''<br />
<br />
Parallel lights can have some quirks. The light seems to fail and do nothing when intersecting multiple walls that are parallel to the face the light is actually casting on. It seems the light will work as long as it doesn’t intersect a face parallel to the one it is casting light on. <br />
<br />
''I have a parallel light but it casts a jagged light on my floor!''<br />
<br />
Similar to above, a parallel light can sometimes have anomalies when intersecting multiple walls and a floor. Since having the light intersect multiple walls when it can only cast on one of them, having a massive bounding box is pointless anyways so pay attention to what the light is touching and you should be fine.<br />
<br />
*<br />
<br />
{{clear}}<br />
<br />
==Light Interaction Properties==<br />
<br />
=== Normal Light ===<br />
<br />
This is the default light type. It performs all the surface interaction stages and shadow calculations. It has the heaviest performance impact.<br />
<br />
=== Ambient Light ===<br />
<br />
Ambient light is really just a lighting texture, but it is also a specific item that is needed in practically every map, so for those purposes it will be treated as if it were its own subset of lights.<br />
<br />
Properties: No shadows, No specular, Bumpmapping or Directionality (Note: The "Enhance Ambient" does add Bumpmapping )<br />
<br />
Use the ambientLight keyword.<br />
<br />
An ambient light can be any form: it can be a point, parallel or even projected (though projected would probably be useless). <br />
<br />
The only requirement of an ambient light is to use one of the available ambient light textures, accessible by opening the light inspector (with the shortcut L in DarkRadiant, and get used to using it), and selecting ambientlightnfo from the list.<br />
<br />
<br />
* Ambient Light is covered in more detail in [[A_-_Z_Beginner_Full_Guide_Page_2#Ambient_Light:_Gloom_not_Doom| Ambient Light: Gloom not Doom]]<br />
<br />
* To understand The Dark Mod's unique ambient light detection system see: [[Virtual Darkness]]<br />
<br />
* Ambient Light can be set to automatically adjust color and brightness per "location" see: [[Location Settings]] and [[Dynamic ambient light]]<br />
<br />
=== Fog Light ===<br />
<br />
This applies Doom 3's style distance fog to a light volume. The texture applied will become more opaque with distance away from the viewer. There is a variant called No Portal Fog which will not apply opaque fog to Portal areas in view. ( [[A_-_Z_Beginner_Full_Guide_Page_3#Fog|Beginner Tutorial: Fog]] )<br />
<br />
In rare cases, you may wish for some surface inside a fog-volume to be fog-free. You can use the "noFog" keyword in the material definition for the texture applied to this surface to keep it from being "fogged".<br />
<br />
Very thin fog (or BlendLight ) can also be used to soften the apparent light interactions near surfaces in a similar manner to the Post Process shader effect but with more mapper control. You can fake certain radiosity effects simply by amplifying small ambient light with small thin fog volumes. <br />
<br />
Use the fogLight keyword.<br />
<br />
=== Blend Light ===<br />
<br />
Blend lights can be considered to be like volumetric decals. They do not perform most of the interaction shader operations and merely apply a texture to a volume using an [http://www.modwiki.net/wiki/Blend_%28Material_stage_keyword%29 OpenGL Blend Mode]. Blend lights have the least performance impact. Blend lights can also be used to create [http://www.doom3world.org/phpbb2/viewtopic.php?f=1&t=12256&start=0&st=0&sk=t&sd=a "negative light"]. <br />
<br />
Use the blendLight keyword.<br />
<br />
<br />
----<br />
<br />
<br />
=== Spectrum ===<br />
<br />
You may use the "spectrum" keyword to isolate specific lights to specific materials which have the same spectrum value in their material definition.<br />
[http://web.archive.org/web/20080704080454/http://www.modwiki.net/wiki/Spectrum_%28Material_global_keyword%29 Spectrum Keyword at Modwiki]<br />
<br />
<br />
----<br />
<br />
<br />
*<br />
<br />
{{clear}}<br />
<br />
== Light Settings ==<br />
There are several settings with which to customize your lights. These settings allow the mapper to customize the look of a light (or a combination of lights) into a near infinity of looks. All are accessed through the light inspector (shortcut of L in DarkRadiant)<br />
<br />
=== Color ===<br />
<br />
The color palette allows the mapper to pick the color of the light emitted, arguably one of the most useful controls the mapper has over a light. To access it, click the button under the “Colour” heading. From there, adjust the settings until you find a correct color (can take some trial and error). In a game like The Dark Mod or Doom 3, where darkness is often more prevalent than light, the color picked often needs to be darker than expected. Without a direct brightness option, the color takes on this task. For a low level ambient light, the color picked would be almost pitch black. A pitch black light would not cast any light, but anything less than pitch black will cast a faint light. As such, it can take some trial and error to find the correct light for a situation, as intiailly, one is likely to pick a seemingly correct color only to find it is far too bright. <br />
<br />
Remember: changing light settings or adding lights (and models) does not require re-compiling the map!<br />
<br />
=== Radius ===<br />
The 'radius' of your light can be changed by dragging its corners around in the 2d windows. Doom 3 lights do not have an actual radius, they are actually square lights and will light up everything they touch inside their bounding box in the editor. They will evenly light everything to their edges. While square lights might seem fairly odd there are options to make them more believable and have a nice fade, namely the 'texture' applied.<br />
<br />
Tip: you can rotate a light so only one corner will touch a wall and make a triangular shaped light. <br />
<br />
Or rotate it so 2 corners touch a wall and make a line of light.<br />
<br />
'''Changing Radius of Light Entity:'''<br />
<br />
If you put a premade light entity into your map, the radius of the light won't be visible. <br />
<br />
To change it, use the following syntax (and whichever value you wish):<br />
<br />
<pre><br />
<br />
"set _color on flame" "0.9 0.8 0.7"<br />
"set light_radius on flame" "250 250 250"<br />
<br />
</pre><br />
<br />
With lanterns and such use 'light' and with torches and candles etc use 'flame'.<br />
<br />
<pre><br />
<br />
"set _color on light" "0.9 0.8 0.7"<br />
"set light_radius on light" "250 250 250"<br />
<br />
</pre><br />
<br />
(Copied from Baddcog's old "Lighting A to Z" article)<br />
<br />
=== Parallel === <br />
<br />
Selecting this option turns the light into a parallel light (as opposed to a point or projected light). See [[Light Properties#Parallel Light|Parallel Light]]<br />
<br />
=== Do not cast shadows (fast) ===<br />
<br />
As the name suggests, this setting causes the light to not cast shadows on any object. This can cause the light itself to not be confined by walls, which can sometimes be beneficial and sometimes not. The main purpose of enabling this option is performance. Shadows are processor intensive and are not needed in some cases, so removing them wherever not beneficial to gameplay can vastly improve performance. Note that ambient lights never cast any shadows. Another way to improve performance similarly is to set the entity property on a model or func_static (this doesn’t work on worldspawn) <tt>noshadows</tt> to 1.<br />
<br />
* '''Further details''': [[Turning Shadows Off]] , [[Noselfshadows]]<br />
<br />
=== Skip Specular Lighting ===<br />
<br />
Specular Lighting refers to a texture's specular map, wherein a flat surface (such as a wall) is painted with a texture that has a specular component. This causes a surface to have shinier and duller parts on a flat surface based on the darkness of the corresponding location on the specular map. Not all textures have specular maps. Checking this option could improve performance or remove the effect if it is not wanted. [http://www.modwiki.net/wiki/Texturing#Specular_maps]<br />
<br />
=== Skip Diffuse Lighting ===<br />
<br />
Like Specular lighting, diffuse lighting also references an attribute of a texture, the Diffuse Map. Diffuse Maps determine the intensity and color of the light reflected off of the different elements of a texture (an example being the difference between bricks and the mortar in between, as well as different bricks having different properties as well giving a less bland appearance). <br />
[http://www.modwiki.net/wiki/Texturing#Diffuse_maps]<br />
<br />
*<br />
<br />
{{clear}}<br />
<br />
<br />
== Chandeliers ==<br />
<br />
Typically chandeliers are setup with multiple particle flames, but just one light entity (for better performance). Bind the candles to the chandelier, then if one is doused, all will extinguish. (See the prefab for an example.)<br />
<br />
<br />
== Lighting Textures ==<br />
<br />
[[Image:LT_Projectedlight.png|400px|thumb|Rich_is_Bored's Example]]<br />
<br />
The lighting textures are also accessed in the light inspector. <br />
<br />
<br />
<br />
Lights can be modified by two different texture types:<br />
<br />
* Projection Image - This is the texture that is projected on the surface<br />
* LightFalloffImage - This texture varies the intensity of the light through the volume along the Z Axis <br />
* (Notes: While the Falloff Image is a 2D texture it is rendered as 1D (one dimensional). You will notice that almost all Falloff Images are thin strips with perpendicular stripes. Traditionally, Falloff will be used to diminish the light with distance to the source but you can violate the physics of real lights and have the intensity increase with distance or vary intensity from bright to dim to bright... etc. )<br />
<br />
<br />
----<br />
<br />
<br />
These textures allow the mapper to change the intensity and falloff of a light. <br />
<br />
Light textures with the addition of material keywords like [http://www.modwiki.net/wiki/Scroll_%28Material_stage_keyword%29 scroll],[http://www.modwiki.net/wiki/Rotate_%28Material_stage_keyword%29 rotate], etc. will grant lights the ability to animate and produce special effects such as; <br />
<br />
* A moving light for a fireplace <br />
* A candle or torch<br />
* A light flickering along with sound volume. <br />
<br />
One can also apply a fog texture to the light (the only way built into Doom 3 to create fog). Color is of a similar concern when [[A_-_Z_Beginner_Full_Guide_Page_3#Fog|creating fog]], as noted in [[Light Properties#Color|Color]]<br />
<br />
{{clear}}<br />
<br />
* A typical "Light Shader" [http://www.iddevnet.com/doom3/materials.php material] definition<br />
<br />
<pre><br />
<br />
lights/My_Custom_Light1<br />
{<br />
<br />
lightFalloffImage makeIntensity( textures/My_Custom_Light1_Z ) // Falloff Image<br />
<br />
{ <br />
forceHighQuality<br />
map textures/My_Custom_Light1_XY // Z-Projection Image<br />
zeroClamp<br />
}<br />
<br />
}<br />
<br />
</pre> <br />
<br />
(For advanced detail and techniques see [[Light Textures and Falloff Images]] )<br />
<br />
*<br />
<br />
{{clear}}<br />
<br />
== Further reading == <br />
<br />
* [[Performance:_Essential_Must-Knows#Lighting_Performance_Options|Lighting Performance Options]]<br />
* [[Relighting Lights]]<br />
* A great tutorial on outdoor lighting can be found here: http://www.katsbits.com/htm/tutorials/doom_3_lighting_outdoor.htm<br />
* Modwiki's summarized Doom 3 lighting article: [http://www.modwiki.net/wiki/Light Light]<br />
<br />
{{tutorial-editing}}<br />
[[Category:Lighting]]<br />
[[Category:Ambient Light]]</div>RJFerrethttps://wiki.thedarkmod.com/index.php?title=Light_Properties&diff=17676Light Properties2014-03-05T01:03:07Z<p>RJFerret: +chandelier</p>
<hr />
<div>'''''NOTE: <br>This is a first-draft article. It has not yet undergone quality control, so take information with a grain of salt <br> as it is subject to change '''''<br />
<br />
== Introduction == <br />
<br />
For Doom 3 (and subsequently, The Dark Mod), there are 4 different types of lights at our disposal. Each has their own advantages and drawbacks, and hopefully this article will help to familiarize The Dark Mod hopefuls with their use. For information on creating lights and a lot of other useful information, see [[A - Z Beginner Full Guide Start Here!]]<br />
<br />
*<br />
<br />
{{clear}}<br />
<br />
==Light Volume Properties==<br />
<br />
=== Point Light ===<br />
<br />
A point light is the default light (also the default for fog). No option must be checked to make a light a point light. A point light casts light, and subsequently shadows in all directions evenly, falling off after a distance defined by the light texture. This works best for most small indoor and outdoor lighting, like lamps, candles, fireplaces etc. For this reason, it is going to be the most used type.<br />
<br />
* Note, a misconception about Point Light is that they project spherically. The box shaped bounding volume in Dark Radiant is no mere simplification, it is the literal area affected by the light for calculation purposes. Point Light volumes should be perceived as cylindrical prisms that on one axis are shaped by the silhouette of the [[Light_Properties#Lighting_Textures | projection texture]] (think of a stack of cheese cut with a cookie cutter) and the other axis (z-axis) traditionally determines the distance from origin brightness (usually vertical... or how tall you make your cheese stack) with the LightFalloffImage.<br />
<br />
=== Projected Light ===<br />
<br />
Projected light is just as the name suggests. It is probably more intuitive and easier to use than a parallel light and is better for things like projecting a window-shaped light on the floor of a room or a spotlight on a wall. To make one, select projected instead of the default omni option at the top of the light inspector. <br />
<br />
This creates a triangular prism as the bounding box for the light (instead of a rectangular prism like a regular light), with the point ending right at the entity itself. This can be rotated using any of the XYZ rotation buttons or manually using DarkRadiant’s rotation tool (shortcut R). <br />
<br />
You can also manipulate the projected light via the vertices (shortcut V to enable vertices dragging). By dragging the vertices in the center of the projected square, you can lengthen and change the angle of the projection while keeping the projected square the same size. To resize the projection, use the two side vertices in the correct XYZ grid view. Making the bounding box flat against a surface (like a floor) is usually unnecessary (for example, making a moonlight window light on a floor or wall), because with shadows enabled and making the projection long enough to intersect the plane on which the shadow is to be cast, the full shadow will be cast (its simple geometry and just requires minor toying). <br />
<br />
As with all the lights, projected lights have a full range of color and texture options to let the mapper find just the effect they need, allowing you to create a great atmosphere for your map.<br />
<br />
<br />
=== Parallel Light ===<br />
<br />
A light is said to be parallel when the parallel checkbox is checked in the light inspector. It is subject to all the same options as a point light, but it has a few distinct differences. A parallel light tends to not care exactly where the entity itself is placed. The most important thing is where the light_center vertex is placed and where the light entities bounding box intersects with elements in your map. <br />
<br />
The light_center vertex starts right in the middle of the entity. The main difference between the parallel and point lights is that a parallel light does not radiate from the origin around the entity itself. What controls the direction that shadows are cast is the placement of the light_center vertex. Shadows will run parallel (hence the name) to a line between this vertices and the light entity itself. As such, this makes it an excellent choice for sunlight or moonlight. As such, it has some of the elements of a point light and a projected light, it can seem to radiate in a circle (if you use the appropriate texture) whilst casting a shadow in any direction preferred. <br />
<br />
Switch to Vertex mode in [[DarkRadiant]] to drag the light_center vertex of your selected light entity.<br />
<br />
Posted by Greebo: Also, note that a parallel light will only light surfaces "matching" the direction of the "light vector" <br>(origin minus light_center). All other surfaces will stay completely unlit, therefore it should be combined with an ambient light to <br>achieve good lighting effects. [http://modetwo.net/darkmod/index.php?s=&showtopic=8091&view=findpost&p=159842]<br />
<br />
What this means is, you can draw a line from the center vertex to the light entity's origin and on from there, and only objects in the direction of that line will be lit. The light won't light 4 walls of a room and the floor, it would only light one of the walls or the floor (or ceiling)<br />
<br />
==== Troubleshooting Parallel Lights ====<br />
<br />
''I added a parallel light but I can’t see any light at all!''<br />
<br />
Parallel lights can have some quirks. The light seems to fail and do nothing when intersecting multiple walls that are parallel to the face the light is actually casting on. It seems the light will work as long as it doesn’t intersect a face parallel to the one it is casting light on. <br />
<br />
''I have a parallel light but it casts a jagged light on my floor!''<br />
<br />
Similar to above, a parallel light can sometimes have anomalies when intersecting multiple walls and a floor. Since having the light intersect multiple walls when it can only cast on one of them, having a massive bounding box is pointless anyways so pay attention to what the light is touching and you should be fine.<br />
<br />
*<br />
<br />
{{clear}}<br />
<br />
==Light Interaction Properties==<br />
<br />
=== Normal Light ===<br />
<br />
This is the default light type. It performs all the surface interaction stages and shadow calculations. It has the heaviest performance impact.<br />
<br />
=== Ambient Light ===<br />
<br />
Ambient light is really just a lighting texture, but it is also a specific item that is needed in practically every map, so for those purposes it will be treated as if it were its own subset of lights.<br />
<br />
Properties: No shadows, No specular, Bumpmapping or Directionality (Note: The "Enhance Ambient" does add Bumpmapping )<br />
<br />
Use the ambientLight keyword.<br />
<br />
An ambient light can be any form: it can be a point, parallel or even projected (though projected would probably be useless). <br />
<br />
The only requirement of an ambient light is to use one of the available ambient light textures, accessible by opening the light inspector (with the shortcut L in DarkRadiant, and get used to using it), and selecting ambientlightnfo from the list.<br />
<br />
<br />
* Ambient Light is covered in more detail in [[A_-_Z_Beginner_Full_Guide_Page_2#Ambient_Light:_Gloom_not_Doom| Ambient Light: Gloom not Doom]]<br />
<br />
* To understand The Dark Mod's unique ambient light detection system see: [[Virtual Darkness]]<br />
<br />
* Ambient Light can be set to automatically adjust color and brightness per "location" see: [[Location Settings]] and [[Dynamic ambient light]]<br />
<br />
=== Fog Light ===<br />
<br />
This applies Doom 3's style distance fog to a light volume. The texture applied will become more opaque with distance away from the viewer. There is a variant called No Portal Fog which will not apply opaque fog to Portal areas in view. ( [[A_-_Z_Beginner_Full_Guide_Page_3#Fog|Beginner Tutorial: Fog]] )<br />
<br />
In rare cases, you may wish for some surface inside a fog-volume to be fog-free. You can use the "noFog" keyword in the material definition for the texture applied to this surface to keep it from being "fogged".<br />
<br />
Very thin fog (or BlendLight ) can also be used to soften the apparent light interactions near surfaces in a similar manner to the Post Process shader effect but with more mapper control. You can fake certain radiosity effects simply by amplifying small ambient light with small thin fog volumes. <br />
<br />
Use the fogLight keyword.<br />
<br />
=== Blend Light ===<br />
<br />
Blend lights can be considered to be like volumetric decals. They do not perform most of the interaction shader operations and merely apply a texture to a volume using an [http://www.modwiki.net/wiki/Blend_%28Material_stage_keyword%29 OpenGL Blend Mode]. Blend lights have the least performance impact. Blend lights can also be used to create [http://www.doom3world.org/phpbb2/viewtopic.php?f=1&t=12256&start=0&st=0&sk=t&sd=a "negative light"]. <br />
<br />
Use the blendLight keyword.<br />
<br />
<br />
----<br />
<br />
<br />
=== Spectrum ===<br />
<br />
You may use the "spectrum" keyword to isolate specific lights to specific materials which have the same spectrum value in their material definition.<br />
[http://web.archive.org/web/20080704080454/http://www.modwiki.net/wiki/Spectrum_%28Material_global_keyword%29 Spectrum Keyword at Modwiki]<br />
<br />
<br />
----<br />
<br />
<br />
*<br />
<br />
{{clear}}<br />
<br />
== Light Settings ==<br />
There are several settings with which to customize your lights. These settings allow the mapper to customize the look of a light (or a combination of lights) into a near infinity of looks. All are accessed through the light inspector (shortcut of L in DarkRadiant)<br />
<br />
=== Color ===<br />
<br />
The color palette allows the mapper to pick the color of the light emitted, arguably one of the most useful controls the mapper has over a light. To access it, click the button under the “Colour” heading. From there, adjust the settings until you find a correct color (can take some trial and error). In a game like The Dark Mod or Doom 3, where darkness is often more prevalent than light, the color picked often needs to be darker than expected. Without a direct brightness option, the color takes on this task. For a low level ambient light, the color picked would be almost pitch black. A pitch black light would not cast any light, but anything less than pitch black will cast a faint light. As such, it can take some trial and error to find the correct light for a situation, as intiailly, one is likely to pick a seemingly correct color only to find it is far too bright. <br />
<br />
Remember: changing light settings or adding lights (and models) does not require re-compiling the map!<br />
<br />
=== Radius ===<br />
The 'radius' of your light can be changed by dragging its corners around in the 2d windows. Doom 3 lights do not have an actual radius, they are actually square lights and will light up everything they touch inside their bounding box in the editor. They will evenly light everything to their edges. While square lights might seem fairly odd there are options to make them more believable and have a nice fade, namely the 'texture' applied.<br />
<br />
Tip: you can rotate a light so only one corner will touch a wall and make a triangular shaped light. <br />
<br />
Or rotate it so 2 corners touch a wall and make a line of light.<br />
<br />
'''Changing Radius of Light Entity:'''<br />
<br />
If you put a premade light entity into your map, the radius of the light won't be visible. <br />
<br />
To change it, use the following syntax (and whichever value you wish):<br />
<br />
<pre><br />
<br />
"set _color on flame" "0.9 0.8 0.7"<br />
"set light_radius on flame" "250 250 250"<br />
<br />
</pre><br />
<br />
With lanterns and such use 'light' and with torches and candles etc use 'flame'.<br />
<br />
<pre><br />
<br />
"set _color on light" "0.9 0.8 0.7"<br />
"set light_radius on light" "250 250 250"<br />
<br />
</pre><br />
<br />
(Copied from Baddcog's old "Lighting A to Z" article)<br />
<br />
=== Parallel === <br />
<br />
Selecting this option turns the light into a parallel light (as opposed to a point or projected light). See [[Light Properties#Parallel Light|Parallel Light]]<br />
<br />
=== Do not cast shadows (fast) ===<br />
<br />
As the name suggests, this setting causes the light to not cast shadows on any object. This can cause the light itself to not be confined by walls, which can sometimes be beneficial and sometimes not. The main purpose of enabling this option is performance. Shadows are processor intensive and are not needed in some cases, so removing them wherever not beneficial to gameplay can vastly improve performance. Note that ambient lights never cast any shadows. Another way to improve performance similarly is to set the entity property on a model or func_static (this doesn’t work on worldspawn) <tt>noshadows</tt> to 1.<br />
<br />
* '''Further details''': [[Turning Shadows Off]] , [[Noselfshadows]]<br />
<br />
=== Skip Specular Lighting ===<br />
<br />
Specular Lighting refers to a texture's specular map, wherein a flat surface (such as a wall) is painted with a texture that has a specular component. This causes a surface to have shinier and duller parts on a flat surface based on the darkness of the corresponding location on the specular map. Not all textures have specular maps. Checking this option could improve performance or remove the effect if it is not wanted. [http://www.modwiki.net/wiki/Texturing#Specular_maps]<br />
<br />
=== Skip Diffuse Lighting ===<br />
<br />
Like Specular lighting, diffuse lighting also references an attribute of a texture, the Diffuse Map. Diffuse Maps determine the intensity and color of the light reflected off of the different elements of a texture (an example being the difference between bricks and the mortar in between, as well as different bricks having different properties as well giving a less bland appearance). <br />
[http://www.modwiki.net/wiki/Texturing#Diffuse_maps]<br />
<br />
*<br />
<br />
{{clear}}<br />
<br />
<br />
== Chandeliers ==<br />
<br />
Typically chandeliers are setup with multiple particle flames, but just one light entity (for better performance). Bind the candles to the chandelier, then if one is doused, all will extinguish. (See the prefab for an example.)<br />
<br />
<br />
== Lighting Textures ==<br />
<br />
[[Image:LT_Projectedlight.png|400px|thumb|Rich_is_Bored's Example]]<br />
<br />
The lighting textures are also accessed in the light inspector. <br />
<br />
<br />
<br />
Lights can be modified by two different texture types:<br />
<br />
* Projection Image - This is the texture that is projected on the surface<br />
* LightFalloffImage - This texture varies the intensity of the light through the volume along the Z Axis <br />
* (Notes: While the Falloff Image is a 2D texture it is rendered as 1D (one dimensional). You will notice that almost all Falloff Images are thin strips with perpendicular stripes. Traditionally, Falloff will be used to diminish the light with distance to the source but you can violate the physics of real lights and have the intensity increase with distance or vary intensity from bright to dim to bright... etc. )<br />
<br />
<br />
----<br />
<br />
<br />
These textures allow the mapper to change the intensity and falloff of a light. <br />
<br />
Light textures with the addition of material keywords like [http://www.modwiki.net/wiki/Scroll_%28Material_stage_keyword%29 scroll],[http://www.modwiki.net/wiki/Rotate_%28Material_stage_keyword%29 rotate], etc. will grant lights the ability to animate and produce special effects such as; <br />
<br />
* A moving light for a fireplace <br />
* A candle or torch<br />
* A light flickering along with sound volume. <br />
<br />
One can also apply a fog texture to the light (the only way built into Doom 3 to create fog). Color is of a similar concern when [[A_-_Z_Beginner_Full_Guide_Page_3#Fog|creating fog]], as noted in [[Light Properties#Color|Color]]<br />
<br />
{{clear}}<br />
<br />
* A typical "Light Shader" [http://www.iddevnet.com/doom3/materials.php material] definition<br />
<br />
<pre><br />
<br />
lights/My_Custom_Light1<br />
{<br />
<br />
lightFalloffImage makeIntensity( textures/My_Custom_Light1_Z ) // Falloff Image<br />
<br />
{ <br />
forceHighQuality<br />
map textures/My_Custom_Light1_XY // Z-Projection Image<br />
zeroClamp<br />
}<br />
<br />
}<br />
<br />
</pre> <br />
<br />
(For advanced detail and techniques see [[Light Textures and Falloff Images]] )<br />
<br />
*<br />
<br />
{{clear}}<br />
<br />
== Further reading == <br />
<br />
[[Performance:_Essential_Must-Knows#Lighting_Performance_Options|Lighting Performance Options]]<br />
<br />
A great tutorial on outdoor lighting can be found here: <br />
http://www.katsbits.com/htm/tutorials/doom_3_lighting_outdoor.htm<br />
<br />
Modwiki's summarized Doom 3 lighting article: [http://www.modwiki.net/wiki/Light Light]<br />
<br />
{{tutorial-editing}}<br />
[[Category:Lighting]]<br />
[[Category:Ambient Light]]</div>RJFerrethttps://wiki.thedarkmod.com/index.php?title=Triggers&diff=17673Triggers2014-03-03T14:58:41Z<p>RJFerret: /* Triggering via Stim/Response */ not "via"</p>
<hr />
<div>There are many different ways of triggering [[Entity|entities]], the Trigger entities themselves, as well as through [[Stim/Response]], [[Conversations]], Movers, [[Objectives]], and more. How the trigger occurs will typically dictate which manner you choose for your map. <br />
<br />
=Triggers=<br />
To create triggers that rely on boundaries (once, multiple and their derivations), you need to drag out a worldspawn brush, right-click, select "Create Entity". They need to be connected to their subjects, either via "Connect Selected Entities" menu option/shortcut key, or adding "Target", "Target0", "Target1" or subsequent "Target"# spawnargs. The triggers below are listed roughly by frequency of usage, with related triggers beneath.<br />
<br />
==trigger_once==<br />
When the origin of an entity enters the bounds of this entity, the target(s) will be triggered one time only. (Note, to resize the brush after creating the entity, select it then press Tab once.)<br />
<br />
==trigger_once_entityname==<br />
Similar to [[Triggers#trigger_once|trigger_once]], but may be set to only respond to the entity specified by the spawnarg, "entityname". Note the entity must move into the boundaries itself, not be moved by the player (AI walking themselves for example). (If you want something to happen based on the player dropping or placing an item somewhere, use the [[Objectives]] system instead.)<br />
<br />
==trigger_multiple==<br />
Similar to [[Triggers#trigger_once|trigger_once]] but will activate again and again, use "Wait" spawnarg to control how many seconds between triggerings. <br />
<br />
==trigger_entityname ==<br />
Similar to [[Triggers#trigger_multiple|trigger_multiple]] but only reacts to the entity defined by the "entityname" spawnarg.<br />
<br />
== trigger_facing ==<br />
Also similar to [[Triggers#trigger_multiple|trigger_multiple]], but requires the triggering entity to be within 30° of the specified "angle" spawnarg. For details see [[Trigger Facing]].<br />
<br />
==trigger_relay ==<br />
Most commonly used to trigger many targets, or do so after a delay (per the "delay" spawnarg). May be set to only work once (spawnarg "wait" "-1") or limit firing based upon how many seconds have passed. The "random" spawnarg may be used with "wait" to vary the firings. Very useful as the target of worldspawn, to trigger things at map start (since worldspawn currently only activate one "Target"), or as the target of Objectives.<br />
<br />
==trigger_count ==<br />
This will fire at it's targets upon a specific number of times being triggered itself, based upon the "count" spawnarg. If "count" "3" is set, it will do nothing until the third triggering. <br />
<br />
== trigger_timer ==<br />
This trigger will fire repeatedly every "wait" # seconds. The spawnarg "start_on" defines if it should do so at the start of the map, or wait to be triggered (defaults to 0, off at map start). Spawnarg "random" adds variability to the triggerings.<br />
<br />
== trigger_fade ==<br />
Will cause the display to fade or dissolve to a specified color. The spawnarg "fadeColor" specifies which color, and how transparent in RGBA (red, green, blue, and alpha, ranging from 0-1). Default is fade to black: "fadeColor" "0 0 0 1". To fade up from whatever, use alpha of 0, IE to fade up from black, "0 0 0 0". "fadeTime" controls how quickly the fade transpires.<br />
<br />
== trigger_hurt ==<br />
(needs experienced write-up, compare with stim/response damage please)<br />
<br />
== trigger_presize ==<br />
(needs experienced write-up)<br />
<br />
== trigger_touch ==<br />
Continuously checks if entities are touching, costly performance wise, probably done via [[Objectives]] more efficiently.<br />
<br />
=Triggering Stim/Response=<br />
Within the [[Stim/Response]] editor, add a response stim set to "Trigger", now when this entity is targeted, whatever specified effect will occur.<br />
<br />
=Triggering via Conversation=<br />
The command, [[Conversations#Conversation Commands 2|ActivateTarget]] will trigger the specified entity at that time in the Conversation script.<br />
<br />
=Triggering via Doors, Buttons, Levers, Movers=<br />
[[Doors]] trigger their targets by default upon opening (spawnarg "trigger_on_open" "1"). They may also trigger when completely open by changing "trigger_when_opened" to 1 instead of the default 0, or when fully closed via "trigger_on_close". Note, those conditions on Buttons came from doors, so are counter-intuitive.<br />
<br />
=Triggering via Objectives=<br />
In the [[Objectives Editor]] you may select an entity to be triggered upon an objective succeeding or failing. Therefore all the possible objective conditions may become trigger events (knock out an AI, move an object away from another or to a spot, cause another objective to become visible, disappear or complete, etc.)<br />
<br />
=Triggering via Worldspawn=<br />
You may set "Target" on Worldspawn (usually at a trigger_relay since it only may target one entity currently) to cause things to be triggered at map start. If you use this to kill an AI or other affect with audio, note if in range of the player's start, it will be heard during the fade up from black.<br />
<br />
=Triggering via Lights=<br />
Lights trigger their target(s) both upon being extinguished and lit. This is useful to match window glow to actual light condition. Depending on the light, it may be tricky to set the targets however. A basic light entity can simply have target(s) spawnargs, but a candle, lamp or torch with attached flame entity, you need to use the "set" spawnarg. For example, "set target0 on flame" "EntityToBeTriggered".<br />
<br />
[[Category:Editing]]</div>RJFerrethttps://wiki.thedarkmod.com/index.php?title=Triggers&diff=17672Triggers2014-03-03T14:56:58Z<p>RJFerret: /* trigger_fade */ nuance</p>
<hr />
<div>There are many different ways of triggering [[Entity|entities]], the Trigger entities themselves, as well as through [[Stim/Response]], [[Conversations]], Movers, [[Objectives]], and more. How the trigger occurs will typically dictate which manner you choose for your map. <br />
<br />
=Triggers=<br />
To create triggers that rely on boundaries (once, multiple and their derivations), you need to drag out a worldspawn brush, right-click, select "Create Entity". They need to be connected to their subjects, either via "Connect Selected Entities" menu option/shortcut key, or adding "Target", "Target0", "Target1" or subsequent "Target"# spawnargs. The triggers below are listed roughly by frequency of usage, with related triggers beneath.<br />
<br />
==trigger_once==<br />
When the origin of an entity enters the bounds of this entity, the target(s) will be triggered one time only. (Note, to resize the brush after creating the entity, select it then press Tab once.)<br />
<br />
==trigger_once_entityname==<br />
Similar to [[Triggers#trigger_once|trigger_once]], but may be set to only respond to the entity specified by the spawnarg, "entityname". Note the entity must move into the boundaries itself, not be moved by the player (AI walking themselves for example). (If you want something to happen based on the player dropping or placing an item somewhere, use the [[Objectives]] system instead.)<br />
<br />
==trigger_multiple==<br />
Similar to [[Triggers#trigger_once|trigger_once]] but will activate again and again, use "Wait" spawnarg to control how many seconds between triggerings. <br />
<br />
==trigger_entityname ==<br />
Similar to [[Triggers#trigger_multiple|trigger_multiple]] but only reacts to the entity defined by the "entityname" spawnarg.<br />
<br />
== trigger_facing ==<br />
Also similar to [[Triggers#trigger_multiple|trigger_multiple]], but requires the triggering entity to be within 30° of the specified "angle" spawnarg. For details see [[Trigger Facing]].<br />
<br />
==trigger_relay ==<br />
Most commonly used to trigger many targets, or do so after a delay (per the "delay" spawnarg). May be set to only work once (spawnarg "wait" "-1") or limit firing based upon how many seconds have passed. The "random" spawnarg may be used with "wait" to vary the firings. Very useful as the target of worldspawn, to trigger things at map start (since worldspawn currently only activate one "Target"), or as the target of Objectives.<br />
<br />
==trigger_count ==<br />
This will fire at it's targets upon a specific number of times being triggered itself, based upon the "count" spawnarg. If "count" "3" is set, it will do nothing until the third triggering. <br />
<br />
== trigger_timer ==<br />
This trigger will fire repeatedly every "wait" # seconds. The spawnarg "start_on" defines if it should do so at the start of the map, or wait to be triggered (defaults to 0, off at map start). Spawnarg "random" adds variability to the triggerings.<br />
<br />
== trigger_fade ==<br />
Will cause the display to fade or dissolve to a specified color. The spawnarg "fadeColor" specifies which color, and how transparent in RGBA (red, green, blue, and alpha, ranging from 0-1). Default is fade to black: "fadeColor" "0 0 0 1". To fade up from whatever, use alpha of 0, IE to fade up from black, "0 0 0 0". "fadeTime" controls how quickly the fade transpires.<br />
<br />
== trigger_hurt ==<br />
(needs experienced write-up, compare with stim/response damage please)<br />
<br />
== trigger_presize ==<br />
(needs experienced write-up)<br />
<br />
== trigger_touch ==<br />
Continuously checks if entities are touching, costly performance wise, probably done via [[Objectives]] more efficiently.<br />
<br />
=Triggering via Stim/Response=<br />
Within the [[Stim/Response]] editor, add a response stim set to "Trigger", now when this entity is targeted, whatever specified effect will occur.<br />
<br />
=Triggering via Conversation=<br />
The command, [[Conversations#Conversation Commands 2|ActivateTarget]] will trigger the specified entity at that time in the Conversation script.<br />
<br />
=Triggering via Doors, Buttons, Levers, Movers=<br />
[[Doors]] trigger their targets by default upon opening (spawnarg "trigger_on_open" "1"). They may also trigger when completely open by changing "trigger_when_opened" to 1 instead of the default 0, or when fully closed via "trigger_on_close". Note, those conditions on Buttons came from doors, so are counter-intuitive.<br />
<br />
=Triggering via Objectives=<br />
In the [[Objectives Editor]] you may select an entity to be triggered upon an objective succeeding or failing. Therefore all the possible objective conditions may become trigger events (knock out an AI, move an object away from another or to a spot, cause another objective to become visible, disappear or complete, etc.)<br />
<br />
=Triggering via Worldspawn=<br />
You may set "Target" on Worldspawn (usually at a trigger_relay since it only may target one entity currently) to cause things to be triggered at map start. If you use this to kill an AI or other affect with audio, note if in range of the player's start, it will be heard during the fade up from black.<br />
<br />
=Triggering via Lights=<br />
Lights trigger their target(s) both upon being extinguished and lit. This is useful to match window glow to actual light condition. Depending on the light, it may be tricky to set the targets however. A basic light entity can simply have target(s) spawnargs, but a candle, lamp or torch with attached flame entity, you need to use the "set" spawnarg. For example, "set target0 on flame" "EntityToBeTriggered".<br />
<br />
[[Category:Editing]]</div>RJFerrethttps://wiki.thedarkmod.com/index.php?title=Triggers&diff=17671Triggers2014-03-03T14:55:10Z<p>RJFerret: /* trigger_fade */ grammar</p>
<hr />
<div>There are many different ways of triggering [[Entity|entities]], the Trigger entities themselves, as well as through [[Stim/Response]], [[Conversations]], Movers, [[Objectives]], and more. How the trigger occurs will typically dictate which manner you choose for your map. <br />
<br />
=Triggers=<br />
To create triggers that rely on boundaries (once, multiple and their derivations), you need to drag out a worldspawn brush, right-click, select "Create Entity". They need to be connected to their subjects, either via "Connect Selected Entities" menu option/shortcut key, or adding "Target", "Target0", "Target1" or subsequent "Target"# spawnargs. The triggers below are listed roughly by frequency of usage, with related triggers beneath.<br />
<br />
==trigger_once==<br />
When the origin of an entity enters the bounds of this entity, the target(s) will be triggered one time only. (Note, to resize the brush after creating the entity, select it then press Tab once.)<br />
<br />
==trigger_once_entityname==<br />
Similar to [[Triggers#trigger_once|trigger_once]], but may be set to only respond to the entity specified by the spawnarg, "entityname". Note the entity must move into the boundaries itself, not be moved by the player (AI walking themselves for example). (If you want something to happen based on the player dropping or placing an item somewhere, use the [[Objectives]] system instead.)<br />
<br />
==trigger_multiple==<br />
Similar to [[Triggers#trigger_once|trigger_once]] but will activate again and again, use "Wait" spawnarg to control how many seconds between triggerings. <br />
<br />
==trigger_entityname ==<br />
Similar to [[Triggers#trigger_multiple|trigger_multiple]] but only reacts to the entity defined by the "entityname" spawnarg.<br />
<br />
== trigger_facing ==<br />
Also similar to [[Triggers#trigger_multiple|trigger_multiple]], but requires the triggering entity to be within 30° of the specified "angle" spawnarg. For details see [[Trigger Facing]].<br />
<br />
==trigger_relay ==<br />
Most commonly used to trigger many targets, or do so after a delay (per the "delay" spawnarg). May be set to only work once (spawnarg "wait" "-1") or limit firing based upon how many seconds have passed. The "random" spawnarg may be used with "wait" to vary the firings. Very useful as the target of worldspawn, to trigger things at map start (since worldspawn currently only activate one "Target"), or as the target of Objectives.<br />
<br />
==trigger_count ==<br />
This will fire at it's targets upon a specific number of times being triggered itself, based upon the "count" spawnarg. If "count" "3" is set, it will do nothing until the third triggering. <br />
<br />
== trigger_timer ==<br />
This trigger will fire repeatedly every "wait" # seconds. The spawnarg "start_on" defines if it should do so at the start of the map, or wait to be triggered (defaults to 0, off at map start). Spawnarg "random" adds variability to the triggerings.<br />
<br />
== trigger_fade ==<br />
Will cause the display to fade to a specified color. The spawnarg "fadeColor" specifies which color, and how transparent in RGBA (red, green, blue, and alpha, ranging from 0-1). Default is fade to black: "fadeColor" "0 0 0 1". To fade up from whatever, use alpha of 0, IE to fade up from black, "0 0 0 0".<br />
<br />
== trigger_hurt ==<br />
(needs experienced write-up, compare with stim/response damage please)<br />
<br />
== trigger_presize ==<br />
(needs experienced write-up)<br />
<br />
== trigger_touch ==<br />
Continuously checks if entities are touching, costly performance wise, probably done via [[Objectives]] more efficiently.<br />
<br />
=Triggering via Stim/Response=<br />
Within the [[Stim/Response]] editor, add a response stim set to "Trigger", now when this entity is targeted, whatever specified effect will occur.<br />
<br />
=Triggering via Conversation=<br />
The command, [[Conversations#Conversation Commands 2|ActivateTarget]] will trigger the specified entity at that time in the Conversation script.<br />
<br />
=Triggering via Doors, Buttons, Levers, Movers=<br />
[[Doors]] trigger their targets by default upon opening (spawnarg "trigger_on_open" "1"). They may also trigger when completely open by changing "trigger_when_opened" to 1 instead of the default 0, or when fully closed via "trigger_on_close". Note, those conditions on Buttons came from doors, so are counter-intuitive.<br />
<br />
=Triggering via Objectives=<br />
In the [[Objectives Editor]] you may select an entity to be triggered upon an objective succeeding or failing. Therefore all the possible objective conditions may become trigger events (knock out an AI, move an object away from another or to a spot, cause another objective to become visible, disappear or complete, etc.)<br />
<br />
=Triggering via Worldspawn=<br />
You may set "Target" on Worldspawn (usually at a trigger_relay since it only may target one entity currently) to cause things to be triggered at map start. If you use this to kill an AI or other affect with audio, note if in range of the player's start, it will be heard during the fade up from black.<br />
<br />
=Triggering via Lights=<br />
Lights trigger their target(s) both upon being extinguished and lit. This is useful to match window glow to actual light condition. Depending on the light, it may be tricky to set the targets however. A basic light entity can simply have target(s) spawnargs, but a candle, lamp or torch with attached flame entity, you need to use the "set" spawnarg. For example, "set target0 on flame" "EntityToBeTriggered".<br />
<br />
[[Category:Editing]]</div>RJFerrethttps://wiki.thedarkmod.com/index.php?title=Triggers&diff=17670Triggers2014-03-03T14:52:43Z<p>RJFerret: /* trigger_relay */ nuance</p>
<hr />
<div>There are many different ways of triggering [[Entity|entities]], the Trigger entities themselves, as well as through [[Stim/Response]], [[Conversations]], Movers, [[Objectives]], and more. How the trigger occurs will typically dictate which manner you choose for your map. <br />
<br />
=Triggers=<br />
To create triggers that rely on boundaries (once, multiple and their derivations), you need to drag out a worldspawn brush, right-click, select "Create Entity". They need to be connected to their subjects, either via "Connect Selected Entities" menu option/shortcut key, or adding "Target", "Target0", "Target1" or subsequent "Target"# spawnargs. The triggers below are listed roughly by frequency of usage, with related triggers beneath.<br />
<br />
==trigger_once==<br />
When the origin of an entity enters the bounds of this entity, the target(s) will be triggered one time only. (Note, to resize the brush after creating the entity, select it then press Tab once.)<br />
<br />
==trigger_once_entityname==<br />
Similar to [[Triggers#trigger_once|trigger_once]], but may be set to only respond to the entity specified by the spawnarg, "entityname". Note the entity must move into the boundaries itself, not be moved by the player (AI walking themselves for example). (If you want something to happen based on the player dropping or placing an item somewhere, use the [[Objectives]] system instead.)<br />
<br />
==trigger_multiple==<br />
Similar to [[Triggers#trigger_once|trigger_once]] but will activate again and again, use "Wait" spawnarg to control how many seconds between triggerings. <br />
<br />
==trigger_entityname ==<br />
Similar to [[Triggers#trigger_multiple|trigger_multiple]] but only reacts to the entity defined by the "entityname" spawnarg.<br />
<br />
== trigger_facing ==<br />
Also similar to [[Triggers#trigger_multiple|trigger_multiple]], but requires the triggering entity to be within 30° of the specified "angle" spawnarg. For details see [[Trigger Facing]].<br />
<br />
==trigger_relay ==<br />
Most commonly used to trigger many targets, or do so after a delay (per the "delay" spawnarg). May be set to only work once (spawnarg "wait" "-1") or limit firing based upon how many seconds have passed. The "random" spawnarg may be used with "wait" to vary the firings. Very useful as the target of worldspawn, to trigger things at map start (since worldspawn currently only activate one "Target"), or as the target of Objectives.<br />
<br />
==trigger_count ==<br />
This will fire at it's targets upon a specific number of times being triggered itself, based upon the "count" spawnarg. If "count" "3" is set, it will do nothing until the third triggering. <br />
<br />
== trigger_timer ==<br />
This trigger will fire repeatedly every "wait" # seconds. The spawnarg "start_on" defines if it should do so at the start of the map, or wait to be triggered (defaults to 0, off at map start). Spawnarg "random" adds variability to the triggerings.<br />
<br />
== trigger_fade ==<br />
Will cause the display to fade to specified color. The spawnarg "fadeColor" specifies which color and how transparent in RGBA (red, green, blue, alpha). Default is fade to black: "fadeColor" "0 0 0 1". To fade up from whatever, use alpha of 0, IE to fade up from black, "0 0 0 0".<br />
<br />
== trigger_hurt ==<br />
(needs experienced write-up, compare with stim/response damage please)<br />
<br />
== trigger_presize ==<br />
(needs experienced write-up)<br />
<br />
== trigger_touch ==<br />
Continuously checks if entities are touching, costly performance wise, probably done via [[Objectives]] more efficiently.<br />
<br />
=Triggering via Stim/Response=<br />
Within the [[Stim/Response]] editor, add a response stim set to "Trigger", now when this entity is targeted, whatever specified effect will occur.<br />
<br />
=Triggering via Conversation=<br />
The command, [[Conversations#Conversation Commands 2|ActivateTarget]] will trigger the specified entity at that time in the Conversation script.<br />
<br />
=Triggering via Doors, Buttons, Levers, Movers=<br />
[[Doors]] trigger their targets by default upon opening (spawnarg "trigger_on_open" "1"). They may also trigger when completely open by changing "trigger_when_opened" to 1 instead of the default 0, or when fully closed via "trigger_on_close". Note, those conditions on Buttons came from doors, so are counter-intuitive.<br />
<br />
=Triggering via Objectives=<br />
In the [[Objectives Editor]] you may select an entity to be triggered upon an objective succeeding or failing. Therefore all the possible objective conditions may become trigger events (knock out an AI, move an object away from another or to a spot, cause another objective to become visible, disappear or complete, etc.)<br />
<br />
=Triggering via Worldspawn=<br />
You may set "Target" on Worldspawn (usually at a trigger_relay since it only may target one entity currently) to cause things to be triggered at map start. If you use this to kill an AI or other affect with audio, note if in range of the player's start, it will be heard during the fade up from black.<br />
<br />
=Triggering via Lights=<br />
Lights trigger their target(s) both upon being extinguished and lit. This is useful to match window glow to actual light condition. Depending on the light, it may be tricky to set the targets however. A basic light entity can simply have target(s) spawnargs, but a candle, lamp or torch with attached flame entity, you need to use the "set" spawnarg. For example, "set target0 on flame" "EntityToBeTriggered".<br />
<br />
[[Category:Editing]]</div>RJFerrethttps://wiki.thedarkmod.com/index.php?title=Fan_Missions_for_The_Dark_Mod&diff=17669Fan Missions for The Dark Mod2014-03-03T14:42:48Z<p>RJFerret: +Inn Business, and Southquarter website obsolete</p>
<hr />
<div>__NOTOC__<br />
{{infobox|<center>'''Big Ugly Disclaimer:'''</center><br> '''The Dark Mod''' team does not necessarily support or endorse content listed here, and only hosts missions listed on the [http://www.thedarkmod.com/ official TDM website]. This is a community maintained list, and an ongoing work in progress. Most of the mirror links in this list are dead or are for missions that are not 2.0 compliant. Mission entries which are suspected to violate copyright must be text-only, and cannot contain links. Report and/or remove links found in violation of this rule.}}<br />
<br />
<br />
* For details about editing this table, see [http://modetwo.net/darkmod/wiki/index.php?title=Fan_Missions_for_The_Dark_Mod#Editing_This_Table below].<br />
* For details about how to install Fan Missions please visit: [[Installing and Running Fan Missions]]<br />
* To sort by a different criterion, click the [[Image:Sort none.gif]] icon in the relevant column header.<br />
<br />
<br />
{|class="wikitable sortable" border=1 style="border-collapse: collapse;" cellspacing=0 cellpadding=2 width=100%<br />
|-<br />
!bgcolor=#d0d0e0 width="21%"|Fan Mission Title<br />
!bgcolor=#d0d0e0 width="12%"|Author(s)<br />
!bgcolor=#d0d0e0 width="9%" class="unsortable"|Links<br />
!bgcolor=#d0d0e0 width="5%"|First Release<br />
!bgcolor=#d0d0e0 width="4%"|Size (MB)<br />
!bgcolor=#d0d0e0 width="10%"|Series<br />
!bgcolor=#d0d0e0 width="13%"|Mission Type<br />
!bgcolor=#d0d0e0 width="6%"|Spiders and Undead<br />
|-<br />
<br />
<!--INSERT NEW MISSIONS BELOW THIS LINE--><br />
|-<br />
!align=left|{{TDM-FM|83|Inn Business}}<br>(v.1.47, 2014/03/03)<br />
|RJFerret<br />
|{{Mirrorlink|https://drive.google.com/file/d/0B81T2ZXLPqhTYWVaODRiSExGeGc}} {{Forumlink|1=http://forums.thedarkmod.com/topic/16018-fan-mission-inn-business-by-rjferret-20140303/}}<br />
|2014-03-03<br />
|6<br />
|<br />
|Mansion/Estate FMs<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|82|William Steele 3: Cleighmoor}}<br />
|grayman<br />
|{{Forumlink|http://forums.thedarkmod.com/topic/16011-fan-mission-cleighmoor-by-grayman-201431/#entry338349/}}<br />
|2014-03-01<br />
|38<br />
|William Steele 3<br />
|Sewer / Prison<br />
|none<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|81|William Steele 2: Home Again}}<br />
|grayman<br />
|{{Forumlink|http://forums.thedarkmod.com/topic/15919-fan-mission-home-again-by-grayman-2014212/page__fromsearch__1}}<br />
|2014-02-12<br />
|26<br />
|William Steele 2<br />
|Thieves' Highway / Rooftop<br />
|none<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|80|The Gatehouse}}<br />
|Bikerdude Goldchocobo<br />
|{{Mirrorlink|http://www.southquarter.com/tdm/fms/gatehouse.pk4}} {{Forumlink|http://forums.thedarkmod.com/topic/15844-fan-mission-the-gatehouse-by-bikerdude-goldchocobo-20140114/}}<br />
|2014-01-29<br />
|100<br />
|Remake of Evilartist's Doom 3 mod<br />
|Castle/Fortress Missions<br />
|Ghosts<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|79|Window of Opportunity}}<br>(v.1.43, 2014/01/01)<br />
|RJFerret<br />
|{{Mirrorlink|https://drive.google.com/file/d/0B81T2ZXLPqhTWTMzQXZtMVFBSG8}} {{Forumlink|1=http://forums.thedarkmod.com/topic/15727-fan-mission-window-of-opportunity-by-rjferret-20140101/}}<br />
|2014-01-01<br />
|7<br />
|<br />
|Outdoor/caves<br />
|Spiders (not in short mode)<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|78|In A Time Of Need}}<br />
|kyyrma<br />
| {{Mirrorlink|http://www.mediafire.com/download/a97or40t1xrybh3/timeofneed_v1.zip}} {{Forumlink|http://forums.thedarkmod.com/topic/15354-fan-mission-in-a-time-of-need-by-kyyrma-20131112/}}<br />
|2013-11-12<br />
|5.6<br />
|<br />
|Mansion/Estate FMs<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|76|Requiem}}<br />
|Moonbo<br />
| {{Mirrorlink|http://www.mediafire.com/download/l6o3vvj9y78hu89/requiem.pk4}} {{Forumlink|http://forums.thedarkmod.com/topic/15101-fan-mission-requiem-by-gelo-moonbo-fleisher-2013106/}}<br />
|2013-10-08<br />
|107.3<br />
|[http://www.amazon.com/Shadowcursed-ebook/dp/B00BYEW02M Shadowcursed]<br />
|Lost Civilizations<br />
|Undead<br />
|-<br />
<br />
<br />
|-<br />
!align=left|{{TDM-FM|75|Vengeance for a Thief Part 2}}<br />
|Sir Taffsalot<br />
| {{Mirrorlink|https://dl.dropboxusercontent.com/u/17706561/vfat2.pk4}} {{Forumlink|http://forums.thedarkmod.com/topic/15051-fan-mission-vengeance-for-a-thief-part-2-by-sir-taffsalot-06092013/}}<br />
|2013-09-06<br />
|22<br />
|VFAT 2 and CUC 13<br />
|Museum Missions<br />
|<br />
|-<br />
<br />
<br />
|-<br />
!align=left|{{TDM-FM|74|Lords and Legacy}}<br />
|Kvorning<br />
| {{Mirrorlink|https://dl.dropboxusercontent.com/u/17706561/lordsnlegacy.pk4}} {{Forumlink|http://forums.thedarkmod.com/topic/15016-fan-mission-lords-legacy-by-kvorning-20130830/}}<br />
|2013-08-30<br />
|45<br />
|<br />
|Thieves' Highway / Rooftop<br />
|<br />
|-<br />
<br />
<br />
|-<br />
!align=left|{{TDM-FM|72|Not An Ordinary Guest}}<br />
|Fieldmedic<br />
| {{Mirrorlink|https://dl.dropboxusercontent.com/u/17706561/naog.pk4}} {{Forumlink|http://forums.thedarkmod.com/topic/14965-fan-mission-not-an-ordinary-guest-by-fieldmedic-20130801/}}<br />
|2013-08-01<br />
|79.6<br />
|CUC 13<br />
|City Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|71|Penny Dreadful: Grail of Regrets}}<br />
|Melan<br />
| {{Forumlink|http://forums.thedarkmod.com/topic/14952-fan-mission-penny-dreadful-by-melan-20130728/}}<br />
|2013-07-27<br />
|74<br />
|Penny Dreadful 1<br />
|Horror FMs<br />
|Undead and Spiders<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|70|Solar Escape 1}}<br />
|Tr00pertj<br />
| {{Forumlink|http://forums.thedarkmod.com/topic/14944-fan-mission-solar-escape-1/}}<br />
|2013-07-22<br />
|6<br />
|<br />
|Mansion/Estate FMs<br />
|Undead<br />
|-<br />
<br />
<br />
|-<br />
!align=left|{{TDM-FM|69|The Lich Queen's Demise}}<br />
|Sotha<br />
|{{Mirrorlink|https://dl.dropboxusercontent.com/u/17706561/lich_queens_demise.pk4}} {{Forumlink|http://forums.thedarkmod.com/topic/14826-fan-mission-the-lich-queens-demise-by-sotha-20130520/unread/}}<br />
|2013-05-20<br />
|97.6<br />
|Thomas Porter 6 CUC 13<br />
|Horror FMs<br />
|Undead<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|77|Old Habits Rebuild}}<br />
|Obsttorte<br />
|{{Bloodgate|mc.pk4}} {{Mirrorlink|http://www.mediafire.com/download/u2gwucibh17c45a/oldhabits.pk4}} {{Forumlink|http://forums.thedarkmod.com/topic/14827-fan-mission-old-habits-rebuild-by-obsttorte-20052013/}}<br />
|2013-05-20<br />
|28.6<br />
|<br />
|Mansion/Estate FMs<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|68|The Builder's Blocks}}<br />
|Jesps<br />
|{{Mirrorlink|https://dl.dropboxusercontent.com/u/17706561/builders_blocks.pk4}} {{Forumlink|http://forums.thedarkmod.com/topic/14592-unusual-gameplay-contest-fm-the-builders-blocks-by-jesps/}}<br />
|2013-03-18<br />
|2.85<br />
|CUC 13<br />
|<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|67|Crystal Grave}} <br>(v.2.0, 2013/02/09)<br />
|ERH+ Bikerdude<br />
|{{Mirrorlink|https://dl.dropbox.com/u/17706561/crystalgravev2.pk4}} {{Forumlink|http://forums.thedarkmod.com/topic/14510-fan-mission-crystal-grave-v2-by-erh-and-bikerdude-20130209/unread/}}<br />
|2011-11-15<br />
|12.4<br />
|<br />
|Horror FMs<br />
|Undead<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|66|The Builder Roads}}<br />
|Obsttorte<br />
|{} {{Forumlink|http://forums.thedarkmod.com/topic/14449-fan-mission-the-builder-roads-by-obsttorte-20130119/}}<br />
|2013-01-19<br />
|?<br />
|<br />
|Horror FMs <br />
|Ghosts<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|65|William Steele 1: In the North}}<br />
|grayman<br />
|{{Bloodgate|ws1_north.pk4}} {{Forumlink|http://forums.thedarkmod.com/topic/14214-fan-mission-in-the-north-by-grayman-20121020/}}<br />
|2012-10-20<br />
|39.8<br />
|William Steele 1<br />
|Mansion/Estate FMs<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|64|Old Habits}}<br />
|Obsttorte<br />
|{{Bloodgate|mc.pk4}} {{Mirrorlink|http://www.mediafire.com/download.php?andes2xnsonssfj}} {{Forumlink|http://forums.thedarkmod.com/topic/14206-fan-mission-old-habits-by-obsttorte-20121019/}}<br />
|2012-10-19<br />
|12.8<br />
|<br />
|Mansion/Estate FMs<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|63|Deceptive Shadows}}<br />
|ShadowHide<br />
|{{Bloodgate|DeceptiveShadows.pk4}} {{Mirrorlink|http://www.sendspace.com/file/jzr9s7}} {{Forumlink|http://forums.thedarkmod.com/topic/14103-fan-mission-deceptive-shadows-by-shadowhide-16sep12/}}<br />
|2012-09-16<br />
|22.4<br />
|<br />
|Pagan/Outdoor Missions<br />
|Spiders<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|62|Vengeance for a Thief: Part 1}}<br />
|Sir Taffsalot <br />
|{{Bloodgate|VFAT1.pk4}} {{Mirrorlink|https://dl.dropbox.com/u/17706561/VFAT1.pk4}} {{Forumlink|http://forums.thedarkmod.com/topic/14068-fan-mission-vengeance-for-a-thief-part-1-by-sir-taffsalot-06092012/}}<br />
|2012-09-06<br />
|20.9<br />
|VFAT 1<br />
|Jail/Prison Missions<br />
|<br />
|-<br />
<br />
<br />
|-<br />
!align=left|{{TDM-FM|61|The Phrase Book}}<br />
|Sotha<br />
|{{Bloodgate|phrase_book.pk4}} {{Mirrorlink|http://dl.dropbox.com/u/17706561/phrase_book.pk4}} {{Forumlink|http://forums.thedarkmod.com/topic/13799-fan-mission-the-phrase-book-by-sotha-20120512/}}<br />
|2012-05-11<br />
|24<br />
|Thomas Porter 5<br />
|Thieves' Highway / Rooftop<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|60|In Remembrance of Him}}<br />
|RPGista<br />
|{{Bloodgate|remembrance.pk4}} {{Mirrorlink|http://dl.dropbox.com/u/17706561/remembrance.pk4}} {{Forumlink|http://forums.thedarkmod.com/topic/13749-fan-mission-in-remembrance-of-him-by-rpgista/}}<br />
|2012-04-22<br />
|27.6<br />
|CBC 12<br />
|City Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|59|Rightful Property}}<br />
|jysk<br />
|{{Bloodgate|rightful.pk4}} {{Mirrorlink|http://dl.dropbox.com/u/17706561/rightful1.1b.pk4}} {{Forumlink|http://forums.thedarkmod.com/topic/13711-fan-mission-rightful-property-by-jysk-20120413/}}<br />
|2012-04-12<br />
|22.5<br />
|CBC 12<br />
|Bank Jobs<br />
|Spiders<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|58|Sneak and Destroy}}<br />
|SeriousToni<br />
|{{Bloodgate|kneipe24.pk4}} {{Mirrorlink|http://minus.com/mVcf61n3G/1f}} {{Forumlink|http://forums.thedarkmod.com/topic/13706-fan-mission-sneak-destroy-by-serioustoni-beginners-contest-2012/}}<br />
|2012-04-11<br />
|158<br />
|CBC 12<br />
|City Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|56|House of Theo}}<br />
|Theothesnopp<br />
|{{Bloodgate|houseoftheo.pk4}} {{Mirrorlink|http://www.gamefront.com/files/21053391/houseoftheo__2__2.pk4}} {{Forumlink|http://forums.thedarkmod.com/topic/13242-fan-mission-house-of-theo/}}<br />
|2011-12-04<br />
|6.2<br />
|<br />
|Castle/Fortress Missions<br />
|<br />
|-<br />
<br />
<br />
|-<br />
!align=left|{{TDM-FM|53|Dragon's Claw}}<br />
|Bikerdude, Flanders (map assets)<br />
|{{Bloodgate|claw.pk4}}{{Mirrorlink|http://www.gamefront.com/files/20948800/claw.pk4}} {{Forumlink|http://forums.thedarkmod.com/topic/13181-fan-missiondragons-claw-by-b1k3rdude-31102011/}}<br />
|2011-10-31<br />
|98<br />
|HSC 11<br />
|City Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|52|A Night to Remember}}<br />
|Fieldmedic<br />
|{{Bloodgate|antr.pk4}}{{Mirrorlink|http://www.mediafire.com/?d4hch59m4nef3dc}} {{Forumlink|http://forums.thedarkmod.com/topic/13177-fan-mission-a-night-to-remember-by-fieldmedic-20111030/}}<br />
|2011-10-31<br />
|32<br />
|HSC 11<br />
|Mansion/Estate FMs<br />
|Ghosts<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|51|The Creeps}}<br />
|Mortem Desino<br />
|{{Bloodgate|thecreeps.pk4}}{{Mirrorlink|http://www.gamefront.com/files/20939925/thecreeps.pk4}} {{Forumlink|http://forums.thedarkmod.com/topic/13176-fan-mission-creeps-the-20111030-by-mortem-desino/}}<br />
|2011-10-30<br />
|61<br />
|HSC 11<br />
|Horror FMs<br />
|Ghosts<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|50|House in Blackbog Hollow}}<br />
|Stumpy<br />
|{{Bloodgate|blackbog.pk4}}{{Mirrorlink|http://www.bookofages.co.uk/doom3/mods/blackbog.html}} {{Forumlink|http://forums.thedarkmod.com/topic/13172-fan-mission-house-in-blackbog-hollow-by-stumpy-20111028/}}<br />
|2011-10-28<br />
|12<br />
|HSC 11<br />
|Horror FMs<br />
|Undead and Spiders<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|49|Let Sleeping Thieves Lie}}<br />
|Sir Taffsalot, Bikerdude<br />
|{{Bloodgate|lstl.pk4}}{{Mirrorlink|http://www.mediafire.com/?zkd1jn4lpwgioh9}} {{Forumlink|http://modetwo.net/darkmod/index.php?/topic/13153-let-sleeping-thieves-lie-by-sir-taffsalot-bikerdude-20102011/}}<br />
|2011-10-20<br />
|13<br />
|<br />
|Tombs, Catacombs & Crypts<br />
|Undead<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|48|Samhain Night}}<br />
|PranQster<br />
|{{Bloodgate|samhain.pk4}}{{Mirrorlink|http://jdchoate.mcn.org/games/darkmod/samhain.zip}} {{Forumlink|http://modetwo.net/darkmod/index.php?/topic/13127-fan-mission-samhain-night-on-bone-hill-by-pranqster-20111009/}}<br />
|2011-10-09<br />
|10<br />
|HSC 11<br />
|Horror FMs<br />
|Undead and Spiders<br />
|-<br />
<br />
<br />
|-<br />
!align=left|{{TDM-FM|47|A Score to Settle}}<br />
|Springheel<br />
|{{Bloodgate|score_to_settle.pk4}}{{Mirrorlink|http://www.mediafire.com/?f3o7hm4h4ew7o3l}} {{Forumlink|http://modetwo.net/darkmod/index.php?/topic/12894-fan-mission-%2348-a-score-to-settle-by-springheel-20110701/}}<br />
|2011-07-01<br />
|135<br />
|<br />
|City Missions<br />
|<br />
|-<br />
<br />
<br />
|-<br />
!align=left|{{TDM-FM|46|Siege Shop}}<br>(v3.0 2013/10/10)<br />
|PranQster and Lowenz<br />
|{{Bloodgate|siegeshop.pk4}}{{Mirrorlink|http://jdchoate.mcn.org/games/darkmod/siegeshop.pk4}} {{Forumlink|http://modetwo.net/darkmod/index.php?/topic/12874-fan-mission-the-siege-shop-by-pranqster-20110626/}}<br />
|2011-06-26<br />
|20.51<br />
|<br />
|Castle/Fortress Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|44|Alberic's Curse}}<br />
|Bikerdude<br />
|{{Bloodgate|alberic.pk4}} {{Mirrorlink|http://www.gamefront.com/files/20459738/alberic.pk4}} {{Forumlink|http://modetwo.net/darkmod/index.php?/topic/12850-fan-mission-alberics-curse-by-b1k3rdude-20062011/}}<br />
|2011-06-20<br />
|29<br />
|CSC 11 (Winner), T2 FM homage<br />
|Church/Cathedral<br />
|Undead and Spiders<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|45|Reap as you sow}}<br />
|Fieldmedic<br />
|{{Bloodgate|reap.pk4}} {{Forumlink|http://modetwo.net/darkmod/index.php?/topic/12849-fan-mission-reap-as-you-sow-by-fieldmedic-20110619/}}<br />
|2011-06-19<br />
|52<br />
|CSC 11<br />
|Daylight Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|43|Rake Off}}<br />
|Jesps<br />
|{{Bloodgate|rake_off.pk4}} {{Forumlink|http://modetwo.net/darkmod/index.php?/topic/12846-fm-rake-off-19-06-2011/}}<br />
|2011-06-19<br />
|8<br />
|CSC 11, Selis Woderose 2<br />
|Castle/Fortress Missions <br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|42|Winter Harvest}}<br>(v2.0 2011/07/24 with Bikerdude)<br />
|ShadowHide<br />
|{{Bloodgate|winterharvest.pk4}} {{Forumlink|http://modetwo.net/darkmod/index.php?/topic/12690-seasons-contest-entry-winter-harvest-by-shadowhide/}}<br />
|2011-05-08<br />
|10<br />
|CSC 11<br />
|Pagan/Outdoor Missions<br />
|Spiders<br />
|-<br />
<br />
<br />
|-<br />
!align=left|{{TDM-FM|41|Fiasco at Fauchard Street}}<br />
|Melan<br />
|{{Bloodgate|fauchard.pk4}} {{Mirrorlink|https://rapidshare.com/files/460141132/fauchard.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/12655-fan-mission-fiasco-at-fauchard-street-by-melan-20110501//}}<br />
|2011-05-01<br />
|62<br />
|Talbot 3<br />
|Thieves' Highway / Rooftop<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|40|Mandrasola}}<br />
|Sotha<br />
|{{Bloodgate|mandrasola.pk4}} {{Mirrorlink|http://www.mediafire.com/?2ox2nbhh796ne71}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/12575-fan-mission-mandrasola-by-sotha-20110410/}}<br />
|2011-04-10<br />
|10<br />
|Thomas Porter 0, CSC 11<br />
|City Missions<br />
|Undead<br />
|-<br />
<br />
|-<br />
!align=left|[http://www.gamefront.com/files/20167184/yantdm1.1.pk4 Q4 Conversion: Yan's Test]<br />
|Bikerdude<br />
|{{Mirrorlink|http://www.mediafire.com/?2nona089nzi00sv}} {{Mirrorlink|http://www.gamefront.com/files/20167184/yantdm1.1.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/12506-fan-mission-q4-map-conversion-yantdm1-280311/}}<br />
|2011-03-28<br />
|28<br />
|<br />
|<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|38|The Transaction}}<br />
|Sotha<br />
|{{Bloodgate|transaction.pk4}} {{Mirrorlink|http://www.mediafire.com/?ux7mx79wumnvcb6}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/12408-fan-mission-the-transaction-by-sotha-20110304/}}<br />
|2011-03-04<br />
|10<br />
|Thomas Porter 4<br />
|City Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|13|Return to the City}}<br>(v2.0 2011/03/01)<br />
|Melan, Bikerdude<br />
|{{Bloodgate|ReturnToTheCityV2.pk4}}{{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/10509-fan-mission-return-to-the-city-by-melan-20100110/}} {{Forumlink|1=http://www.ttlg.com/forums/showthread.php?t=130519/}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/12390-fan-mission-return-to-the-city-v2-01032011/}}<br />
|2010-01-10<br />
|26<br />
|Version 1.0, GCC 09 (Winner); Talbot 2<br />
|City Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|39|Lockdown}}<br />
|GameDevGoro Bikerdude Fidcal<br />
|{{Bloodgate|lockdown1_2_1.pk4}} {{Mirrorlink|http://www.fidcal.com/darkuser/missions/lockdown1_2_1.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/12064-fm-lockdown-part-1-by-gamedevgoro-and-bikerdude-20101224/}}<br />
|2010-12-25<br />
|3<br />
|Lockdown 1<br />
|City Missions<br />
|Undead<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|37|Flakebridge Monastery}}<br />
|Jesps<br />
|{{Bloodgate|flakebridge.pk4}} {{Mirrorlink|http://www.file-upload.net/download-3024426/flakebridge.pk4.html}} {{Mirrorlink|http://rapidshare.com/files/434997519/flakebridge.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/11991-fm-flakebridge-monastery-by-jesps/}}<br />
|2010-12-05<br />
|16<br />
|Selis Woderose 1<br />
|Church/Cathedral<br />
|Undead<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|36|Knighton Manor, The}}<br />
|Sotha<br />
|{{Bloodgate|knighton_manor.pk4}} {{Mirrorlink|http://www.mediafire.com/?xrdts3j4t2qxre2}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/11898-fan-mission-the-knighton-manor-by-sotha-20101109/page__view__getnewpost}}<br />
|2010-11-09<br />
|21<br />
|Thomas Porter 1<br />
|Mansion/Estate FMs<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|35|St Albans Cathedral}}<br>(v1.6 2011/03/13)<br />
|Bikerdude<br />
|{{Bloodgate|stac160.pk4}} [[http://www.bloodgate.com/fms/stac142.pk4 Classic]] {{Mirrorlink|http://www.filefront.com/17464439/stac141.pk4}}{{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/11872-fan-mission-st-albans-cathedral-01112010/}} {{Loot|FM:TDM_St_Alban's_Cathedral_-_Bikerdude}}<br />
|2010-11-01<br />
|67<br />
|St Alban<br />
|Church/Cathedral<br />
|Undead<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|33|Swing}}<br />
|Komag<br />
|{{Bloodgate|swing_v1.2.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/11660-vertigo-contest-entry-swing-by-komag-20100825/}} {{Loot|FM:TDM_Swing_-_Komag}}<br />
|2010-08-25<br />
|3<br />
|SVC 10<br />
|Platforming / Jumping<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|32|The Caduceus of St. Alban}}<br>(v.1.5.5 2010/08/26)<br />
|Bikerdude<br />
|{{bloodgate|stalban.pk4}} {{Mirrorlink|http://www.filefront.com/17237609/stalban.pk4/}}{{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/11644-the-caduceus-of-st-alban-vertical-fm-contest-entry-aug-8th-2010/}}<br />
|2010-08-23<br />
|11.3<br />
|SVC 10/St Alban<br />
|Church/Cathedral<br />
|Spiders<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|30|Somewhere Above the City}}<br>(v1.1 2010/08/27)<br />
|Grayman<br />
|{{Bloodgate|somewhere1.1.pk4}}{{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/11619-vertical-contest-mission-somewhere-above-the-city-by-grayman-aug-20-2010/}} {{Loot|FM:TDM_Somewhere_Above_the_City_-_grayman}}<br />
|2010-08-20<br />
|11<br />
|SVC 10<br />
|Tombs, Catacombs & Crypts<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|29|Betrayal}}<br>(v.1.1, 2010/09/01)<br />
|Fieldmedic<br />
|{{Bloodgate|betrayal.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/11605-betrayal-by-fieldmedic-20100817-summer-fm-vertical-contest-entry/}} {{Loot|FM:TDM_Awaiting_the_Storm_-_HappyCheeze}}<br />
|2010-08-17<br />
|12<br />
|SVC 10<br />
|Horror FMs<br />
|Undead<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|31|Rift, The}}<br />
|Baddcog<br />
|{{Bloodgate|rift.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/11599-vert-contest-mission-the-rift-by-baddcog-aug-15-2010/}}<br />
|2010-08-15<br />
|10<br />
|SVC 10<br />
|Lost Civilizations<br />
|Undead and Spiders<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|34|Illusionist's Tower}}<br />
|stumpy<br />
|{{Bloodgate|holetower.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/11541-illusionists-tower-by-stumpy-201085-summer-fm-vertical-contest-entry}} {{Forumlink|1=http://www.bookofages.co.uk/doom3/mods/holetower.html}} {{Loot|FM:TDM_Illusionist%27s_Tower_-_stumpy}}<br />
|2010-08-05<br />
|9<br />
|SVC 10<br />
|Horror FMs<br />
|Undead and Spiders<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|28|Mad's Mountain}}<br />
|Jesps<br />
|{{Bloodgate|madmountain.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/11510-fan-mission-mads-mountain-by-jesps-20100731}} {{Loot|FM:TDM_Lord_Dufford%27s_-_stumpy}}<br />
|2010-07-31<br />
|2<br />
|SVC 10<br />
|Tombs, Catacombs & Crypts<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|27|Glenham Tower, The}}<br />
|Sotha<br />
|{{Bloodgate|glenham_tower.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/11423-fan-mission-the-glenham-tower-by-sotha-20100717}}<br />
|2010-07-17<br />
|5<br />
|Thomas Porter 3, SVC 10 (Winner)<br />
|Horror FMs<br />
|Undead<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|25|Pandora's Box}}<br />
|Jesps, Fidcal<br />
|{{Bloodgate|pandoras_box.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/11381-fan-mission-pandoras-box-by-jesps20100711}} {{Loot|FM:TDM_Pandora%27s_Box_-_Jesps}}<br />
|2010-07-11<br />
|7<br />
|<br />
|Pirate Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|23|Beleaguered Fence, The}}<br />
|Sotha<br />
|{{Bloodgate|beleaguered_fence.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/11298-fan-mission-the-beleaguered-fence-by-sotha-20100623}} {{Loot|FM:TDM_The_Beleaguered_Fence_-_Sotha}}<br />
|2010-06-23<br />
|11<br />
|Thomas Porter 2<br />
|Jail/Prison Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|22|Special Delivery, A}}<br />
|Silencium18<br />
|{{Bloodgate|delivery.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/11247-fan-mission-a-special-delivery-by-silencium1820100612}} {{Loot|FM:TDM_A_Special_Delivery_-_Silencium18}}<br />
|2010-06-12<br />
|2<br />
|<br />
|Warehouse Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|21|Alchemist, The}}<br>(2010/06/04)<br />
|Sotha, Fidcal<br />
|{{Bloodgate|alchemist.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/11170-fan-mission-the-alchemist-by-sotha-fidcal20100601}} {{Loot|FM:TDM_The_Alchemist_-_Sotha_%26_Fidcal}}<br />
|2010-06-01<br />
|27<br />
|Thief's Den 4<br />
|City Missions<br />
|Undead<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|20|Awaiting The Storm}}<br />
|HappyCheeze<br />
|{{Bloodgate|storm.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/11095-fm-awaiting-the-storm-by-happycheeze-20200522}} {{Loot|FM:TDM_Awaiting_the_Storm_-_HappyCheeze}}<br />
|2010-05-22<br />
|4<br />
|<br />
|City Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|18|No Honor Among Thieves}}<br>(v.2.0, 2013/10/16)<br />
|Goldchocobo, RailGun, Mortem Desino<br />
|{{Mirrorlink|http://tinyurl.com/2a9mdcs}}{{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/10993-fan-mission-no-honor-among-thieves-20100429}} {{Loot|FM:TDM_No_Honor_Among_Thieves_-_Goldchocobo}}<br />
|2010-04-29<br />
|144<br />
|<br />
|Pagan/Outdoor Missions<br />
|Undead and Spiders<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|17|Heart of Lone Salvation, The}}<br>(v.2.0, 2010/04/12)<br />
|Fidcal, Baddcog<br />
|{{Bloodgate|heart.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/10878-fan-mission-the-heart-of-lone-salvation-by-fidcal-baddcog-20100402/}} {{Walkthrough|FM:TDM_The_Heart_of_Lone_Salvation_-_Fidcal_%26_Baddcog}} {{loot|FM:TDM_The_Heart_of_Lone_Salvation_-_Fidcal_%26_Baddcog}}<br />
|2010-04-02<br />
|41<br />
|Thief's Den 3<br />
|City Missions<br />
|Spiders<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|73|Lord Dufford's}}<br />
|stumpy<br />
|{{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/10868-fan-mission-lord-duffords-20100331}} {{Loot|FM:TDM_Lord_Dufford%27s_-_stumpy}}<br />
|2010-03-31<br />
|22<br />
|<br />
|City Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|16|Builder's Influence, The}}<br>(2010/03/23)<br />
|Railgun, Springheel<br />
|{{Bloodgate|builders_influence.pk4}} {{Mirrorlink|http://www.fidcal.com/darkuser/missions/builders_influence.pk4}}{{Forumlink|http://modetwo.net/darkmod/index.php?/topic/10811-fan-mission-the-builders-influence-20100320/}} {{Loot|FM:TDM_The_Builders_Influence_-_Railgun%26Springheel}}<br />
|2010-03-20<br />
|15<br />
|<br />
|Castle/Fortress Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|14|Business as Usual}}<br>(v2.0 2011/09/24)<br />
|Bikerdude<br />
|{{Bloodgate|business.pk4}}{{Mirrorlink|1=http://rapidshare.com/files/335299431/business.pk4.html}}{{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/10533-fan-mission-business-as-usual-by-b1k3rdude-14012010-christmas-fm-contest-entry/page__view__findpost__p__207055}}<br />
|2010-01-14<br />
|4<br />
|GCC 09<br />
|Sewer<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|12|Sons of Baltona 1, The}}<br />
|Carnage<br />
|{{Bloodgate|sons_of_baltona_1.pk4}} {{Mirrorlink|1=http://www.mediafire.com/?m4ywobjodm0}}{{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/10498-fan-mission-the-sons-of-baltona-1-by-carnage-20100109}}<br />
|2010-01-09<br />
|3<br />
|GCC 09 / Baltona 1<br />
|Mansion/Estate FMs<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|11|Living Expenses}}<br />
|Sonosuke<br />
|{{Bloodgate|living_expenses.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/10451-fm-living-expenses-by-sonosuke-2-jan-10/page__view__findpost__p__205386}}<br />
|2010-01-02<br />
|6<br />
|GCC 09<br />
|Mansion/Estate FMs<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|10|Trapped!}}<br />
|RailGun<br />
|{{Bloodgate|trapped.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/10442-fm-trapped-by-railgun-dec-30/page__view__findpost__p__205092}}<br />
|2009-12-30<br />
|6<br />
|<br />
|Jail/Prison Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|8|Parcel, The}}<br />
|Xonze<br />
|{{Bloodgate|parcel.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/10404-fm-the-parcel-by-xonze-dec-24/page__view__findpost__p__204459}}<br />
|2009-12-24<br />
|7<br />
|GCC 09<br />
|Mansion/Estate FMs<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|9|Too Late}}<br />
|Nielsen74<br />
|{{Bloodgate|too_late.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/10400-fm-too-late-by-nielsen74-24-dec-09/page__view__findpost__p__204396}}<br />
|2009-12-24<br />
|4<br />
|GCC 09<br />
|Warehouse Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|7|Thieves}}<br />
|Silencium, RailGun, Fidcal<br />
|{{Bloodgate|thieves.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/10286-fm-the-thieves-nov-2509/}}<br />
|2009-11-26<br />
|9<br />
|<br />
|City Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|6|Patently Dangerous}}<br>(v.2.0, 2013/10/08)<br />
|demagogue<br />
|{{Bloodgate|patently_dangerous.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/10125-fm-patently-dangerous-oct3109/page__view__findpost__p__199324/}}<br />
|2009-10-31<br />
|24<br />
|<br />
|City Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|5|Dark Mod Training Mission, The}}<br />
|TDM Team<br />
|{{Bloodgate|training_mission.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/9932-fm-training-mission-17-oct-09/}}<br />
|2009-10-17<br />
|6<br />
|<br />
|Training<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|2|Crown of Penitence, The}}<br />
|Jesps<br />
|{{Bloodgate|crow_of_penitence.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/9934-fm-crown-of-penitence-by-jesps-17-oct-09/}}<br />
|2009-10-16<br />
|12<br />
|<br />
|Mansion/Estate FMs<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|3|Chalice of Kings, The}}<br />
|Fidcal<br />
|{{Bloodgate|chalice.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/9935-fm-chalice-of-kings-by-fidcal-17-oct-09/}} {{Loot|FM:TDM_Chalice_of_Kings_-_Fidcal}}<br />
|2009-10-15<br />
|3<br />
|Thief's Den 2<br />
|Castle/Fortress Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|1|Outpost, The}}<br />
|angua, greebo<br />
|{{Bloodgate|outpost.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/9937-fm-the-outpost-by-angua-greebo-17-oct-09/}}<br />
|2008-12-23<br />
|2<br />
|<br />
|Castle/Fortress Missions<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|15|Tears of Saint Lucia, The}}<br>(v.1.01, 2010/04/29)<br />
|TDM Team<br />
|{{Bloodgate|saintlucia.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/10579-fan-mission-the-tears-of-st-lucia-20081021/page__view__findpost__p__207972}} {{Loot|FM:TDM_The_Tears_of_Saint_Lucia_-_jdude}}<br />
|2008-10-21<br />
|18<br />
|<br />
|Church/Cathedral<br />
|Spiders<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|57|Closemouthed Shadows}}<br>(v.2.0, 2012/01/15)<br />
|LordSavage, Bikerdude<br />
|{{Bloodgate|closemouthed_shadows.pk4}} {{Forumlink|1=http://forums.thedarkmod.com/topic/13383-fan-mission-closemouthed-shadows-2008-reworked-for-tdm-107-20120115/}} <br />
|2008-09-21<br />
|2<br />
|Closemouthed Shadows 1<br />
|Mansion/Estate FMs<br />
|<br />
|-<br />
<br />
|-<br />
!align=left|{{TDM-FM|24|Thief's Den}}<br>(v.2.0, 2010/07/04)<br />
|Fidcal, greebo<br />
|{{Bloodgate|thiefs_den.pk4}} {{Forumlink|1=http://modetwo.net/darkmod/index.php?/topic/11347-fan-mission-thiefs-den-re-release-by-fidcal20100704}} {{Walkthrough|FM:TDM_Thief's_Den_-_Fidcal}} {{Loot|FM:TDM_Thief%27s_Den_-_Fidcal}}<br />
|2008-01-18<br />
|3<br />
|Thief's Den 1<br />
|City Missions<br />
|<br />
|}<br />
<br />
If the aforementioned download links are down, [http://www.southquarter.com/downloads/missions_view.php South Quarter] has some TDM missions (-2011) as well as a link to it's TTLG forum thread. Just click the 'game column' to sort the list with TDM.<br />
<br />
To see a speculative list of Upcoming Fan Missions please visit: [[Upcoming Fan Missions]]<br />
<br />
<br />
<br />
'''Series Key'''<br />
<br />
GCC 09: Grand Christmas Contest 2009<br />
<br />
SVC 10: Summer Vertical Contest 2010<br />
<br />
CSC 11: Community Seasons Contest 2011<br />
<br />
HSC 11: Halloween Speed-Build Contest 2011<br />
<br />
CBC 12: Community Beginner Contest 2012<br />
<br />
CUC 13: Community Unusual Contest 2013<br />
<br />
<br />
'''Links Key'''<br />
<br />
{|class="wikitable" border=1 style="border-collapse: collapse;" cellspacing=0 cellpadding=2<br />
<br />
|-<br />
|[http://modetwo.net/darkmod/wiki/images/b/be/Icon_forum.png http://modetwo.net/darkmod/wiki/images/b/be/Icon_forum.png]<br />
|Link to discussion in Forums<br />
<br />
|-<br />
|{{Mirrorlink|}}<br />
|Misc. download mirror<br />
<br />
|-<br />
|{{Bloodgate|}}<br />
|Bloodgate download mirror<br />
<br />
|-<br />
|{{Loot|}}<br />
|Loot list<br />
<br />
|-<br />
|{{Walkthrough|}}<br />
|Walkthrough<br />
<br />
|}<br />
<br />
<br />
== Editing This Table ==<br />
* Please only include playable missions that are fully released, not those currently in development or testing. Tutorials, demos, prefabs, etc. should be listed elsewhere. <br />
* A mission title may be listed in plain text as a record of release, or preferably a link to an information page or primary direct download.<br />
* List by release date descending (newest at the top).<br />
* If a fan mission only has a single mirror/host please consider adding additional mirrors. <br />
{{general|sort=Fan Missions}}<br />
[[Category:Fan Missions]]</div>RJFerrethttps://wiki.thedarkmod.com/index.php?title=Triggers&diff=17668Triggers2014-03-03T14:26:04Z<p>RJFerret: Changed positionally relational comments since might not maintain position in future, typos</p>
<hr />
<div>There are many different ways of triggering [[Entity|entities]], the Trigger entities themselves, as well as through [[Stim/Response]], [[Conversations]], Movers, [[Objectives]], and more. How the trigger occurs will typically dictate which manner you choose for your map. <br />
<br />
=Triggers=<br />
To create triggers that rely on boundaries (once, multiple and their derivations), you need to drag out a worldspawn brush, right-click, select "Create Entity". They need to be connected to their subjects, either via "Connect Selected Entities" menu option/shortcut key, or adding "Target", "Target0", "Target1" or subsequent "Target"# spawnargs. The triggers below are listed roughly by frequency of usage, with related triggers beneath.<br />
<br />
==trigger_once==<br />
When the origin of an entity enters the bounds of this entity, the target(s) will be triggered one time only. (Note, to resize the brush after creating the entity, select it then press Tab once.)<br />
<br />
==trigger_once_entityname==<br />
Similar to [[Triggers#trigger_once|trigger_once]], but may be set to only respond to the entity specified by the spawnarg, "entityname". Note the entity must move into the boundaries itself, not be moved by the player (AI walking themselves for example). (If you want something to happen based on the player dropping or placing an item somewhere, use the [[Objectives]] system instead.)<br />
<br />
==trigger_multiple==<br />
Similar to [[Triggers#trigger_once|trigger_once]] but will activate again and again, use "Wait" spawnarg to control how many seconds between triggerings. <br />
<br />
==trigger_entityname ==<br />
Similar to [[Triggers#trigger_multiple|trigger_multiple]] but only reacts to the entity defined by the "entityname" spawnarg.<br />
<br />
== trigger_facing ==<br />
Also similar to [[Triggers#trigger_multiple|trigger_multiple]], but requires the triggering entity to be within 30° of the specified "angle" spawnarg. For details see [[Trigger Facing]].<br />
<br />
==trigger_relay ==<br />
Most commonly used to trigger multiple targets, or do so after a delay (per the "delay" spawnarg). May be set to only work once (spawnarg "wait" "-1") or limit firing based upon how many seconds have passed. The "random" spawnarg may be used with "wait" to vary the firings. Very useful as the target of worldspawn, to trigger things at map start (since worldspawn currently only activate one "Target").<br />
<br />
==trigger_count ==<br />
This will fire at it's targets upon a specific number of times being triggered itself, based upon the "count" spawnarg. If "count" "3" is set, it will do nothing until the third triggering. <br />
<br />
== trigger_timer ==<br />
This trigger will fire repeatedly every "wait" # seconds. The spawnarg "start_on" defines if it should do so at the start of the map, or wait to be triggered (defaults to 0, off at map start). Spawnarg "random" adds variability to the triggerings.<br />
<br />
== trigger_fade ==<br />
Will cause the display to fade to specified color. The spawnarg "fadeColor" specifies which color and how transparent in RGBA (red, green, blue, alpha). Default is fade to black: "fadeColor" "0 0 0 1". To fade up from whatever, use alpha of 0, IE to fade up from black, "0 0 0 0".<br />
<br />
== trigger_hurt ==<br />
(needs experienced write-up, compare with stim/response damage please)<br />
<br />
== trigger_presize ==<br />
(needs experienced write-up)<br />
<br />
== trigger_touch ==<br />
Continuously checks if entities are touching, costly performance wise, probably done via [[Objectives]] more efficiently.<br />
<br />
=Triggering via Stim/Response=<br />
Within the [[Stim/Response]] editor, add a response stim set to "Trigger", now when this entity is targeted, whatever specified effect will occur.<br />
<br />
=Triggering via Conversation=<br />
The command, [[Conversations#Conversation Commands 2|ActivateTarget]] will trigger the specified entity at that time in the Conversation script.<br />
<br />
=Triggering via Doors, Buttons, Levers, Movers=<br />
[[Doors]] trigger their targets by default upon opening (spawnarg "trigger_on_open" "1"). They may also trigger when completely open by changing "trigger_when_opened" to 1 instead of the default 0, or when fully closed via "trigger_on_close". Note, those conditions on Buttons came from doors, so are counter-intuitive.<br />
<br />
=Triggering via Objectives=<br />
In the [[Objectives Editor]] you may select an entity to be triggered upon an objective succeeding or failing. Therefore all the possible objective conditions may become trigger events (knock out an AI, move an object away from another or to a spot, cause another objective to become visible, disappear or complete, etc.)<br />
<br />
=Triggering via Worldspawn=<br />
You may set "Target" on Worldspawn (usually at a trigger_relay since it only may target one entity currently) to cause things to be triggered at map start. If you use this to kill an AI or other affect with audio, note if in range of the player's start, it will be heard during the fade up from black.<br />
<br />
=Triggering via Lights=<br />
Lights trigger their target(s) both upon being extinguished and lit. This is useful to match window glow to actual light condition. Depending on the light, it may be tricky to set the targets however. A basic light entity can simply have target(s) spawnargs, but a candle, lamp or torch with attached flame entity, you need to use the "set" spawnarg. For example, "set target0 on flame" "EntityToBeTriggered".<br />
<br />
[[Category:Editing]]</div>RJFerrethttps://wiki.thedarkmod.com/index.php?title=Editing_FAQ_-_Troubleshooting_%26_How-To&diff=17667Editing FAQ - Troubleshooting & How-To2014-03-03T04:38:27Z<p>RJFerret: /* Events and SFX */ wikilink</p>
<hr />
<div>Below are some common issues and questions mappers have had in the Editor's Guild forum with common solutions. Some of this assumes you've already gone through the [[A_-_Z_Beginner_Full_Guide_Start_Here!]], [[Startpack_Mappers'_Guide]], and [[Dark_Radiant_Must_Know_Basic_Intro]]. (If you know a FAQ not here and worth going in this list, and you know the right answer(!), or you can improve an existing answer, please add it if you have edit control or PM it to a team-member if you don't.) <br />
<br />
= Troubleshooting FAQ =<br />
<br />
== Rendering & VisPortal Issues == <br />
<br />
'''Q. Some of my brushes have disappeared or turned black and won't render.'''<br />
<br />
'''A.''' This can happen when two touching brushes around the seam are not perfectly flush with one another and the rendering hiccups for those brushes & brushes behind it, either there's a tiny wedge or overlap or gap or weird angle between them. The usual solution is to make sure the brushes are snapped to the grid and perfectly flush against one another, or more generally to simplify the brushwork around the seam of the disappearing brushes.<br />
<br />
<br />
'''Q. My visportal is not showing up or not closing like it should (you can check this with by typing "r_showportals 1" in the console. The portal edge will show green when open and red when closed.).'''<br />
<br />
'''A.''' A common reason for that is that the two areas separated by the portal are not hermetically sealed and there's an internal leak, either (1) there may be an unportaled gap between the two, possibly covered up by func_static (which do not seal) or possibly caused by an inadvertent hole created by the first FAQ question above, or (2) an internal leak can happen when all sides of the visportal are not buried in or flush against sealing brushes, and there's a gap between the visportal and brush, or possibly even a tiny gap just touching the visportal side is enough to break it. A way to check if there's an internal leak, and locating it if there is, is described here: [[Visportals#Trouble-shooting]]. Other reasons it might fail are also described there (such as accidentally changing a nodraw texture to something else).<br />
<br />
<br />
'''Q. I can see other rooms behind a mirror (or any reflective surface) through it, instead of just a reflection.'''<br />
<br />
'''A.''' The area behind a mirror should be in a separate leaf (visportaled area) behind a closed visportal so it doesn't render. This problem usually means the two areas aren't in separate leafs, the portal isn't closed, or there's an internal leak between the areas in front of and behind the mirror.<br />
<br />
<br />
'''Q. Help! I'm having rendering & visPortal issues all over the place ... broken portals, sparkly lines, disappearing brushes, z-fighting, uneven walls, etc.'''<br />
<br />
'''A.''' As a general piece of advice, messy brushwork leads to trouble one way or another. To keep your brushwork clean: <br />
* keep snapped to the grid (Ctrl+G toggles) & stay away from small grid levels (Typing a number or Plus/Minus changes the grid scale; 8 is a good starting grid; staying at or above 2 or 4 is fine for most stuff; going below 1 is usually just for special situations). <br />
* Make brush intersections perfectly flush. <br />
* Stay away from unnecessary tiny brushes & wedges (leave detail work to func_statics; brushes are for closing off leafs and the void. Of course you can do fine detail work with brushes & convert them to a func_static). <br />
* Don't use the "CGS Subtract" tool if it will shatter the brush into tiny slivers; use the cut tool instead (open by pushing "X"). <br />
* You can use patches for uneven geometry with square brushes underneath textured with caulk. <br />
* When rotating geometry, avoid weird angles when you can (where vertexes end up off the grid), and for multi-brush structures, build the whole thing first *then* rotate it all together instead of rotating & placing each brush individually. <br />
These aren't rules set in concrete if you want to do something special once in a while, but general rules of thumb that will make life a lot easier if you generally stick to them.<br />
<br />
== Crashes and Warnings ==<br />
<br />
'''Q. My map has a leak in it, but a pointfile either isn't generated or doesn't make sense. (A pointfile is generated when dmap occurs and there's a leak, then you open DarkRadient and click File>Pointfile to see it. It normally runs a red line that ends in the void, pointing out the leak).'''<br />
<br />
'''A.''' Make sure a gap isn't covered up with func_statics. If the origin of a model is in the void it will also cause a leak with a non-sense pointfile. Read more on the [[Leaking maps]] page.<br />
<br />
'''Q. How do I scroll up through the console output to see what a problem was during dmap or map or in-game?'''<br />
<br />
'''A.''' Use the mouse wheel or PageUp/Down to scroll through the console.<br />
<br />
'''Q. I'm getting an error message "warning: aas is out of date" once my map has loaded. What does it mean and what do I do?'''<br />
<br />
'''A.''' The AAS is for AI pathfinding. It usually means you changed brushwork and started a map without dmapping first. The solution is to dmap. If you dmap and still get the warning, delete your .aasxx, .proc, and .cm files in the maps folder and dmap again. If you're still getting a warning, then it could be a sign that something in your map is breaking the AAS pathfinding. Try monsterclipping tricky areas for the AI to path (like around objects and uneven ground) or clean up messy brushwork that might break the dmapping like sliver brushes. <br />
<br />
'''Q. I have encountered a malloc failure error while dmapping my level. Instead of finishing with the dmap operation, it crashes midway with an error message.'''<br />
<br />
'''A1.''' One solution to this is given in the Dmap wiki entry here: [[Dmap#Malloc_Errors]]. <br />
<br />
'''A2.''' This is what I've done to fix this exact issue. Open the map in DarkRadiant, select everything, copy to clipboard. Open another instance of DarkRadiant and paste from clipboard. Save as new filename and dmap new file and that has worked 3 times now with random unresolvable crashes.<br />
<br />
'''A3.''' GC and I have found correlations between visportalling and mAlloc errors. Time to re-arrange your visportals. In NHAT, we had many malloc problems until we retooled how each area was portaled. Originally, every other visleaf had tons of entities, while half had hardly any. That's not neccessarily bad, but it strains the dmapper when one or two visleafs are cluttered with entities that really bloat your mapname.proc file. We added a few more portals to even out entity distribution, and dmap was happy again.<br />
<br />
== Performance Issues ==<br />
<br />
'''Q. My map is so slow. How do I improve performance?'''<br />
<br />
'''A.''' See these wiki entry: [[Performance:_Essential_Must-Knows]]. Tips include: <br />
* Reduce AI [[Pathfinding]] with Monsterclipping helps performance, simplifying complex bumpy surfaces into 1 smooth monsterclipped surface (or raise the monsterclip height to be inside the ceiling and there is no pathfinding computation at all), or excluding entire surfaces AI should never walk on, like detail brushwork or some roofs. <br />
* Use [[Interleaved_Thinking_optimization]]. Reducing AI think-time helps performance quite a bit. <br />
* break-up long lines of sight, <br />
* improve visportal & leaf placement (so less architecture is rendered at a time), <br />
* use fewer AI, <br />
* convert ornamental brushwork into func_static, <br />
* reduce the overlap of light sources on surfaces by adjusting their placement & reducing their light-radius. (Every time a new light hits a surface, it's another render pass. So 4 lights hitting a surface processes it 4 times. If only 1 light hit it, its lighting is processed in 1/4 the time), and <br />
* set objects and lights to "noshadow" if it won't be noticable to the player or affect gameplay (possibly in combination with low-poly shadow meshes or shadowy decals. Note that "noshadow" has two jobs. Put on lights, it means that light will cast no shadows on any object. Put on objects, it means that object will not cast a shadow from any light.) <br />
<br />
There are also lots of other tricks out there if you check around the forums, including more advanced & optional tricks such as using the [[LOD]] system or [[SEED]] system, or even crazier tricks (cross-leaf func_statics, skybox architecture, Strombine lighting, Camera Cubemapped Visportal Patches, lots of crazy tricks out there), that you don't have to worry about if you're a new mapper but you can ask us about or search for in the forum if you're curious. Generally speaking there are pros and cons trade-offs between performance & dazzle for many things (like lights or visportal placement); so it's good to think about the best performance-dazzle balance for your scene. E.g, lots of highpoly brushwork, lights, & AI can look good in a small or medium room, but may not be worth the performance hit in a big courtyard, and try to find ways to get better performance "for free" without the player noticing anything missing, like smart use of noshadows, monsterclips, and interleaved thinking distances.<br />
<br />
== Gameplay Issues that Mappers sometimes Overlook ==<br />
<br />
'''Below is a list of common gameplay issues that players sometimes complain about and that mappers & testers sometimes overlook or should at least be aware of.'''<br />
<br />
- Players find it very difficult to frob objects (loot, keys, readables) when the frob distance is set too short or the space is awkward (like in a drawer or up on a wall, etc). In testing, please double-check that every frobable object is easy to frob from a comfortable place, and increase the frob distance if it's not, erring on the side of more space. (See the question on making frobbing easier under "Handling Objects" below for more information.) <br />
<br />
- Objects can get stuck into brushwork while moving them around. <br />
<br />
- Players can get stuck in narrow spaces and can't mantle out, so try to avoid this kind of geometry if possible. <br />
<br />
- A very low ceiling can prevent hitting AI with a BJ, so try to avoid it when AI are around. <br />
<br />
- Make sure AI have a flee path. <br />
<br />
- Some players would like the ability to drop used keys and other inventory items, done by turning the can_be_dropped property to true, unless for gameplay reasons you don't want to. <br />
<br />
- Some players don't like long readables that don't get to the point. At least be conscious of how your readables read to a player.<br />
<br />
- Think about how you want to handle non-functioning doors (or other "unnatural" situations like windows that can open) in a way that visually or fairly communicates to the player that something is special about this door or window, but isn't too immersion breaking either.<br />
<br />
== Issues with Objects == <br />
<br />
'''Q. My streetlight, candle, lamp, light-creating object, causes a weird shadow I want to get rid of.'''<br />
<br />
'''A.''' Put the spawnarg "noshadows" "1" on the offending object.<br />
<br />
== AI Issues == <br />
<br />
'''Q. My AI will not pass through a visportal no matter how I set up the path nodes.'''<br />
<br />
'''A.''' Check that the sides of the visportal use the nodraw texture (except for the portal-face itself of course).<br />
<br />
<br />
'''Q. How do you get AI to walk on complex terrain patches or func_statics?'''<br />
<br />
'''A.''' You can always lay down invisible monsterclip brushes and the AI can walk on it. Overlay with a brush with a "material" clip texture so it causes the right sound for footsteps.'''<br />
<br />
== Problems with Patches ==<br />
<br />
'''Q. I have 2 curved patches and they're not aligning. What do I do?'''<br />
<br />
'''A.''' See this wiki page [[Patch_Troubleshooter]].<br />
<br />
'''Q. My patch is rendering strangely, like fractured into slivers.'''<br />
<br />
'''A.''' See this wiki page [[Patch_Troubleshooter]].<br />
<br />
== Issues with Lighting & Sound == <br />
<br />
'''Q. Some of the parallel lights I use for moonlight aren't giving off any light.'''<br />
<br />
'''A.''' This is a known problem with parallel lights. For some reason in some arrangements you get no light at all. Just fiddle with it a bit - move it slightly, change the radii, move the vertex a bit - and it should suddenly work. Once you've got it working then it's stable. Likely the code chokes on certain values in its calculations. ... Also, to help optimize your moonlight, you should adjust the radius so it's only as big as it needs to be. You may also want to move the actual position of the little moon cube in the skybox to match the parallel light (and make sure to fix the texture on it if you mess it up - hint: lock textures before moving cube to make it easy)<br />
<br />
= General How-To Editing FAQ =<br />
<br />
== Dark Radiant Questions == <br />
<br />
'''Q. How do I see all the default properties already on an object?'''<br />
<br />
'''A.''' In the entity inspector there's a checkbox near the top that says "Show Inherited Properties". Click that box.<br />
<br />
'''Q. What are some basic units, scales, limits, maxs, and mins of various things when editing?'''<br />
<br />
'''A.''' A list of all these things is here: [[Limits,_Max,_Min,_Stats,_etc]].<br />
<br />
'''Q. Can I manipulate brushes to resize and reshape them?'''<br />
<br />
'''A.''' Yes. In DarkRadiant you can select a brush and push "V" to select verticies to drag and resize, "E" to select edge(s) to drag and resize, and "F" to select face(s) to drag and resize. "Ctrl+#" makes a selected brush be #-sided. You can also use the Brush>Prism and Brush>Cone to convert a brush to those shapes. <br />
<br />
'''Q. What are some common DR shortcut commands?'''<br />
<br />
'''A.''' <br />
* "H" hides selected items. <br />
* "I" inverts selected. <br />
* "Ctrl+I" inverts a patch's normal. <br />
* "J" brings up entity list. <br />
* "Ctrl+K" makes 1st-selected-entity "target" 2nd-selected-entity. <br />
* "L" brings up light inspector. <br />
* "Ctrl+L" brings up the Layers menu. <br />
* "N" brings up entity inspector. <br />
* "T" brings up texture browser. <br />
* "X" go into clipper mode. <br />
* Brush manipulation modes: are "R" rotate brush, "Q" free-move & resize, "W" translate-move.<br />
<br />
'''Q. How do I make my own shortcut key commands?'''<br />
<br />
'''A.''' Under the Edit menu, at the bottom is "Keyboard Shortcuts" which allows you to set your own shortcuts.<br />
<br />
'''Q. I screwed something up! What do I do?!'''<br />
<br />
'''A.''' Ctrl+Z undos. Ctrl+Y redos.<br />
<br />
'''Q. Is there a way to organize & simplify building, so I can build one section at a time without other sections getting in the way?'''<br />
<br />
'''A.''' DR has a [[Layers]] function that lets you build one "layer" at a time (open with ctrl+L or View>Layers). It also improves DR performance, which is handy as the map gets bigger.<br />
<br />
'''Q. How do I set up things like the pre-game shop, the player inventory, and an in-game map?'''<br />
<br />
'''A.''' All these things are described in the Startpack Mappers' Guide: [[Startpack_Mappers'_Guide#Ammo.2C_Weapons.2C_Player_Tools.2C_Start_Inventory]], [[Startpack_Mappers'_Guide#Purchase_Shop]], [[Startpack_Mappers'_Guide#Adding_an_In-game_Map_to_your_FM]]<br />
<br />
'''Q. How do I put spawnargs on def_attached entities?'''<br />
<br />
'''A.''' You can put spawnargs on def_attached entities by using the spawnarg "set SPAWNARGNAME on ATTACHMENTNAME" "value" on the base entity. Here's an example of setting a color property on a flame attachment to a torch "set _color on flame" "0.2 0.2 0.9". Read more here [[Combined_light_entities#Setting_spawnargs]].<br />
<br />
'''Q. What's an easy way to find materials in DR?'''<br />
<br />
'''A.''' Tip to help find materials in Dark Radiant's materials browser: <br />
# Point to Textures (or any tree). <br />
# Shift + Right key to fully open the tree. <br />
# Type the key letters of what you want to find. <br />
# Up/down arrows to go to next/previous occurrence. <br />
# Esc to get out of input field. <br />
Oh yeah, avoid F3 because that is likely to switch to render mode which in my case crashes DR (but may not if the map is small).<br />
<br />
'''Q. How do I make an N-sided brush?'''<br />
<br />
'''A.''' A quick way to make an N-sided brush is to highlight the brush and push cntl+N (N being the number of sides for the top face). So if you want a 5-sided brush, highlight it and push cntl+5. But the best way to get the walls of a multi-sided brush to line up seamlessly is still to use the clipper-tool and precisely cut off a slice. (And don't use CSG Subtract unless you know what you're doing and aren't creating a million splinters!)<br />
<br />
== Console Questions ==<br />
<br />
'''Q. How do I open the console?'''<br />
<br />
'''A.''' Open the console with ctrl+alt+~ in a normal game, and just ~ when playing through "map". <br />
<br />
'''Q. How do I scroll through the console output?'''<br />
<br />
'''A.''' Use the mouse wheel or PageUp/PageDown.<br />
<br />
'''Q.What's a list of all the Doom3 Console Commands and CVars?'''<br />
<br />
'''A.''' A list of all commands & Cvars is here [http://www.doomwadstation.com/doom3/console/]. Darkmod Cvars are listed here [[Cvars_in_The_Dark_Mod]].<br />
<br />
'''Q. What are some *useful* console commands and cvars for editing?'''<br />
<br />
'''A.''' Here's one list: [[Console_Useful_Controls]]. Here's a list more tailored to mapping: <br />
<br />
Commands: <br />
"'''dmap <name>'''" compiles a map, <br />
"'''give <name>'''" gives the player an item, <br />
"'''god'''" player cannot be harmed,<br />
"'''killmonsters'''" takes out all AI<br />
"'''map <name>'''" loads a map to play, <br />
"'''noclip'''" lets the player go through objects and walls, <br />
"'''notarget'''" let's the player be invisible to AI, <br />
"'''reloadDecls'''" will reload material defs without having to re-start TDM, <br />
"'''reloadimages'''" does the same for lights and <br />
"'''reloadSurface'''" for surfaces, <br />
"'''saveRagdolls'''" saves the positions of all ragdolls to the .map file (see the FAQ under Handling AI), <br />
"'''teleport <name>'''" teleports the player to an entity. <br />
"'''tdm_show_loot'''" Shows loot.<br />
"'''spawn <name>'''" spawns an entity: <br />
spawn atdm:weapon_blackjack<br />
spawn atdm:weapon_shortsword<br />
spawn atdm:ammo_broadhead<br />
spawn atdm:ammo_firearrow<br />
spawn atdm:ammo_gasarrow<br />
spawn atdm:ammo_mossarrow<br />
spawn atdm:ammo_noisemaker<br />
spawn atdm:ammo_ropearrow<br />
spawn atdm:ammo_waterarrow<br />
Append "inv_ammo_amount 50" to any of the above to spawn 50 arrows at once: spawn atdm:ammo_broadhead inv_ammo_amount 50<br />
Cvars (1 turns on, 0 turns off, unless otherwise noted): <br />
"'''com_showFPS 1'''", <br />
"'''r_showLightCount 1'''" (colors shows the number of lights hitting a surface, black = 0, red = 1, blue = 2... etc), <br />
"'''r_showPortals 1'''" (red=closed,green=open) If your portals dont show up they are most likely not sealing.<br />
"'''r_showTris n'''" (n=1) Shows tris rendered directly, (n=2) shows overdrawn tri's, (n=3) shows all tri's, direct and indirect.<br />
<br />
== Objectives ==<br />
<br />
'''Q. How do I set up a put-object-here objective?'''<br />
<br />
'''A.''' Instructions are here [http://forums.thedarkmod.com/topic/9082-newbie-darkradiant-questions/page__view__findpost__p__182924]<br />
<br />
'''Q. How do I set up a "ghosting" objective (e.g., you are busted if you are seen.)'''<br />
<br />
'''A.''' Instructions are here [http://forums.thedarkmod.com/topic/9082-newbie-darkradiant-questions/page__view__findpost__p__204695]<br />
<br />
== Handling Objects == <br />
<br />
'''Q. How do I attach a door handle to a door?'''<br />
<br />
'''A.''' Just position the handle and input "bind" and the door entity ID/name as a spawnarg. <br />
<br />
'''Q. How do I make an object into loot?'''<br />
<br />
'''A.''' Instructions are here [http://forums.thedarkmod.com/topic/9082-newbie-darkradiant-questions/page__view__findpost__p__182921]<br />
<br />
'''Q. How do I make an entity frobable?'''<br />
<br />
'''A.''' See the entry for [[Making an Entity frobable]].<br />
<br />
'''Q. Ok it's frobable, but doesn't fall or move. How do I make an entity act like a world object?'''<br />
<br />
'''A.''' You need to make the object a moveable, see [[Moveables]].<br />
<br />
'''Q. How do I get a lever or button to open a door?'''<br />
<br />
'''A.''' Instructions are here [http://forums.thedarkmod.com/topic/9082-newbie-darkradiant-questions/page__view__findpost__p__212036]<br />
<br />
'''Q. How do I put some text on a sign or wall?'''<br />
<br />
'''A.''' You can use this method [http://forums.thedarkmod.com/topic/11159-add-text-to-your-signs-signposts-walls-etc/]<br />
<br />
'''Q. How do I bind something to a rope (like a body) so it doesn't fall?'''<br />
<br />
'''A.''' Dynamic ropes are unreliable, so it's good to use a func_static like a chain or make a func_static rope from a cylinder brush. For a ragdoll, place the ragdoll so he clips into the func_static. You need to bind the ragdoll to the chain (so the spawnarg is on the ragdoll), with "bind" "func_static_...", where func_static_... is the chain. Or, through DR, you can just select the entity you want to attach (the ragdoll), then also select the thing you want to attach it to (the chain), and in the menus select "Entity" - "Bind selected entities". But it's been reported the clipping does the job, not binding. See this link [http://forums.thedarkmod.com/topic/9082-newbie-darkradiant-questions/page__view__findpost__p__221262]<br />
<br />
'''Q. How do I make something switch from frobable to unfrobable like a used lever, or unfrobable to frobable like contents in a chest or drawer you don't want frobable until it's open?'''<br />
<br />
'''A.''' Make a brush around the object with a clip texture and convert it to an atdm:target_set_frobable entity, with the property "start_frobable" 1 or 0 (which mean true or false) depending on your case (it affects everything inside), and a triggering entity, such as the lever or the chest itself, that targets the set_frobable entity that triggers the switch when it's frobbed. For the record, you can also switch the frobability of an object in a script with the command: '''$<entityname>.setFrobable(n);''', where n is "1" to make it frobable and "0" for unfrobable.<br />
<br />
'''Q. How do I make breakable glass?'''<br />
<br />
'''A.''' Instructions are here [http://forums.thedarkmod.com/topic/9082-newbie-darkradiant-questions/page__view__findpost__p__222734]. You basically convert your glass brush to a func_fracture entity and set the "health" spawnarg to the value you want the glass to break at. <br />
<br />
'''Q. What about an object that gets increasingly damaged-looking as you hit it?'''<br />
<br />
'''A.''' Use a func_damagable entity, which replaces its model and/or shader with increasingly "damaged" versions (as many stages as you like) when its health goes below the threshold you set with the "health" spawnarg, and you can use "target" to trigger something when damage occurs (such as a sound effect or event). See here for details on the spawnargs involved in setting it up: [http://www.modwiki.net/wiki/Func_damagable_(entity)]<br />
<br />
'''Q. How do I make an object that you can frob and it does something or something happens?'''<br />
<br />
'''A.''' If it's an object you made from patches or brushes, make it into a frobable func_static, or if it's already a func_static, make sure it's frobable ([[Making an Entity frobable]]). Then give it a Frob response whose effect is a trigger, and give it a "target" spawnarg to the entity that causes your effect when triggered.<br />
<br />
'''Q. Can a lever or button target multiple entities?'''<br />
<br />
'''A.''' Yes! Use the spawnargs "target1", "target2", "target3", etc, with each entity-target as a value. A quicker way is to use the keyboard shortcut Ctrl+K. Select the button or lever, then select the target-entity and hit Ctrl+K. De-select the target-entity then select the next one, hit Ctrl+K again. Each time adds a new target to the switch. (Many other spawnargs allow you to have multiple entries by numbering them, such as bind and def_attach.)<br />
<br />
'''Q. How do I make a rotating entity, like a fan?'''<br />
<br />
'''A.''' Instructions are here [http://forums.thedarkmod.com/topic/9082-newbie-darkradiant-questions/page__view__findpost__p__242385]<br />
<br />
'''Q. How do I make objects non-solid so they still render but the player can walk through them?'''<br />
<br />
'''A.''' Add the spawnarg: noclipmodel 1 to turn them into non-solids.<br />
<br />
'''Q. How do I make a firefly or will-o-wisp, basically a glowing ball that floats around?'''<br />
<br />
'''A.''' This is a rough explanation to help you get started. A firefly is a func_emitter. Click the model property then use the button bottom right to select a suitable particle effect, possibly tdm_glare_lamp_01.prt. Bind to something invisible that will move it along a path, typically a func_mover with nurb curves used as the path. A tutorial for setting up nurb curves is here [http://www.doom3world.org/phpbb2/viewtopic.php?t=5123].<br />
<br />
'''Q. How do I trigger an event from something in the player's inventory?'''<br />
<br />
'''A.''' give the object a "target" to trigger and also the property/value: scriptobject InvTriggerScript. If your object does not already go in the inventory then use the entity: items > custom > atdm:moveable_custom_item. If you get a collision model error then ask on the forums for help (or read the wiki entry for [[Moveables]]).<br />
<br />
'''Q. How do I teleport an entity?'''<br />
<br />
'''A.''' Use targets/atdm:teleport. See this wiki page [[Teleporting_entities]]. <br />
<br />
'''Q. How do I make a custom inventory item with its own inventory icon graphic?'''<br />
<br />
'''A.''' See this entry [[A_-_Z_Beginner_Full_Guide_Page_6#Special_Items]] for setting the inventory category, loot type, inventory name and inventory icon. To repeat the instructions for a custom icon: on the object put the property "inv_icon" with a value "guis/assets/hud/inventory_icons/<name>.tga" (substitute whatever name you gave it for <name>), and package your .pk4 to put your image file in that relative location. You can also see other inventory_icons there and can use an existing one, or package your .pk4 to replace an existing one with your custom one. A method for making an inventory icon is described here [http://forums.thedarkmod.com/topic/9082-newbie-darkradiant-questions/page__view__findpost__p__259172] (be sure to use an alpha channel to make the background transparent, tutorial: [http://www.axialis.com/tutorials/tutorial-misc001.html]).<br />
<br />
'''Q. How do make an object that's hard to frob easier to frob?'''<br />
<br />
'''A.''' One easy way is to add this property: frobbox_size 5. If it's still hard, see this post for other things you can do. [http://forums.thedarkmod.com/topic/11570-editing-tip-of-the-day/page__view__findpost__p__228245]<br />
<br />
'''Q. How do I make a candle you can pinch to go out?'''<br />
<br />
'''A.''' I made a bunch of pinchable non-moveable candles into my WIP like this: <br />
# Make a func_static candlestick. place light source entity candleflame on it. <br />
# Give the candlestick "frobable 1." <br />
# Give the candlestick S&R response frob, extinguish light and candleflame name. <br />
# You can optionally add another response frob to trigger a speaker with a "snuff" sound effect. <br />
# Done.<br />
You can copy the entity bunch around and all the params should update correctly for the new replica. Frobbing will not relight it: the player needs to relit them with a flame source.<br />
<br />
== Handling AI == <br />
<br />
'''Q. How do I make sure a guard can unlock a door?'''<br />
<br />
'''A.''' There are a few different ways, explained here [http://forums.thedarkmod.com/topic/9082-newbie-darkradiant-questions/page__view__findpost__p__217915]<br />
<br />
'''Q. How do I attach a key or purse to an AI's belt, or similar kinds of attachments?'''<br />
<br />
'''A.''' The easiest way is with "bind". Place the key or purse around the belt area where you want it, sticking a little farther out than usual, and rotate it as desired. On the key add the property "bind" with the value of the AI's entity-ID or name, then the property "bindToJoint" with the value "leftHips_dummy" or "rightHips_dummy" as needed. For attaching things in other places (like a ring or hat or necklace), it's the same general principle but you should look up the joint to attach to. A list of all the joint names is here: [[BindToJoint]]. See this wiki entry for more info [[Attaching_Items]]. For another method using def_attach see [[Attaching_Props_to_AI]], and this post for an example of the spawnargs involved [http://forums.thedarkmod.com/topic/13084-ai-attach-keys/page__view__findpost__p__276064]. The issue with def_attach is that the attached thing spawns at its own rotation angle, which might not look great and is tricky to change (if you insist, see [[AI_Attachment_Ingame_Editing]] and [[Cvars_in_The_Dark_Mod#Attachment_related]]). With bind you just place and "bind", and it stays where you put it.<br />
<br />
'''Q. What about other kinds of attachments where special animations are involved, like torches and weapons?'''<br />
<br />
'''A.''' For these you want to use Def_Attach. See this wiki entry [[Attaching_Props_to_AI]]. For heads & weapons specifically see this wiki entry [[Adding_Heads_and_Weapons_to_AI]]. (You can set spawnargs on the def_attached entities with the method described here [[Combined_light_entities#Setting_spawnargs]].)<br />
<br />
'''Q. How do I mute an AI?'''<br />
<br />
'''A.''' Give the AI the spawnarg: def_vocal_set atdm:ai_vocal_set_mute. If you only want to mute some barks, you'll have to modify the AI's .def file by hand, taking or commenting out the barks you don't want, and packaging the new def file in your mission's pk4. For coughing and animation based barks, see this post [http://forums.thedarkmod.com/topic/9082-newbie-darkradiant-questions/page__view__findpost__p__224558]<br />
<br />
'''Q. Can I hide an AI until I trigger him?'''<br />
<br />
'''A.''' No, the spawnarg "hide" doesn't work well with AI (they're made invisible, but still audibly there). Put the AI in a blueroom and use a teleport instead, or a teleporting script command. See the wiki entry for [[Teleporting_entities]]. Note, after teleporting an AI, pathing becomes a problem for it. See this post [http://forums.thedarkmod.com/topic/9082-newbie-darkradiant-questions/page__view__findpost__p__280818] and the previous posts on this issue to make sure the AI can path properly after a teleport. <br />
<br />
'''Q. How do I manage AI teams, who is a friend, enemy and neutral?'''<br />
<br />
'''A.''' To set the teams, see [[Relations]]. If you want to trigger a change in team with a script, see [[AI_Relations_(Scripting)]]. Another method to switch AI teams using S&R (stim & response) is described here [http://forums.thedarkmod.com/topic/9082-newbie-darkradiant-questions/page__view__findpost__p__256126] and see the entry [[Stim/Response]]. <br />
<br />
'''Q. How do I make an AI play an animation when I want?'''<br />
<br />
'''A.''' Instructions are here [http://forums.thedarkmod.com/topic/9082-newbie-darkradiant-questions/page__view__findpost__p__253169]. There may be other ways possible.<br />
<br />
'''Q. How do I set or change the health of AI?'''<br />
<br />
'''A.''' AI use the spawnarg "health" to set their hit points. To change it in-game, use a script and the function "setHealth". <br />
<br />
'''Q. How do I pose ragdolls so they look naturally placed?'''<br />
<br />
'''A.''' Save a backup, pose all the ragdolls in-game, then use the console command saveRagdolls which saves their positions to the .map file. cf. [http://forums.thedarkmod.com/topic/9082-newbie-darkradiant-questions/page__view__findpost__p__265650].<br />
<br />
'''Q. How do I make a scene of AI playing cards?'''<br />
<br />
'''A.''' Probably the easiest thing to do is load the prefab (under AI), place it, and adjust it how you want.<br />
<br />
'''Q. How do I make an AI frob something?'''<br />
<br />
'''A.''' To get an AI to frob something, eg, a lever (doesn't work to pick up and carry) create a path_interact entity. You can include it in a normal pathing patrol. Give it these 2 spawnargs: ent <name of entity you want the AI to frob>; target <next path entity (if any)>. Note that the AI won't walk to this entity; you have to use a path_corner to get him where you want then target to the path_interact to get him to frob.<br />
<br />
'''Q. How do I make an AI catch fire?'''<br />
<br />
'''A.''' You can bind some unlit fires to an NPC (like a zombie) and shoot it when a fire arrow, he'll erupt in flames, but the flames won't damage him. You could also light him with a candle. I'd bet theres some way to make that actually kill the creature, or at least cause it damage. ... One improvement suggestion: When the the light gets the fire stim, target a trigger multiple, which delays for a 120-240 seconds and then turns the fire off. You could make the fire damaging by starting a trigger timer which applies the stim damage to the target every few seconds. Remember to switch off the timer when the flames are doused.<br />
<br />
'''Q. How do I keep an AI ragdoll from sinking into the bed model, e.g., if he's KO'd?'''<br />
<br />
'''A.''' I found one way to keep [an unconscious/dead ragdoll body] from sinking into the model below it is to use a platform of nodraw_solid underneath the body. You should be able to place such a brush within the bed model and test it with a ragdoll on the bed. Adjust it's top surface height until the body lays just on top of the bed (then delete the ragdoll)... then a blackjacked AI should be able to stay on top of the bed like the ragdoll did.<br />
<br />
== The Player == <br />
<br />
'''Q. How do I do things with the player's inventory, like trigger an inventory item to be deleted, or an item to be added to the inventory, or one item being replaced with another item?'''<br />
<br />
'''A.''' You can do all these things with a script (read [[A_Beginner's_Guide_to_Scripting]] and the scripting FAQ below to learn about scripting). Have your triggering mechanism trigger a target_callscriptfunction entity which calls a custom script, then use the appropriate script command in the script on $player1. A list of the commands is here [[Inventory#Scriptsupport]]. <br />
Useful commands are (replacing the "Item" variables with the item ID): <br />
* '''$player1.addInvItem(inv_item);''' and <br />
* '''$player1.replaceInvItem(oldItem, newItem);''' (note: If <newItem> is the $null_entity, <oldItem> is just removed and no replacement happens.) <br />
For example, to remove a key from the player's inventory, use a command like: '''$player1.replaceInvItem ($key, $null_entity);'''<br />
<br />
'''Q. How do I teleport the player?'''<br />
<br />
'''A.''' Use base > info_player_teleport. Give it the spawnarg and value: target info_player_start_1. Give it the spawnarg: angle with a value if you want to force the player to turn to face a particular direction.<br />
<br />
'''Q. How can I simulate a crawl for the player to pass under things like tables that he couldn't normally do?'''<br />
<br />
'''A.''' See this post [[http://forums.thedarkmod.com/topic/11570-editing-tip-of-the-day/page__view__findpost__p__229174]]<br />
<br />
== Scripting ==<br />
<br />
'''Q. How do I make a custom script?'''<br />
<br />
'''A.''' First read [[A_Beginner's_Guide_to_Scripting]], [[Scripting_basics]], and [[My_first_map_script]] to learn the basics of scripting. You write a custom script as a text file named <mapname>.script and packaged in your .pk4 in the same place as your .map file. Inside it you make your own script object in the format the Beginner's Guide gives you, usually looking like '''void MyScript() { code goes here }'''. Then the game can "call" "threads" of that "script object" that will run until they end or are killed, so you can have more than one thread running of the same object concurrently. If you want multiple script objects, put them all in your <mapname>.script file and the game-engine will find them. You run scripts by the object name, not the file name. <br />
<br />
'''Q. How do I run a script in-game?'''<br />
<br />
'''A.''' A few common ways of calling a script object thread in-game are <br />
# creating a target_callscriptfunction entity with the spawnarg: "call" "<name of your script object>", then creating some other entity (such as a button or trigger brush) that "targets" that entity; <br />
# creating a button with the property "state_change_callback" "<script object>", which runs the script when pushed or triggered, <br />
# Using [[Location_Settings#Script_calls]] to call a script when you enter or leave a location; <br />
# triggering a script with the [[Objectives_Editor]] when you fulfill or fail an objective (possibly a hidden objective only for triggering the script); <br />
# A script can call another thread in itself with the "thread" function; see the command in the link below. <br />
# An entity can call a script when it spawns. Add a property/value either in the .def file or as a spawnarg on the entity: "ScriptEvent void <script object>(<parameters>);". <br />
# The script "void main();" is always called at game start. So if you add code under that heading in your script file, it will run at game start. <br />
There are other methods too. (Note, if you call a persistent script, i.e., it runs all game, be especially sure to avoid performance hits, or make it non-persistent if possible, that is, you "kill" it at some point in the game so it doesn't hog resources..) <br />
<br />
'''Q. What are script events (aka commands or functions)?'''<br />
<br />
'''A.''' A script event is a pre-made object that does something for you, usually to some game item you specify, just when you write it in your code (like '''$item.eventX();''' does X to item). Sometimes it wants parameters or arguments to run (the stuff in parentheses) and will give an error if you don't put the arguments in the parentheses in exactly the way it wants, with the right number of them & right data types, etc. And some of them return values too, especially the "get" functions, which are handed over to a variable (e.g., '''X = getValue();''', now X has the value. If X is an entity, you can even act on X as if it's the entity itself. Just be sure the data type of X and Value are the same, e.g. float, or string, or entity, etc, or you'll get an error). <br />
<br />
'''Q. What are some common or useful script events for editing?'''<br />
<br />
'''A.''' A list of all Doom3 and TDM script events are listed on this wiki page [[TDM_Script_Reference]], including the proper syntax (or this page, but it's down now: [http://www.modwiki.net/wiki/Script_events_%28Doom_3%29]), or also these two files in your Dark Mod folder (open with a text editor): scripts/doom_events.script, scripts/tdm_events.script. Note that TDM has some of its own script events, like setFrobable (in the tdm_events.script list). <br />
<br />
A quick short list of common or useful script events good for editing is here: [[Script_Events_User-Friendly_List]], with syntax and description, and including TDM events. It doesn't list all script events and all details, just common & useful ones for actual mapping IMO. If you want the full list, use the TDM_Script_Reference link I gave above.<br />
<br />
== World Building == <br />
<br />
'''Q. What's a good way to make caves?'''<br />
<br />
'''A.''' Some tips are here [http://forums.thedarkmod.com/topic/9082-newbie-darkradiant-questions/page__view__findpost__p__204909] & [http://forums.thedarkmod.com/topic/9082-newbie-darkradiant-questions/page__view__findpost__p__289484] Instructions for quick-cavern pattern building is here [http://forums.thedarkmod.com/topic/14469-quick-caverns-recipe/page__view__findpost__p__304250]<br />
<br />
'''Q. How do I make a good looking roof using clean brushwork, including with an attic inside?'''<br />
<br />
'''A.''' Here are descriptions of method that all use a similar trick [http://forums.thedarkmod.com/topic/9082-newbie-darkradiant-questions/page__view__findpost__p__325945], [http://forums.thedarkmod.com/topic/9082-newbie-darkradiant-questions/page__view__findpost__p__325944], [http://forums.thedarkmod.com/topic/9082-newbie-darkradiant-questions/page__view__findpost__p__244109]. The trick is to "cut out" a roof from a square brush using the clipper tool. Avoid rotating brushes to make it by hand. Alternatively, use patches over a rectangular under-structure of BSP brushes, although this is not good if you want a portaled attic. <br />
<br />
'''Q. What's a good way for making a city area that performs well?'''<br />
<br />
'''A.''' Sotha gave a good method in this post. [http://forums.thedarkmod.com/topic/10003-so-what-are-you-working-on-right-now/page__view__findpost__p__312133]<br />
<br />
'''Q. What's a good way for making a forest or a big outdoorsy area?'''<br />
<br />
'''A.''' One good method is making large "rooms" in the shape of a big oval cylinder with very high natural-looking "rocky" & skybox walls and uneven ground using patches, filling it with trees and hiding some of the walls behind trees and greenery (you could also fill it with thick cylinder brushes of different sizes with bark texture to look like more trees, and place branches coming off them or to make a canopy), and possibly filling it with tons of grass (using [[SEED]]) and rocks and streams, with visportaled openings at "kiss points" in the walls to other large oval rooms at different orientations (maybe 2-5 connections per oval) so there's a dense web of interconnected forested rooms that (sort of) appear to be one big dense forest to the player. Some useful things to use are the [[Object_detail]], [[SEED]], and [[LOD]] systems. See the blueprint for the Thief 2 level Trail of Blood for a rough idea: [http://thief.wikia.com/wiki/T2_M10_Trail_of_Blood?file=T2_m10a_editor_colored.gif]. For good examples in Dark Radiant, look at the construction of mission 3 of No Honor Among Thieves ("No Honor Among Anyone") and Shadowhide's slenderman forest map. (Somebody post links to screenshots of those maps in DR, or remind me to.) <br />
<br />
'''Q. How do I make uneven ground?'''<br />
<br />
'''A.''' One method is by burying patches into the ground that stick out and make the ground lumpy as described here [http://forums.thedarkmod.com/topic/13338-newbie-mapper-tip-making-uneven-ground/page__view__findpost__p__274917]. For more encompassing unevenness, you can use much larger patches laid over square caulk brushes underneath that seal the leaf to make the entire ground uneven. <br />
<br />
'''Q. How do I make a natural looking road where there isn't a sharp seam between the road material and grass but a nice fading transition?'''<br />
<br />
'''A.''' See the Wiki page for [[Roads]]. <br />
<br />
'''Q. How do I make curved ceilings and archways?'''<br />
<br />
'''A.''' Use patches. Here's a list of some good tutorials for this sort of thing [http://forums.thedarkmod.com/topic/9082-newbie-darkradiant-questions/page__view__findpost__p__254764]. Also look at this wiki page [[Patches#Archways]].<br />
<br />
'''Q. What's a way to get good-looking fog in my mission?'''<br />
<br />
'''A.''' There are numerous values to make good fog. The setup for the fog from Fidcal's Heart mission is here [http://forums.thedarkmod.com/topic/9082-newbie-darkradiant-questions/page__view__findpost__p__248277].<br />
<br />
'''Q. What are some tips to making a better looking map?'''<br />
<br />
'''A.''' See this wiki entry [[10_Simple_Tricks_for_Better_Looking_Maps]].<br />
<br />
'''Q. What's a good method or plan-of-action for building?'''<br />
<br />
'''A.''' This is a matter of personal preference, but a method that professionals use is called the "stepwise refinement" method. It means you build the *entire* space of your mission first in rough blocks (so you have it all planned out first), then refine the whole thing in increasingly more detailed steps section by section, leaving the most fine detailing towards the end. It can help to use DR's Layer system to organize your building by sections too, without other sections interfering. Also, when you're drawing your map, think about arranging space into winding "rooms" (so there's no long lines of sight), even outside with tunnels, walls and skybox; and think about visPortal placement right at the start. Also think about the gameplay-performance balance of shadowing-lights & AI when thinking about placing them.<br />
<br />
'''Q. How do I cleanly connect two brush edges meeting together, especially at a diagonal?'''<br />
<br />
'''A.''' See this post [[http://forums.thedarkmod.com/topic/11570-editing-tip-of-the-day/page__view__findpost__p__257111]].<br />
<br />
'''Q. What's a method for building very fast & efficiently?'''<br />
<br />
'''A.''' Sotha came up with "modular" approach where you build a few stock modules of architecture that you can combine to make a lot of geometry very quickly and efficiently. Here's his description: [http://forums.thedarkmod.com/topic/12833-sir-taffsalots-mapping-thread/page__view__findpost__p__290747]<br />
<br />
'''Q. How do I make a good looking waterfall?'''<br />
<br />
'''A.''' There's a discussion about this in this thread [http://forums.thedarkmod.com/topic/11901-waterfalls/page__pid__303963#entry303963]. For a small waterfall, a white foamy particle effect raining down by itself looks good. You can copy Bikerdude's example from St. Alban's Cathedral. [http://www.youtube.com/watch?v=gIrZDpc1m68]. For a bigger waterfall, people talked about a combination of a flowing vertical water block with the foamy particle effect towards the bottom.<br />
<br />
'''Q. How do I make a nice little pond.'''<br />
<br />
'''A.''' See this wiki entry [[How_to_create_a_pond]]. This thread [http://forums.thedarkmod.com/topic/14647-how-can-i-make-a-realistic-looking-pond/page__view__findpost__p__308916] has discussion on it.<br />
<br />
== Patches! ==<br />
<br />
'''Q. Is it possible to split patches?'''<br />
<br />
'''A.''' See this tutorial on it [[Patch_Splitting_-_Basic_Tutorial]].<br />
<br />
'''Q. How do I bend patches?'''<br />
<br />
'''A.''' See the instructions at [[Patches#Bending_Patches.2C_Curves.2C_L-shapes.2C_etc]] (Here's another small tutorial in a post [http://forums.thedarkmod.com/topic/9082-newbie-darkradiant-questions/page__view__findpost__p__277350].)<br />
<br />
'''Q. I want to use a patch to round off a corner.'''<br />
<br />
'''A.''' See this part of the Patch wiki page [[Patches#Round_and_Soft]].<br />
<br />
'''Q. How can I make a perfect circle with patches?'''<br />
<br />
'''A.''' Select verts of 4 corners, select the "rotate and scale" tool, and use the value "0.9428" to scale "up" (actually down) in the 2 corresponding axis of the scale tool. See this post [http://forums.thedarkmod.com/topic/11570-editing-tip-of-the-day/page__view__findpost__p__279356].<br />
<br />
'''Q. How do I make a dome or sphere?'''<br />
<br />
'''A.''' Make a cone patch and drag down the top vertex to form a dome. Invert the matrix if you want an internal dome or thicken if you want it to be visible inside and out. A sphere is just two of these stuck together. Also tweak the tesselation in patch inspector if it is too chunky. You can have fun with the textures though; try fit. If you totally flatten the dome you have a disc which can produce some nice texture effects, eg, the marble floor centrepiece or a round rug. Drag a side to make it oval. See this post for a picture [http://forums.thedarkmod.com/topic/11570-editing-tip-of-the-day/page__view__findpost__p__233107].<br />
<br />
'''Q. How do you align a texture on a curved patch?'''<br />
<br />
'''A.''' When you want to align properly texture to curved patch like this one in the image [NB: image is missing], divide a brush according to the angle of the patch then use it's shader for your purpose. ... I made it with one edge is at one end of the curved patch and the other edge is at the other end. It gets distortions without this way.<br />
<br />
== Events and SFX ==<br />
<br />
'''Q. How do I trigger an earthquake event?'''<br />
<br />
'''A.''' Earthquakes can be done with a speaker. Just use the spawnarg "s_shakes" "1" on the speaker, and the screen will shake violently however loud the sound gets.<br />
<br />
'''Q. How do I emulate something like a blizzard or dust storm?'''<br />
<br />
'''A.''' Doom3 made a dust storm area, and the same method can be used to make a blizzard, so it's possible. I'm leaving this here to look up instructions for future reference.<br />
<br />
'''Q. How do I make the screen fade to black (or some other color), or from black back to the game.'''<br />
<br />
'''A.''' Create entity: [[Triggers#trigger_fade|Trigger_Fade]]. Adjust "fadeTime" and "fadeColor" spawnargs as desired.<br />
<br />
== Textures == <br />
<br />
'''Q. What's a quick way to align textures between two surfaces?'''<br />
<br />
'''A.''' For two brushes, select the first surface, then '''edit --> copy shader''', then click on the second surface and '''edit --> paste shader'''. This will seamlessly match the 2nd surface to the texture of the 1st. DR also comes with a useful tool for texture alignment, [[Texture_Tool]], which you bring up with Ctrl+Alt+T. If it's textures on two patches, you can follow these directions: [http://forums.thedarkmod.com/topic/14034-tutorial-for-road-creation/page__view__findpost__p__294114]<br />
<br />
'''Q. How do I randomize the position of textures on multiple brushes, e.g., for a row of stairs or pillars all with the same texture that I want to look different?'''<br />
<br />
'''A.''' Select multiple faces and in the surface inspector, press the natural button once you set the scale properly.<br />
<br />
'''Q. Can I blend textures?'''<br />
<br />
'''A.''' Yes. This is particularly good for dirtying some textures up by blending in a grime texture. You can blend textures with a custom material file. Link to instructions coming. Also see the entry for [[Basic_Material_File]].<br />
<br />
'''Q. How about blending texture transitions so there isn't a sharp seam, e.g., for a dirt path in grass?'''<br />
<br />
'''A1.''' DR comes with grass edge transition decal patches to overlay the hard edges. Read how to set it up here [[Grass_Edges]], or a more detailed tutorial on making roads here [[Roads]].<br />
<br />
'''A2.''' In NHAT blended terrain was made from patches broken into segments then exported as ASE models. Then the models were vertex painted in Blender and imported back into Dark Radiant. See this tutorial [[DrVertexBlend_(tutorial)]].<br />
<br />
'''Q. How do I set the color for some textures (like glowing mushrooms) and make lightbulbs go dark when turned off?<br />
<br />
'''A.''' "Colorme" textures allow you to set the color with a spawnarg. So e.g. for colored mushrooms, choose a colorme skin with the spawnarg like "skin" "mushroom_selflit_green_colorme" and choose the color with a spawnarg like "_color" "0.24 0.50 0.40" (where the value is the RGB values you want). For lightbulbs you can trigger a colorme texture switch with the lightswitch (so it switches between "lit up" and "black"). Instructions on that coming.<br />
<br />
'''Q. What's a fast way to put different textures on a lot of objects?'''<br />
<br />
'''A.''' 1. Click the mouse wheel on the texture to copy it. 2. To paste it naturally (i.e., in a random position): shift+mousewheel click. 3. To just paste it: ctrl+mousewheel click.<br />
<br />
'''Q. Can you tile a texture a specific number of times to fit a surface?'''<br />
<br />
'''A.''' When you want to tile a texture a certain number of times, enter the values 1/X and 1/Y (you need to compute them in your head) in the little boxes in the surface inspector, then press "Fit". It will tile your texture horizontally X times and vertically Y times. You can also enter things like "2" and "1" and get a texture that only occupies half of the width. You can then use the "Right" or "Left" buttons to align it quickly at the ends. Pro-tip: Press CTRL+ALT+T to open the texture tool, it allows super quick aligning of textures on patches. Esp. useful for decals where the decal texture consists of multiple decals.<br />
<br />
== Readables & GUIs ==<br />
<br />
'''Q. How do I put custom art in a book or scroll, like a picture?'''<br />
<br />
'''A.''' Use a custom .gui. Here's a rough idea to get you started [http://forums.thedarkmod.com/topic/9082-newbie-darkradiant-questions/page__view__findpost__p__263836]. I'll try to put better instructions in later.<br />
<br />
'''Q. How do I trigger a text message to pop up and say something?'''<br />
<br />
'''A.''' Create an entity: darkmod > targets > atdm:gui_message and give it the properties/values that you want. Popups will explain each one. You can target it with a triggering entity or trigger it from a script or any other triggering mechanism. An example is here [http://forums.thedarkmod.com/topic/9082-newbie-darkradiant-questions/page__view__findpost__p__256592]<br />
<br />
== Lighting and Sound == <br />
<br />
'''Q. How do I add music or ambient sounds?''' '''Q. Can I dynamically adjust the ambient lighting?'''<br />
<br />
'''A.''' For both of these things, check out the article for [[Location Settings]]<br />
<br />
{{editing|sort=Editing FAQ (Troubleshooting & How-To)}} {{tutorial-editing|sort=Editing FAQ (Troubleshooting & How-To)}} {{darkradiant|sort=Editing FAQ (Troubleshooting & How-To)}}<br />
<br />
'''Q. How do I set up Reverb (EAX) settings for my rooms? (E.g., the echo of a large hall, etc.)'''<br />
<br />
'''A.''' Create a text file and name it <mapname>.eax; place it in your .pk4 with your .map file; and in it create entries by location name with the values you want for that location. See this wiki entry to see the format & values [[Setting_Reverb_Data_of_Rooms_(EAX)]].</div>RJFerrethttps://wiki.thedarkmod.com/index.php?title=Triggers&diff=17666Triggers2014-03-03T04:27:24Z<p>RJFerret: Moved common elements to header, suggested objectives for dropping items.</p>
<hr />
<div>There are many different ways of triggering [[Entity|entities]], the Trigger entities themselves, as well as through [[Stim/Response]], [[Conversations]], Movers, [[Objectives]], and more. How the trigger occurs will typically dictate which manner you choose for your map. <br />
<br />
=Triggers=<br />
To create triggers that rely on boundaries (once, multiple and their derivations), you need to drag out a worldspawn brush, right-click, select "Create Entity". They need to be connected to their subjects, either via "Connect Selected Entities" menu option/shortcut key, or adding "Target", "Target0", "Target1" or subsequent "Target"# spawnargs. The triggers below are listed roughly by frequency of usage, with related triggers beneath.<br />
<br />
==trigger_once==<br />
When the origin of an entity enters the bounds of this entity, the target(s) will be triggered one time only. (Note, to resize the brush after creating the entity, select it then press Tab once.)<br />
<br />
==trigger_once_entityname==<br />
Similar to above, but may be set to only respond to the entity specified by the spawnarg, "entityname". Note the entity must move into the boundaries itself, not be moved by the player (AI walking themselves for example). (If you want something to happen based on the player dropping or placing an item somewhere, use the [[Objectives]] system instead.)<br />
<br />
==trigger_multiple==<br />
Similar to above but will activate again and again, use "Wait" spawnarg to control how many seconds between triggerings. <br />
<br />
==trigger_entityname ==<br />
Similar to trigger_multiple but only reacts to the entity defined by the "entityname" spawnarg.<br />
<br />
== trigger_facing ==<br />
Also similar to trigger_multiple, but requires the triggering entity to be within 30° of the specified "angle" spawnarg. For details see [[Trigger Facing]].<br />
<br />
==trigger_relay ==<br />
Most commonly used to trigger multiple targets, or do so after a delay (per the "delay" spawnarg). May be set to only work once (spawnarg "wait" "-1") or limit firing based upon how many seconds have passed. The "random" spawnarg may be used with "wait" to vary the firings. Very useful as the target of worldspawn, to trigger things at map start (since worldspawn currently only activate one "Target").<br />
<br />
==trigger_count ==<br />
This will fire at it's targets upon a specific number of times being triggered itself, based upon the "count" spawnarg. If "count" "3" is set, it will do nothing until the third triggering. <br />
<br />
== trigger_timer ==<br />
This trigger will fire repeatedly ever "wait" # seconds. The spawnarg "start_on" defines if it should do so at the start of the map or wait to be triggered (defaults to 0, off at map start). Spawnarg "random" may at variability to the triggerings.<br />
<br />
== trigger_fade ==<br />
Will cause the display to fade to specified color. The spawnarg "fadeColor" specifies which color and how transparent in RGBA (red, green, blue, alpha). Default is fade to black: "fadeColor" "0 0 0 1". To fade up from whatever, use alpha of 0, IE to fade up from black, "0 0 0 0".<br />
<br />
== trigger_hurt ==<br />
(needs experienced write-up, compare with stim/response damage please)<br />
<br />
== trigger_presize ==<br />
(needs experienced write-up)<br />
<br />
== trigger_touch ==<br />
Continuously checks if entities are touching, costly performance wise, perhaps done via [[Objectives]] more efficiently.<br />
<br />
=Triggering via Stim/Response=<br />
Within the [[Stim/Response]] editor, add a response stim set to "Trigger", now when this entity is targeted, whatever specified effect will occur.<br />
<br />
=Triggering via Conversation=<br />
The command, [[Conversations#Conversation Commands 2|ActivateTarget]] will trigger the specified entity at that time in the Conversation script.<br />
<br />
=Triggering via Doors, Buttons, Levers, Movers=<br />
[[Doors]] trigger their targets by default upon opening (spawnarg "trigger_on_open" "1"). They may also trigger when completely open by changing "trigger_when_opened" to 1 instead of the default 0, or when fully closed via "trigger_on_close". Note, those conditions on Buttons came from doors, so are counter-intuitive.<br />
<br />
=Triggering via Objectives=<br />
In the [[Objectives Editor]] you may select an entity to be triggered upon an objective succeeding or failing. Therefore all the possible objective conditions may become trigger events (knock out an AI, move an object away from another, cause another objective to become visible or disappear, etc.)<br />
<br />
=Triggering via Worldspawn=<br />
You may set "Target" on Worldspawn (usually at a trigger_relay since it only may target one entity currently) to cause things to be triggered at map start. If you use this to kill an AI or other affect with audio, note if in range of the player's start, it will be heard during the fade up from black.<br />
<br />
=Triggering via Lights=<br />
Lights trigger their target(s) both upon being extinguished and lit. This is useful to match window glow to actual light condition. Depending on the light, it may be tricky to set the targets however. A basic light entity can simply have target(s) spawnargs, but a candle, lamp or torch with attached flame entity, you need to use the "set" spawnarg. For example, "set target0 on flame" "EntityToBeTriggered".<br />
<br />
[[Category:Editing]]</div>RJFerrethttps://wiki.thedarkmod.com/index.php?title=Objectives&diff=17665Objectives2014-03-03T04:15:18Z<p>RJFerret: /* Objectives */ wikilink Triggers & fixed _relay redlink</p>
<hr />
<div>{{Original_Reference|Ishtvan|4121}} ''additions by greebo''<br />
<br />
This article covers details of the objectives system. Note that mappers can use <br />
DarkRadiant's [[Objectives Editor]] to make it easier to create objectives.<br />
<br />
The objectives system exists to determine when the player has completed the mission. At the highest level, a mission consists of a list of objectives to be completed and boolean logic to determine when the mission has succeeded or failed based on which of the objectives are complete. At the objective level, an objective consists of individual components and boolean logic to determine when the objective is completed or failed. At the component level, each component has a type, a specifier, and arguments. These will be explained fully in the components section.<br />
<br />
= Mission =<br />
Objectives are stored by entities named [[target_tdm_addobjectives]]. Your mission can have several of these but typically you will only want one for all your objectives.<br />
<br />
By default these entities self-trigger (activates themselves) at mission start. If you need to delay this and activate it later (via any trigger entity that can have a target spawnarg) then add the spawnarg ''wait_for_trigger'' with a value of 1.<br />
<br />
When triggered, these entities add objectives to the mission based on their spawnargs.<br />
<br />
Spawnargs governing mission level behavior may be entered on any target_addobjectives. Non-empty spawnargs will be overwritten by the most recently triggered target_addobjectives (FM authors may want to do this if they add an objective later on and want to change the mission success logic to include that objective, for example). The following is a list of the mission-level spawnargs and what they mean:<br />
<br />
== Success/Failure Logic ==<br />
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.<br />
<br />
=== Default Logic ===<br />
*;<tt>mission_logic_success</tt> (string) <br />
:A string of boolean logic applied to individual objective states to determine if the mission succeeds. AND, OR, NOT and parenthesis are available. The FM author can construct strings using these and the integer index for an objective. For example: "1 OR (NOT(2) AND 3)" would complete the mission if either objective 1 is true, or if 2 is false and 3 is true. By default, a mission succeeds when all mandatory objectives are completed.<br />
<br />
*;<tt>mission_logic_failure</tt> (string) <br />
:Boolean logic applied to individual objective component states to determine if the mission has failed. By default, if any mandatory objective fails, the mission fails.<br />
<br />
=== Difficulty Dependent Logic ===<br />
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):<br />
<br />
*;<tt>mission_logic_success_diff_N</tt> (string) <br />
:Defines the success logic for the difficulty level N (override the default logic), e.g. "1 AND 2 AND 3".<br />
*;<tt>mission_logic_failure_diff_N</tt> (string) <br />
:Defines the failure logic for the difficulty level N (override the default logic). When this condition is fulfilled, the mission has failed.<br />
<br />
If specific logic is not specified for a certain difficulty level, the default spawnargs (without _diff_*) will be used.<br />
<br />
= Objectives =<br />
Objectives added by the target_addobjectives each have a unique integer index, starting with objective 1, the first objective. The spawnargs associated with an objective are prefixed in the following manner:<br />
obj<objective index>_<spawnarg name><br />
Example: ''obj3_desc''<br />
<br />
The spawnargs (minus prefix) and meanings for objective attributes are listed below. Each objective also includes a list of components and their attributes, which will be covered in the next section.<br />
<br />
*;<tt>objN_desc</tt> (string) <br />
: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. The default value is an empty string.<br />
<br />
*;<tt>objN_state</tt> (int) Defines the state of the objective at map start. <br />
:'''Possible Objective States:'''<br />
:* 0 = STATE_INCOMPLETE<br />
:* 1 = STATE_COMPLETE<br />
:* 2 = STATE_INVALID<br />
:* 3 = STATE_FAILED<br />
:Code defaults to 0 = incomplete.<br />
<br />
*;<tt>objN_mandatory</tt> (1/0) <br />
:Set to 0 for optional objective that doesn't fail the mission if you fail it. Objective must be completed to complete the mission if 1. Code defaults to 1.<br />
<br />
*;<tt>objN_irreversible</tt> (1/0) <br />
: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.<br />
<br />
*;<tt>objN_ongoing</tt> (1/0) <br />
:If true, this objective is not marked as complete and the player is not informed that it's complete until the end of the mission. Typically used for "do not kill" type objectives, because technically they would be complete right from the beginning, but we don't want to mark them off or tell the player they're complete right at the beginning. Could also be used for "have some item with you when you complete the mission." Code defaults to 0.<br />
<br />
*;<tt>objN_visible</tt> (1/0) <br />
: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 another 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.<br />
<br />
*;<tt>objN_difficulty</tt> (integer)<br />
:Space delimited list of difficulty levels that should include this objective. For example, "2 3" would enable this objective at difficulty levels 2 and 3, but not for other difficulty levels. Default value is empty - the objective applies to all difficulty levels.<br />
:''Note:'' When the objective is not active for a given difficutly, it is invalidated and hidden, but it still exists, so the numbering of the next objective should still increase by 1. E.g., objective 5 only appears on hard difficulty, but you still have to call the next objective objective 6, you can't call it objective 5 only appearing on easy or medium difficulty.<br />
<br />
*;<tt>objN_enabling_objs</tt> (space-delimited integers) <br />
:This is a list of objectives which must 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.<br />
<br />
*;<tt>objN_script_complete</tt> (string)<br />
*;<tt>objN_script_failed</tt> (string)<br />
: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.<br />
<br />
*;<tt>objN_target_complete</tt> (string)<br />
*;<tt>objN_target_failed</tt> (string)<br />
:Name of a target entity to [[Triggers|trigger]] when this objective is completed or failed, similar to the completion/failure script. Only one entity name is allowed here. If you need to trigger multiple entities on objective state change, use a [[Triggers#trigger_relay|trigger_relay]] entity.<br />
<br />
*;<tt>objN_logic_success</tt> (string)<br />
:Boolean logic applied to individual objective component states to determine if the objective is complete. The same boolean logic options are available as in the mission-level logic described above. By default, all of the components must be true to complete the objective. In other words, all components are ANDed together (1 AND 2 AND 3...).<br />
*;<tt>objN_logic_failure</tt> (string)<br />
:Boolean logic applied to individual objective component states to determine if the objective is failed. By default, if an objective is ongoing, and any opponent becomes false, that objective will fail.<br />
<br />
= Objective Components =<br />
Each objective has an associated list of components and spawnargs defining the attributes of those components. These component spawnargs associated with a given objective are prefixed in the following manner:<br />
obj<objective index>_<component index>_<spawnarg name><br />
Example: ''obj1_2_state''<br />
<br />
In the following, the index N defines the objective number and M refers to the component number. Programmers beware that both numbers start from the value 1.<br />
<br />
*;<tt>objN_M_state</tt> (1/0) <br />
:Defines the state of the component at map start, which can only be "1" (complete) or "0" (incomplete). Code defaults to 0.<br />
<br />
*;<tt>objN_M_player_responsible</tt> (1/0) <br />
:When true, the player must be responsible for the events that satisfy this component. Events the player is not responsible for are not counted. (e.g., the player kills an AI vs. another AI killing an AI). Code defaults to 1.<br />
<br />
*;<tt>objN_M_not</tt> (1/0) <br />
:Code defaults to 0. If true, this component is logically NOTed, so when the conditions described by the type and speifiers are not met, the component state is true, and when they are met, it is false.<br />
<br />
*;<tt>objN_M_irreversible</tt> (1/0) <br />
:When the component state changes from its initial state, it will stay in its new state regardless of what happens later. (There is a script event to "unlatch" a latched objective component if needed). Code defaults to 0.<br />
<br />
*;<tt>objN_M_type</tt> (string) <br />
:Defines the type of this objective component. See the section [[#Component_Types|Component Types]] below for detailed information.<br />
:'''Possible 'Objective Component' Types:'''<br />
:* kill (also includes non-living things being destroyed)<br />
:* ko<br />
:* ai_find_item (not implemented)<br />
:* ai_find_body (not implemented)<br />
:* alert<br />
:* destroy (inanimate item destroyed ("killed"))<br />
:* item (picked up or dropped an inventory item)<br />
:* pickpocket (inventory item acquired from conscious AI)<br />
:* 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)<br />
:* custom (custom component that is set true/false by a map script)<br />
:These components are triggered every N milliseconds by a system clock:<br />
:* custom_clocked (runs a custom map script that should check something and set the objective)<br />
:* info_location (Item A at info_location area B) - TODO: more information needed<br />
:* distance (distance between the origin of entity X and that of entity Y)<br />
<br />
Any component can have up to two specifiers, each of which can carry a value. Here, K refers to the number of the specifier, e.g. ("obj2_1_spec4" "name").<br />
*;<tt>objN_M_specK</tt> (string) <br />
:'''Specification Methods:'''<br />
: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). See the section [[#Specifiers|Specifiers]] below for a detailed description.<br />
:'''The following apply to both AIs and items:'''<br />
:* none<br />
:* name (name of entity)<br />
:* overall (overall count of something: kills, loot, kos, etc)<br />
:* group (inventory group)<br />
:* classname (soft/scripting classname)<br />
:* spawnclass (hard / SDK classname, e.g. "idPlayer")<br />
:'''The following specification methods apply only to AI:'''<br />
:* ai_type (human, beast, undead, bot, etc)<br />
:* ai_team (mapper defined team of the AI)<br />
:* ai_innocence (For distinguishing noncombatants)<br />
<br />
*;<tt>objN_M_spec_valK</tt><br />
:Value that the Kth specifier should match in order to count towards this component. (E.g., an entity name if we specify by name.)<br />
<br />
*;<tt>objN_M_args</tt> (space-delimited string) <br />
:'''Integer and String Arguments:'''<br />
: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.<br />
<br />
*;<tt>objN_M_clock_interval</tt> (float/seconds)<br />
:For clocked components like "custom_clocked" this determines how often they are updated. The value is to be set in seconds.<br />
<br />
== Component Types ==<br />
=== AI-Related Components ===<br />
The following specifiers are termed "Standard AI Specifiers": All specifiers minus the <tt>group</tt> specifier.<br />
<br />
;*<tt>kill</tt><br />
:An AI must be killed to satisfy this component.<br />
:'''SDK Name''': COMP_KILL<br />
:'''Number of Specificatons''': 1 (object that must be killed)<br />
:'''Applicable Specifiers''': Standard AI Specifiers<br />
:'''Expected Arguments''': int (number of kills required)<br />
<br />
;*<tt>ko</tt> (Knockout)<br />
:An AI must be knocked out by any means (gas, blackjack, other).<br />
:'''SDK Name''': COMP_KO<br />
:'''Number of Specificatons''': 1 (AI that must be KO'd)<br />
:'''Applicable Specifiers''': Standard AI Specifiers<br />
:'''Expected Arguments''': int (number of KOs required)<br />
<br />
;*<tt>ai_find_item</tt><br />
:''not yet implemented''<br />
:'''SDK Name''': COMP_AI_FIND_ITEM<br />
:'''Number of Specificatons''': --<br />
:'''Applicable Specifiers''': --<br />
:'''Expected Arguments''': --<br />
<br />
;*<tt>ai_find_body</tt><br />
:''not yet implemented'' An AI must find a body. Currently, the specifiers apply to the bodies found, and any AI finding the bodies triggers this component. Future revisions might add another specifier for the AI that finds the body.<br />
:'''SDK Name''': COMP_AI_FIND_BODY<br />
:'''Number of Specificatons''': 1 (Type of body that must be found)<br />
:'''Applicable Specifiers''': Standard AI Specifiers<br />
:'''Expected Arguments''': int (number of bodies that must be found)<br />
<br />
;*<tt>alert</tt><br />
:True if an AI or type of AI is alerted. Use the player_responsible flag to determine if this should count alerts not caused by the player's actions (e.g., enemy AI being sighted)<br />
:'''SDK Name''': COMP_ALERT<br />
:'''Number of Specificatons''': 1 (AI that must be alerted)<br />
:'''Applicable Specifiers''': Standard AI Specifiers<br />
:'''Expected Arguments''': int (number of alerts required), int (minimum alert level that counts: 1-5 with 5 being the combat state)<br />
<br />
=== Non-AI Components ===<br />
<br />
;*<tt>destroy</tt><br />
:An inanimate item must be destroyed (damage it until its health is lower than zero).<br />
:'''SDK Name''': COMP_DESTROY<br />
:'''Number of Specificatons''': 1 (item to be destroyed)<br />
:'''Applicable Specifiers''': all<br />
:'''Expected Arguments''': int (number of items to be destroyed)<br />
<br />
;*<tt>item</tt><br />
:Completed when the player has this inventory item or loot.<br />
:'''SDK Name''': COMP_ITEM<br />
:'''Number of Specificatons''': 1 (item the player must have)<br />
:'''Applicable Specifiers''': All except AI type, team and innocence.<br />
:'''Expected Arguments''': int (number of items to have, 1 by default)<br />
<br />
;*<tt>pickpocket</tt><br />
:An inventory item must be taken from a conscious AI. Note that it doesn't matter what happens to the item after it is pickpocketed. It could be destroyed or dropped, but as long as it was originally pickpocketed, it counts.<br />
:'''SDK Name''': COMP_PICKPOCKET<br />
:'''Number of Specificatons''': 1 (Item the player must pickpocket)<br />
:'''Applicable Specifiers''': All except AI type, team and innocence<br />
:'''Expected Arguments''': int (number of items to pickpocket, 1 by default)<br />
<br />
;*<tt>location</tt> Object in location brush (using info_tdm_objective_location brush)<br />
:A particular item must be in a particular location, defined by an info_objective_location brush. For optimization reasons, the entity or entities to be checked must also have this spawnarg: "objective_ent" set to "1". NOTE: Multiple objects in a single location are not counted up for this component, this is a single-shot objective. If you want the player to put more than one object in a location, you must currently create several of these components, specifying by name, and OR them together in the objective logic.<br />
:'''SDK Name''': COMP_LOCATION<br />
:'''Number of Specificatons''': 2 (object entity to check, location entity to check)<br />
:'''Applicable Specifiers''': For the object to check, all specifiers apply, but multiple objects are not counted up. Typically the objects will be specified by name. For the location to check, it will either be specified by name or by group.<br />
:'''Expected Arguments''': None (if both specifiers match, the objective is completed).<br />
<br />
;*<tt>info_location</tt> Object in location area (using info_location entities)<br />
:A particular item must be in a particular location, defined by an info_location area (see vanilla D3 documentation for info_location). Multiple objects in a single location are not counted up for this component, this is a single-shot objective. If you want the player to put more than one object in a location, you must currently create several of these components, specifying by name, and OR them together in the objective logic.<br />
:This check is done periodically. Set spawnarg <tt>clock_interval</tt> to the time in seconds between periodic checks.<br />
:'''SDK Name''': COMP_INFO_LOCATION<br />
:'''Number of Specificatons''': 2 (object entity to check, location entity to check)<br />
:'''Applicable Specifiers''': For the object to check, all specifiers apply, but multiple objects are not counted up. Typically the objects will be specified by name. For the location to check, it will either be specified by name or by group.<br />
:'''Expected Arguments''': None (if both specifiers match, the objective is completed).<br />
<br />
;*<tt>custom</tt><br />
:This custom objective component is only changed when an external script changes it. Otherwise it does nothing.<br />
:'''SDK Name''': COMP_CUSTOM_ASYNC<br />
:'''Number of Specificatons''': none<br />
:'''Applicable Specifiers''': none<br />
:'''Expected Arguments''': none<br />
<br />
;*<tt>custom_clocked</tt><br />
:This component calls a custom script periodically to check some condition. When run, the script is expected to this component true or false based on the custom check. This objective component could also be used as a convenient method to periodically call a script that has nothing to do with objectives.<br />
:Set spawnarg <tt>clock_interval</tt> to the time in seconds between periodic calls of the script.<br />
:'''SDK Name''': COMP_CUSTOM_CLOCKED<br />
:'''Number of Specificatons''': none<br />
:'''Applicable Specifiers''': none<br />
:'''Expected Arguments''': string (name of the script to call periodically)<br />
<br />
;*<tt>distance</tt><br />
:Two entities must be sufficiently close to eachother to satisfy this component. The distance check is done between the origin of the first object and that of the second object. If this distance is below the input maximum distance, the component is set to true.<br />
:This check is done periodically. Set spawnarg "clock_interval" to the time in seconds between periodic checks.<br />
:'''SDK Name''': COMP_DISTANCE<br />
:'''Number of Specificatons''': none (see arguments below)<br />
:'''Applicable Specifiers''': none<br />
:'''Expected Arguments''': string (name of first entity), string (name of second entity), int (maximum distance in doom units)<br />
<br />
;*<tt>readable_opened</tt><br />
:''available since TDM 1.02''<br />
:The player must open a named readable to satisfy this component. This doesn't refer to a specific page, just opening the readable is enough.<br />
:'''SDK Name''': COMP_READABLE_OPENED<br />
:'''Number of Specificatons''': 1 (The name of the readable)<br />
:'''Applicable Specifiers''': name<br />
:'''Expected Arguments''': none<br />
<br />
;*<tt>readable_closed</tt><br />
:''available since TDM 1.02''<br />
:The player must close a named readable to satisfy this component. This doesn't check whether the player has finished reading all pages, just closing the previously opened readable is enough.<br />
:'''SDK Name''': COMP_READABLE_CLOSED<br />
:'''Number of Specificatons''': 1 (The name of the readable)<br />
:'''Applicable Specifiers''': name<br />
:'''Expected Arguments''': none<br />
<br />
;*<tt>readable_page_reached</tt><br />
:''available since TDM 1.02''<br />
:The player must open/read a specific page of a named readable to fulfil this component. Scrolling to the page is enough to trigger this event.<br />
:'''SDK Name''': COMP_READABLE_PAGE_REACHED<br />
:'''Number of Specificatons''': 1 (The name of the readable)<br />
:'''Applicable Specifiers''': name<br />
:'''Expected Arguments''': int (the page number which should be reached, the number 1 refers to the first page)<br />
<br />
== Specifiers ==<br />
;*<tt>none</tt> <br />
:No specifier. Component will be completed as soon as any event of that component type happens. (E.g., if you set a KO component type, with specifier none, it would be set to true as soon as soon as the player KO's anyone). This is the default specifier if none is entered. Not very useful, except for blanket "don't do this" objectives. Even then, it is better to use "overall" described below.<br />
:'''SDK Name''': SPEC_NONE<br />
:'''Specifier Argument Type Expected''': No spec argument needed since we don't have to match anything.<br />
<br />
;*<tt>name</tt> <br />
:Name of the entity<br />
:'''SDK Name''': SPEC_NAME<br />
:'''Specifier Argument Type Expected''': string<br />
<br />
;*<tt>overall</tt> <br />
:In the context of inventory item objectives, this refers to overall loot. In the context of AI objectives, this refers to all AI, regardless of team, type, etc.<br />
:'''SDK Name''': SPEC_OVERALL<br />
:'''Specifier Argument Type Expected''': No spec argument needed since we don't have to match anything.<br />
<br />
;*<tt>Group</tt> <br />
:For inventory items, the item's <tt>inv_name</tt> spawnarg value will be used here. For example, if you want the player to get 5 flashbombs, you would use this with group equal to the <tt>inv_name</tt> of flashbombs. As opposed to getting a specific flashbomb in the map, where you would use the <tt>name</tt> specifier instead. If an inventory item is loot, the loot group is used here instead (e.g., <tt>loot_gold</tt>).<br />
:Group is also used for other component types as a convenient way to group things, such as info_objective_location or info_location entities checked by COMP_LOCATION and COMP_INFO_LOCATION, respectively.<br />
:'''SDK Name''': SPEC_GROUP<br />
:'''Specifier Argument Type Expected''': string<br />
:'''Loot group names:''' <tt>loot_gold</tt>, <tt>loot_goods</tt>, <tt>loot_jewels</tt> and <tt>loot_total</tt><br />
<br />
;*<tt>Classname</tt> <br />
:The entityDef classname of the entity. For example: atdm:ai_builder_guard<br />
:'''SDK Name''': SPEC_CLASSNAME<br />
:'''Specifier Argument Type Expected''': string<br />
<br />
;*<tt>Spawnclass</tt> <br />
: The SDK classname of the entity. For example: idAI<br />
:'''SDK Name''': SPEC_SPAWNCLASS<br />
:'''Specifier Argument Type Expected''': string<br />
<br />
;*<tt>ai_type</tt> <br />
:Type of AI: human, beast, undead, steambot, etc. (reads m_AIType in the SDK, which is set by the "type" spawnarg on idActors. Not sure if this is implemented yet).<br />
:'''SDK Name''': SPEC_AI_TYPE<br />
:'''Specifier Argument Type Expected''': int<br />
<br />
;*<tt>ai_team</tt> <br />
:The AI's team integer. This can be set up by the mapper to put AI on arbitrary teams. Mapper can also team up AI for objective purposes, and use this team specifier as a fast way of saying "KO any of these 5 AI." Alternatively, one could use the name specifier and put in multiple components for each of those 5 AI, then OR all the components in the objective success logic. Making a new team may save time over that method.<br />
:'''SDK Name''': SPEC_AI_TEAM<br />
:'''Specifier Argument Type Expected''': int<br />
<br />
;*<tt>ai_innocence</tt> <br />
:Differentiates between combatants and non-combatants. A value of 1 = non-combatant, a value of 0 => non-combatant, or otherwise not deemed "innocent" by the FM author.<br />
:'''SDK Name''': SPEC_AI_INNOCENCE<br />
:'''Specifier Argument Type Expected''': int (1 = innocent, 0 = not)<br />
<br />
= Objective Conditions =<br />
With the campaign code added to TDM 1.06 a new set of spawnargs can be used to let objectives depend on those in a previous mission. These spawnargs are starting with the <tt>obj_condition</tt> prefix.<br />
<br />
Each condition defines the "source" mission and the source objective by number, plus the state of the source objective. It also needs to specify the "target" objective (which is always in the current mission) by number and which action to take. Right now, three different actions are supported: <br />
* Change Objective State (complete, failed, etc.)<br />
* Change the Objective's Visibility (hide or show)<br />
* Change the Objective's Mandatory Flag<br />
<br />
== Syntax ==<br />
<br />
*;<tt>obj_condition_N_src_mission</tt> (integer) <br />
:Defines the source mission the condition depends on. The integer is 0-based, i.e. the first mission has the number 0. The placeholder N is the number of the condition.<br />
<br />
*;<tt>obj_condition_N_src_obj</tt> (integer) <br />
:Defines the number of the source objective in the source mission. The integer is 0-based, i.e. the first objective has the number 0. The placeholder N is the number of the condition.<br />
<br />
*;<tt>obj_condition_N_src_state</tt> (integer) <br />
:Defines the state the source objective needs to be in for this condition to apply. The value can be in the same range as the objN_state spawnarg above:<br />
:* 0 = STATE_INCOMPLETE<br />
:* 1 = STATE_COMPLETE<br />
:* 2 = STATE_INVALID<br />
:* 3 = STATE_FAILED<br />
<br />
*;<tt>obj_condition_N_target_obj</tt> (integer) <br />
:Defines the number of the target objective in the current mission. The integer is 0-based, i.e. the first objective has the number 0. The placeholder N is the number of the condition.<br />
<br />
*;<tt>obj_condition_N_type</tt> (string) <br />
:Defines the action to take if the condition applies. There are three possible action types available:<br />
:* "changestate" Change the state of the target objective.<br />
:* "changevisibility" Change the visibility of the target objective.<br />
:* "changemandatory" Change the mandatory flag of the target objective.<br />
:The combination of this "type" spawnarg and the "value" spawnarg below defines exactly what action is performed on the target objective.<br />
<br />
*;<tt>obj_condition_N_value</tt> (integer) <br />
:The meaning and possible values of this spawnarg depend on the "type" spawnarg above. It is used as "parameter" or "argument" for the above action, e.g. the "changevisibility" action needs to know whether to show or hide the target objective. The possible values are listed below:<br />
:* For type "changestate"<br />
:** 0: set to incomplete<br />
:** 1: set to complete<br />
:** 2: set to invalid<br />
:** 3: set to failed<br />
:* For type "changevisibility"<br />
:** 0: set to invisible<br />
:** 1: set to visible<br />
:* For type "changemandatory"<br />
:** 0: clear mandatory flag<br />
:** 1: set mandatory flag<br />
<br />
= Conclusion =<br />
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.<br />
<br />
= Using Objectives Creatively =<br />
<br />
==A method for using objectives to change AI patrols when alert.==<br />
<br />
This works beautifully. The AI are placed at the seats just like in the card player prefab. Each player have "sitting 1" so they sit down at map start. AI's have no targets.<br />
<br />
Then I have one unseen objective per player:<br />
Objective component is only "AI is alerted", with the single entity card playing AI name. I can set the minimum alert level required for the AI to react. I set that to 3, so if the AI search actively, he won't be playing cards anymore, but goes patrolling instead.<br />
Basically the objective component says: "Alert entity cardgamer1 1 times to a minimum alert level of 3."<br />
<br />
And when that gets satisfied, the objective has completion target gopatrol_start, which is an ordinary trigger_once. This in turn targets a func_static which gives all the cardgamers new targets to their patrol routes. <br />
<br />
This is done as follows: Choose any kind of func_static. Open it in the Stim&Response editor. Add response trigger. Add an effect to this response. Choose "Add Target." Put in the entity box the name of the AI. Put in the target box the name of the path_node where the AI should go.<br />
<br />
When I make one objective for each player, alerting any single one of them will make everyone of them to go for patrol. And once the trigger_once is gone, further alerting of the AI has no effect.<br />
<br />
==A way to replace AI when others are knocked out or killed.==<br />
<br />
Have spare AIs isolated in an inaccessible place either of your map, or room off in the void, targeting a path_waitfortrigger which then carries on their path. Have the AI subject to substitution on a unique team in your map (or identify another way), as well as the spare AIs. An objective is set up like the usual fail if you knock out or kill an AI, but not visible, set to the appropriate team. I found I needed multiple Objective Components, the first no knock/no kill set to an amount of one. Then two and three, etc. Take note of what objective number the objective is and plan on not altering that. Set the failure target to a trigger relay, which targets as many trigger_counts as you have replacement AI. That's it for setting up the objective part.<br />
<br />
Add the aforementioned trigger relay, trigger_counts, and a target_setobjective_state. Setup the target_setobjective_state with "Obj_id0" #, where # is the objective number noted earlier, and set "obj_state" to "0". Add a matching number of atdm:teleport (in target/) as trigger_counts, each teleport targeting one of the stored AI. The first trigger_count is set to 1, and targets the first teleport and AI (to release it from the path_waitfortrigger). The second trigger_count is set to 2, and targets the next teleport and AI, etc. The trigger_relay targets all the trigger_counts and the target_setobjective_state.<br />
<br />
So when the initial AI is knocked out or killed, the objective failure triggers the relay. It in turns increments the counts and resets the objective to work again. The first count activates the teleport and triggers the AI to move off it's path_waitfortrigger on to the next path node. Test and voilà!<br />
<br />
<br />
<br />
[[Category:Editing]]<br />
[[Category:Tutorial]]</div>RJFerret