This tutorial shows you how to set up your map for TOW.
First you need a multiplayer map built so you can place in the TOW objectives. Once you have a map ready and your spawn points in lets begin placing the TOW objective. Your .map and .scr file names must be the same and placed in the “/maps/obj/” folder. The filename must be in this form in order for the game to read them as a TOW map: “MP_filename_TOW.map”. filename can be anything you like, but the MP_ at the beginning and the _TOW at the end are necessary.
You can place up to 5 objectives for your TOW map. For this example we are going to place 5 objectives in the level, one that destroys the axis spawn point, one that destroys the allied spawn point and three more that each side will have to fight over controlling. Objective 1 will be the allied spawn point and Objective 5 will be the axis spawn point. Objectives 2, 3 and 4 are what we are going to set up first. In our “MP_tutorial_TOW.map” we have three light switches that indicated who has control of the objective(Red light = axis, Green light = allies).
In your map file, create a brush that will be your light switch box. Now create another brush surrounding the switch. This will be your trigger. With the brush selected, right click on the grid and select “trigger” -> “use”. Press the “n” key to bring up the entities window and give your trigger a targetname by enter the below values into the Key and Value fields.
Key: setthread
Value: switch1
Diagram 1-1 (Side View, Entity Window and 3D window)
We have to create a TOW objective and link it to our trigger. Right click on the grid and select “func” -> “TOWObjective”. Press “n” to bring up the “Entity” window and enter the following TOW values into the Key and Value fields.
Key: $targetname
Value: switchObj1
Key: AlliesObjNum
Value: 2
Key: AxisObjNum
Value: 4
Key: ControlledBy
Value: 1
Key: ObjectiveNbr
value: 2
Select the trigger that you created while the TOWObjective is still selected and press (ctrl + k) to link the two together. Now build three more Objectives following the same steps and using these values for trigger and TOWObjectives:
Trigger Setthread switch2 TOWobjective $targetname switchObj2 AlliesObjNum 3 AxisObjNum 3 ControlledBy 2 ObjectiveNbr 3 Trigger Setthread switch3 TOWobjective $targetname switchObj3 AlliesObjNum 4 AxisObjNum 2 ControlledBy 0 ObjectiveNbr 4
Diagram 1-2 (Top view)
Now we have to add the last two TOW Objectives, the allied spawn and the axis spawn. First we will create a bomb and then we will set the TOW objective. Right click on the grid and select “script” -> “object”. Enter the following lines into the key and value:
Key Value $explosion_fx fx/fx_flak88_explosion.tik $explosion_sound explode_aagun $targetname axis_bomb $trigger_name allie_bomb_trigger model items//pulse_explosive.tik
This will create your bomb. Around it create a trigger with the following values:
Key Value $targetname allie_bomb_trigger
Now create a TOWObject and give it the following values:
Key Value $targetname Obj_alliespawnpoint AlliesObjNum 1 AxisObjNum 5 ControlledBy 1 ObjectiveNbr 1
Link the TOWobjective to the trigger. Now you have to set up the axis spawn point. Follow the same steps above but change all the targetnames and trigger_names to the opposite team. (allie = axis)
Key Value $explosion_fx fx/fx_flak88_explosion.tik $explosion_sound explode_aagun $targetname allie_bomb $trigger_name axis_bomb_trigger model items//pulse_explosive.tik
This will create your bomb. Around it create a trigger with the following values:
Key Value $targetname axis_bomb_trigger
Now create a TOWObject and give it the following values:
Key Value $targetname Obj_axisspawnpoint AlliesObjNum 5 AxisObjNum 1 ControlledBy 0 ObjectiveNbr 5
Diagram 1-3 (Top View and 3D View)
Your TOW map will now work if you add the script provided to it. If you would like to add lights so you know who has control of the objective, then continue reading.
Lets create the green light, that will be on when the Allies control an objective. First we will create the light bulb and then we will make the corona.
Create a brush and then press “n” to open your “Entity” window. Select from the “Entity” window “addon_static_lamp_lightbulb-caged-green” and rotate it to face the direction you want.
Next we add the corona. Create a brush and press “n” to open your “Entity” window. Select from the “Entity” window “addon_fx_corona_green-bright” and rotate it to face the direction you want. Give it a $targetname obj2_light_allie. The number after obj should correspond with the objective number you are working on(2, 3 or 4). Place the corona on top of your lightbulb and you are all set to go. Top make the red light bulb follow the same directions above but select the “red” objects instead of “green”. Also change the $targetname to obj2_light_axis. Make three sets of red and green lights and place them over their corresponding objective. Now lets move on to the script.
To get an understanding on how the scripting for TOW is read the Tug of War doc. Here we will just go over the things not covered in that doc.
main: level.script="maps/obj/MP_Tutorial_TOW.scr" exec global/tow_dm.scr level.gametype = int( getcvar( g_gametype ) ) //gametype 5 = Tug of War if( level.gametype == 5 ) { setcvar "g_obj_alliedtext1" "Protect Spawn Point" setcvar "g_obj_alliedtext2" "Control Switch 1" setcvar "g_obj_alliedtext3" "Control Switch 2" setcvar "g_obj_alliedtext4" "Control Switch 3" setcvar "g_obj_alliedtext5" "Detonate Axis Spawn Point" setcvar "g_obj_axistext1" "Protect Spawn Point" setcvar "g_obj_axistext2" "Control Switch 1" setcvar "g_obj_axistext3" "Control Switch 2" setcvar "g_obj_axistext4" "Control Switch 3" setcvar "g_obj_axistext5" "Destroy Allied Spawn Point" } else { //Not a TOW game remove the bombs $allie_bomb remove $axis_bomb remove // set scoreboard messages setcvar "g_obj_alliedtext1" "Tow Tutorial" setcvar "g_obj_alliedtext2" "" setcvar "g_obj_alliedtext3" "" setcvar "g_obj_axistext1" "" setcvar "g_obj_axistext2" "" setcvar "g_obj_axistext3" "" } ////////////////////////// level waittill prespawn ////////////////////////// ////////////////////////// level waittill spawn ////////////////////////// level.bRoundStarted = 0 // level.bswitch1SwitchUp = 1 // level.bswitch2SwitchUp = 1 // level.bswitch3SwitchUp = 1 level.axisFire = 1 // set the parameters for this round based match level.dmrespawning = 1 // 1 or 0 level.dmroundlimit = 15 // round time limit in minutes level.clockside = draw // set to axis, allies, kills, or draw level.numObjectives = 5 // Number of objectives needed to win level.numAxisObjectives = 0 // Number of objectives taken by the axis level.numAlliedObjectives = 0 // Number of objectives taken by the allies ////////////////////////// // level waittill roundstart ////////////////////////// //If this is a tug of war game then we init all the TOW stuff if( level.gametype == 5 ) { //init the objectives thread init_objectives thread init_spawner_bombs thread init_switch_lights //Setup the starting team objectives thread set_objectives level.bRoundStarted = 1 } end //---------------------------------------------------------- //Destroy the allied spawner here //---------------------------------------------------------- alliesspawnpoint: iprintln "The Allied Spawn Point has been Destroyed!" //Take over the objective $Obj_alliespawnpoint TakeOver 0 level.numAxisObjectives++ level.numAlliedObjectives-- iprintln "The Allied Team Can No Longer Respawn!" waitthread Check_End_Match end //---------------------------------------------------------- //Destroy the axis spawner here //---------------------------------------------------------- axisspawnpoint: iprintln "The Axis Spawn Point has been Destroyed!" $Obj_axisspawnpoint TakeOver 1 level.numAlliedObjectives++ level.numAxisObjectives-- iprintln "The Axis Team Can No Longer Respawn!" waitthread Check_End_Match end //---------------------------------------------------------- //control switch 1 green/red //---------------------------------------------------------- switch1: if( level.bRoundStarted == 1 ) { if( parm.other.dmteam == axis ) { if( $Obj_switch1.ControlledBy != 0 ) { $Obj_switch1 TakeOver 0 level.numAxisObjectives++ level.numAlliedObjectives-- $obj2_light_allie hide //Turns the allied light off $obj2_light_axis show //Turns the axis light on iprintln "The Axis Control Switch 1!" waitthread Check_End_Match } } else if( parm.other.dmteam == allies ) { if( $Obj_switch1.ControlledBy != 1 ) { $Obj_switch1 TakeOver 1 level.numAlliedObjectives++ level.numAxisObjectives-- $obj2_light_axis hide //Turns the Axis light off $obj2_light_allie show //Turns the allied light on iprintln "The Allies Control Switch 1!" waitthread Check_End_Match } } //Update team current objectives thread set_objectives } end //---------------------------------------------------------- //control switch 2 green/red //---------------------------------------------------------- switch2: if( level.bRoundStarted == 1 ) { if( parm.other.dmteam == axis ) { if( $Obj_switch2.ControlledBy != 0 ) { $Obj_switch2 TakeOver 0 level.numAxisObjectives++ level.numAlliedObjectives-- $obj3_light_allie hide $obj3_light_axis show iprintln "The Axis Control Switch 2!" waitthread Check_End_Match } } else if( parm.other.dmteam == allies ) { if( $Obj_switch2.ControlledBy != 1 ) { $Obj_switch2 TakeOver 1 level.numAlliedObjectives++ level.numAxisObjectives-- $obj3_light_axis hide $obj3_light_allie show iprintln "The Allies Control Switch 2!" waitthread Check_End_Match } } //Update team current objectives thread set_objectives } end //---------------------------------------------------------- //control switch 3 green/red //---------------------------------------------------------- switch3: if( level.bRoundStarted == 1 ) { if( parm.other.dmteam == axis ) { if( $Obj_switch3.ControlledBy != 0 ) { $Obj_switch3 TakeOver 0 level.numAxisObjectives++ level.numAlliedObjectives-- $obj4_light_allie hide $obj4_light_axis show iprintln "The Axis Control Switch 3!" waitthread Check_End_Match } } else if( parm.other.dmteam == allies ) { if( $Obj_switch3.ControlledBy != 1 ) { $Obj_switch3 TakeOver 1 level.numAlliedObjectives++ level.numAxisObjectives-- $obj4_light_axis hide $obj4_light_allie show iprintln "The Allies Control Switch 3!" waitthread Check_End_Match } } //Update team current objectives thread set_objectives } end //---------------------------------------------------------- //Set the teams current objectives //---------------------------------------------------------- set_objectives: //First lets do the allies if( $Obj_switch3.ControlledBy == 0 ) { $Obj_switch3 SetCurrent 1 } else if( $Obj_switch2.ControlledBy == 0 ) { $Obj_switch2 SetCurrent 1 } else if( $Obj_switch1.ControlledBy == 0 ) { $Obj_switch1 SetCurrent 1 } else if( $Obj_axisspawnpoint.ControlledBy == 0 ) { $Obj_axisspawnpoint SetCurrent 1 } //Now the Axis if( $Obj_switch1.ControlledBy == 1 ) { $Obj_switch1 SetCurrent 0 } else if( $Obj_switch2.ControlledBy == 1 ) { $Obj_switch2 SetCurrent 0 } else if( $Obj_switch3.ControlledBy == 1 ) { $Obj_switch3 SetCurrent 0 } else if( $Obj_alliespawnpoint.ControlledBy == 1 ) { $Obj_alliespawnpoint SetCurrent 0 } end //-------------------------------------------------------------- //init the spawner bombs //-------------------------------------------------------------- init_spawner_bombs: //Allied spawner bomb $axis_bomb thread global/tow_dm.scr::bomb_thinker "axis" maps/obj/MP_Tutorial_TOW.scr::alliesspawnpoint $allie_bomb thread global/tow_dm.scr::bomb_thinker "allies" maps/obj/MP_Tutorial_TOW.scr::axisspawnpoint end //----------------------------------------------- // Blow up Allied Spawner //----------------------------------------------- axis_bomb_relay_explode: self waittill trigger thread alliesspawnpoint end //----------------------------------------------- // Blow up Axis Spawner //----------------------------------------------- allie_bomb_relay_explode: self waittill trigger thread axisspawnpoint end //---------------------------------------------------------- //Initialize the switch lights (start all lights off) //---------------------------------------------------------- init_switch_lights: $obj2_light_allie hide $obj2_light_axis hide $obj3_light_allie hide $obj3_light_axis hide $obj4_light_allie hide $obj4_light_axis hide end //----------------------------------------------- // init the objectives //----------------------------------------------- init_objectives: //Allied spawn point if( $Obj_alliespawnpoint.ControlledBy == 0 ) { level.numAxisObjectives++ } else if( $Obj_alliespawnpoint.ControlledBy == 1 ) { level.numAlliedObjectives++ } //Axis spawn point if( $Obj_axisspawnpoint.ControlledBy == 0 ) { level.numAxisObjectives++ } else if( $Obj_axisspawnpoint.ControlledBy == 1 ) { level.numAlliedObjectivse++ } //switch 1 if( $Obj_switch1.ControlledBy == 0 ) { level.numAxisObjectives++ } else if( $Obj_switch1.ControlledBy == 1 ) { level.numAlliedObjectives++ } //switch 2 if( $Obj_switch2.ControlledBy == 0 ) { level.numAxisObjectives++ } else if( $Obj_switch2.ControlledBy == 1 ) { level.numAlliedObjectives++ } //switch 3 if( $Obj_switch3.ControlledBy == 0 ) { level.numAxisObjectives++ } else if( $Obj_switch3.ControlledBy == 1 ) { level.numAlliedObjectives-- } end //----------------------------------------------- // init the objectives //----------------------------------------------- Check_End_Match: //Allies first if( level.numAlliedObjectives == level.numObjectives ) { //ignore the clock level ignoreclock 1 //if there is a bomb ticking stop it. waitthread global/tow_dm.scr::StopBomb //Allies win play the movie teamwin allies } else if( level.numAxisObjectives == level.numObjectives ) { //ignore the clock level ignoreclock 1 //if there is a bomb ticking stop it. waitthread global/tow_dm.scr::StopBomb //Axis win do their movie and end the map teamwin axis } end
How to
Setup a Tug-of-War Map func_TOWObjective: This new entity type allows easy setup of the new Tug-of-War Objectives. This section will document the settings for this new entity type. $targetname
-Use this to give the objective a descriptive name. AlliesObjNum
- Assign which objective number this is for the allies. This is important because it will
affect how the checkboxes work in the new tab score screen. Each objective can be a different
number for each team. For
instance the first objective on the map may be the allied spawner. This should be assigned as the
first allied objective but the last objective for the axis side. AxisObjNum
- Assign which objective number this is for the axis. See AlliesObjNum for more
information. ControlledBy
- This should be assigned to 0, 1, or 2. When the map starts this setting
will determine which objectives are owned by whom, and which are
neutral. 0 = Axis, 1 =
Allies, 2 = Neutral. ObjectiveNbr
- This just needs to be a unique number that does not conflict
with the other objectives.
Typically use 0 – 5. There are also 2 check boxes that can be checked. StartOn, and Respawner. Check the Respawner box if this
objective is to halt the team’s ability to respawn in when killed. For now always check the StartOn
box. Setting Up the Objectives in
MOHRadiant: Here are the steps needed to create a working
Tug-of-War Entity in MOHRadiant:
Scripting Tug-of-War Objectives: Every Tug-of-War map is going to have different
scripting requirements. I’ll
document the basic things that need to be setup and show some
examples. Scoreboard
Text: setcvar "g_obj_alliedtext1" "Allied Objective Text 1" setcvar "g_obj_alliedtext2" "Allied Objective Text 2" setcvar "g_obj_alliedtext3" "Allied Objective Text 3" setcvar "g_obj_alliedtext4" "Allied Objective Text 4" setcvar "g_obj_alliedtext5" "Allied Objective Text
5" setcvar "g_obj_axistext1" "Axis Objective Text 1" setcvar "g_obj_axistext2" "Axis Objective Text 2" setcvar "g_obj_axistext3" "Axis Objective Text 3" setcvar "g_obj_axistext4" "Axis Objective Text 4" setcvar "g_obj_axistext5" "Axis Objective Text 5" There are 5 objective text entries for each team. The example above shows how
to setup this text. Func_TOWObjective Variables and
Functions: Variables: ControlledBy - This is the team number that controls the objective. Example: if( $ObjectiveName.ControlledBy == 0 ) { println “This objective is owned by the axis team.” } Will check to see if the
objective named $ObjectiveName to test if it is controlled by the axis
team and if it is will print out a message indicating as much. Functions: TakeOver – Call this to have a
team take over the objective.
Pass it 0, 1, or 2 which represent the team taking it over. 0 = axis, 1 = allies, 2 =
neutral. Example: $ObjectiveName TakeOver
0 Will cause the objective
named $ObjectiveName to be taken over by the axis team. SetCurrent – Call this to make this the current objective for the passed in team. Pass it 0, 1, or 2 to represent the team that sets this as the priority objective. This will cause the compass for the passed in team to point at this objective. Example: $ObjectiveName SetCurrent
0 This will cause the
objective named $ObjectiveName to be set as the current objective on the
compass for the axis team. Scripting
Objective Take Over: When an opposing team takes an objective there should
be a triggered setthread that gets called in script. This is where the handling should
take place. Here is an
example from Sub Pen: toggle_subpen_doors: if( parm.other.dmteam == axis ) { if( $obj_subpen_doors.ControlledBy != 0 ) { $obj_subpen_doors TakeOver 0 iprintln "The Axis have closed the pen doors!" } } else if( parm.other.dmteam == allies ) { if( $obj_subpen_doors.ControlledBy != 1 ) { $obj_subpen_doors TakeOver 1 iprintln "The Allies have opened the pen doors!" }
} //Update team current objectives
thread set_objectives end This function gets triggered when a team hits the sub
pen doors trigger. Here is a
breakdown of this function:
//---------------------------------------------------------- //Set the teams current objectives //---------------------------------------------------------- set_objectives: //First lets do the allies if( $obj_sub_clamps.ControlledBy == 0 ) { $obj_sub_clamps SetCurrent 1 } else if( $obj_subpen_doors.ControlledBy == 0 ) { $obj_subpen_doors SetCurrent 1 } else if( $obj_steal_sub.ControlledBy == 0 ) { $obj_steal_sub SetCurrent 1
} //Now the Axis if( $obj_subpen_doors.ControlledBy == 1 ) { $obj_subpen_doors SetCurrent 0 } else if( $obj_sub_clamps.ControlledBy == 1 ) { $obj_sub_clamps SetCurrent 0 } else { $obj_allied_spawner SetCurrent 0
} end This function prioritizes which objectives each team
needs to be set to. This
function is called everytime an objective gets taken. This function is not automatically
called but rather called from inside the script. For the allies the priority
objectives are first the sub clamps, followed by the sub pen doors and
finally the sub itself. If
the clamps get taken by the axis then this function will set the clamps as
the current objective for the allies. Respawners This new game type allows a team to destroy an enemy
objective that will stop that team from spawning when killed. This is surprisingly easy. First take over the objective as
normal, then use the name assigned to the spawner and call
disablespawn. Example
below: //---------------------------------------------------------- //Destroy the allied spawner here //---------------------------------------------------------- destroy_allied_spawner: //Make sure we are the allies if( parm.other.dmteam != allies && $obj_allied_spawner.ControlledBy != 0 ) { iprintln "The allied transport has been destroyed!" //Take over the objective $obj_allied_spawner TakeOver 0 $Allied_Spawn_Locations disablespawn } end Win
Conditions The following are handled automatically:
// set the parameters for this round based match level.defusing_team = "axis" level.planting_team = "allies" level.dmrespawning = 1 // 1 or 0 level.dmroundlimit = 5 // round time limit in minutes
level.clockside
= axis
// set to axis, allies, kills, or draw level waittill roundstart The defusing and planting
teams need to be set but it does not matter which team. Just make sure they have different
team values set to them.
dmrespawning should always be set to 1. dmroundlimit is the amount of time
for each round. clockside is
set to determine which team wins if the clock runs out. Sometimes you may want to have a custom victory
condition as in sub pen. Only
3 objectives need to be taken by the allies in sub pen to win the
map. Here is the code that
handles that: //---------------------------------------------------------- //steal the sub //---------------------------------------------------------- steal_sub: //Only the allies can actually take this objective if( dm_other.dmteam != axis && $obj_steal_sub.ControlledBy != 1 ) { if( $obj_sub_clamps.ControlledBy == 1 && $obj_subpen_doors.ControlledBy == 1 ) { $obj_steal_sub TakeOver 1 iprintln "Tha Allies have stolen the U-Boat!" //Allies have won teamwin allies } } //Update team current objectives thread set_objectives end This function is called when a team hits the trigger on the top of the sub. It checks to see if it is the allies, and if so then checks to see if the allies have opened the doors and disengaged the clamps. If all these conditions are met the script calles teamwin and passes the winning team as the parameter. |