Tutorial 03: Basic Capture and Hold
Capture and Hold is a little harder to implement successfully than CTF, but can lead to some very entertaining maps. For this tutorial I'll assume you have read through the CTF tut's and know the basics of Q3F mapping.
As with Advanced CTF we'll start by defining our goals:
1) 2 teams, red and blue.
2) Neither team is allowed recons, red team is not allowed grenadiers, blue team is not allowed soldiers.
3) Agent will be called 'Sneaky' on both teams.
4) Each team has 3 flags to use for capturing commandpoints.
4) 4 command points that each give 2 points per minute to the holding team.
1)
--
Open the entity editor and select worldspawn. Set team name and message as normal:
2)
--
Next we need to define the playerclass limits. We will use the "class"_playerlimit key for the recons and team_"colour"_"class"_playerlimit key for the soldiers/grenadiers.
3)
--
Now we rename Agent to Sneaky (I'm sure theres a reason we want to... :)). We use the "class"_name key for this:
4)
--
We've completed the map setup now - time for the C&H elements. We are going to use the func_commandpoint. This entity is very powerful but has the trade-off of being very complex. In this tutorial we will only scratch the surface of what it can do - believe me it'll be enough to start you off :)
Before even looking at the commandpoint we need to clearly define the game logic. This is essential - you'll tie yourself in knots later on if this isn't precisely defined from the outset.
- there are 3 flags per team. These will be labeled "color"_flag_"number" - eg. red_flag_2
- there are four commandpoints.
- any flag can be used to capture any capture point.
- if you attempt to capture a point you already own the flag will be returned to base.
- capturing with red_flag_x will return red_flag_x to base, but not red_flag_y. The same logic will be used for the blue team.
- flags will return to base immediatly upon being dropped.
- a visual clue will be displayed above the commandpoint to show who owns it - we will use a red/blue flag model.
We'll start with the flags. These should be familiar from CTF, although the keys have to be modified a bit:
{
"classname" "func_goalitem"
"groupname" "red_flag_1"
"allowteams" "red" // note not blue this time
"model" "models/flags/r_flag.md3"
"flags" "showcarry,revealspy"
"inactive_all_message" "The ^1red^* flag returned to base!"
"inactive_flaginfo" "The ^1Red^* flag is at base."
"carried_flaginfo" "%N is carrying the ^1Red^* flag!"
"wait" "0"
"_color" "1.000000 0.392157 0.392157"
"light" "150"
}
We'll obviously need 6 of these with slight modifications - just copy this one and change whats needed.
Next is the fun part - the commandpoints!
The process:
Player carrying flag walks into trigger.
Trigger sets:
- a func_goalinfo that displays the right color flag and hides the wrong color flag.
- the func_commandpoint which then starts pulsing and rewarding 2 points per minute to the team that holds the commandpoint.
The triggers
------------
As there are 6 flags and we want to be able to control them seperatly that means we need 6 triggers. Its ugly but theres no convenient way around it.
{
"classname" "trigger_multiple" // its a trigger
"holding" "red_flag_1" // it needs red flag one
"activetarget" "red_cp1=~active,blue_cp1=~invisible,red_flag_1=~inactive,cp1"
// display the red CP flag, hide the blue CP flag, send red_flag_1 home, give cp1 to the red team.
"wait" "1" // no ones capturing twice in that time....
}
Repeat this for each trigger and stack them neatly over the commandpoint:
The func_goalinfos
------------------
We've already seem func_goalinfo's so this is straight forward:
{
"classname" "func_goalinfo"
"groupname" "red_cp1" // this displays when red have the CP
"initialstate" "invisible" // initially no one has the CP so set both flags to invisible
"model" "models/flags/r_flag.md3" // red flag model
}
{
"classname" "func_goalinfo"
"groupname" "blue_cp1" // this displays when blue have the CP
"initialstate" "invisible" // initially no one has the CP so set both flags to invisible
"model" "models/flags/b_flag.md3" // blue flag model
}
The func_commandpoint itself!
-----------------------------
{
"classname" "func_commandpoint" // its a commandpoint ;)
"groupname" "cp1" // its CP 1
"initialstate" "inactive" // no one owns it to begin with
"active_all_message" "~%N has claimed the\nupper CP for the %T!"
// let everyone know about your glorious capture
"pulseteamscore" "2" // 2 points every...
"wait" "60" // ...seconds
}
There you have it - a fully functional commandpoint. Duplicate all the entities and replace all reference to cp1 with cp2-4 to make the rest of your commandpoints.
- by Steve 'MrChumble' Batham